Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More

printing : Basic printing functionality

As a application developer you can use several approaches for adding printing functionality to your application:

Lino has the following plugins related to printing:

build method

The technology to use for building a printable document.

We have build methods, print actions and mixins for printable database objects.

The build method specifies both the required template format (usually each build method has its specific template language) and the format of the produced output file.

>>> rt.show(printing.BuildMethods)  
============ ============ ======================
 value        name         text
------------ ------------ ----------------------
 appydoc      appydoc      AppyDocBuildMethod
 appyodt      appyodt      AppyOdtBuildMethod
 appypdf      appypdf      AppyPdfBuildMethod
 appyrtf      appyrtf      AppyRtfBuildMethod
 latex        latex        LatexBuildMethod
 pub          pub          PublisherBuildMethod
 rtf          rtf          RtfBuildMethod
 weasy2html   weasy2html   WeasyHtmlBuildMethod
 weasy2pdf    weasy2pdf    WeasyPdfBuildMethod
 xml          xml          XmlBuildMethod
============ ============ ======================

The print action is either defined manually on the model, or dynamically at startup when excerpts is installed.

The mixins defined in lino.modlib.printing (Printable, TypedPrintable, CachedPrintable TypedPrintable) are needed to make your database objects printable. Note that when your application uses lino_xl.lib.excerpts, you don’t need to worry about their difference, you just inherit from Printable.

The template context

When a printable document is generated, Lino parses a template using Jinja. Here is a list of template context names available when parsing a template.

See also lino.core.requests.BaseRequest.get_printable_context()

class lino.modlib.printing.PrintableContext

The printable object instance


shortcut for settings.SITE


“amount to string” using decfmt()




Shortcut to babelitem.




HTML tag generator, see etgen.html


the builtin Python unicode() function


the builtin Python len() function


The Django settings.py module


shortcut for settings.SITE


a Lino lino.core.requests.BaseRequest instance around the calling Django request


the Django HttpRequest instance (available in admin_main.html, rendered by get_main_html, which calls lino.modlib.jinja.render_from_ar())

Date formatting functions

Lino includes shortcuts to python-babel’s date formatting functions:


“format date short”, see Date formatting functions


“format date medium”, see Date formatting functions


“format date long”, see Date formatting functions


“format date full”, see Date formatting functions


deprecated for fds


deprecated for fdl


>>> d = datetime.date(2013,8,26)
>>> print(fds(d)) # short
>>> print(fdm(d)) # medium
26 Aug 2013
>>> print(fdl(d)) # long
26 August 2013
>>> print(fdf(d)) # full
Monday 26 August 2013

Printing a normal pdf table

>>> settings.SITE.appy_params.update(raiseOnError=True)
>>> url = ''
>>> test_client.force_login(rt.login('robin').user)
>>> res = test_client.get(url, REMOTE_USER='robin')
>>> print(res.status_code)
>>> result = json.loads(res.content)
>>> print(result['success'])
>>> print(result['open_url'])

Printing address labels

>>> settings.SITE.appy_params.update(raiseOnError=True)
>>> url = ''
>>> test_client.force_login(rt.login('robin').user)
>>> res = test_client.get(url, REMOTE_USER='robin')
>>> print(res.status_code)
>>> result = json.loads(res.content)
>>> print(result['success'])
>>> print(result['open_url'])

Model mixins

class lino.modlib.printing.Printable

Mixin for models for which Lino can generate a printable document.

Extended by CachedPrintable and TypedPrintable. Other methods for printing a printable is to add an excerpt type or to provide your own subclass of DirectPrintAction.


Return a Django language code to be activated when an instance of this is being printed. The default implementation returns the Site’s default language.

Returning None is equivalent to the Site’s default language.

get_print_templates(self, bm, action)

Return a list of file names of templates for the specified build method. Returning an empty list means that this item is not printable. For subclasses of SimpleBuildMethod the returned list may not contain more than 1 element.

The default method calls BuildMethod.get_default_template() and returns this as a list with one item.

get_printable_context(self, ar=None, **kw)

Adds a series of names to the context used when rendering printable documents.

lino_xl.lib.notes.models.Note extends this.


Return the name of the body template to use when rendering this object in a printable excerpt (lino_xl.lib.excerpts). An empty string means that Lino should use the default value defined on the ExcerptType.


Return an iterable of database objects for which Lino should generate a printable excerpt.

This is being called by lino_xl.lib.excerpts.fixtures.demo2.


Return the build method to use when printing this object.

This is expected to rather raise an exception than return None.

get_excerpt_options(self, ar, **kw)

Set additional fields of newly created excerpts from this. Called from lino_xl.lib.excerpts.models.ExcerptType.get_or_create_excerpt.

before_printable_build(self, bm)

