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


This is the 2024 change log for Lino. Learn how to read and maintain this document in Documenting changes.


The master_key of a slave table is no longer automtically added as a simple parameter field. For example lino.modlib.dashboard.WidgetsByUser.


The functionality for verifying the email address of a user is now available also when allow_online_registration is False.


The as_paragraph of contacts.Partner did not always return a safe string. Such a stupid bug should not have slipped through our test suite! So lino_react.react.views now uses lino.utils.html.assert_safe() and the lino.api.doctest.walk_menu_items() function now also calls every table with display_mode set to 'list'. This detected two more models whose as_paragraph doesn’t yet return a safe string (working.Session and contacts.Role).

The lino.core.site.Site.remote_user_header is no longer being used. #5618 (Stop supporting HTTP authentication (Site.remote_user_header))


Lino no longer sets a default time when inserting a calendar entry. New function show_change_watchers for usage in tested documents.


New plugin lino_xl.lib.agenda. Visible in Lino Amici where calendar entries have a new tab “Agend” in their detail view and when you print an entry. Lino will also list the agenda items.


Rename plugin: ledger (lino_xl.lib.ledger) to accounting (lino_xl.lib.accounting).


A series of internal optimizations: Fixed a bug in lino.modlib.jinja : the config directory of the site_dir was searched last when looking for a template, but it should get searched first. The polls and polls2 demo sites were probably the only victims of that bug. show_menu no longer requires a username. ar.action_link. The docutils.conf of the Developer Guide no longer sets smart_quotes to False; this might cause a series of help texts to get marked as needing work in the .po files. #5600 (react plugin no longer needs lino.modlib.system).


Work in progress for ##5596 (Better names for obj2href() and obj2html()): Model.as_summary_row() and Model.as_paragraph() now call Model.obj2href() instead of ar.obj2html(). Some more internal optimizations: The lino.utils.html.tostring() function is now a copy of etgen.html.tostring() and it now escapes the value when it is an unsafe str.


Fixing #5576 (My teams should show description in only one language) was trivial but caused an avalanche of internal optimizations. The default implementation of detail_link now uses lino.core.model.Model.as_paragraph() as default text instead of ar.obj2htmls(). #5353 (Use mark_safe instead of ElementTree). New feature: #5589 (Simple parameters should be considered obvious fields). Optimization: #5590 (Render href in tested docs more consistently). To avoid making etgen depend on Django, I created a new module lino.utils.html with a function tostring that wraps Django’s safestring tools around etgen.html.tostring(). All Lino code now imports tostring() from this new lino.utils.html module. I started a topic guide Generating HTML.


New feature Job providers with multiple workplaces for Lino Welfare Châtelet (#5567). New database fields jobs.Job.workplace and contacts.Company.job_provider. New slave table WorkplacesByProvider in the detail view of a job provider.


Internal optimizations: the lino_xl.lib.contacts.Partner model now inherits from Commentable. This fixes #5578 (Amici says ‘Household’ object has no attribute ‘is_comment_private’). Optimized Plugin.__repr__().


Fixed several bugs that caused the background task runner to get stuck. pm linod now also starts a log server when linod.use_channels is False.

Database needs migration because lino.modlib.linod.SystemTask and lino_xl.lib.invoicing.Task have a new field name.


Done #5565 (Replace “Project” by “Topics” in Noi). Fixed a database design bug in lino_xl.lib.topics: New model lino_xl.lib.topics.Tag, and lino_xl.lib.topics.Interest no longer has an owner field. InterestsByController has become TagsByOwner, InterestsByPartner has become TagsByTopic. Topic is no longer a BabelNamed. The Interesting mixin has been renamed to Taggable. The topics.partner_model can now be None, which means that there is no Interest model, use cases are Lino Tera and Lino CMS.


Fixed #5553 (Invalid panel spec. start_invoicing_1 POST null). The lino_xl.lib.invoicing plugin now creates a single menu command “My invoicing plan” instead of creating one command per invoicing task.

Started documentation about Single-row tables.


Lino now supports the new Estonian VAT rate. (Not already since Januar because there is no production site yet in Estonia). Changes are visible in eevat : Estonian VAT declarations. Side effect: lino.mixins.periods.DateRange.get_period_text() is now more generally available as lino.mixins.periods.rangetext() and used by lino_xl.lib.vat.


New actions reset_password and verify_user. The “Verify” action on lino.modlib.users.User is now named verify_me. New database field lino.modlib.users.User.verification_password. Interesting to note how lino.modlib.users.User.verify_me inherits from lino.modlib.about.About.verify_user and how they do almost the same in different situations.

The react.UserSettings view no longer sets require_verification and code_expiry.


Renamed model linod.BackgroundTask to linod.SystemTask. Requires database migration.


Optimize background tasks: add possibility to have multiple task classes (django models); run separate task classes in separate coroutines.


The ChangesByMaster and ChangesByObject tables are now available on every watched model as toolbar button (). For this to work, applications must call lino.modlib.changes.watch_changes() from setup_actions rather than from do_site_startup. Side effects: Renamed Plugin.on_site_startup to Plugin.pre_site_startup. The watch_all_changes() feature has been removed because it was not used. Moved lino.utils.watch to lino.modlib.changes.utils. Updated documentation pages: When Lino starts up, changes: Keep track of changes in the database, watch – Watching database changes and More about plugins.


I renamed Site.get_installed_apps() to Site.get_installed_plugins() and Site.get_apps_modifiers() to Site.get_plugin_modifiers(). A technically simple change to improve readability for newcomers. But it will require local settings.py files to get updated. Lino raises an ChangedAPI exception if you forget to do it.


New field User.nickname and users.with_nickname. The CreateAccount action is now presented in the admin_main.html, and its dialog no longer shows the third-party auth providers because we have them in the SignIn action.


Renamed lino_xl.lib.sales to lino_xl.lib.trading because it can be used for any trade type, not only for sales. Requires database migration.


Fixed #5520 (Recent comments shows comments to tickets that the user cannot see). In lino.modlib.comments.Commentable, get_comments_filter() has been changed to add_comments_filter. New database field lino_xl.lib.groups.Group.private. The ar argument to lino.core.actors.Actor.get_request_summary and lino.core.model.Model.get_request_summary can now be a BaseRequest.

Noi no longer adds a group owner to (database field Group.user has been removed). And the view parameter subscriber has been removed.


Some subtle optimizations in Lino core: Default value for lino.core.actors.Actor.summary_sep changed from "<br/>" to ", ". New keyword argument max_width for TableRequest.show(). React renderer still used mjames icons for renderering actions even when a PrimeIcon icon exists. Clickable links sometimes had no style="text-decoration:none".


New method lino.core.site.Site.get_config_value() for #5497 (SITE.site_config is sometimes None on asgi server).


Resurrection of the commondata package. They had been sleeping for many years because the original idea assumed that people who know the data would site down and write Python code. A first example is commondata.countries. Because commondata was a namespace package and no longer is, you need to manually uninstall the old commondata packages by removing commondata*-nspkg.pth from your site-packages directory.


A developer in Uruguay started an internship, so we added Uruguayan demo data in cosi4 : a Lino Così for Uruguay.


Added the new plugin :mod:’lino_xl.lib.sources’ (#5214).


Automatically run invoicing plans as background tasks (#5399). Replace InvoicingAreas by lino_xl.lib.invoicing.Task


rename StorageState to ProvisionState


New field lino_xl.lib.products.Product.pieces_per_unit


Add the lino_xl.lib.nicknames plugin.


Review socket file of log server ():ticket:5379).