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

publisher : render database content as styled html

The lino.modlib.publisher plugin adds the notion of content pages used to produce the pages of websites or books.

It doesn’t add any database model, but a choicelist, a model mixin and an action. It also adds a printing build method (lino.modlib.printing.BuildMethods).

This page contains code snippets (lines starting with >>>), which are being tested during our development workflow. The following snippet initializes the demo project used throughout this page.

>>> from lino_book.projects.noi2.startup import *
>>> from django.db.models import Q

Content pages

content page

The basic building unit of a website or book, consisting of a title and a body.

Named pages

Named pages are pages with a user-given name in their Page name field. If this field is not empty, the page will have this name instead of its primary key in the url.

lino.core.actors.Actor.get_row_by_pk() uses a new class attribute unique_keys, which defaults to ['id'], and on lino.modlib.publisher.Pages it is overridden to ['id', 'ref']. And a method lino.modlib.publisher.Publishable.get_publisher_pk(), which for Pages returns self.ref or str(self.pk).

Root pages

>>> rt.show('publisher.RootPages', column_names="id title", display_mode="grid")
==== ===============
 ID   Title
---- ---------------
 1    Home
 28   Songbook
 30   Laundry
 81   Flying Circus
==== ===============

Note that the “New songbook” page is not listed. That’s because this page is in draft state:

>>> publisher.Page.objects.get(title="New songbook").publishing_state
<publisher.PublishingStates.draft:10>

You can see it only when you are authenticated as an OfficeStaff:

>>> ar = rt.login('robin')
>>> ar.show('publisher.RootPages', column_names="id title", display_mode="grid")
==== ===============
 ID   Title
---- ---------------
 1    Home
 28   Songbook
 29   New songbook
 30   Laundry
 81   Flying Circus
==== ===============
>>> home = publisher.Page.objects.get(pk=1)
>>> rt.show('publisher.TranslationsByPage', master_instance=home)
`⏏ <…>`__ | (bn) `হোম <…>`__, (de) `Startseite <…>`__
>>> rt.show('publisher.TranslationsByPage', master_instance=home, nosummary=True)
============ ========== ====
 Title        Language   ID
------------ ---------- ----
 হোম          bn         2
 Startseite   de         3
============ ========== ====

When I am on the English home page, the link to translation DE will redirect me to the corresponding page in German:

>>> publisher.Page.objects.get(pk=1).language
'en'
>>> publisher.Page.objects.get(pk=3).language
'de'
>>> test_client.get("/p/1?ul=de")
<HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="/p/home?ul=de">

There is no redirect when asking with ul=de for a page that is already German:

>>> test_client.get("/p/3?ul=de")
<HttpResponse status_code=200, "text/html;charset="utf-8"">

The previous_page fields have been updated:

>>> ar.show('publisher.Pages', display_mode="grid", language="en",
...     column_names="id title language root_page previous_page")
...
===== =============================== ========== =============== ===============================
 ID    Title                           Language   Root page       Previous page
