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
 34   Songbook
 36   Laundry
 87   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
 34   Songbook
 35   New songbook
 36   Laundry
 87   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     আমাদের সম্পর্কে                   bn         হোম             হোম
 6     Über uns                        de         Startseite      Startseite
 7     Terms and conditions            en         Home            About us
 8     শর্তাবলী                         bn         হোম             আমাদের সম্পর্কে
 9     Allgemeine Geschäftsbediungen   de         Startseite      Über uns
 10    Privacy policy                  en         Home            Terms and conditions
 11    গোপনীয়তা নীতি                   bn         হোম             শর্তাবলী
 12    Datenschutz                     de         Startseite      Allgemeine Geschäftsbediungen
 13    Cookie settings                 en         Home            Privacy policy
 14    কুকি সেটিং                     bn         হোম             গোপনীয়তা নীতি
 15    Cookie settings                 de         Startseite      Datenschutz
 16    Copyright                       en         Home            Cookie settings
 17    কপিরাইট                         bn         হোম             কুকি সেটিং
 18    Autorenrecht                    de         Startseite      Cookie settings
 19    Root pages                      en         Home            Copyright
 20    Root pages                      bn         হোম             কপিরাইট
 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    ক্যালেন্ডার                       bn         হোম             Blog
 27    Kalender                        de         Startseite      Blog
 28    Contact                         en         Home            Synodality
 29    যোগাযোগ                         bn         হোম             ক্যালেন্ডার
 30    Kontakt                         de         Startseite      Kalender
 31    Register                        en         Home            Contact
 32    নিবন্ধন করুন                     bn         হোম             যোগাযোগ
 33    Registrieren                    de         Startseite      Kontakt
 34    Songbook                        en
 35    New songbook                    en
 36    Laundry                         en
 37    Services                        en         Laundry         Laundry
 38    Washing                         en         Laundry         Services
 39    Drying                          en         Laundry         Washing
 40    Air drying                      en         Laundry         Drying
 41    Machine drying                  en         Laundry         Air drying
 42    Drying foos                     en         Laundry         Machine drying
 43    Drying bars                     en         Laundry         Drying foos
 44    Drying bazes                    en         Laundry         Drying bars
 45    Ironing                         en         Laundry         Drying bazes
 46    Prices                          en         Laundry         Ironing
 47    Photos                          en         Laundry         Prices
 48    About us                        en         Laundry         Photos
 49    Team                            en         Laundry         About us
 50    History                         en         Laundry         Team
 51    Contact                         en         Laundry         History
 52    Terms & conditions              en         Laundry         Contact
 53    Laundry                         bn
 54    পরিষেবা                         bn         Laundry         Laundry
 55    Washing                         bn         Laundry         পরিষেবা
 56    Drying                          bn         Laundry         Washing
 57    Air drying                      bn         Laundry         Drying
 58    Machine drying                  bn         Laundry         Air drying
 59    Drying foos                     bn         Laundry         Machine drying
 60    Drying bars                     bn         Laundry         Drying foos
 61    Drying bazes                    bn         Laundry         Drying bars
 62    Ironing                         bn         Laundry         Drying bazes
 63    Prices                          bn         Laundry         Ironing
 64    Photos                          bn         Laundry         Prices
 65    আমাদের সম্পর্কে                   bn         Laundry         Photos
 66    Team                            bn         Laundry         আমাদের সম্পর্কে
 67    History                         bn         Laundry         Team
 68    যোগাযোগ                         bn         Laundry         History
 69    Terms & conditions              bn         Laundry         যোগাযোগ
 70    Laundry                         de
 71    Dienstleistungen                de         Laundry         Laundry
 72    Washing                         de         Laundry         Dienstleistungen
 73    Drying                          de         Laundry         Washing
 74    Air drying                      de         Laundry         Drying
 75    Machine drying                  de         Laundry         Air drying
 76    Drying foos                     de         Laundry         Machine drying
 77    Drying bars                     de         Laundry         Drying foos
 78    Drying bazes                    de         Laundry         Drying bars
 79    Ironing                         de         Laundry         Drying bazes
 80    Prices                          de         Laundry         Ironing
 81    Photos                          de         Laundry         Prices
 82    Über uns                        de         Laundry         Photos
 83    Team                            de         Laundry         Über uns
 84    History                         de         Laundry         Team
 85    Kontakt                         de         Laundry         History
 86    Nutzungsbestimmungen            de         Laundry         Kontakt
 87    Flying Circus                   en
 88    Places                          en         Flying Circus   Flying Circus
 89    Programme                       en         Flying Circus   Places
 90    Mission                         en         Flying Circus   Programme
 91    Blog                            en         Flying Circus   Mission
 92    Comments                        en         Flying Circus   Blog
 93    About us                        en         Flying Circus   Comments
 94    Team                            en         Flying Circus   About us
 95    History                         en         Flying Circus   Team
 96    Contact                         en         Flying Circus   History
 97    Terms & conditions              en         Flying Circus   Contact
 98    Flying Circus                   bn
 99    স্থান                            bn         Flying Circus   Flying Circus
 100   Programme                       bn         Flying Circus   স্থান
 101   Mission                         bn         Flying Circus   Programme
 102   Blog                            bn         Flying Circus   Mission
 103   মন্তব্য                           bn         Flying Circus   Blog
 104   আমাদের সম্পর্কে                   bn         Flying Circus   মন্তব্য
 105   Team                            bn         Flying Circus   আমাদের সম্পর্কে
 106   History                         bn         Flying Circus   Team
 107   যোগাযোগ                         bn         Flying Circus   History
 108   Terms & conditions              bn         Flying Circus   যোগাযোগ
 109   Flying Circus                   de
 110   Orte                            de         Flying Circus   Flying Circus
 111   Programme                       de         Flying Circus   Orte
 112   Mission                         de         Flying Circus   Programme
 113   Blog                            de         Flying Circus   Mission
 114   Kommentare                      de         Flying Circus   Blog
 115   Über uns                        de         Flying Circus   Kommentare
 116   Team                            de         Flying Circus   Über uns
 117   History                         de         Flying Circus   Team
 118   Kontakt                         de         Flying Circus   History
 119   Nutzungsbestimmungen            de         Flying Circus   Kontakt
 120   FlyingCon                       en         Home            Calendar
 121   Cascaded Continuous Voting      en         Home            FlyingCon
 122   Liquid democracy                en         Home            Cascaded Continuous Voting
 123   Digital vs analog               en         Home            Liquid democracy
 124   Software should be free         en         Home            Digital vs analog
 125   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.