This is called by print actions before the printable is being generated. Application code may e.g. raise a Warning exception in order to refuse the print action. The warning message can be a translatable string.

class lino.modlib.printing.CachedPrintable

Mixin for Models that generate a unique external file at a determined place when being printed.

Adds a “Print” button, a “Clear cache” button and a build_time field.

The “Print” button of a CachedPrintable transparently handles the case when multiple rows are selected. If multiple rows are selected (which is possible only when cell_edit is True), then it will automatically:

  • build the cached printable for those objects who don’t yet have one

  • generate a single temporary pdf file which is a merge of these individual cached printable docs

Database fields:


Timestamp of the built target file. Contains None if no build hasn’t been called yet.



The action used to print this object. This is an instance of DirectPrintAction or CachedPrintAction by default. And if lino_xl.lib.excerpts is installed, then set_excerpts_actions possibly replaces do_print by a lino_xl.lib.excerpts.CreateExcerpt instance.

class lino.modlib.printing.TypedPrintable

A CachedPrintable that uses a “Type” for deciding which template to use on a given instance.

A TypedPrintable model must define itself a field type which is a ForeignKey to a Model that implements PrintableType.

Alternatively you can override get_printable_type() if you want to name the field differently. An example of this is ml.sales.SalesDocument.imode.

class lino.modlib.printing.PrintableType

Base class for models that specify the TypedPrintable.type.


Default value for templates_group is the model’s full name.


A pointer to an item of BuildMethods.


The name of the file to be used as template.

If this field is empty, Lino will use the filename returned by lino.modlib.printing.Plugin.get_default_template().

The list of choices for this field depend on the build_method. Ending must correspond to the build_method.


class lino.modlib.printing.CachedPrintableChecker

Checks for missing cache files on all objects which inherit CachedPrintable.

When a CachedPrintable has a non-empty build_time field, this means that the target file has been built. That file might no longer exists for several reasons:

  • it has really beeen removed from the cache directory.

  • we are working in a copy of the database, using a different cache directory.

  • the computed name of the file has changed due to a change in configuration or code.

An easy quick “fix” would be to set build_time to None, but this is not automatic because in cases of real data loss a system admin might want to have at least that timestamp in order to search for the lost file.


Yield a series of five dates, starting at the given date which should be a Monday.

Utility function available in the default printable context.

TODO: move this to lino_xl.lib.cal and let plugins add items to the printable context.

>>> from lino.modlib.printing.models import weekdays
>>> list(weekdays(i2d(20190603)))
[datetime.date(2019, 6, 3), datetime.date(2019, 6, 4), datetime.date(2019, 6, 5), datetime.date(2019, 6, 6), datetime.date(2019, 6, 7)]

Build methods

class lino.modlib.printing.BuildMethods

The choicelist of build methods offered on this site.

class lino.modlib.printing.BuildMethod

Base class for all build methods. A build method encapsulates the process of generating a “printable document” that inserts data from the database into a template, using a given combination of a template parser and post-processor.


Whether this build method results is an editable file. For example, .odt files are considered editable while .pdf files aren’t.

In that case the target will be in a webdav folder and the print action will respond open_davlink_url instead of the usual open_url, which extjs3 ui will implement by calling Lino.davlink_open() instead of the usual window.open().

When lino.modlib.davlink is not installed, this setting still influences the target path of resulting files, but the clients will not automatically recognize them as webdav-editable URLs.

class lino.modlib.printing.TemplatedBuildMethod

A BuildMethod which uses a template.

class lino.modlib.printing.DjangoBuildMethod

A TemplatedBuildMethod which uses Django’s templating engine.

class lino.modlib.printing.XmlBuildMethod

Generates .xml files from .xml templates.

class lino.modlib.printing.SimpleBuildMethod

Base for build methods which use Lino’s templating system (find_config_file).

TODO: check whether this extension to Django’s templating system is still needed.

class lino.modlib.printing.CustomBuildMethod

For example CourseToXls.

Simple example:

from lino.modlib.printing.utils import CustomBuildMethod

class HelloWorld(CustomBuildMethod):
    target_ext = '.txt'
    name = 'hello'
    label = _("Hello")

    def custom_build(self, ar, obj, target):
        # this is your job
        file(target).write("Hello, world!")

class MyModel(Model):
    say_hello = HelloWorld.create_action()
custom_build(self, ar, obj, target)

Concrete subclasses must implement this.

This is supposed to create a file named target.

class lino.modlib.printing.LatexBuildMethod

Not actively used. Generates .pdf files from .tex templates.

class lino.modlib.printing.RtfBuildMethod

Not actively used. Generates .rtf files from .rtf templates.

class lino.modlib.printing.PisaBuildMethod

Deprecated. Generates .pdf files from .html templates. Requires pisa. Usage example see lino_book.projects.pisa.