Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
More about the Site
class¶
In Create your first Lino site you shortly met the Site
class in your
Django settings file. Now let me tell you more about this class.
Usage¶
In your Django settings file you import, extend and instantiate a
Site
class:
from ... import * # import a Site class from somewhere
class Site(Site): # extend your class definition
...
SITE = Site(globals(), ...) # instantiate it and store it as SITE
The last line instantiates your Site
class and installs default values
for all required Django settings (e.g. DATABASES
and
LOGGING
) into your global namespace (which you pass to it as
globals()).
A Lino application is defined by its Site
class¶
A Django project becomes a Lino site when a Django settings file
has a variable named SITE
, which holds an instance of a subclass of
the lino.core.site.Site
class.
The lino.core.site.Site
class is the ancestor of all Lino applications.
It is designed to be subclassed by the application developer, then
imported into a local settings.py
, where a server administrator may
possibly subclass it another time.
Subclassing the Site
class doesn’t yet make a Lino site: a Lino site
starts to exist when such a Site
class gets instantiated in a
Django settings file. Lino does quite a few things during this
instantiation.
This concept brings an additional level of encapsulation to Django. Django
settings usually contain simple values (strings, integers, or lists or
dictionaries thereof). But Lino’s SITE
setting holds a Python
object, with methods that can be called by application code at runtime.
If you had previous experience with Django, imagine the Site
class as
a kind of “project model” and read What is an application?.
In other words, the central and fundamental definition of a Lino
application is formulated by a Site
class object. This Site
class object usually defined as part of the Python package that implements your
application.
Remember Discover some demo projects.
For example, the Site
class for the Lino Voga application is defined
in the module lino_voga.lib.voga.settings
. Please have a look at its
source code:
https://gitlab.com/lino-framework/voga/-/blob/master/lino_voga/lib/voga/settings.py
Note that this module defines a Site
class object but does not
instantiate it. You cannot use this module as a Django settings
file. The following attempt fails:
>>> from lino import startup
>>> startup('lino_voga.lib.voga.settings')
>>> from lino.api.rt import *
Traceback (most recent call last):
...
AttributeError: 'Settings' object has no attribute 'SITE'
You use such an application settings module by importing it into a Django settings file. An example of a Lino site that does this is the voga3 demo project. Please have a look at the source code of this file as well: https://gitlab.com/lino-framework/book/-/blob/master/lino_book/projects/voga3/settings.py
You can see that this file
imports everything from
lino_voga.lib.voga.settings
,subclasses the site by saying
class Site(Site):
instantiates the site by saying
SITE = Site(globals())
That’s why you can use it as a Django settings file.
Often-used attributes of Site
¶
How Lino builds the INSTALLED_APPS setting¶
In a Lino application you set your INSTALLED_APPS
indirectly by
overriding the get_installed_plugins
method. Alternatively, in very small projects (such as the projects in
Tutorials) you might prefer to specify them as positional
arguments to the Site
constructor.
Example (taken from chatter):
def get_installed_plugins(self):
yield 'lino.modlib.users'
yield 'lino_xl.lib.groups'
yield 'lino.modlib.comments'
yield 'lino.modlib.notify'
yield super().get_installed_plugins()
Lino calls this method exactly once at site startup, and it expects it to yield a list of strings. More precisely, each yield item must be either a Python module name or a generator to be iterated recursively (again expecting either strings or generators of strings).
The resulting list of names will then possibly altered by the
get_plugin_modifiers()
method.
Lino then stores the resulting list into the INSTALLED_APPS
setting.
When you override the Site.get_installed_plugins()
method, don’t forget to
call the super()
method. This is important because the core
get_installed_plugins
method yields a
series of plugins: lino.modlib.about
, lino.modlib.ipdict
, the
web_front_ends
, and maybe even more
(as an application developer you don’t want to worry about these technical
details).
You should call the super()
method at the end (not at the beginning) of
your own method because the ordering of installed plugins has an influence on
the application menu and you probably want the plugins returned by the
super method to come at the end of the menu because they are rather “technical”
compared to your rather “application-specific” menu items.
Additional local plugins¶
An optional second positional argument can be specified by the server
administrator in order to specify additional local plugins. These will go
into the INSTALLED_APPS
setting, together with any other plugins
needed by them. As an application developer you won’t specify this
argument, you should specify your installed plugins by overriding
get_installed_plugins
.
>>> from lino_book.projects.min1.settings import Site
>>> pseudoglobals = {}
>>> Site(pseudoglobals, "lino_xl.lib.events")
<lino_book.projects.min1.settings.Site object at ...>
>>> print('\n'.join(pseudoglobals['INSTALLED_APPS']))
...
lino
lino.modlib.about
lino.modlib.jinja
lino.modlib.bootstrap3
lino.modlib.extjs
lino.modlib.printing
lino.modlib.system
lino.modlib.users
lino.modlib.office
lino_xl.lib.xl
lino_xl.lib.countries
lino_xl.lib.contacts
django.contrib.staticfiles
lino_xl.lib.events
django.contrib.sessions
- class lino.core.site.Site
- get_installed_plugins(self)¶
Yield the list of plugins to be installed on this site.
- get_plugin_configs(self)¶
Return a series of plugin configuration settings.
This is called before plugins are loaded.
rt.plugins
is not yet populated.The method must return an iterator that yields tuples with three items each: The name of the plugin, the name of the setting and the value to set.
Example:
def get_plugin_configs(self): yield super().get_plugin_configs() yield ('countries', 'hide_region', True) yield ('countries', 'country_code', 'BE') yield ('vat', 'declaration_plugin', 'lino_xl.lib.bevats') yield ('accounting', 'use_pcmn', True) yield ('accounting', 'start_year', 2014)
- get_plugin_modifiers(self, **kwargs)¶
Override or hide individual plugins of the application.
Deprecated because this approach increases complexity instead of simplifying things.
For example, if your site inherits from
lino.projects.min2
:def get_plugin_modifiers(self, **kw): kw = super().get_plugin_modifiers(**kw) kw.update(sales=None) kw.update(courses='my.modlib.courses') return kw
The default implementation returns an empty dict.
This method adds an additional level of customization because it lets you remove or replace individual plugins from
INSTALLED_APPS
without rewriting your ownget_installed_plugins()
.This will be called during Site instantiation and is expected to return a dict of app_label to full_python_path mappings which you want to override in the list of plugins returned by
get_installed_plugins()
.Mapping an app_label to None will remove that plugin from
INSTALLED_APPS
.It is theoretically possible but not recommended to replace an existing
app_label
by a plugin with a differentapp_label
. For example, the following might work but is not recommended:kw.update(courses='my.modlib.myactivities')