Welcome | Get started | Dive into Lino | Contribute | Topics | Reference | More

The main page

This page explains how to customize the elements of the main page of a Lino application.

Vocabulary

dashboard item

An individual item of the dashboard, rendered directly (inline) into the main page because it is considered an important entry point.

This page is a tested document and the following instructions are used for initialization:

Code snippets in this document are tested using the lino_book.projects.noi1e demo project.

>>> import lino
>>> lino.startup('lino_book.projects.noi1e.settings.demo')
>>> from lino.api.doctest import *

Welcome messages

As the application developer you have several methods to define welcome messages:

The admin_main.html calls get_welcome_messages. This code inserts the "welcome messages" for this user on this site. get_welcome_messages returns an etree element (see etgen.html).

>>> ar = rt.login("robin")
>>> print(tostring(settings.SITE.get_welcome_messages(ar)))
... 
<span>Your nicknamed Tickets are <a href="Detail">daily</a>, <a
href="Detail">friday</a>, <a href="Detail">inbox</a>.</span><p><span><a
href="Detail">Jean</a> is working on: <a href="Detail" title="'NoneType' object
has no attribute 'isocode'">#97 ('NoneType' object has no attribute
'isocode')</a>, <a href="Detail" title="'NoneType' object has no attribute
'isocode'">#109 ('NoneType' object has no attribute
'isocode')</a>.</span><br/><span><a href="Detail">Luc</a> is working on: <a
href="Detail" title="Bars have no foo">#111 (Bars have no foo)</a>, <a
href="Detail" title="Foo never matches Bar">#9 (Foo never matches
Bar)</a>.</span><br/><span><a href="Detail">Mathieu</a> is working on: <a
href="Detail" title="'NoneType' object has no attribute 'isocode'">#73
('NoneType' object has no attribute 'isocode')</a>, <a href="Detail"
title="'NoneType' object has no attribute 'isocode'">#85 ('NoneType' object has
no attribute 'isocode')</a>, <a href="Detail" title="'NoneType' object has no
attribute 'isocode'">#97 ('NoneType' object has no attribute 'isocode')</a>, <a
href="Detail" title="'NoneType' object has no attribute 'isocode'">#109
('NoneType' object has no attribute 'isocode')</a>.</span></p><span>You have
<b>13 items in Tickets to triage</b>.</span>

The dashboard

As the application developer you define which actors are available as dashboard item for your application. You can do this in two different ways:

This list is hard-coded per application and applies to all users. But Lino respects view permissions, i.e. an item will appear only if the user has permission to see it. For each dashboard item you can specify certain options to influence how Lino renders them. For example they usually don't appear if the table contains no data.

Independently of how you define the dashboard items for your application, you can additionally opt to install the lino.modlib.dashboard plugin.

List of available dashboard items

The list of available dashboard items exists also without this plugin.

>>> ar = rt.login("robin")
>>> user = ar.get_user()
>>> pprint(list(settings.SITE.get_dashboard_items(user)))
... 
[lino_xl.lib.cal.ui.MyTasks,
 lino.core.dashboard.ActorItem(cal.MyEntries,header_level=2,min_count=None),
 lino_xl.lib.cal.ui.MyOverdueAppointments,
 lino_xl.lib.cal.ui.MyUnconfirmedAppointments,
 lino_xl.lib.cal.ui.MyPresences,
 lino_xl.lib.cal.ui.PublicEntries,
 lino_xl.lib.calview.ui.DailyPlanner,
 lino.modlib.comments.ui.RecentComments,
 lino_xl.lib.tickets.ui.MyTickets,
 lino_xl.lib.tickets.ui.MySites,
 lino_xl.lib.tickets.ui.TicketsToTriage,
 lino_xl.lib.tickets.ui.MyTicketsToWork,
 lino_xl.lib.tickets.ui.TicketsNeedingMyFeedback,
 lino_xl.lib.tickets.ui.MyTicketsNeedingFeedback,
 lino_xl.lib.working.ui.WorkedHours,
 lino_xl.lib.groups.models.MyGroups,
 lino_xl.lib.ledger.ui.MyMovements,
 lino_xl.lib.ledger.ui.JournalsOverview]

Note that in practice you would probably prefer to not use above list directly, but rather its "processed" form, stored in the user's preferences:

>>> pprint(user.get_preferences().dashboard_items)
... 
[lino.core.dashboard.ActorItem(cal.MyTasks,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(cal.MyEntries,header_level=2,min_count=None),
 lino.core.dashboard.ActorItem(cal.MyOverdueAppointments,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(cal.MyUnconfirmedAppointments,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(cal.MyPresences,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(calview.DailyPlanner,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(comments.RecentComments,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(tickets.MyTickets,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(tickets.MySites,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(tickets.TicketsToTriage,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(tickets.MyTicketsToWork,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(tickets.TicketsNeedingMyFeedback,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(tickets.MyTicketsNeedingFeedback,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(working.WorkedHours,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(groups.MyGroups,header_level=2,min_count=1),
 lino.core.dashboard.ActorItem(ledger.JournalsOverview,header_level=2,min_count=1)]

See dashboard : customizable dashboard.

Behind the scenes

The content of the main page is generated from the admin_main.html template.

admin_main_base.html
admin_main.html

This is the template used to generate the content of the main page. It is split into two files admin_main.html and admin_main_base.html.

For illustration compare the content of the latter template with its result in the following screenshots (taken from the noi1e demo project which runs Lino Noi).

../_images/admin_main_000.png

Main page for AnonymousUser.

../_images/admin_main_900.png

Main page for user robin.

Customizing the main page

You may define a custom admin_main.html template, as we did in The Lino Polls tutorial. But this was rather an exercise for pedagogical reasons than something we would recommend to do for application developers.

You may even go further and override the get_main_html method of your Site class to return your own html.