Skip to content

Page Structure

Overview

A single layout [layout-name] model element that is not referenced from another layout element is turned into a web page. A web page always belongs to a business capability, which is modeled like this: capability [capability-name]. The relative URL to access that web page is:

/[context-root]/[capability-name]/[layout-name]/[layout-name].xhtml.

Lets have a look at an example where we assume that the context-root is ‘myapp’:

...

layout MyPage {
    ...
}

capability MyCapability {
    ...
}

application-ui MyApp {
    ...
}

...

The generated page is opened with this relative URL: /MyApp/mycapability/mypage/mypage.xhtml.

Note

When you want to get shorter URLs you have to set the context-root of your web application to / or you have to run your web application behind a webserver or proxy that is capable to rewrite URLs.

Templates

A web page is assembled by a number of XHTML files. One of those XHTML files is a template file, that defines the overall layout of a page, kind of dividing the page into sections. As of this writing, three different templates are supported:

The software architecture of generated applications allows to extend the list of available templates by other PrimeFaces premium layouts or by your own template. This is not an easy task, though. You need to have a good understanding of the inner workings of the template mechanism.

Related to those templates there are different template files that can be used as a web application’s main template:

  • /template/desktop/template.xhtml
  • /template/responsive/template.xhtml
  • /template/primefaces/california/template.xhtml

You choose a template by implementing Template getDefaultTemplate() in AppLayoutCustomization.java in your web application project. If you don’t implement this, DESKTOP will be chosen since it is the default template.

Future Support of other Templates

The list of supported templates is going to grow over time. Promising candidates are further PrimeFaces Premium templates, the new free themes Nova and Luna and the Admin Template of adminfaces. If you want to implement your own template, please contact us so we can help you implementing it.

Web Page Sections

All of the above templates in principal divide the screen estate of a web page into at least five logical areas: north, west, center, east, south. It is important to note that every template has its specialities. PrimeFaces Premium templates for instance do always have north and west sections and they feature more fine grained sections than only north, west, center, east and south.

Template Sections

The center section is further split into two separate sections: center-north and center-center. This is done in order to have an easy means to place common content into the top area of the center section (e.g. the name and ID of a selected customer in case of a web application for online commerce functionality). Using a nested template file that is dependend on the chosen template achieves this split:

  • /template/desktop/template-embedded-north-center.xhtml
  • /template/responsive/template-embedded-north-center.xhtml
  • /template/primefaces/california/template-embedded-north-center.xhtml

Template Sections in Center

For a web page you can switch off some of the sections. By doing so you can for instance get layouts as follows:

Template without East and South

Template with Center-Center only

XHTML Files per Web Page

For every web page that is modeled as layout [layout-name], the generator JSF Web-Fragment generates 9 XHTML files into a web fragment component:

File Purpose
[layout-name].xhtml references the file template.xhtml
[layout‑name]‑center‑center.xhtml includes the file [layout-name]_generated.xhtml
[layout-name]-center-north.xhtml the default XHTML file that is included in the center-north section (to of the center section)
[layout-name]-center.xhtml references the file template-embedded-north-center.xhtml
[layout-name]-east.xhtml the default XHTML file that is included in the east section
[layout-name]-north.xhtml the default XHTML file that is included in the north section
[layout-name]-south.xhtml the default XHTML file that is included in the south section
[layout-name]-west.xhtml the default XHTML file that is included in the west section
[layout-name]_generated.xhtml the XHTML file that contains all the JSF components like input fields, labels, tables, buttons, links, …

The file [layout-name]_generated.xhtml is the most important one. It holds all input components for a specific web page. All other files listed above are either simple placeholders or hold template functionality.

Manually Modifying the Web Page’s Main Content

In case you want to manually change the content of the generated file [layout‑name]_generated.xhtml, you have to create a copy of it (e.g. [layout‑name]_custom.xhtml) and manually change the method implementation of the method getXhtmlInclude() in [layout‑name]BeanCustomization.java in the web fragment project. A more powerful way to do this customization is to use so-called Layout Variants.

Note

Often it is not required to manually modify …_generated.xhtml at all. There are plenty of ways to customize a web page by writing Java code in the generated managed bean classes.

Web Page Content Customization

