Custom layouts can be contributed to the web layout service, using its extension point. The layout definition is then available through the service to control how it will be displayed in a given mode.
Some jsf tags have been added to the Nuxeo ECM layout tag library to make then easily available from an xhtml page.
Layout registration
Layouts are registered using a regular extension point on the Nuxeo ECM layout service. Here is a sample contribution.
Layout definition
The above layout definition is used to display the title and the description of a document. Here are its properties:
- name: string used as an identifier. In the example, the layout name is "heading".
- templates: list of templates to use for this layout global rendering. In the example, the layout template in any mode is the xhtml file at "
/layouts/layout_default_template.xhtml". Please refer to section about custom layout templates for more information. - rows: definition about what widgets will have to be displayed on this row. Each row can hold several widgets, and an empty widget tag can be used to control the alignment. The widget has to match a widget name given in this layout definition. In the example, two rows have been defined, the first one will hold the "title" widget, and the second one will hold the "description" widget.
- widget: a layout definition can hold any number of widget definitions. If the widget is not referenced in the rows definition, it will be ignored. Since 5.1.7 and 5.2.0, it will be searched in the global widget registry before being ignored. This new feature is a convenient way to share widget definitions between layouts. Please refer the widget definition section.
Widget definition
Two widget definitions are presented on the above example. Let's look into the "title" widget and present its properties:
- name: string used as an identifier in the layout context. In the example, the widget name is "title".
- type: the widget type that will manage the rendering of this widget. In this example, the widget type is "text". This widget type is a standard widget types, more information about widget types is available here.
- labels: list of labels to use for this widget in a given mode. If no label is defined in a specific mode, the label defined in the "any" mode will be taken as default. In the example, a single label is defined for any mode to the "label.dublicore.title" message. If no label is defined at all, a default label will be used following the convention: "label.widget.[layoutName].[widgetName]".
- translated: string representing a boolean value ("true" or "false") and defaulting to "false". When set as translated, the widget labels will be treated as messages and displayed translated. In the example, the "label.dublincore.title" message will be translated at rendering time. Default is true.
- fields: list of fields that will be managed by this widget. In the example, we handle the field "dc:title" where "dc" is the prefix for the "dublincore" schema. If the schema you would like to use does not have a prefix, use the schema name instead. Note that most of standard widget types only handle one field. Side note: when dealing with an attribute from the document that is not a metadata, you can use the property name as it will be resolved like a value expression of the form #{document.attribute}.
- properties: list of properties that will apply to the widget in a given mode. Properties listed in the "any" mode will be merged with properties for the specific mode. Depending on the widget type, these properties can be used to control what jsf component will be used and/or what attributes will be set on these components. In standard widget types, only one component is used given the mode, and properties will be set as attributes on the component. For instance, when using the "text" widget type, every property accepted by the "<h:inputText />" tag can be set as properties on "edit" and "create" modes, and every property accepted by the "<h:outputText />" tag can be set as properties. Properties can also be added in a given widget mode.
Additional properties can be set on a widget:
- helpLabels: list that follows the same pattern as labels, but used to set help labels.
- widgetModes: list of local modes used to override the local mode (from the layout).
- subWidgets: list of widget definitions, as the widget list, used to describe sub widgets use to help the configuration of some complex widget types.
Here is a more complex layout contribution that shows the syntax to use for these additional properties:
Listing layout definition
Layouts can also be used to render table rows, as long as their mode (or their widgets mode) do not depend on the iteration variable, as the layout is built when building the JSF tree (too early in the JSF construction mechanism for most iteration variables).
For this usage, columns/column aliases have been defined because they are more intuitive when describing a row in the layout. The layout layout_listing_template.xhtml makes it possible to define new properties to take care of when rendering the table header or columns.
Here widgets have been defined globally, as well as their types. New widget types, or simply widget templates, can be made taking example on the existing ones, see http://hg.nuxeo.org/nuxeo/nuxeo-jsf/file/5.4/nuxeo-platform-webapp-base/src/main/resources/OSGI-INF/layouts-listing-contrib.xml.
More information about how to write a listing layout template can be read in chapter about Custom templates. If you need to define listing layouts that handle column selection, please refer to the Advanced search chapter as it gives a complete example on how this is achieved for this feature.
EL expressions in layouts and widgets
Some variables are made available to the EL context when using layout or widget templates.
- Inside the layout context, the following global variables are available: value (and equivalent document) + levels and changing "value" context
- layoutValue: represents the value (evaluated) passed in a "nxl:layout" or "nxl:documentLayout" tag attributes.
- layoutMode: represents the mode (evaluated) passed in a "nxl:layout" or "nxl:documentLayout" tag attributes.
- value: represents the current value as manipulated by the tag: in a "nxl:layout" tag, it will represent the value resolved from the "value" tag attribute ; in a "nxl:widget" tag, it will represent the value resolved from the "value" tag attribute. This value will work with field information passed in the widget definition to resolve fields and subfields. The variable "document" is available as an alias, although it does not always represent a document model (as layouts can apply to any kind of object).
- value_n: represents the current value as manipulated by the tag, as above, excepts it includes the widget level (value_0, value_1, etc...). This is useful when needing to use the value as defined in a parent widget, for instance.
- Inside a layout template, the variable "layout" is available, it make its possible to access the generated layout object.
- Inside a "nxl:layoutRow", or equivalent "nxl:layoutColumn" tag, the variables "layoutRow" and "layoutRowIndex" are available to access the generated layout row, and its index within the iteration over rows. The equivalent "layoutColumn" and "layoutColumnIndex" variables are also available.
- Inside a "nxl:layoutRowWidget", or equivalent "nxl:layoutColumn" widget, the variables "widget" and "widgetIndex" are available to access the generated current widget, and its index in the row or column. The variables added the level information are also available: widget_0, widget_1, ... and widgetIndex_0, widgetIndex_1... This is useful when needed to use the widget as defined in a higher level.
- Inside a widget template, some "field_n" variables are available: "field_0" represents the resolved first field value, "field_1" the second value, etc... Since 5.3.1, the variable "field" is available as an alias to "field_0". Since 5.3.2, the widget properties are also exposed for easier resolution of EL expressions: for instance, the variable "widgetProperty_onchange" represents the resolved property with name "onchange".
The complete reference is available at http://community.nuxeo.com/api/nuxeo/5.4/tlddoc/nxl/tld-summary.html.