Welcome | Get started | Dive into Lino | Contribute | Topics | Reference | More
More about the Site
class¶
A Lino application is defined by its Site
class¶
A Django project becomes a Lino site when a Django settings
module has a variable named SITE
holding 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 site maintainer 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 module. 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.
To hook this into Django, imagine the Site
class as a kind of a
"project model". Read What is an application? if you wonder why we chose that name.
In other words, the central and fundamental definition of a Lino
application is formulated by a Site
class object. This Site
class object is not defined in a Django settings module but as part of
the Python package that implements your application.
Remember the Discover some demo projects
For example, the Site
class for Lino Noi is defined in the module
lino_noi.lib.noi.settings
. Please have a look at its source code.
Note that this module defines a Site
class object but does not
instantiate it. You can import this module into a Django settings
module, but you cannot use it directly as a settings module. The following
attempt can only fail:
>>> 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'
Example of a Lino site that uses the Voga application is in the ivo demo project, which has its settings.py
file in the
lino_book.projects.ivo.settings
module of the book repository.
Please have also a look at this source code
You can see that this settings.py
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 module.
Often-used attributes of Site
¶
In your Site
class you define some general description of your
application.
- title¶
The title to appear in the browser window. If this is None, Lino will use
verbose_name
as default value.
- verbose_name¶
The name of this application, to be displayed to end users at different places.
Note the difference between title
and verbose_name
:
title
may be None,verbose_name
not.title
is used by the index.html forlino.modlib.extjs
.title
andverbose_name
are used byadmin_main.html
to generate the fragments "Welcome to the title site" and "We are running verbose_name version x.y" (the latter only ifversion
is set).Site.site_version()
usesverbose_name
(nottitle
)
IOW, the title
is rather for usage by a site maintainer,
while the verbose_name
is rather for usage by the application
developer.
- version¶
An optional version number.
Common practice is to fill this from your SETUP_INFO.
- url¶
The URL of the website that describes this application.
Used e.g. in a
dialog box.Common practice is to fill this from your SETUP_INFO.
See also
Site.site_version()
Site.welcome_text()
Site.using_text()
How Lino builds the INSTALLED_APPS
setting¶
A Lino application is usually meant to install a given set of Django
"apps" (i.e. what's in the INSTALLED_APPS
setting).
An application is a collection of plugins that make up a whole.
To define this collection, the application developer usually overrides the
Site.get_installed_plugins()
method.
Lino calls this method once at startup, and it expects it to yield a list of
strings. Lino then adds some more "system" plugins and stores the resulting
list into your INSTALLED_APPS
setting.
Additional local plugins¶
An optional second positional argument can be specified by the site
maintainer in order to specify additional local plugins. These will go into
the INSTALLED_APPS
setting, together with any other plugins needed by
them.
>>> 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
As an application developer you won't specify this argument, you should
specify your installed plugins by overriding get_installed_plugins
.
- class lino.core.site.Site
- get_installed_plugins(self)¶
Yield the list of plugins to be installed on this site.
Each item must be either a Python module name or a generator to be iterated recursively (again expecting either strings or generators of strings).
Lino will call this method exactly once when the
Site
instantiates. The resulting list of names will then possibly altered by theget_plugin_modifiers()
method before being assigned to Django'sINSTALLED_APPS
setting.Example (taken from chatter):
def get_installed_plugins(self): yield super().get_installed_plugins() yield 'lino.modlib.users' yield 'lino_xl.lib.groups' yield 'lino.modlib.comments' yield 'lino.modlib.notify'
- 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 ('ledger', 'use_pcmn', True) yield ('ledger', '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')