----- ------------------------------- ---------- --------------- -------------------------------
 1     Home                            en
 2     হোম                             bn
 3     Startseite                      de
 4     About us                        en         Home            Home
 5     About us                        bn         হোম             হোম
 6     Über uns                        de         Startseite      Startseite
 7     Terms and conditions            en         Home            About us
 8     Terms and conditions            bn         হোম             About us
 9     Allgemeine Geschäftsbediungen   de         Startseite      Über uns
 10    Privacy policy                  en         Home            Terms and conditions
 11    Privacy policy                  bn         হোম             Terms and conditions
 12    Datenschutz                     de         Startseite      Allgemeine Geschäftsbediungen
 13    Cookie settings                 en         Home            Privacy policy
 14    Cookie settings                 bn         হোম             Privacy policy
 15    Cookie settings                 de         Startseite      Datenschutz
 16    Copyright                       en         Home            Cookie settings
 17    Copyright                       bn         হোম             Cookie settings
 18    Autorenrecht                    de         Startseite      Cookie settings
 19    Root pages                      en         Home            Copyright
 20    Root pages                      bn         হোম             Copyright
 21    Root pages                      de         Startseite      Autorenrecht
 22    Blog                            en         Home            Root pages
 23    Blog                            bn         হোম             Root pages
 24    Blog                            de         Startseite      Root pages
 25    Calendar                        en         Home            Blog
 26    Calendar                        bn         হোম             Blog
 27    Kalender                        de         Startseite      Blog
 28    Songbook                        en
 29    New songbook                    en
 30    Laundry                         en
 31    Services                        en         Laundry         Laundry
 32    Washing                         en         Laundry         Services
 33    Drying                          en         Laundry         Washing
 34    Air drying                      en         Laundry         Drying
 35    Machine drying                  en         Laundry         Air drying
 36    Drying foos                     en         Laundry         Machine drying
 37    Drying bars                     en         Laundry         Drying foos
 38    Drying bazes                    en         Laundry         Drying bars
 39    Ironing                         en         Laundry         Drying bazes
 40    Prices                          en         Laundry         Ironing
 41    Photos                          en         Laundry         Prices
 42    About us                        en         Laundry         Photos
 43    Team                            en         Laundry         About us
 44    History                         en         Laundry         Team
 45    Contact                         en         Laundry         History
 46    Terms & conditions              en         Laundry         Contact
 47    Laundry                         bn
 48    Services                        bn         Laundry         Laundry
 49    Washing                         bn         Laundry         Services
 50    Drying                          bn         Laundry         Washing
 51    Air drying                      bn         Laundry         Drying
 52    Machine drying                  bn         Laundry         Air drying
 53    Drying foos                     bn         Laundry         Machine drying
 54    Drying bars                     bn         Laundry         Drying foos
 55    Drying bazes                    bn         Laundry         Drying bars
 56    Ironing                         bn         Laundry         Drying bazes
 57    Prices                          bn         Laundry         Ironing
 58    Photos                          bn         Laundry         Prices
 59    About us                        bn         Laundry         Photos
 60    Team                            bn         Laundry         About us
 61    History                         bn         Laundry         Team
 62    Contact                         bn         Laundry         History
 63    Terms & conditions              bn         Laundry         Contact
 64    Laundry                         de
 65    Dienstleistungen                de         Laundry         Laundry
 66    Washing                         de         Laundry         Dienstleistungen
 67    Drying                          de         Laundry         Washing
 68    Air drying                      de         Laundry         Drying
 69    Machine drying                  de         Laundry         Air drying
 70    Drying foos                     de         Laundry         Machine drying
 71    Drying bars                     de         Laundry         Drying foos
 72    Drying bazes                    de         Laundry         Drying bars
 73    Ironing                         de         Laundry         Drying bazes
 74    Prices                          de         Laundry         Ironing
 75    Photos                          de         Laundry         Prices
 76    Über uns                        de         Laundry         Photos
 77    Team                            de         Laundry         Über uns
 78    History                         de         Laundry         Team
 79    Kontakt                         de         Laundry         History
 80    Nutzungsbestimmungen            de         Laundry         Kontakt
 81    Flying Circus                   en
 82    Places                          en         Flying Circus   Flying Circus
 83    Programme                       en         Flying Circus   Places
 84    Mission                         en         Flying Circus   Programme
 85    Blog                            en         Flying Circus   Mission
 86    Comments                        en         Flying Circus   Blog
 87    About us                        en         Flying Circus   Comments
 88    Team                            en         Flying Circus   About us
 89    History                         en         Flying Circus   Team
 90    Contact                         en         Flying Circus   History
 91    Terms & conditions              en         Flying Circus   Contact
 92    Flying Circus                   bn
 93    স্থান                            bn         Flying Circus   Flying Circus
 94    Programme                       bn         Flying Circus   স্থান
 95    Mission                         bn         Flying Circus   Programme
 96    Blog                            bn         Flying Circus   Mission
 97    Comments                        bn         Flying Circus   Blog
 98    About us                        bn         Flying Circus   Comments
 99    Team                            bn         Flying Circus   About us
 100   History                         bn         Flying Circus   Team
 101   Contact                         bn         Flying Circus   History
 102   Terms & conditions              bn         Flying Circus   Contact
 103   Flying Circus                   de
 104   Orte                            de         Flying Circus   Flying Circus
 105   Programme                       de         Flying Circus   Orte
 106   Mission                         de         Flying Circus   Programme
 107   Blog                            de         Flying Circus   Mission
 108   Kommentare                      de         Flying Circus   Blog
 109   Über uns                        de         Flying Circus   Kommentare
 110   Team                            de         Flying Circus   Über uns
 111   History                         de         Flying Circus   Team
 112   Kontakt                         de         Flying Circus   History
 113   Nutzungsbestimmungen            de         Flying Circus   Kontakt
 114   FlyingCon                       en         Home            Calendar
 115   Cascaded Continuous Voting      en         Home            FlyingCon
 116   Liquid democracy                en         Home            Cascaded Continuous Voting
 117   Digital vs analog               en         Home            Liquid democracy
 118   Software should be free         en         Home            Digital vs analog
 119   Synodality                      en         Home            Software should be free
