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

Content Management System (CMS)

The noi2 demo project shows Lino as a Content Management System.

>>> from lino_book.projects.noi2.startup import *
>>> mp = settings.SITE.plugins.memo.parser
>>> rt.show(uploads.ImageSizes)
========= ========= =========
 value     name      text
--------- --------- ---------
 tiny      tiny      Tiny
 small     small     Small
 default   default   Default
 big       big       Big
 huge      huge      Huge
 solo      solo      Solo
 duo       duo       Duo
 trio      trio      Trio
 quartet   quartet   Quartet
========= ========= =========
>>> rt.show(uploads.ImageFormats)
========== ========== ===============
 value      name       text
---------- ---------- ---------------
 default    default    Normal
 cool       cool       Cool
 right      right      Right-aligned
 left       left       Left-aligned
 wide       wide       Wide
 carousel   carousel   Carousel
 square     square     Square
========== ========== ===============
>>> rt.models.uploads.Upload.objects.get(description__startswith="Murder")
Upload #13 ('Murder on the orient express cover')
>>> print(mp.parse("[include upload:13] Some text."))
...
<a href="/admin/#/api/uploads/Uploads/13" target="_blank"><img
src="/media/thumbs/uploads/2024/05/MurderontheOrientExpress.jpg"  title="Murder
on the orient express cover"
style="..."/></a> Some text.
>>> print(mp.parse('[include upload:13 My caption] Some text.'))
...
<a href="/admin/#/api/uploads/Uploads/13" target="_blank"><img
src="/media/thumbs/uploads/2024/05/MurderontheOrientExpress.jpg"  title="My
caption" style="..."/></a> Some text.
>>> print(mp.parse('[include upload:13 wide|] Some text.'))
...
<a href="/admin/#/api/uploads/Uploads/13" target="_blank"><img
src="/media/thumbs/uploads/2024/05/MurderontheOrientExpress.jpg"
title="Murder on the orient express cover" style="..."/></a>
Some text.
>>> print(mp.parse('[include upload:13 wide|My caption] Some text.'))
...
<a href="/admin/#/api/uploads/Uploads/13" target="_blank"><img
src="/media/thumbs/uploads/2024/05/MurderontheOrientExpress.jpg"
title="My caption"
style="..."/></a> Some text.

Spaces around the pipe character don’t count:

>>> print(mp.parse('[include upload:13 wide | My caption] Some text.'))
...
<a href="/admin/#/api/uploads/Uploads/13" target="_blank"><img
src="/media/thumbs/uploads/2024/05/MurderontheOrientExpress.jpg"  title="My
caption" style="..."/></a> Some text.

“image URL” versus “download URL”

>>> obj = uploads.Upload.objects.get(pk=13)
>>> mf = obj.get_media_file()
>>> print(mf.get_download_url())
/media/uploads/2024/05/MurderontheOrientExpress.jpg
>>> print(mf.get_image_url())
/media/thumbs/uploads/2024/05/MurderontheOrientExpress.jpg
>>> # obj = uploads.Upload.objects.get(pk=18)
>>> obj = uploads.Upload.objects.get(description__startswith="History")
>>> obj
Upload #20 ('History of PDF')
>>> mf = obj.get_media_file()
>>> print(mf.get_download_url())
/media/uploads/2024/05/History_of_PDF.pdf
>>> print(mf.get_image_url())
/media/thumbs/uploads/2024/05/History_of_PDF.pdf.png

Don’t read me

The following request had caused a traceback:

>>> res = test_client.get("/s/1")
>>> txt = beautiful_soup(res.content.decode()).text
>>> "Private collection by Luc Saffre" in txt
True
>>> res = test_client.get("/b/1")

Let’s extend above test to systematically loop over all publisher locations and GET each item:

>>> for loc, dv in dd.plugins.publisher.locations:
...     for obj in dv.create_request():
...         url = "/{}/{}".format(loc, obj.pk)
...         # print(dv, url)
...         if obj.is_public():
...             res = test_client.get(url)
...             if res.status_code not in {200, 302}:
...                 print(f"{url} failed with {res.status_code}")
...                 # print(f"({res.content.decode()})")
...         # elif res.status_code != 404:
...         #     print(f"{url} should return 404 but returned {res.status_code}")
>>> [obj.pk for obj in blogs.LatestEntries.create_request()]
[2, 3, 4, 5, 1]
>>> obj = blogs.Entry.objects.get(id=2)
>>> obj.get_root_page()
Page #1 ('Home')