Defines the Site class. See Introducing the Site class and Introduction to plugins and The languages of a Lino site.

Module Attributes

LanguageInfo(django_code, name, index, suffix)






html2text(html, **kwargs)


Simplified copy of django.utils.translation.to_locale, but we need it while the settings module is being loaded, i.e. we cannot yet import django.utils.translation.


LanguageInfo(django_code, name, index, suffix)



Site([settings_globals, local_apps])

The base class for a Lino application.

TestSite(*args, **kwargs)

Used to simplify doctest strings because it inserts default values for the two first arguments that are mandatory but not used in our examples.

class, name, index, suffix)

Bases: tuple



Alias for field number 0


Alias for field number 2


Alias for field number 1


Alias for field number 3

Simplified copy of django.utils.translation.to_locale, but we need it while the settings module is being loaded, i.e. we cannot yet import django.utils.translation. Also we don't need the to_lower argument.

class, local_apps=[], **kwargs)

Bases: object

The base class for a Lino application. This class is designed to be overridden by both application developers and local site administrators. Your SITE setting is expected to contain an instance of a subclass of this.


An AttrDict with one entry for each installed plugin, mapping the app_label of every plugin to the corresponding lino.core.plugin.Plugin instance.

This attribute is automatically filled by Lino and available as dd.plugins already before Django starts to import modules.


Old name for models. Deprecated.


An AttrDict which maps every installed app_label to the corresponding module object.

This is also available as the shortcut rt.models.

See Introduction to plugins


Until 20180926 this was a string like e.g. 'beid' in order to use a custom protocol for reading eid cards. Now it is deprecated. Use lino_xl.lib.beid.Plugin.urlhandler_prefix instead.

upload_to_tpl = 'uploads/%Y/%m'

The value to use as upload_to for the Upload.file field.

auto_fit_column_widths = True

The default value for the auto_fit_column_widths of tables in this application.

site_locale = None

The locale to use for certain localized things on this site.

Used by format_currency().

This should be a string of type '<language>_<country>.<encoding>', and it must have been generated previously. For example:

sudo locale-gen de_BE.utf8
kernel = None

This attribute is available only after startup(). See lino.core.kernel.

readonly = False

Setting this to True turns this site in a readonly site. This means that DATABASES must point to the DATABASES of some other (non-readonly) site, and that initdb will do nothing.

hoster_status_url = ''

This is mentioned in 500.html.

description = None

A multi-line plain text description of up to 250 characters.

Common practice is to fill this from your SETUP_INFO.

It is listed on

device_type = 'desktop'

The default device type used on this server. Should be one of 'desktop', 'tablet' or 'mobile'.

This is used by DeviceTypeMiddleware.

obj2text_template = '*{0}*'

The format template to use when rendering a ForeignKey as plain text.

Note: reSTructuredText uses italic and bold. Changing this can cause lots of trivial failures in test suites. It is also used by lino.modlib.notify when generating the mail body.

postgres_migratable_plugin_prefixes = []

List of prefixes used in initdb and pm prep command for plugins other then the plugins whose name startswith lino. For example: for plugins in welfare app, put 'welfare' in the list, so it the commands will prepare the postgres database properly.

make_missing_dirs = True

Set this to False if you don't want Lino to automatically create missing directories when needed. If this is False, Lino will raise an exception in these cases, asking you to create it yourself.

site_dir = None

The directory where Lino stores local files. See Lino and local files.

project_dir = None

The Django project directory for this site. See Lino and local files.

media_root = None

The root directory at which to build the Javascript and json cache files. See Lino and local files.

project_name = None

A nickname for this project.

This is used only when LINO_CACHE_ROOT is set, and only to set the site_dir. In that case all Lino projects in a given repository must have a unique project name.

