In my previous blog on Live Documentation, we looked into the Nuxeo Platform Explorer and how to browse and find extension points and their documentation. Today we’ll continue exploring further into the Platform Explorer to understand and identify the JSF UI structures for customization. This will be combined with UI Dev mode usage as referenced by another blog. The UI Dev mode will help you identify components on screen, such as actions, widgets, templates and layouts.

Once you identify what you want to change, or use as examples and where, you can use the Platform Explorer to look at the configuration. This method is also useful for understanding the JSF UI structures of the Layout - Template - Widget nesting, in general.

The Summary Tab Example

Let’s take an example where we want to understand the default Summary Tab and how it’s put together. Using the UI Dev mode, we can click on the Summary tab and see that it’s an action called TAB_VIEW.

In the Explorer we first go to the Actions Extension Point:

Actions Extension Point


Tab View


Searching in the Explorer under the Actions Extension Point for TAB_VIEW, we get the following search result and definition:

<action accessKey="v" icon="/icons/file.gif" id="TAB_VIEW" label="action.view.summary" link="/incl/tabs/document_view.xhtml" order="0" type="rest_document_link">
   <category>VIEW_ACTION_LIST</category>
      <filter-id>view</filter-id>
    <properties>
      <property name="ajaxSupport">true</property>
    </properties>
 </action>

From this definition, we see that it’s a link to an XHTML, JSF template, /incl/tabs/document_view.xhtml
Next, we can find this template on our server, within /nxserver/nuxeo.war, where all JSF UI files are deployed. Opening this JSF template we see the the following:

<c:if test="#{empty summaryLayouts}">
  <a4j:outputPanel id="documentViewPanel" layout="block">
    <nxl:documentLayout documentMode="grid_summary" mode="view"
          value="#{currentDocument}" defaultLayout="grid_summary_layout"
          includeAnyMode="false" />
  </a4j:outputPanel>
</c:if>

Other than a backward compatibility section, by default it’s using the grid_summary_layout in the tag for the document layout and it’s in view mode. At this point we know the name of the top level layout of the Summary Tab action, and we can probe further to find the definition of this layout and more component nesting as we explore this UI structure.

Layouts

We then go to the Layouts Extension Point in Explorer as we did with Actions earlier, to search for grid_summary_layout.

Layouts Extension Point


Grid Summary Layout


The definition is as follows:

<layout name="grid_summary_layout">
  <templates>
    <template mode="any">
      /layouts/layout_grid_template.xhtml
    </template>
  </templates>
  <rows>
    <row>
      <widget>summary_panel_top</widget>
    </row>
    <row>
      <widget>summary_panel_left</widget>
      <widget>summary_panel_right</widget>
    </row>
    <row>
      <widget>summary_panel_bottom</widget>
    </row>
  </rows>
</layout>

It’s simply a layout with 2 rows and widgets for each grid position. This can also be seen by clicking on the 2 sections using Dev mode. The Explorer tells us that we can also add components to a top and bottom row, which isn’t shown in Dev mode because nothing is put into those sections as standard. Next we search for any of these widgets under the Widgets Extension Point.

Summary Panel Left


Summary_panel_left gives us the search result and its definition. We find that it is of type Document Actions and define respective action categories.

<widget name="summary_panel_left" type="documentActions">
  <labels>
    <label mode="any"/>
  </labels>
  <properties widgetMode="any">
    <property name="category">SUMMARY_PANEL_LEFT</property>
    <property name="styleClass">summaryActions</property>
  </properties>
  <controls mode="any">
    <control name="handleLabels">true</control>
    <control name="gridStyleClass">gridStyle8</control>
  </controls>
</widget>

This now tells us that to add components into these sections we have to add actions with the appropriate category. By browsing actions and definition formats, we can see that an action has relative orders, so we can organize the layout order just by setting the order number.

Actions

Finally, let’s look for Actions with the SUMMARY_PANEL_LEFT category. Back in the Actions Extension Point section as we did earlier, we search for and find 4 matching contributions:

Summary Panel


3 of those are defined as follows:

<action id="summary_current_document_view" order="300" type="widget">
  <category>SUMMARY_PANEL_LEFT</category>
  <properties>
    <property name="widgetName">summary_current_document_view</property>
  </properties>
  <filter-id>notHasNote</filter-id>
  <filter-id>denyForFile</filter-id>
</action>
<action id="summary_current_document_dublincore" order="350" type="widget">
  <category>SUMMARY_PANEL_LEFT</category>
  <properties>
    <property name="widgetName">summary_current_document_dublincore</property>
  </properties>
  <filter-id>hasDublincore</filter-id>
</action>
<action id="summary_current_document_comments" order="400" type="widget">
  <category>SUMMARY_PANEL_LEFT</category>
  <properties>
    <property name="widgetName">summary_current_document_comments</property>
  </properties>
</action>

We see that these are of type widget with the expected order number, as well as conditional filter. So in this case, we see that this layout is built very dynamically, simply by contributing an Widget Action of the appropriate category. These 3 Actions, themselves use the referenced widgets in their definition, which would then have a layout and more widgets for the individual fields, for further nesting.

The first one is a summary_current_document_view. This places whatever fields that particular Doc Type has defined for it’s view, either in Studio or defined for standard types.

The second one, summary_current_document_dublincore, shows a standard set of fields generally applicable to all document types, since it’s the dublincore schema. If you don’t want this on your summary page, you’ll need to set a filter for this action. Hint: Look under the Filters Extension Point in Explorer for how filters are defined and used.

The last type is the summary_current_document_comments, which by its name indicates that it’s for document comments.

Seeing this list explains how the default Document Summary page is configured and what you need to do to modify it.

These could also be any other type of Action with this category including layouts. This gives great flexibility to dynamically build a page with only configuration. You just need to add an action with that category to have it appear in that location.

Conclusion

We can continue down this path and look at all the widgets by name and their definitions.

The point of this example is to see how it can be used to understand the JSF system and the approach to using it. Not everything will be structured with actions as the summary tab was. It could be any combination of Actions, Layouts, Widgets and Templates. Hence the best way to investigate is to trace down using the Dev Mode on the UI and definitions of components using the Platform Explorer.