Introduction to layouts¶
A layout is a description of how to visually arrange the fields and other data elements in an entry form or a table.
Layouts are one of Lino's important features that make Lino projects different from plain Django projects. Layouts provide a way to design forms using the Python language and independently of the chosen front end.
Code examples in this document are taken from The LETS tutorial.
class Products(dd.Table): ... column_names = 'id name providers customers' ...
More about columns in The columns of a data view.
The most important usage of layouts is to describe detail windows.
You define a detail window by setting the
detail_layout attribute of an actor. For example:
class Members(dd.Table): ... detail_layout = """ id name place email OffersByMember DemandsByMember """
Note that the names
DemandsByMember refer to multi-line
panels containing a grid.
More examples in More about layouts.
Insert windows are similar to detail windows, but they are used on rows that do not yet exist. The most visible difference is their default size: while detail windows usually take the full screen, insert windows usually are pop-up windows.
You define an insert window by setting the
insert_layout attribute of your data view. For
class Members(dd.Table): ... insert_layout = """ name place email """
Until now we have seen that the following attributes of your tables contain layouts:
detail_layoutcontains an instance of
insert_layoutcontains an instance of
There are two other places where Lino uses layouts:
The data elements of a normal layout (
InsertLayout), can be:
For simple layouts it is enough to specify them just as a string
template, as in the examples above. Lino will automatically convert
such string templates into instances of
A layout template is a string containing words, where each word is the name of a data element.
A Layout consists of panels.
Every layout has at least one panel whose name is
a string, then Lino replaces this by a
whose main panel is that string.
After the element name there can be a colon (":") followed by configuration arguments. This can be
A integer numeric means preferred width (in logical characters)
A specification 60x5 means 60 characters wide and 5 lines high (for multiline widgets)
The keyword collapsible means that a htmlbox is collapsible
In more complex situations it may be preferrable or even necessary to define your own layout class.
You do this by subclassing
DetaiLayout. For example:
class PartnerDetail(dd.DetailLayout): main = """ id name description contact """ contact = """ phone email url """ class Partners(dd.Table): ... detail_layout = PartnerDetail()
Each panel is a class attribute defined on your subclass, containing a string value to be used as template describing the content of that panel.
It can define more panels whose names may be chosen by the application
developer (just don't chose the name
window_size which has a
special meaning, and don't start your panel names with an underscore
because these are reserved for internal use).
Panels are either horizontal or vertical, depending on whether their template contains at least one newline character or not.
Indentation doesn't matter.
If the main panel of a
FormLayout is horizontal,
ExtJS will render the Layout using as a tabbed main panel.
If you want a horizontal main panel instead, just insert
a newline somewhere in your main's template. Example:
class NoteLayout(dd.FormLayout): left = """ date type subject person company body """ right = """ uploads.UploadsByController cal.TasksByController """ # the following will create a tabbed main panel: main = "left:60 right:30" # to avoid a tabbed main panel, specify: main = """ left:60 right:30 """