===== =============================== ========== =============== ===============================

Classes reference

class lino.modlib.publisher.Page

The Django model that represents a content page.

Inherits from PublishableContent, TranslatableContent.

title
body
language
parent
seqno
root_page

The page that defines the top of the menu tree containing this page.

special_page

If this page implements a “special page”, then this field points to a choice in SpecialPages.

pub_date
pub_time
publishing_state

See PublishingStates

class lino.modlib.publisher.Publishable

Model mixin to add to models that are potentially publishable.

publisher_template

The name of the template to use when rendering a database row via the publisher interface.

“publisher/page.pub.html”

preview_publication

Show this database row via the publisher interface.

Icon: 🌐

class lino.modlib.publisher.PublishableContent

Model mixin to add to models that are potentially publishable.

Inherits from Publishable.

language

The language of this content.

publishing_state

Default value is ‘draft’

Pointer to PublishingStates

filler

Pointer to PageFillers

class lino.modlib.publisher.PublisherBuildMethod

This deserves better documentation. Maybe useless.

class lino.modlib.publisher.PublishingStates

A choicelist with the possible states of a publisher page.

>>> rt.show(publisher.PublishingStates, language="en")
======= =========== ========= ============= ========
 value   name        text      Button text   public
------- ----------- --------- ------------- --------
 10      draft       Draft                   No
 20      ready       Ready                   No
 30      published   Public                  Yes
 40      removed     Removed                 No
======= =========== ========= ============= ========
class lino.modlib.publisher.SpecialPages

A choicelist with the special pages available on this site.

>>> rt.show(publisher.SpecialPages, language="en")
=========== ====================== ======================================
 name        text                   Pages
----------- ---------------------- --------------------------------------
 home        Home                   `en <…>`__ | `bn <…>`__ | `de <…>`__
 about       About us               `en <…>`__ | `bn <…>`__ | `de <…>`__
 terms       Terms and conditions   `en <…>`__ | `bn <…>`__ | `de <…>`__
 privacy     Privacy policy         `en <…>`__ | `bn <…>`__ | `de <…>`__
 cookies     Cookie settings        `en <…>`__ | `bn <…>`__ | `de <…>`__
 copyright   Copyright              `en <…>`__ | `bn <…>`__ | `de <…>`__
 roots       roots                  `en <…>`__ | `bn <…>`__ | `de <…>`__
 blog        blog                   `en <…>`__ | `bn <…>`__ | `de <…>`__
 events      events                 `en <…>`__ | `bn <…>`__ | `de <…>`__
=========== ====================== ======================================

Configuration

lino.modlib.publisher.with_trees

Whether this site supports multiple publisher trees.

lino.modlib.publisher.locations

A tuple of 2-tuples (loc, cls) where loc is a location string and cls a data table.

>>> pprint(dd.plugins.publisher.locations)
(('b', lino_xl.lib.blogs.models.LatestEntries),
 ('p', lino.modlib.publisher.ui.Pages),
 ('r', lino.modlib.publisher.ui.RootPages),
 ('f', lino.modlib.uploads.ui.Uploads),
 ('i', lino.modlib.publisher.ui.ItemsByPage),
 ('src', lino_xl.lib.sources.models.Sources),
 ('sng', lino_xl.lib.songs.ui.LatestSongs),
 ('e', lino_xl.lib.cal.ui.UpcomingEvents),
 ('t', lino_xl.lib.tickets.ui.Tickets),
 ('tp', lino_xl.lib.topics.models.Topics))

When setting this setting (usually in a get_plugin_configs() method), the application developer should specify the data tables using their names. The above locations have been set in lino_cms.lib.cms.settings as follows:

yield ('publisher', 'locations', (
    ('b', 'blogs.LatestEntries'),
    ('p', 'publisher.Pages'),
    ('t', 'topics.Topics'),
    ('u', 'users.Users')))
lino.modlib.publisher.skin

Which skin to use. Default value is ‘boots’.

Currently the only alternative to ‘boots’ is ‘silly’, which is there just to show an alternative. You can see it by activating a line in the noi2 demo project settings.py file.

lino.modlib.publisher.use_markup

(Deprecated)

Whether to use markup (instead of wysiwyg) for editing content.

When this is False, the body of pages gets edited using a wysiwyg editor and stored as (bleached) html.