If this is None, Lino will find a default value by splitting project_dir and taking the last part (or the second-last if the last part is 'settings'.

django_settings = None

This is a reference to the globals() dictionary of your file (the one you provided when instantiating the Site object).

startup_time = None

The time when this Site has been instantiated, in other words the startup time of this Django process. Don't modify this.

top_level_menus = [('master', 'Master'), ('main', None), ('reports', 'Reports'), ('config', 'Configure'), ('explorer', 'Explorer'), ('site', 'Site')]

The list of top-level menu items. See The application menu and The XL and application menus.

ignore_model_errors = False

Not yet sure whether this is needed. Maybe when generating documentation.

loading_from_dump = False

Whether the process is currently loading data from a Python dump.

When loading from a python dump, application code should not generate certain automatic data because that data is also part of the dump.

This is normally False, but a Python dump created with pm dump2py explicitly calls install_migrations(), which sets this to True.

Application code should not change this setting except for certain special test cases.

migration_class = None

If you maintain a data migrator module for your application, specify its name here.

See Database Migration and/or lino.utils.dpy.install_migrations().

TODO: rename this to migrator_class

partners_app_label = 'contacts'

Temporary setting, see Polymorphism.

trusted_templates = False

Set this to True if you are sure that the users of your site won't try to misuse Jinja's capabilities.

uid = 'myuid'

A universal identifier for this Site. This is needed when synchronizing with CalDAV server. Locally created calendar components in remote calendars will get a UID based on this parameter, using "%s@%s" % (, settings.SITE.kernel).

The default value is 'myuid', and you should certainly override this on a production server that uses remote calendars.

project_model = None

Specifies the application's project model.

A project in this context means what the users consider "the central most important thing that is used to classify most other things". For example in Lino Avanti the "project" is a Client while in Lino Tera it is a therapy.

This can be either None (the default value) or the full name of the model used as "central project model" in this application.

If this is not None, all models that inherit from ProjectRelated will have an additional ForeignKey to this model.

TODO: convert this into a plugin setting of the office plugin?

user_model = None

The database model used for users. This is automatically set to 'users.User' when lino.modlib.users is installed.

Default value is None, meaning that this application has no user management. See also set_user_model()

See also users : user management.

use_linod = False

Whether this site uses the lino.modlib.linod plugin for ASGI interface as well as an asynchronous lino daemon for background tasks and logging. See: lino.modlib.linod.

auth_middleware = None

Override used authorisation middlewares with supplied tuple of middleware class names.

If None, use logic described in Authentication

legacy_data_path = None

Used by custom fixtures that import data from some legacy database.

propvalue_max_length = 200

Used by

show_internal_field_names = True

Whether the internal field names should be visible. ExtUI implements this by prepending them to the tooltip, which means that use_quicktips must also be True. Default is True.

use_solr = False

Whether to use solr backend server for search document indexing.

never_build_site_cache = False

Probably deprecated. Set this to True if you want that Lino never (re)builds the site cache, even when asked. This can be useful on a development server when you are debugging directly on the generated lino*.js. Or for certain unit test cases.

keep_erroneous_cache_files = False

Whether to keep partly generated files in the the site cache.

use_java = True

A site-wide option to disable everything that needs Java. Note that it is up to the plugins which include Java applications to respect this setting. Usage example is lino_xl.lib.beid.

use_silk_icons = False

If this is True, certain Lino plugins use the deprecated silk icons library for representing workflows.

The recommended but not yet fully implemented "modern" style is to use unicode symbols instead of icons.

use_new_unicode_symbols = False

Whether to use "new" unicode symbols (e.g. from the Miscellaneous Symbols and Pictographs block) which are not yet implemented in all fonts.

Currently used by lino_noi.lib.noi.workflows

use_experimental_features = False

Whether to include "experimental features". Deprecated. lino_xl.lib.inspect

site_config_defaults = {}

Default values to be used when creating the site_config.

Usage example:

site_config_defaults = dict(default_build_method='appypdf')
default_build_method = None

The default build method to use when rendering printable documents.

This is the last default value, used only when default_build_method in SiteConfig is empty.

is_demo_site = False

When this is True, then this site runs in "demo" mode. "Demo mode" means:

  • the welcome text for anonymous users says "This demo site has X users, they all have "1234" as password", followed by a list of available usernames.

Default value is True. On a production site you will of course set this to False.

See also demo_fixtures and the_demo_date.

See also quick_startup.

demo_fixtures = []

The list of fixtures to be loaded by the pm prep command. See also Demo fixtures.

django_admin_prefix = None

The prefix to use for Django admin URLs. Leave this unchanged as long as is not solved.

calendar_start_hour = 7

The first hour of a work day.

Limits the choices of a lino.core.fields.CalendarTimeField.

calendar_end_hour = 21

The last hour of a work day.

Limits the choices of a lino.core.fields.CalendarTimeField.

time_format_extjs = 'H:i'

Format (in ExtJS syntax) to use for displaying dates to the user. If you change this setting, you also need to override parse_time().

alt_time_formats_extjs = 'g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A|Hi|g.ia|g.iA|g.i a|g.i A|h.i|g.i|H.i'

Alternative time entry formats accepted by ExtJS time widgets.

ExtJS default is:

"g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A"

Lino's extended default also includes:

"Hi" (1900) and "g.ia|g.iA|g.i a|g.i A|h.i|g.i|H.i" (Using . in replacement of ":")

date_format_extjs = 'd.m.Y'

Format (in ExtJS syntax) to use for displaying dates to the user. If you change this setting, you also need to override parse_date().

alt_date_formats_extjs = 'd/m/Y|Y-m-d'

Alternative date entry formats accepted by ExtJS Date widgets.

uppercase_last_name = False

Whether last name of persons should (by default) be printed with uppercase letters. See lino.test_apps.human

jasmine_root = None

Path to the Jasmine root directory. Only used on a development server if the media directory has no symbolic link to the Jasmine root directory and only if use_jasmine is True.

default_user = None

Username of the user to be used for all incoming requests. Setting this to a nonempty value will disable authentication on this site. The special value 'anonymous' will cause anonymous requests (whose user attribute is the AnonymousUser singleton).

See also get_auth_method().

This setting should be None when user_model is None.

remote_user_header = None

The name of the header (set by the web server) that Lino should consult for finding the user of a request. The default value None means that http authentication is not used. Apache's default value is "REMOTE_USER".

use_eid_applet = False

Whether to include functionality to read Belgian id cards using the official eid-applet. This option is experimental and doesn't yet work. See /blog/2012/1105.

use_esteid = False

Whether to include functionality to read Estonian id cards. This option is experimental and doesn't yet work.

use_awesome_uploader = False

Whether to use AwesomeUploader. This option was experimental and doesn't yet work (and maybe never will).

use_tinymce = True

Replaced by lino.modlib.tinymce.

use_jasmine = False

Whether to use the Jasmine testing library.

use_quicktips = True

Whether to make use of Ext.QuickTips for displaying Help texts and internal field names (if show_internal_field_names).

use_css_tooltips = False

Whether to make use of CSS tooltips when displaying help texts defined in lino.models.HelpText.

use_vinylfox = False

Whether to use VinylFox extensions for HtmlEditor. This feature was experimental and doesn't yet work (and maybe never will). See /blog/2011/0523.

sidebar_width = 0

Used by lino.modlib.plain. Width of the sidebar in 1/12 of total screen width. Meaningful values are 0 (no sidebar), 2 or 3.

preview_limit = 15

Default value for the preview_limit parameter of all tables who don't specify their own one. Default value is 15.

bleach_allowed_tags = ['a', 'b', 'i', 'em', 'ul', 'ol', 'li', 'strong', 'p', 'br', 'span', 'pre', 'def', 'div', 'img', 'table', 'th', 'tr', 'td', 'thead', 'tfoot', 'tbody']

A list of tag names that are to remain in HTML comments if bleaching is active.

See Bleaching.

bleach_allowed_attributes = {'a': ['href', 'title'], 'abbr': ['title'], 'acronym': ['title'], 'p': ['href', 'title', 'align'], 'span': ['class', 'data-index', 'data-denotation-char', 'data-link', 'data-title', 'data-value', 'contenteditable']}

A dictionary of key-values for tagname-attributes_list which are to remain in HTML comments if bleaching is active.

textfield_bleached = True

Default value for RichTextField.textfield_bleached.

See Bleaching.

textfield_format = 'plain'

The default format for text fields. Valid choices are currently 'plain' and 'html'.

Text fields are either Django's models.TextField or lino.core.fields.RichTextField.

You'll probably better leave the global option as 'plain', and specify explicitly the fields you want as html by declaring them:

foo = fields.RichTextField(..., format='html')

We even recommend that you declare your plain text fields also using fields.RichTextField and not models.TextField:

foo = fields.RichTextField()

Because that gives subclasses of your application the possibility to make that specific field html-formatted:

log_each_action_request = False

Whether Lino should log every incoming request for non readonly actions.

This is experimental. Theoretically it is useless to ask Lino for logging every request since the web server does this. OTOH Lino can produce more readable logs.

Note also that there is no warranty that actually each request is being logged. It corrently works only for requests that are being processed by the kernel's run_action methods.

verbose_client_info_message = False

Set this to True if actions should send debug messages to the client. These will be shown in the client's Javascript console only.

help_email = ''

An e-mail address where users can get help. This is included in admin_main.html.

catch_layout_exceptions = True

Lino usually catches any exception during startup (in create_layout_element) to report errors of style "Unknown element "postings.PostingsByController ('postings')" referred in layout <PageDetail on pages.Pages>."

Setting this to False is useful when there's some problem within the framework.

strict_master_check = True

Whether to raise BadRequest when master instance is not correctly specified. This was introducted in March 2023 and is not yet implemented everywhere.

strict_dependencies = True

This should be True unless this site is being used just for autodoc or similar applications.

strict_choicelist_values = True

Whether invalid values in a ChoiceList should raise an exception.

This should be True except for exceptional situations. Setting this to True won't allow you to store invalid choicelist values in the database, but at least Lino will not raise an exception as soon as it reads an invalid value from existing data. This can happen e.g. after a code upgrade without data migration. In such a situation you may want to run in order to migrate the data.

csv_params = {}

Site-wide default parameters for CSV generation. This must be a dictionary that will be used as keyword parameters to Python csv.writer()

Possible keys include:

logger_filename = 'lino.log'

The name of Lino's main log file, created in setup_logging().

See also About logging.

auto_configure_logger_names = 'atelier django lino radicale'

A string with a space-separated list of logger names to be automatically configured. See setup_logging().

decimal_separator = ','

Set this to either '.' or ',' to define wether to use comma or dot as decimal point separator when entering a DecimalField.

decimal_group_separator = '\xa0'

Decimal group separator for decfmt().

time_format_strftime = '%H:%M'

Format (in strftime syntax) to use for displaying dates to the user. If you change this setting, you also need to override parse_time().

date_format_strftime = '%d.%m.%Y'

Format (in strftime syntax) to use for displaying dates to the user. If you change this setting, you also need to override parse_date().

date_format_regex = '/^[0123]?\\d\\.[01]?\\d\\.-?\\d+$/'

Format (in Javascript regex syntax) to use for displaying dates to the user. If you change this setting, you also need to override parse_date().

datetime_format_strftime = '%Y-%m-%dT%H:%M:%S'

Format (in strftime syntax) to use for formatting timestamps in AJAX responses. If you change this setting, you also need to override parse_datetime().

datetime_format_extjs = 'Y-m-d\\TH:i:s'

Format (in ExtJS syntax) to use for formatting timestamps in AJAX calls. If you change this setting, you also need to override parse_datetime().

quick_startup = False

Whether to skip startup operations that are useful during development but not one production site.

master_site = None

Another Site instance to be used as the master for this site. DATABASES and SECRET_KEY and the site_dir

override_modlib_models = None

A dictionary which maps model class names to the plugin which overrides them.

This is automatically filled at startup. You can inspect it, but you should not modify it. Needed for is_abstract_model().

The challenge is that we want to know exactly where every model's concrete class will be defined before actually starting to import the modules. That's why we need extends_models.

This can be tricky, see e.g. 20160205.

installed_plugin_modules = None

Used internally by is_abstract_model(). Don't modify.

A set of the full Python paths of all imported plugin modules. Not just the plugin modules themselves but also those they inherit from.

the_demo_date = None

A hard-coded constant date to be used as reference by today() and demo_date().

Many demo projects have this set because certain tests rely on a constant reference date.

This is either None or a object, If it is an int or a str, Lino will convert it during startup to a using rstgen.utils.i2d().

migrations_package = None

The full Python name of the local package that holds Django migrations for all plugins of this site.

You might manually specify a name, but the recommended way is to create a migrations directory. See Django migrations on a Lino site.

confdirs = None

Pointer to the config directories registry. See Introduction to config directories and lino.utils.config. Lino sets this attribute during site startup.

init_before_local(settings_globals, local_apps)

If your project_dir contains no, but does contain a fixtures subdir, then Lino automatically adds this as a local fixtures directory to Django's FIXTURE_DIRS.

But only once: if your application defines its own local fixtures directory, then this directory "overrides" those of parent applications. E.g. does not want to load the application-specific fixtures of


Modifies the DEFAULT_LOGGING setting.

This is called before any plugins are loaded because all this must happen before Django passes the setting to the logging.config.dictConfig function.

It is designed to work with the LOGGING and LOGGER_CONFIG settings unmodified.

It does the following modifications:

  • Define a default logger configuration which is initially the same as the one used by Django:

        'handlers': ['console', 'mail_admins'],
        'level': 'INFO',
  • If the site_dir has a subdirectory named log, and if logger_filename is not empty, add a handler named file and a formatter named verbose, and add that handler to the default logger configuration.

  • Apply the default logger configuration to every logger name in auto_configure_logger_names.

  • (does no longer) configure the console handler to write to stdout instead of Django's default stderr (as explained here) because that breaks testing.

It does nothing at all if auto_configure_logger_names is set to None or empty.

See also About logging.


Return a dict to be set as the DATABASE setting.

The default behaviour uses SQLite (1) on a file named default.db in the site_dir if that attribute is specified, and (2) in :memory: when site_dir is None.

And alternative might be for example:

def get_database_settings(self):
    return {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'test_' + self.project_name,
            'USER': 'django',
            'PASSWORD': os.environ['MYSQL_PASSWORD'],
            'HOST': 'localhost',
            'PORT': 3306,
            'OPTIONS': {
               "init_command": "SET storage_engine=MyISAM",



Load all plugins and build the INSTALLED_APPS setting for Django.

This includes a call to get_apps_modifiers() and get_installed_apps().


Collect requirements from plugins. Add some more requirements which depend on options in the local file.


Collect modules.

Deprecated. We plan to remove the design_name attribute.

Note the situation when a module exists but causes itself an ImportError because it contains a programming mistake. In that case we want the traceback to occur, not to silently do as if no module existed.


Deprecated. Use get_plugin_configs() instead.

This method is called exactly once during site startup, after load_plugins() but before populating the models registry.

See Introduction to plugins.


When LINO_CACHE_ROOT is set, Lino adds a stamp file called lino_cache.txt to every project's cache directory in order to avoid duplicate use of same cache directory.


A small text file with one line of text which contains the path of the project which uses this cache directory.


This can be called during the on_init of plugins which provide user management (the only plugin which does this is currently lino.modlib.users).


Returns the authentication method used on this site. This is one of None, 'remote' or 'session'.

It depends on the values in user_model, default_user and remote_user_header.

It influences the results of get_middleware_classes() and get_installed_apps(), and the content of AUTHENTICATION_BACKENDS.


Return True if the app is known, but has been disabled using get_apps_modifiers().


This may be called from within a


Same as update_settings(), but raises an exception if a setting already exists.

TODO: Currently this exception is deactivated. Because it doesn't work as expected. For some reason (maybe because settings is being imported twice on a devserver) it raises a false exception when override_defaults() tries to use it on MIDDLEWARE_CLASSES...


Start up this Site.

You probably don't want to override this method as it might be called several times. e.g. under mod_wsgi: another thread has started and not yet finished startup().

If you want to run custom code on site startup, override do_site_startup().


This method is called exactly once during site startup, just between the pre_startup and the post_startup signals. A hook for subclasses.

TODO: rename this to on_startup?

property logger

This must not be used before Django has done its logging config. For example don't use it in a module.


Yield all (existing) directories named subdir_name of this Site's project directory and its inherited project directories.


Make missing directories if they don't exist and if make_missing_dirs is True.

is_abstract_model(module_name, model_name)

Return True if the named model is declared as being extended by lino.core.plugin.Plugin.extends_models.

Typical usage:

class MyModel(dd.Model):
     class Meta:
         abstract = dd.is_abstract_model(__name__, 'MyModel')

See Plugin inheritance.


Deprecated. This feature was a bit too automagic and caused bugs to pass silently. See e.g. 2013-10-25.


Return True if INSTALLED_APPS contains an item which ends with the specified app_label.

setup_model_spec(obj, name)

If the value of the named attribute of obj is a string, replace it by the model specified by that string.

Example usage:

# library code:
class ThingBase(object):
    the_model = None

    def __init__(self):
        settings.SITE.setup_model_spec(self, 'the_model')

# user code:
class MyThing(ThingBase):
    the_model = "contacts.Partner"
on_each_app(methname, *args)

Call the named method on the module of each installed app.

Note that this mechanism is deprecated. It is still used (on names like setup_workflows and setup_site) for historical reasons but will disappear one day.

for_each_app(func, *args, **kw)

Call the given function on each installed plugin. Successor of on_each_app().

This also loops over plugins that don't have a models module and the base plugins of plugins which extend some plugin.

demo_date(*args, **kwargs)

Deprecated. Should be replaced by today(). Compute a date using lino.utils.date_offset() based on the process startup time (or the_demo_date if this is set).

Used in Python fixtures and unit tests.

today(*args, **kwargs)

Almost the same as

One difference is that the system's today is replaced by the_demo_date if that attribute is set.

Another difference is that arguments can be passed to add some offset. See atelier.utils.date_offset().

This feature is being used in many test cases where e.g. the age of people would otherwise change.


Return the text to display in a console window when this application starts.


Return the text to display in a console window when Lino starts.


Return the name of the application running on this site, including the version (if a version is specified).

Used in footnote or header of certain printed documents.


See lino.utils.dpy.install_migrations().


Convert a string formatted using date_format_strftime or date_format_extjs into a (y,m,d) tuple (not a instance). See /blog/2010/1130.


Convert a string into a datetime.time instance using regex. only supports hours and min, not seconds.


Convert a string formatted using datetime_format_strftime or datetime_format_extjs into a datetime.datetime instance.


Call lino_resolve_type after startup.


Hook for subclasses to add or modify actions.


Yield a list of (name, version, url) tuples describing the third-party software used on this site.

This function is used by using_text() and welcome_html().


This function is called when a Site object gets instantiated, i.e. while Django is still loading the settings. It analyzes the languages attribute and converts it to a tuple of LanguageInfo objects.


Reduce Django's LANGUAGES to my languages. Note that are not yet translated, we take these from django.conf.global_settings.


Returns a string with a diagnostic report about this site. diag is a command-line shortcut to this.


Return whether the specified Partner instance obj is to be considered as imported from some legacy database.


Used in footnote or header of certain printed documents.

The convention is to call it as follows from an appy.pod template (use the html function, not xhtml)

do text
from html(settings.SITE.site_header())

Note that this is expected to return a unicode string possibly containing valid HTML (not XHTML) tags for formatting.


Expected to yield a sequence of items to be rendered on the dashboard (admin_main.html).

The default implementation calls get_dashboard_items on every installed plugin and yields all items.

The items will be rendered in that order, except if lino.modlib.dashboard is installed to enable per-user customized dashboard.

property site_config

This property holds a cached version of the one and only SiteConfig row that holds site-wide database-stored and web-editable Site configuration parameters.

If no instance exists (which happens in a virgin database), we create it using default values from site_config_defaults.

This is always None when lino.modlib.system is not installed.


Clear the cached SiteConfig instance.

This is needed e.g. when the test runner has created a new test database.

The list of quick links.

This is lazily created when first accessed.

Yield the quick links that are visible for the given user type.

Return or yield a sequence of quick link descriptors to be added to the list of quick links.

Override this to define application-specific quick links.

Customize the list of quick links. Override this to define application-specific quick links.

Default implementation calls get_quicklinks and setup_quicklinks for each installed plugin.

The quicklinks yielded by get_quicklinks will be added before calling setup_quicklinks.


Return this site's main menu for the given UserType. Must be a lino.core.menus.Toolbar instance. Applications usually should not need to override this.

setup_menu(user_type, main)

Set up the application's menu structure.

See The application menu and The XL and application menus.


Yields the strings to be stored in the MIDDLEWARE_CLASSES setting.

In case you don't want to use this method for defining MIDDLEWARE_CLASSES, you can simply set MIDDLEWARE_CLASSES in your after the Site has been instantiated.

Django and standard HTTP authentication

get_main_html(ar, **context)

Return a chunk of html to be displayed in the main area of the admin index. This is being called only if get_main_action() returns None. The default implementation renders the admin_main.html template.

build_site_cache(force=False, later=False)

Populate the site cache, especially the lino*.js files, one per user user type and language.

  • force: rebuild the files even if they are up to date

  • later: don't rebuild now, just touch the so that they get rebuild next time.


Yields a list of "welcome messages" (see lino.core.actors.Actor.get_welcome_messages()) of all actors. This is being called from admin_main.html.

add_welcome_handler(func, actor=None, msg=None)

Add the given callable as a "welcome handler". Lino will call every welcome handler for every incoming request, passing them a BaseRequest instance representing this request as positional argument. The callable is expected to yield a series of messages (usually either 0 or 1). Each message must be either a string or a E.span element.

copyright_name = None

Name of copyright holder of the site's content.

server_url = ''

The "official" URL used by "normal" users when accessing this Lino site.

This is used by templates such as summary.eml (used by lino.modlib.notify to send notification emails)

Django has a HttpRequest.build_absolute_uri() method, but e.g. notification emails are sent via linod where no HttpRequest exists. That's why we need to manually set server_url.

site_prefix = '/'

The string to prefix to every URL of the Lino web interface.

This must start and end with a *slash. Default value is '/'.

This must be set if your project is not being served at the "root" URL of your server.

If this is different from the default value, Lino also sets SESSION_COOKIE_PATH.

When this Site is running under something else than a development server, this setting must correspond to your web server's configuration. For example if you have:

WSGIScriptAlias /foo /home/luc/mypy/lino_sites/foo/

Then your should specify:

site_prefix = '/foo/'

See also Mass hosting Lino applications.

send_email(subject, sender, body, recipients)

Send an email message with the specified arguments (the same signature as django.core.mail.EmailMessage.

recipients is an iterator over a list of strings with email addresses. Any address containing '' will be removed. Does nothing if the resulting list of recipients is empty.

If body starts with "<", then it is considered to be HTML.


Return a HTML version of the "This is APPLICATION version VERSION using ..." text. to be displayed in the About dialog, in the plain html footer, and maybe at other places.

login(username=None, **kw)

Open a session as the user with the given username.

For usage from a shell or a tested document. Does not require any password because when somebody has command-line access we trust that she has already authenticated.

It returns a BaseRequest object.


Returns a string like "Eupen, den 26. August 2013".

decfmt(v, places=2, **kw)

Format a Decimal value using lino.utils.moneyfmt(), but applying the site settings lino.Lino.decimal_group_separator and lino.Lino.decimal_separator.

format_currency(*args, **kwargs)

Return the given number as a string formatted according to the site_locale setting on this site.

All arguments are forwarded to locale.locale().

lookup_filter(fieldname, value, **kw)

Return a models.Q to be used if you want to search for a given string in any of the languages for the given babel field.

get_plugin_setting(plugin_name, option_name, *default)

Return the given plugin setting if the plugin is installed, otherwise the provided default value.

class*args, **kwargs)

Bases: Site

Used to simplify doctest strings because it inserts default values for the two first arguments that are mandatory but not used in our examples.


>> from import Site
>> Site(globals(), ...)

>> from import TestSite as Site >> Site(...)