Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
Introduction to actions¶
Overview¶
An action, in Lino, is a Python object that describes “something that an end user might want to do”.
Actions are rendered as menu items, as toolbar buttons or as clickable text in arbitrary places.
A series of standard actions gets installed automatically on every actor when
Lino starts up. For example DeleteSelected
, ShowInsert
,
TableInsert
. They are defined in lino.core.actions
.
Actions are always bound to a given actor. For example it makes no
sense to request a ShowInsert
action without also specifying the actor
on which you want to insert a new row. That’s why Lino differentiates between
the actions themselves (instances of a subclass of
lino.core.actions.Action
) and the bound actions
(instances of lino.core.boundaction.BoundAction
).
- bound action¶
An action that is bound to its actor.
When you ask an actor for a list of actions that it “offers”, you actually get a list of bound actions.
As an application developer you can define new Write custom actions, or also override standard actions to customize their behaviour.
Window actions¶
Some actions open a new window on the client. We call them window actions.
Examples of window actions are ShowTable
, ShowDetail
and
ShowInsert
.
This behaviour is specified by the opens_a_window
attribute.
- Action.opens_a_window¶
Specifies whether this action opens a window. It is up to the front end to actually render that window.
Another class of actions also open a window, but that window is not their main purpose. For example the Merge action always opens a dialog window with miscellaneous parameters, and the action itself will execute only when the user confirms that dialog window. These actions are called parameter actions.
Or the DeleteSelected
action is visible in the toolbars of
the grid and the detail windows and in the context menu on a grid row.
DeleteSelected
,SubmitDetail
andSubmitInsert
send an AJAX request which causes something to happen on the server.
Read-only actions¶
A read-only action is an action that claims to not change anything in the current database object.
Note that this is just a claim. Even a read-only action may still actually modify the current database object or even other database objects. Lino doesn’t control it. The
For example the lino.modlib.printing.DirectPrintAction
action is
read-only. Otherwise it would be disabled on a registered invoice.
Also ShowInsert
is read-only because it does not modify the
current data object.
Setting readonly
to False will (1) disable the
action for readonly user types or when lino.core.site.Site.readonly
is
True, and (2) will cause it to be logged when log_each_action_request
is set to True.
Discussion
Maybe we should change the name readonly
to modifying
or
writing
(and set the default value False). Because that would look
more intuitive for the application developer. Or –maybe better but probably
with even more consequences– the default value should be False. Because
being read-only, for actions, is a kind of “privilege”: they don’t get logged,
they also exist for read-only users… It would be more “secure” when the
developer must explicitly “say something” in order to grant that privilege.
Another subtlety is the fact that this attribute is used by
lino.modlib.users.UserAuthored
. For example the
StartTicketSession
action in
Lino Noi is declared readonly
because we want Workers who are not
Triager
to see this action even if they are not the author (reporter)
of a ticket. Similar for the state change actions of a ticket.
TicketAction.readonly
is True because we want any Triager
to
change the state of a ticket, not only its author. The
lino_xl.lib.tickets.TicketAction.get_action_permission()
applies (i.e. you
need to be a Triager, and the project field may not be empty). In these use
cases the attribute name should rather be requires_authorship.
Action instances¶
A same action instance can be shared by many actors. For example the
DeleteSelected
action exists only as one instance shared among all
actors that use it.
Other actions can exist as different instances even on a same actor. For example
the lino.modlib.printing.DirectPrintAction
.
Instance actions¶
- instance action¶
An action that has been bound to a given database object.
An instance action exists only as long as the Python representation of the database object exists.
The default action of an actor¶
Each actor has a default action. The default action for data tables is ShowTable
. That’s why you can define a menu item by
simply naming the table view.
For example the setup_menu
method in
the Polls tutorial (file
lino_book/projects/polls/mysite/settings.py
) says:
def setup_menu(self, user_type, main):
super().setup_menu(user_type, main)
m = main.add_menu("polls", "Polls")
m.add_action('polls.Questions')
m.add_action('polls.Choices')
The add_action
method of
Lino’s lino.core.menus.Menu
is smart enough to understand
that if you specify a Table, you mean in fact that table’s default
action.