The deprecated, static Way

There is a meanwhile deprecated way to customize the content for the different web page section: setting <context-param> values in web-fragment.xml and web.xml. Such an entry can look like this:

<context-param>
    <param-name>layout.produkt.rechnungen.center.north</param-name>
    <param-value>/produkt/rechnungen/rechnungen-center-north.xhtml</param-value>
</context-param>

This functionality still works, but only for the templates DESKTOP and RESPONSIVE. It is deprecated since it quickly becomes unmanageable due to the sheer number of entries in the web.xml file. And it has no dynamic aspect: If you for instance have a web application with 10 pages and one single application menu, you would have to make 10 entries just to show that menu for each page.

In a web application project you can write code to control, which content should be displayed in the various page sections by implementing the following methods of the LayoutCustomizationI interface, which is found in the common web fragment component.

public static interface LayoutCustomizationI {
...
    Boolean isLayoutNorthRendered(UIViewRoot view);
    Boolean isLayoutEastRendered(UIViewRoot view);
    Boolean isLayoutSouthRendered(UIViewRoot view);
    Boolean isLayoutWestRendered(UIViewRoot view);
    Boolean isLayoutCenterRendered(UIViewRoot view);
    Boolean isLayoutCenterNorthRendered(UIViewRoot view);
    Boolean isLayoutCenterCenterRendered(UIViewRoot view);
    Boolean isLayoutTopMenuRendered(UIViewRoot view);
    Boolean isLayoutDeveloperBarRendered(UIViewRoot view);
    Boolean isLayoutRouteBarRendered(UIViewRoot view);
    String getXhtmlSource(UIViewRoot view, String key);
    String getStyles();
    String getTemplateFile(UIViewRoot view, String key);
    String getTemplateEmbeddedFile(UIViewRoot view, String key);
    Template getDefaultTemplate();
    Boolean isGlobalTooltipUsed(UIViewRoot view);
    String getStylesheet(String key, Template template);
    default String getTheme() { return null; }
    default Boolean isDarkMenu() { return Boolean.TRUE; };
    default Boolean isGradientMenu() { return Boolean.FALSE; };
    default Boolean isDarkMegaMenu() { return Boolean.TRUE; };
    default Boolean isGradientMegaMenu() { return Boolean.FALSE; };
    default String getMenuLayout() { return "static"; };
    default String getProfileMode() { return "topbar"; };
...

The parameter key of the getXhtmlSource() method is the id of a section. The id of a section is constructed like this: layout.[capability-name].[layout-name].[section-name] where section-name is one of:

  • head … nominates an XHTML file that is included in the <head> section of an HTML page
  • north
  • south
  • west
  • east
  • center
  • center.north
  • center.center

Note

All page section names are available through the Java enumeration PageContent. It is useful to use the enumeration instead of hard-coded strings. Otherwise you might use an incorrect section name and maybe are surprised that your web page is not shown as expected.

For the so-called Developer Bar, which is available in all templates, the following ids are being used:

  • layout.developer.bar
  • layout.developer.bar.pages.menu

There are also other ids being used, some of theme are dependent on the selected template. For the PrimeFaces premium template ‘California’ the following ids are being used:

  • layout.north.left … this is typically being used to display a logo, a click on it opens the web app’s home page
  • layout.north.right
  • layout.top.menu
  • layout.megamenu.name … this represents the main menu, a click on it opens the layout.top.menu
  • layout.top.profile.menu
  • layout.sidebar.menu
  • layout.sidebar.profile.menu

PrimeFaces California Sections

California Template’s Right Sidebar

The California template also features a ‘right sidebar’ that hovers over the web page when you click on a menu button. That menu button is not shown in the above picture. You activate this feature and make the additional menu button appear by returning true from isLayoutEastRendered(). The content of the right sidebar can be determined with the implementation of getXhtmlSource(). For more details on this, simply read on.

Programmatic Web Page Content Customization

The generator JSF Application generates a Java file AppLayoutCustomizationBean.java that implements the LayoutCustomizationI interface. Therein you can manually write code to do the customization. The methods isLayout[section-name]Rendered() let you switch off certain sections by returning false. For every call of those functions that returns null, the default configuration of the web page in the web fragment component is being applied.

Typically, you use LayoutCustomizationI.getXhtmlSource() to provide page content that should be displayed by all or at least by a set of the pages that make up your web application, like for instance a common header with a logo and a menu or a common menu on the left side of a web page. The content of the center-center section is already determined by the web fragment components. A check to find out which page section to serve is done like this:
if (key != null && key.endsWith(PageContent.WEST.getNameWithDotsOnly())) { ...

The following table lists the methods of AppLayoutCustomizationBean.java and describes their purpose. In general, when a method returns null, it means that the default value that is set in the web fragment component is being applied.

Method to be implemented in AppLayoutCustomizationBean.java    Purpose
Boolean isLayoutNorthRendered(UIViewRoot view) If this returns false, the northern part of a web page (typically, contains a menu) is not rendered.

Note that for the PrimeFaces Premium templates this method is not used at all. Those layouts always have a northern part.
Boolean isLayoutEastRendered(UIViewRoot view) If this returns false, the eastern part of a web page is not rendered.

Note that for the PrimeFaces Premium templates the eastern part is not a static page section but one that hovers over the web page by clicking on a menu button on the right side of the north section.
Boolean isLayoutSouthRendered(UIViewRoot view) If this returns false, the southern part of a web page is not rendered.

Note that for the PrimeFaces Premium templates the southern part of a web page is called ‘footer’ (footer.xhtml).
Boolean isLayoutWestRendered(UIViewRoot view) If this returns false, the western part of a web page is not rendered. That part of the web page normally holds the application menu.

Note that PrimeFaces Premium templates are designed in a way such that all web pages show an application menu on the west side.
Boolean isLayoutCenterRendered(UIViewRoot view) If this returns false, the main/central part of a web page is not rendered. The only thinkable reason why it could make sense to return false from this method, is to be able to start with a totally empty space in the center of a web page.
Boolean isLayoutCenterNorthRendered(UIViewRoot view) If this returns false, the main/central part of a web page does not display special content on the northern part of the main/central part.
Boolean isLayoutCenterCenterRendered(UIViewRoot view) If this returns false, the main/central part of a web page does at most show special content on the northern part of the main/central part.
Boolean isLayoutTopMenuRendered(UIViewRoot view) This only works for PrimeFaces Premium templates.
If the method returns true, the northern part of a web page features a menu. In case of the PrimeFaces Premium template, this is a so-called ‘mega menu’ (<p:megaMenu>).
Boolean isLayoutDeveloperBarRendered(UIViewRoot view) If this returns true, the so-called Developer Bar, implemented by developerBar.xhtml and DevelopmentBean.java, is displayed between the northern part and the central part of a web page.
Boolean isLayoutRouteBarRendered(UIViewRoot view) This only works for PrimeFaces premium templates.
If the method returns true, a small band is being displayed right underneath the northern section of a web page.

The PrimeFaces Premium layout has this feature, but in the runtime framework this has not yet been generalized.
String getXhtmlSource(UIViewRoot view, String key) This method returns the path of XHTML files, depending on the passed page content id. This is the central point where you can programmatically determine the web page content.
String getStyles() This method returns styles that are used as additional in-line styles for all web pages.
String getTemplateFile(UIViewRoot view, String key) This method returns the template file to be used for the given page. This method only needs to be implemented when you want a customized template to be used for a really special web page.
String getTemplateEmbeddedFile(UIViewRoot view, String key) This method returns the template file to be used for the central part of the given page. This method only needs to be implemented when you want a customized template to be used for a really special web page.
Template getDefaultTemplate() This method determines, which template is going to be used by all web pages of the web application. If this method is not implemented, the template Template.DESKTOP is going to be used.
Boolean isGlobalTooltipUsed(UIViewRoot view) If this method returns true, a global <p:tooltip> component is activated in the template. Enabling this is the easiest and most efficient way to get powerful tooltip functionality for almost all of the UI components that you use.
String getStylesheet(String key, Template template) You find a detailed description of the ‘Styling’ feature that also covers this method.
String getTheme() With this method you determine the theme to be used for the web application by returning the theme name. You find more information about themes in the detailed description of the ‘Styling’ feature.
Boolean isDarkMenu() Only for PrimeFaces Premium templates. Determines whether the dark or light menu mode is being used for the western part of the web pages.
Boolean isGradientMenu() Only for PrimeFaces Premium templates. Determines whether the gradient menu mode is being used for the western part of the web pages.
Boolean isDarkMegaMenu() Only for PrimeFaces Premium templates. Determines whether the dark or light menu mode is being used for the mega menu within the northern part of the web pages.
Boolean isGradientMegaMenu() Only for PrimeFaces Premium templates. Determines whether the gradient menu mode is being used for the mega menu within the northern part of the web pages.
String getMenuLayout() Only for PrimeFaces Premium templates.

Possible values: static, overlay.
static => the western part of a web page consumes screen estate and thus limits the remaining space for the rest of the page.
overlay => the western part of a web page overlays the rest of the web page and thus does not limit the remaining space for the rest of the page.
String getProfileMode() Only for PrimeFaces Premium templates.

Possible values: inline, topbar.
inline => The profile menu is displayed within the western part of a web page.
topbar => The profile menu is displayed on the right side of the northern part of a web page.

Web Page Layout Variants

When you want to provide some variants of a web page in a web fragment component, such that the web page always uses the same set of managed beans, you can configure a set of XHTML file variants. Those variants might for instance have the same JSF components but in a different order or in a different position. Another use-case is to provide one variant of a web page for desktop use and one for being used on a smartphone.

Note

The layout variant functionality has the purpose to provide those variants in a shared component, a web fragment component. Then let a developer of a web application choose one of the variants. To come up with your very own version of an existing web page, without making it available to be used in other web applications, you should rather use the web page content customization functionality that is described further above.

In the model you specify the variants by introducing and assigning an enumeration as follows:

...

enumeration LayoutEnum {
    entry DEFAULT;
    entry OTHER_ORDER;
    entry FLIP_LEFT_TO_RIGHT;
}

layout Page {
    ...

    link LayoutVariants = LayoutEnum;

    ...
}

...

Doing so you will get not only the file page_generated.xhtml, but also page_default.xhtml, page_other_order.xhtml and page_flip_left_to_right.xhtml. And in page-center-center.xhtml you’ll see the following code:

<!DOCTYPE html  [
    <!ENTITY nbsp "&#160;">
]>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui"
    xmlns:pe="http://primefaces.org/ui/extensions"
    xmlns:o="http://omnifaces.org/ui"
    xmlns:of="http://omnifaces.org/functions"
    xmlns:c="http://java.sun.com/jstl/core"
    xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">
<!--DA-START:xhtml.center.center:DA-START-->
<!--DA-ELSE:xhtml.center.center:DA-ELSE-->
<ui:composition>
    <o:importConstants type="com.gs.gapp.LayoutEnum" var="LayoutVariantsEnum"/>
    <c:if test="#{LayoutVariantsEnum.DEFAULT.name() eq pageBeanCustomization.configurationItems.pageLayout.name()}">
        <ui:include src="#{pageBeanCustomization.getXhtmlInclude(LayoutVariantsEnum.DEFAULT.name())}" />
    </c:if>
    <c:if test="#{LayoutVariantsEnum.OTHER_ORDER.name() eq pageBeanCustomization.configurationItems.pageLayout.name()}">
        <ui:include src="#{pageBeanCustomization.getXhtmlInclude(LayoutVariantsEnum.OTHER_ORDER.name())}" />
    </c:if>
    <c:if test="#{LayoutVariantsEnum.FLIP_LEFT_TO_RIGHT.name() eq pageBeanCustomization.configurationItems.pageLayout.name()}">
        <ui:include src="#{pageBeanCustomization.getXhtmlInclude(LayoutVariantsEnum.FLIP_LEFT_TO_RIGHT.name())}" />
    </c:if>
</ui:composition>
<!--DA-END:xhtml.center.center:DA-END-->
</html>

Finally, in a web application project you choose the variant by manually writing code in the class AppPageBeanCustomization that gets generated for the web page:

...
    /**
     *
     * @param configuration  the configuration
     */
    @Override
    public void getConfigurationItems(PageBeanCustomization.Configuration configuration) {
        configuration.setPageLayout(LayoutEnum.FLIP_LEFT_TO_RIGHT);
    }
...