7 Developing Page Templates

Use JDeveloper to create, edit, and publish page templates for use in WebCenter Portal.

Page templates provide the structure for common areas in portal pages. Using JDeveloper, you can design and develop new page templates for building portal pages.

Topics:

Introduction to Developing Page Templates

This section includes the following topics:

Understanding Page Templates

Page templates define how individual pages and groups of pages display on a user's screen, and help to ensure that the pages in a portal are consistent in structure and layout.

If you change a page template, then all pages that reference that template automatically inherit the changes.

Note:

For general information about page templates, see Using Page Templates in Developing Web User Interfaces with Oracle ADF Faces.

For tips and best practices for creating page templates for use in Oracle WebCenter Portal, see Best Practices for Developing Page Templates. Oracle recommends that you use Oracle JDeveloper to develop page templates for use in WebCenter Portal. You can also develop page templates in WebCenter Portal, but the editing capabilities are limited.

When fully developed, you can publish page templates directly to WebCenter Portal as a shared asset or to a specific portal for immediate use or for testing. For more information, see Publishing a Page Template.

Understanding Page Template Structure

Typical elements of a page template include:

  • Header, content area (different in each page), and footer. The header and footer commonly include brand-specific elements. For example, a header usually includes a logo and possibly a slogan, and a footer usually includes contact and copyright information.

  • Navigation. A page template can expose the navigation for a portal in many ways. For example, on a mobile device, portal navigation may be shown as a popup or slide in/out. On a desktop browser, portal navigation is typically shown along the top of the page, or down the side of the page.

  • Branding elements. For example, a page template my include a company logo, slogan, or copyright message.

  • Links and actions. For example, a log in/log out link, drop-down menus, or global links (such as links to send a mail message to the web administrator or to display a privacy statement).

  • Conditional elements. For example, some elements on the page might differ depending on whether the user is public or authenticated or depending on the user's role and privileges.

Figure 7-1 shows a sample application based on a page template that illustrates these elements.

Figure 7-1 Sample Portal that Uses a Page Template

Description of Figure 7-1 follows
Description of "Figure 7-1 Sample Portal that Uses a Page Template"

Understanding Page Template Layout

One of the most important aspects of page template design is the layout of components, both elements of the template and page content.

There are two basic strategies:

  • A flowing layout is the most typical layout. Components are arranged side by side or one below the other, displayed using their natural size. When the content of the page extends beyond the size of the browser window, the browser displays scroll bars on the page.

  • A stretching layout may be a suitable choice when your page content fills a large area, or you want the page content to grow and shrink depending on the size of the browser window. Components are stretched to occupy the available space on the page. For example, a stretching layout may be suitable when a page contains a table or graph that you want to fill up the whole content area, no matter what size it is. Another example is a page that contains an editing area, where you want the editor to be exactly as tall and wide as the space given to the content area. This layout has a region for the page content, and adds scroll bars to the region on the page when the content cannot be contained within the size of the browser window. In other words, individual components display scroll bars (which might mean that you have multiple scroll bars on one page).

    Stretching enables you to maximize the usage of the viewable area. You can use tabs, accordions, menus, and popups to expand your viewable area. When scroll bars are added to the page, the navigation area, page header, and page footer remain in view while the content area scrolls.

Because most web sites use a flowing layout, you will probably also want to use a flowing layout as it will likely feel more familiar to your users. However, stretching layouts are good for dashboards and applications that are rich in nature or when you want to mimic a desktop experience. You can also combine flowing and stretching layout on the same page.

Vertical Behavior

Depending on whether your layout is flowing or stretching, the vertical behavior of the page differs as follows:

  • Flowing layout:

    • The header and/or footer might not always be visible

    • The height of the page is calculated based on the page contents

    • The content is never stretched vertically

    • The browser might display a scroll bar

  • Stretching layout:

    • The header and footer are always visible

    • The height of the page is determined by the browser window

    • The content is stretched vertically

    • The content area might display a scroll bar

Horizontal Behavior

Depending on whether your layout is flowing or stretching, the horizontal behavior of the page differs as follows:

  • Flowing layout:

    • If your page includes a side bar (for example, left-side navigation), the side bar might not always be visible

    • The width of the page is calculated based on the components

    • Some components might be stretched to fill up existing space

    • The browser might display a scroll bar

  • Stretching layout:

    • If your page includes a side bar (for example, left-side navigation), the side bar is always visible

    • The width of the page is determined by the browser window

    • The content is stretched horizontally

    • The content might display a scroll bar

Understanding Page Template Layout Components

The underlying structure of a page template is provided by Oracle Application Development Framework (ADF) layout components.

After you decide on the appropriate layout to use for your page template (see Understanding Page Template Layout), you will use ADF layout components to create your page template. This is a complex task, and requires knowledge of the ADF components that will achieve the structure and layout you require, and best practices to employ (see Best Practices for Developing Page Templates).

Figure 7-2 and Figure 7-3 illustrate common ADF components used in a page template layout, showing the page template code followed by the generated layout:

  • af:panelGridLayout—a versatile layout component that uses rows (gridRow) and cells (gridCell) to define a structured layout. This component is the preferred general layout component as it offers a small client side footprint while being very flexible in layout capabilities. It allows you to more naturally define areas of the page to match your desired layout in the form of rows and columns. With panelGridLayout, you can easily specify fixed or variable column widths (% or pixels), which cannot be done as easily with other layout components. See Figure 7-2.

  • af:panelGroupLayout—a flowing series of components arranged horizontally, vertically, or in scrollable structures. Typically, panelGroupLayout is used with flowing layouts, and with flowing content inside a stretching layout. It provides vertical and horizontal scroll bars if the content does not fit into the available space. See Figure 7-2 and Figure 7-3.

  • af:panelSplitter—a stretched box divided into two user-modifiable sections. See Figure 7-3.

Figure 7-2 Page Template Code and Generated Stretching Layout: Example 1

Description of Figure 7-2 follows
Description of "Figure 7-2 Page Template Code and Generated Stretching Layout: Example 1"

Figure 7-3 Page Template Code and Generated Stretching Layout: Example 2

Description of Figure 7-3 follows
Description of "Figure 7-3 Page Template Code and Generated Stretching Layout: Example 2"

Best Practices for Developing Page Templates

Because page templates are present in every page of a portal, the design of your page templates should be carefully planned to optimize their performance and conform to best practices.

This section provides tips for developing page templates for WebCenter Portal (as a shared asset), or a specific portal.

Note:

Oracle recommends that you use JDeveloper to develop page templates for portals. You can also develop page templates in Oracle WebCenter Portal, but the editing capabilities are limited.

When fully developed, you can publish page templates to WebCenter Portal as a shared asset or to a specific portal for immediate use or for testing. Alternatively, you can export the page template to a file and upload the page template to WebCenter Portal later.

For more information, see Creating a Page Template, Editing a Page Template, and Publishing a Page Template.

Table 7-1 provides a quick reference summary of considerations and guidance for achieving the best results out of your page templates.

Table 7-1 Best Practices Summary for Page Templates

Considerations Best Practices

Performance

While all of this section is aimed at improving the performance of your page templates, there are a few general tips to keep in mind as overall best practices:

  • Minimize the use of embedded task flows. For examples, refer to the latest out-of-the-box page templates included with WebCenter Portal, described in About Built-in Page Templates in WebCenter Portal in Building Portals with Oracle WebCenter Portal.

  • Minimize the use of ADF layout components, using panelGridLayout to implement your page template structure. The fewer ADF layout components, the easier it is to apply skins.

  • Avoid using images for decorative purposes (such as rounded corners). Consider using CSS instead of images.

  • Defer loading of ADF components, such as menus and dialogs, where possible. This can be controlled through ADF such as contentDelivery, childCreation, and so on.

  • Avoid elements that require extra time in rendering page templates and try to substitute for elements that require less processing time.

Layout

One of the most important aspects of page template design is how to lay out components, both elements of the template and page content. Page templates can have a flowing layout or a stretching layout. For more details about these two strategies, see Understanding Page Template Layout.

As a page template developer, you can control whether the content facet is in a stretching or flowing region of the page. Page content must be created taking the layout strategy into consideration.

Once you decide on the best strategy for your page templates, see the following sections for tips on creating the layout you choose:

Navigation

A page template can expose the navigation for a portal in many ways. For example, in a desktop browser, portal navigation is typically shown along the top of the page, or down the side of the page:

  • A top navigation page template exposes the portal navigation in header area. Top navigation makes effective use of the horizontal space on the page, and is recommended when there are seven or fewer top level pages in the portal navigation. This page template design generally has a header, page and footer sections, and is an ideal starting point for sites that require a flowing layout.

  • A side navigation page template exposes the portal navigation in a sidebar on the left side of the page. The vertical nature of side navigation allows for a more lengthy list of navigation items, and is recommended when there are more than seven top level pages in the portal navigation. Choose a side navigation template for more complex navigation models.

On different devices, navigation can be exposed differently. For example, in page templates optimized for mobile devices, navigation can be provided as either a popup or slide in/out.

Skin

Each page template works together with a skin to determine the overall look and feel of the pages in your portal. While the page template controls the structure of components on the page, the skin controls the visual appearance of those components, such as the colors, fonts, and other aspects such as the position, height, and width of components on the page.

Each page template can define a preferred skin to identify the skin that works best with that page template. When the page template is selected as the default page template for a portal or as the system default, the default skin automatically updates to the page template's preferred skin.

For more information, see Developing Skins.

Runtime behavior

If you develop a page template in JDeveloper that you plan to allow authorized users to edit in Composer at runtime, follow the tips provided in Best Practices for Developing Page Templates That Can Be Edited at Runtime.

Components

Select Page or Page Template from the View Source menu for a component to see what tags and attributes are used as well as what the component structure looks like for the page.

Because a page template layout can be changed, create pages and design custom components that display properly in flowing and stretching context.

For tips on customizing the appearance of components, see Best Practices for Customizing the Appearance of Components.

Scrolling

Add scrollbars only around flowing island content. For tips on implementing scrollbars, see Best Practices for Defining Scrolling in a Page Template.

Margins, borders, and padding

Due to browser CSS Box Model Rules, defining margins, borders and padding on components might be complex. For tips on resolving the complexities of defining margins, borders and padding on components, see Best Practices for Defining Margins, Borders, and Padding.

Attributes

Consider attributes that can be set in your page templates or pages that use the page templates. For example, showFooter specifies whether or not to show the page footer.

A page template without attributes is syntactically correct. However, page template attributes are useful when you want to use one page template for several pages where the template should render slightly differently.

Information about using attributes in your page templates is provided throughout this chapter, including Creating a Page Template.

Links

To add links to page templates, copy components provided in the out-of-the-box page templates to include links navigation, menus, breadcrumbs, buttons, and images.

go components such as goButton and goLink have little to no client side footprint since they do not carry client side functionality. They are also preferred over command components (commandButton, commandLink) for general navigation in portals because they enable URLs that are optimized for search engines.

Internationalization

To create page templates with internationalization techniques in mind, see Guidelines for Building Multilanguage Portals for information about recommended practices such as storing static text in resource bundle files.

Naming page templates (display name)

The display name is exposed to users when creating a new page. For this reason, you should make the page template name something that helps users quickly identify which type of pages the template should be used for.

Best Practices for Creating Stretching Layouts

If your page template is best suited to a stretching layout, follow these tips as you develop the layout.

For more information about different layouts, see Understanding Page Template Layout.

  • Build the outer structure with containers that can be stretched and can stretch their children. Inside your document component, use containers such as panelGridLayout (Figure 7-2) with rows (gridRow) and cells (gridCell), and panelSplitter (Figure 7-3).

    Note:

    Each layout or panel component's tag documentation identifies whether it is stretchable and how to achieve it in its "Geometry Management" documentation. Some components have attributes to determine whether children will be stretched or not. For example: document has a maximized attribute, showDetailItem has a stretchChildren attribute.

  • Create flowing islands. Inside of the stretchable outer structure, create islands of flowing (non-stretched) components. To make this transition from stretching to flowing, use panelGroupLayout with layout="scroll" or layout="vertical" since it supports being stretched but will not stretch its children.

  • On stretching components, set dimensionsFrom="auto" so that the stretching component (for example, panelStretchLayout) will only try to stretch its child if it itself is being stretched. If it is not being stretched, then it will flow (not stretch) its children.

  • Do not stretch something vertically (by using a height with a percent value) when inside a flowing container.

  • Do not use the position CSS property in an inlineStyle. Doing so will impede the ability to override this property with a style specified in the skin.

Note:

The following components are just some of the components that cannot be reliably stretched:

  • Most input components

  • panelBorderLayout

  • panelFormLayout

  • panelGroupLayout (with layout="default")

  • panelGroupLayout (with layout="horizontal")

  • panelHeader (with type="flow")

  • panelLabelAndMessage

  • panelList

  • panelGrid

Best Practices for Creating Flowing Layouts

If your page template is best suited to a flowing layout, follow these tips as you develop the layout.

For more information about different layouts, see Understanding Page Template Layout.

  • Use panelGridLayout with rows (gridRow) and cells (gridCell) to define a structured layout that will flow.

  • To avoid multiple scroll bars, do not nest scrolling panelGroupLayout components, instead use layout="vertical".

  • Most stretchable ADF components also work in flowing context with dimensionsFrom="auto".

  • To stretch a component horizontally, use styleClass="AFStretchWidth" (instead of inlineStyle="width:100.0%").

Working with customizable components:

  • In panelCustomizable, use layout="auto" to detect whether to stretch its children.

  • To support flowing and stretching layouts, use showDetailFrame with stretchChildren="auto".

Best Practices for Developing Page Templates That Can Be Edited at Runtime

To create a page template at design time (in Oracle JDeveloper) that is suited to being editable at runtime (in Oracle WebCenter Portal), follow these tips.

  • Add components from the Composer group in the Component Palette.

  • Do not add pageCustomizable to a page template.

  • Add at least one panelCustomizable component, which provides a container with horizontal or vertical layout that holds other components.

  • Inside a panelCustomizable component, add ADF components (such as outputText, richTextEditor, or goLink) surrounded by a showDetailFrame, which provides a chrome for a component that enables you to add actions like show, hide, and move. You can edit the frame or the embedded component properties.

    Caution:

    Use this technique sparingly, as showDetailFrame components impact processing time. If the end user is not expected to move components around, do not wrap them in a showDetailFrame.

Many of the components available to add to a page at design time are also available at runtime in the resource catalog. Table 7-2 maps design time components to runtime components.

Table 7-2 Component Mapping: Design time to Runtime

Design Time (JDeveloper) Runtime (WebCenter Portal)

panelCustomizable

Box

outputText

HTML Markup

goLink

Hyperlink

goImageLink

Image

showDetailFrame

Movable Box

richTextEditor

Text

inlineFrame

Web Page

Best Practices for Customizing the Appearance of Components

To customize the appearance of components, follow these tips.

  • For custom styling, use Cascading Style Sheets (CSS), which is easy to maintain and can be changed without changing the page template source. For example, make the background color of a page blue using the CSS code background-color: blue.

  • Use a custom skin for consistently modified appearances if the existing skin doesn't provide all that you need.

  • For instance-specific alternative styling, use the styleClass attribute. Keep the corresponding style definitions in an easy-to-maintain location such as in a custom skin (recommended) or in a style provided by the af:resource tag.

  • As a last resort, use component attributes such as inlineStyle, contentStyle, and labelStyle. These are harder to maintain as they are scattered throughout components rather than collected in a single style sheet, contribute more to the page's raw HTML size, and may not even be needed if one or more of the above mechanisms are used. Styles are directly processed by the web browser, which gives you a great deal of power but at the cost of being error-prone.

  • Browsers do not support all styles on all elements and certain combinations of styles produce non-obvious results. Here is some guidance on style configurations to avoid:

    • An inlineStyle with a height value with % units

    • An inlineStyle with a width value between 90% and 100% (use styleClass="AFStretchWidth" or styleClass="AFAuxiliaryStretchWidth" instead)

    • An inlineStyle with height, top, and bottom values

    • An inlineStyle with width, left, and right values

    • An inlineStyle with a position value

    • In a child being stretched by a parent component, an inlineStyle with width or height values

Best Practices for Defining Scrolling in a Page Template

To define scrolling in a page template, follow these tips.

  • Try to avoid the need for end users to scroll horizontally by designing the page content to occupy the available screen size.

  • Add scrollbars only around flowing island content. The recommended transition component for switching from a stretching outer frame into a flowing island is the panelGroupLayout with layout="scroll". If the contents of this panelGroupLayout cannot fit in the space allocated, the browser will determine whether scrollbars are needed and will add them automatically.

  • Do not nest scrolling panelGroupLayout components because this will make the user see multiple scrollbars. Also, this should only be used at transitions from stretching to flowing areas and since you should not have stretching areas inside of flowing areas, you would generally never end up with nested scrollbars. It is best to minimize the number of areas that users must scroll in order to see what they are looking to find. Take time to consider what scrolling users will need. In cases where undesired scrollbars exist, you may want to change the layout attribute of the panelGroupLayout to vertical.

Best Practices for Defining Margins, Borders, and Padding

Due to browser CSS Box Model Rules, defining margins, borders and padding on components can be complex. In many cases, to apply these kinds of styles, you need to use multiple components together.

  • In a scrolling area, you can add an extra panelGroupLayout with layout="vertical" with the padding defined on it, inside of the outer panelGroupLayout with layout="scroll".

  • In a stretching area, you may need to wrap a panelGroupLayout component inside a panelGridLayout with spacers inside gridCell components. See Figure 7-2.

Creating a Page Template

This section contains the following subsections:

About Creating Page Templates

Before you can design your page template, you must first create a WebCenter Portal Asset application for the page template.

Before you create a page template, be sure to read through Best Practices for Developing Page Templates.

Note:

Oracle recommends that you use JDeveloper to develop page templates for Oracle WebCenter Portal. You can also develop page templates in WebCenter Portal, but the editing capabilities are limited.

When fully developed, you can publish a page template directly to WebCenter Portal as a shared asset or to a specific portal for immediate use or for testing. Alternatively, you can export the page template to a file and upload the page template to WebCenter Portal later

For more information, see Editing a Page Template and Publishing a Page Template.

For examples of features that you can include in your own page templates, refer to the built-in page templates provided with WebCenter Portal, specifically the latest responsive page templates (Mosaic and Unicorn), and other page templates that minimize the use of task flows and include the performance-optimizing panelGridLayout component, which uses rows (gridRow) and cells (gridCell) to define a structured layout. See About Built-in Page Templates in WebCenter Portal in Building Portals with Oracle WebCenter Portal.

You can start by copying and pasting one of one of the built-in templates into JDeveloper, or you can build an entirely new page template from scratch. Even if you do not intend to base your page templates on the built-in ones at all, it is still worth studying them for ideas. For example, the built-in page templates include a login form, and a good example of navigation visualization, which you can modify according to your requirements.

How to Create a Page Template

This section describes how to create a WebCenter Portal asset application for a new page template.

To create a custom page template:

  1. Create a WebCenter Portal asset application for the asset, selecting Page Template as the Asset Type.

    Figure 7-4 Page Template Asset Type

    Description of Figure 7-4 follows
    Description of "Figure 7-4 Page Template Asset Type"

    See Creating a WebCenter Portal Asset Application for more information about creating WebCenter Portal asset applications.

    A JSPX file is created for the page template.

    Figure 7-5 Page Template JSPX File

    Description of Figure 7-5 follows
    Description of "Figure 7-5 Page Template JSPX File"

    For more information about the artifacts created when you create an asset application for a new page template, see What You May Need to Know About Page Template Artifacts.

  2. Continue by editing the contents of the JSPX file as described in Editing a Page Template.

What You May Need to Know About Page Template Artifacts

Creating a page template asset application produces a default template, with the following artifacts:

  • A JSPX file containing the page elements for the page template (for example, PageTemplate1.jspx)

  • The corresponding page definition file for the page template (for example, PageTemplate1PageDef.xml)

Both of these files appear in the Application Navigator as shown in Figure 7-6.

Figure 7-6 Page Template Asset Application Artifacts

Description of Figure 7-6 follows
Description of "Figure 7-6 Page Template Asset Application Artifacts"

Editing a Page Template

After creating a WebCenter Portal asset application and initial page template, continue by adding or modifying elements.

To edit a page template:

  1. In the Application Navigator, right-click the JSPX file of the page template that you want to edit, and choose Open.
  2. In the editor, make required changes to the layout and content of the page template by dragging components from the Component Palette.

    For more information about how to build your page template, see Introduction to Developing Page Templates and Best Practices for Developing Page Templates.

    The built-in page templates provide useful examples of page templates, and see also Page Template Tutorials and Examples.

    For general information about JSF page templates, see Using Page Templates in Developing Web User Interfaces with Oracle ADF Faces.

  3. Save your changes.

Adding Navigation to a Page Template

One of the key parts of a page template is the navigation visualization. This determines how the navigation looks and behaves in your portal.

You can add navigation to a page or page template using built-in navigation task flows, or you can add custom navigation using ADF navigation components and the Oracle WebCenter Portal navigation APIs, as described in this section.

Note:

You can add navigation visualization to a page, but typically you add it to a page template so that it can be defined in one place and propagated consistently across all pages in a portal.

About Visualizing Portal Navigation

The navigation visualization determines how the navigation appears in a portal. For example, navigation can be provided as a set of tabs along the top of each page, or perhaps as a tree structure along the side of the page. Another common navigation visualization is to provide a "master-detail" navigation of tabs along the top of the page, with each tab having additional navigation provided as a tree structure along the side of the page.

Typically, you add navigation visualization to page templates, so that it can be defined in one place and propagated consistently across the whole portal. However, you can also add navigation visualization to individual pages.

Oracle WebCenter Portal provides three built-in navigation task flows that you can add to pages or page templates to visualize the navigation. These built-in navigation task flows provide a quick way to test your navigation model, but they provide a fairly simple navigation visualization.

It is more likely that you will require a more advanced visualization. To do this, you must create your own navigation UI using ADF navigation components and the Oracle WebCenter Portal navigation APIs.

Note:

If the navigation model referenced by the page or page template includes External Link navigation items that use mailto: links, you must explicitly handle these. The example below uses JSTL to inspect the navigation item's externalURL to see if it starts with the string mailto:. If it does, an ADF Faces goLink component is used to render the link.

<c:choose>
  <c:when test="${fn:startsWith(node.externalURL, 'mailto:')}">
   <af:goLink id="pt_gl_mail" text="#{node.title}
       "destination="#{node.externalURL}"/>
  </c:when>
  <c:otherwise>
    ...
  </c:otherwise>
</c:choose>

Oracle WebCenter Portal provides two sets of APIs for adding navigation to your portal:

  • Expression Language (EL) APIs—Use EL expressions to obtain the navigation model and navigation nodes. For more information, see Using the Navigation Expression Language APIs.

  • REST APIs—Use standard HTTP methods to point to the navigation model and navigation nodes, returning a standard representation of any retrieved object. REST APIs can be used when using client-side programming languages (for example JavaScript + HTML, or environments, for example an iPhone). For more information, see Using the Navigation Expression Language APIs.

Note:

Any task flow that uses the navigation model to trigger navigation within an application must include a parent-action activity, named wcnav_parentAction, in the task flow definition that propagates the wcnav_outcome to the root level, as follows:

<parent-action id="wcnav_parentAction">
  <root-outcome>wcnav_outcome</root-outcome>
</parent-action>

Using the Navigation Expression Language APIs

Oracle WebCenter Portal provides a set of expression language (EL) APIs that you can use to obtain the navigation model and represent that navigation model as a runtime model. The runtime models can be bound directly to ADF Faces navigation components.

The available navigation EL expressions are listed in full in ELs Related to Navigation.

This section includes the following topics:

Note:

This section includes some examples of how to use the navigation EL APIs. For a full working example, see the default page templates (pageTemplate_globe.jspx and pageTemplate_swooshy.jspx) created when you create a portal.

Introduction to the Navigation Context

The Navigation Context is the entry point to access all navigation elements within your system. Specifically, it enables you to access navigation models via preference, state, and direct reference, as well as providing the hooks to create custom UI to actually navigate to the nodes.

Navigation Model Access

  • Default navigation model (preference)—This is the model specified by the ADF preference oracle.webcenter.portalapp.navigation.model in the adf-config.xml file. This enables you to define the general model to be used throughout your application and enables you to change the value in one place rather than having to go to each page and page template to set the value. The EL expression to retrieve the default navigation model is:

    #{navigationContext.defaultNavigationModel}
  • Current navigation model (state)—This model is the one used to navigate to the current portal. The EL expression to retrieve the navigation model for the current portal is:

    #{navigationContext.currentNavigationModel}

    Using this expression enables you to have a single value within a page or page template (for example, for displaying breadcrumbs) and have it display the correct value without having to select a specific navigation model.

  • Direct navigation model access (direct reference)—You can also select a specific navigation model by passing in the path to the XML definition of the model. The EL expression to retrieve a specific navigation model is:

    #{navigationContext.navigationModel['modelPath=path']

    where path is the path to the navigation model definition file, for example:

    #{navigationContext.navigationModel['modelPath=/oracle/webcenter/portalapp/navigations/myNavigation']}

    Note:

    You do not need to include the .xml file name extension.

Resource Navigation

Use these ELs for core bean operations for binding the navigation model to the UI component's actionListener attribute. For example:

#{navigationContext.processAction}

Example 7-1 Simple Tree Navigation UI

This example creates a simple tree UI using the Navigation Context to access the current navigation model and render the tree using <af:outputText/>

<af:tree var="node"   
  value="#{navigationContext.currentNavigationModel.treeModel['startNode=/,    
  includeStartNode=true,     
  depth=1']}"   
  id="t1">  
<f:facet name="nodeStamp"> 
    <af:outputText value="#{node.title}" id="ot1"/>
   </f:facet>
 </af:tree>

Example 7-2 Binding the Navigation Model to the UI Component

This example uses the Navigation Context's processAction listener to handle navigation for an ADF commandImageLink component, passing in the current node as the parameter called node as an attribute to the actionListener.

<af:tree var="node"   
    value="#{navigationContext.currentNavigationModel.treeModel['startNode=/,
       includeStartNode=true,
       depth=1']}"
    id="t1">
  <f:facet name="nodeStamp">
    <af:commandImageLink text="#{node.title}"
        id="sm_c1b"
        actionListener="#{navigationContext.processAction}"
         inlineStyle="#{node.selected ? 'font-weight:bold;' : ''}">
       <f:attribute name="node" value="#{node}"/>
    </af:commandImageLink>
  </f:facet>
</af:tree>
Introduction to the Navigation Runtime Model

The Navigation Runtime Model exposes the underlying XML definition as runtime models, as well as providing direct access to individual nodes. The runtime models take into account such factors as security and visibility to produce a session-specific representation that can be bound to UI objects.

Note:

Note the difference between the navigation model that you create to define the content, structure, and metadata of the navigation and the navigation runtime model that determines how the navigation model behaves at runtime.

You can access the whole model by using the default runtime model (defaultTreeModel, defaultListModel, defaultMenuModel, and defaultSiteMap), or access a specific sub-tree using the various parameters when creating the runtime model. For example:

#{navigationContext.defaultNavigationModel.menuModel['startNode=home,
    includeStartNode=false, depth=2']}

For more information about the underlying ADF Faces MenuModel, TreeModel, and ListModel, see Web User Interface Developer's Guide for Oracle Application Development Framework.

Model Access

You can create the following runtime models based on the underlying navigation model:

  • UI Models

    • Tree model

      #{navigationContext.defaultNavigationModel.defaultTreeModel}
      #{navigationContext.defaultNavigationModel.treeModel['parameters']}
    • Menu model

      #{navigationContext.defaultNavigationModel.defaultMenuModel}
      #{navigationContext.defaultNavigationModel.menuModel['parameters']}
    • List model

      #{navigationContext.defaultNavigationModel.defaultListModel}
      #{navigationContext.defaultNavigationModel.listModel['parameters']}
  • Search Engine Model

    • Sitemap

      #{navigationContext.defaultNavigationModel.defaultSiteMap}
      #{navigationContext.defaultNavigationModel.siteMap['parameters']}

Resource (or Node) Access

You can access specific nodes within the navigation model using the follow EL expressions:

  • #{navigationContext.defaultNavigationModel.currentSelection}
  • #{navigationContext.defaultNavigationModel.rootNode}
  • #{navigationContext.defaultNavigationModel.node['path']}

Example 7-3 Rendering the Navigation Model as a Menu Model

This example renders the current navigation model's menu model as a breadcrumb.

<af:breadCrumbs id="bc1"
    var="node"
    value="#{navigationContext.currentNavigationModel.defaultMenuModel}">
  <f:facet name="nodeStamp">
    <af:commandNavigationItem id="cni1"
        text="#{node.title}"
        actionListener="#{navigationContext.processAction}"
        partialSubmit="true">
      <f:attribute name="node" value="#{node}"/>
    </af:commandNavigationItem>
  </f:facet>
</af:breadCrumbs>

Example 7-4 Producing a Sitemap

This example produces a Sitemap for the application based on the default navigation model.

<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"  version="2.1"
    xmlns:f="http://java.sun.com/jsf/core">
  <jsp:directive.page contentType="text/xml;charset=UTF-8" />
  <f:view>
    ${navigationContext.defaultNavigationModel.defaultSiteMap}
  </f:view>
</jsp:root>
Introduction to the Navigation Resource

The Navigation Resource provides access to individual properties against each node within the navigation model. These fall into the following categories:

  • Attributes-Common properties that the user can specify against any navigation element and are used for rendering the node on the page, including:

    • Title—The title displayed for the node when the navigation model is rendered at runtime.

    • AccessKey—A key mnemonic (single character) that users can enter to access the node without using the mouse

    • Description—A description of the node.

    • IconURI—An icon to visually represent the node. This is displayed next to the Title when the navigation model is rendered at runtime.

    • Subject—Keywords to facilitate searching of the node.

    • Target—The location on the container page where the node is displayed when it is selected, either in the same browser window (_self), a new window (_blank), or a popup (_popup), or any other location supported by the navigation UI.

    • ToolTip—Text that displays to provide additional information about the node when users hover the mouse over the Title.

    • Modified—The date of the last modification of the node. This attribute is used for Sitemap creation.

    • Significance—The priority of this node relative to other nodes in the navigation model, within the range 0.0 to 1.0. This attribute is used for Sitemap creation.

    • ChangeFrequency—This attribute is used to specify how frequently the node is likely to change, for example, always, hourly, daily, weekly, monthly, yearly, never. This attribute is used for Sitemap creation.

    • ExternalId—An ID to enable a direct reference to any node in the navigation model from a static link in the page.

    • ActionsAllowed—This attribute is used to manage security permissions like grant, create, publish, delete, update, contribute, and view for the navigation resource.

    • hasChild—This attribute is used to verify whether the node or resource has any children or not.

  • Parameters—User-defined properties that are specific to each node. These are name/value pairs and can contain any value.

  • State—Built-in properties that you can query and use to navigate to the node. For example:

    • Type of node, for example, folder or separator

    • Whether the node is navigable

    • The path to the node

    • Parent, child, or sibling node access

    • Whether the node is the currently selected node within the navigation model or on the selected node's path

For a complete list, see ELs Related to Navigation

Example 7-5 Rendering a commandImageLink with Attributes

This example renders an ADF commandImageLink component with various attributes.
<af:commandImageLink text="#{node.title}"
    id="cil1"
    actionListener="#{navigationContext.processAction}"
    shortDesc="#{node.attributes['ToolTip']}"
    accessKey="#{node.attributes['AccessKey']}"
    inlineStyle="#{node.selected ? 'font-weight:bold;' : ''}">
  <f:attribute name="node" value="#{node}"/>
</af:commandImageLink>

Example 7-6 Passing Node Values to Page Parameters

This example accesses values passed from a node to the corresponding page through parameters.


homePageDef.xml

<pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel"
    version="11.1.1.55.96" id="homePageDef"
    Package="oracle.webcenter.portalapp.pages">  
  <parameters>
    <parameter id="NavigationParameter"
        value="#{navigationContext.currentNavigationModel.currentSelection.parameters['MyNavParam']}"/>
  </parameters>

Example 7-7 Conditionally Displaying Navigation Nodes

This example conditionally displays breadcrumb links based on whether you can navigate to the node. It also bases the UI component on the type of the node.

<af:breadCrumbs id="bc1"
                var="node"
                value="#{navigationContext.currentNavigationModel.defaultMenuModel}">
  <f:facet name="nodeStamp">
    <af:switcher facetName="#{node.navigable}" id="swn1">
      <f:facet name="true">
        <af:commandNavigationItem id="cni1" text="#{node.title}"
                                  actionListener="#{navigationContext.processAction}"
                                  partialSubmit="true">
          <f:attribute name="node" value="#{node}"/>
        </af:commandNavigationItem>
      </f:facet>
      <f:facet name="false">
        <af:outputText value="#{node.title}" rendered="#{!node.separator}" id="ot3"/>
      </f:facet>
    </af:switcher>
  </f:facet>
</af:breadCrumbs>
How to Render the Navigation Model as a List of Links

One common way to visualize a portal's navigation is as a list of links. Clicking a link navigates to the resource associated with it.

Example 7-8 retrieves the list model for the current navigation model and renders it vertically on the page. The code iterates through the navigation model, binding each node in turn to an ADF commandImageLink component. If a node contains children, a second iterator renders those children on the page. If a node is not navigable, it is not rendered as a link. The currently selected node is displayed in bold.

Example 7-8 Navigation as a List of Links

af:panelGroupLayout id="pgl1" layout="vertical">
  <af:spacer id="sp1" height="20px"/>             
  <af:iterator id="i1"
               value="#{navigationContext.currentNavigationModel.listModel['startNode=/,
                     includeStartNode=false']}"
               var="node">
    <af:panelGroupLayout layout="vertical">
      <af:commandImageLink id="cil2" text="#{node.title}"
                           actionListener="#{navigationContext.processAction}"
                           action="pprnav"
                           icon="#{node.attributes[pageFlowScope.tnBean.iconKey]}"
                           disabled="#{not node.navigable}"
                           inlineStyle="#{node.onSelectedPath ? 'font-weight:bold;' : ''}">
        <f:attribute name="node" value="#{node}"/>
      </af:commandImageLink>
      <af:iterator id="i2" value="#{node.children}" var="node2">
        <af:panelList id="pl1">
          <af:commandImageLink id="cil3" text="#{node2.title}"
                               actionListener="#{navigationContext.processAction}"
                               action="pprnav"
                               icon="#{node2.attributes[pageFlowScope.tnBean.iconKey]}"
                               disabled="#{not node2.navigable}"
                               inlineStyle="#{node2.onSelectedPath ? 'font-weight:bold;' : ''}">
            <f:attribute name="node" value="#{node2}"/>
          </af:commandImageLink>
        </af:panelList>
      </af:iterator>
    </af:panelGroupLayout>
  </af:iterator>
  <af:spacer id="sp3" height="20px"/>
</af:panelGroupLayout>
How to Render the Navigation Model as a Tree

Another common way to visualize portal navigation is as a tree structure. A navigation tree is typically listed down the side of the page, so it is a useful way of displaying the entire navigation hierarchy. Users can navigate immediately to any node in the navigation. The advantage of using a tree structure over a simple list of links, is that users can expand and collapse the different nodes of the navigation model.

To include a tree structure in your page or page template, you can bind the ADF Faces tree navigation component to your navigation model. Example 7-9 shows how to do this. In the example, the second level of the navigation hierarchy is collapsed by default, but an icon enables users to expand a node to show its children.

Example 7-9 Navigation as a Tree

<af:panelGroupLayout id="pgl1" layout="vertical">
  <af:spacer id="sp2" height="20px"/>              
  <af:tree id="tree1" var="node" initiallyExpanded="true"
           value="#{navigationContext.currentNavigationModel.treeModel['includeStartNode=false']}">
    <f:facet name="nodeStamp">
      <af:commandImageLink id="cil2" text="#{node.title}"
                           actionListener="#{navigationContext.processAction}"
                           action="pprnav"
                           icon="#{node.attributes[pageFlowScope.tnBean.iconKey]}"
                           disabled="#{not node.navigable}"
                           inlineStyle="#{node.onSelectedPath ? 'font-weight:bold;' : ''}">
        <f:attribute name="node" value="#{node}"/>
      </af:commandImageLink>
    </f:facet>
  </af:tree>
  <af:spacer id="sp3" height="20px"/>
</af:panelGroupLayout>
How to Render the Navigation Model as a Three-Level Menu

You can also render your navigation as a menu. In a menu, the top level of navigation is displayed. When the user hovers the mouse over a particular node, if that node has children, they are displayed as a popup menu.

Example 7-10 retrieves the list model for the current navigation model and renders it vertically on the page. The code iterates through the navigation model. If a node contains children, then a second iterator iterates through those children. Nodes without children are rendered as menu items. In the second level of the navigation model, if any of the nodes have children, then a third iterator is executed. Again, nodes without children are rendered as menu items. At the third level of the navigation mode, nodes are rendered as menu items. Non-navigable nodes are not rendered as links. The currently selected node is displayed in bold.

Example 7-10 Navigation as a Menu

<af:panelGroupLayout id="pgl1" layout="vertical">
  <af:spacer id="sp1" height="20px"/>
  <af:menuBar id="mb1">
    <af:iterator id="i1"
                 value="#{navigationContext.currentNavigationModel.listModel['startNode=/, 
                       includeStartNode=false']}"
                 var="node">
      <af:switcher id="s1"
                   facetName="#{empty node.children ? 'leafNode' : 'parentNode'}">
        <f:facet name="parentNode">
          <af:menu id="m1" text="#{node.title}"
                   inlineStyle="#{node.onSelectedPath ? 'font-weight:bold;' : ''}">
            <af:iterator id="i2" value="#{node.children}"
                         var="node2">
              <af:switcher id="s2"
                           facetName="#{empty node2.children ? 'leafNode' : 'parentNode'}">
                <f:facet name="parentNode">
                  <af:menu id="m2" text="#{node2.title}"
                           inlineStyle="#{node2.onSelectedPath ? 'font-weight:bold;' : ''}">
                    <af:iterator id="i3" value="#{node2.children}"
                                 var="node3">
                      <af:commandMenuItem id="cml3"
                                          text="#{node3.title}"
                                          actionListener="#{navigationContext.processAction}"
                                          action="pprnav"
                                          icon="#{node3.attributes[pageFlowScope.tnBean.iconKey]}"
                                          disabled="#{not node3.navigable}"
                                          inlineStyle="#{node3.onSelectedPath ?
                                                      'font-weight:bold;' : ''}">
                        <f:attribute name="node" value="#{node3}"/>
                      </af:commandMenuItem>
                    </af:iterator>
                  </af:menu>
                </f:facet>
                <f:facet name="leafNode">
                  <af:commandMenuItem id="cml1"
                                      text="#{node2.title}"
                                      actionListener="#{navigationContext.processAction}"
                                      action="pprnav"
                                      icon="#{node2.attributes[pageFlowScope.tnBean.iconKey]}"
                                      disabled="#{not node2.navigable}"
                                      inlineStyle="#{node2.onSelectedPath ?
                                                  'font-weight:bold;' : ''}">
                    <f:attribute name="node" value="#{node2}"/>
                  </af:commandMenuItem>
                </f:facet>
              </af:switcher>
            </af:iterator>
          </af:menu>
        </f:facet>
        <f:facet name="leafNode">
          <af:commandMenuItem id="cml2" text="#{node.title}"
                              actionListener="#{navigationContext.processAction}"
                              action="pprnav"
                              icon="#{node.attributes[pageFlowScope.tnBean.iconKey]}"
                              disabled="#{not node.navigable}"
                              inlineStyle="#{node.onSelectedPath ? 'font-weight:bold;' : ''}">
            <f:attribute name="node" value="#{node}"/>
          </af:commandMenuItem>
        </f:facet>
      </af:switcher>
    </af:iterator>
  </af:menuBar>
  <af:spacer id="sp3" height="20px"/>
</af:panelGroupLayout>
How to Render the Navigation Model as Breadcrumbs

To provide users with a quick way of orientating themselves within the portal navigation, you can provide a trail of breadcrumbs on the page. Breadcrumbs show the current location in the portal and the path taken through the navigation to get there. Users can then quickly return to any point along that path. Breadcrumbs are typically used on a page in addition to other forms of navigation.

To include breadcrumbs in your page or page template, you can bind the ADF Faces breadCrumbs navigation component to your navigation model. Example 7-11 shows how to do this.

Example 7-11 Navigation as Breadcrumbs

<af:panelGroupLayout id="pgl1" layout="vertical">
  <af:spacer id="sp1" height="20px"/>
  <af:breadCrumbs id="bc1" var="node"
                  value="#{navigationContext.currentNavigationModel.menuModel[
                        'includeStartNode=false']}">
    <f:facet name="nodeStamp">
      <af:commandNavigationItem id="cil1" text="#{node.title}"
                                actionListener="#{navigationContext.processAction}"
                                action="pprnav"
                                icon="#{node.attributes[pageFlowScope.tnBean.iconKey]}"
                                disabled="#{not node.navigable}">
        <f:attribute name="node" value="#{node}"/>
      </af:commandNavigationItem>
    </f:facet>
  </af:breadCrumbs>
  <af:spacer id="sp2" height="20px"/>
</af:panelGroupLayout>
How to Render Master-Detail Navigation

Often portals provide a "master-detail" navigation visualization, for example, as tabs along the top of the page, with each tab having additional navigation provided as a tree structure along the side of the page.

The master-detail navigation in Example 7-12 uses the same navigation model for the master and detail navigation. The master navigation renders the top level of the navigation model as a list of links along the top of the page. The detail navigation renders the children of the currently selected top level node as a tree.

Tip:

For the c:set tag to work correctly in the following examples, you must include the JSTL library by adding the following to the jsp:root tag

xmlns:c="http://java.sun.com/jsp/jstl/core"

Example 7-12 Master-Detail Navigation Using a Single Navigation Model

<af:panelGroupLayout id="pgl1" layout="vertical">
  <af:spacer id="sp1" height="20px"/>
  <!-- Master --><af:navigationPane id="np1" var="node" hint="bar" level="1" value="#{navigationContext.navigationModel['modelPath=/oracle/webcenter/portalapp/navigations/master'].defaultMenuModel}"><f:facet name="nodeStamp">
      <af:commandNavigationItem id="cil1" text="#{node.title}"
                                actionListener="#{navigationContext.processAction}"
                                action="pprnav"
                                icon="#{node.attributes[pageFlowScope.tnBean.iconKey]}"
                                disabled="#{not node.navigable}"
                                inlineStyle="#{node.onSelectedPath ? 'font-weight:bold;' : ''}">
        <f:attribute name="node" value="#{node}"/>
      </af:commandNavigationItem>
    </f:facet>
  </af:navigationPane>
  <af:spacer id="sp2" height="20px"/>
  <!-- Setup the parameters for detail query -->
  <c:set value="startNode=/${navigationContext.navigationModel[
               'modelPath=/oracle/webcenter/portalapp/navigations/master']
               .currentSelection.prettyUrlPath[1]}, includeStartNode=false"
         var="currSel" scope="session"/>
  <!-- Detail --><af:tree id="tree1" var="node2" initiallyExpanded="true" value="#{navigationContext.navigationModel['modelPath=/oracle/webcenter/portalapp/navigations/master'].treeModel[currSel]}">
    <f:facet name="nodeStamp">
      <af:commandImageLink id="cil2" text="#{node2.title}"
                           actionListener="#{navigationContext.processAction}"
                           action="pprnav"
                           icon="#{node2.attributes[pageFlowScope.tnBean.iconKey]}"
                           disabled="#{not node2.navigable}"
                           inlineStyle="#{node2.onSelectedPath ? 'font-weight:bold;' : ''}">
        <f:attribute name="node" value="#{node2}"/>
      </af:commandImageLink>
    </f:facet>
  </af:tree>
  <af:spacer id="sp3" height="20px"/>
</af:panelGroupLayout>

Example 7-13 Master-Detail Navigation Using Multiple Navigation Models

Example 7-12 can also be written to use two different navigation models, one for the master navigation, and one for the detail navigation. This example shows how to write for two different navigation models.

<af:panelGroupLayout id="pgl1" layout="vertical">
  <af:spacer id="sp1" height="20px"/>
  <!-- Master -->
<af:navigationPane id="np1" var="node" hint="bar" level="1"
            value="#{navigationContext.navigationModel[
                 'modelPath=/oracle/webcenter/portalapp/navigations/master']
                 .defaultMenuModel}">
  <f:facet name="nodeStamp">
      <af:commandNavigationItem id="cil1" text="#{node.title}"
                                actionListener="#{navigationContext.processAction}"
                                action="pprnav"
                                icon="#{node.attributes[pageFlowScope.tnBean.iconKey]}"
                                disabled="#{not node.navigable}"
                                inlineStyle="#{node.onSelectedPath ? 'font-weight:bold;' : ''}">
        <f:attribute name="node" value="#{node}"/>
      </af:commandNavigationItem>
    </f:facet>
  </af:navigationPane>
  <af:spacer id="sp2" height="20px"/>
  <!-- Setup the parameters for detail query -->
  <c:set value="startNode=/${navigationContext.navigationModel[
               'modelPath=/oracle/webcenter/portalapp/navigations/master']
               .currentSelection.prettyUrlPath[1]}, includeStartNode=false"
         var="currSel" scope="session"/>
  <!-- Detail -->
<af:tree id="tree1" var="node2" initiallyExpanded="true"
          value="#{navigationContext.navigationModel
             ['modelPath=/oracle/webcenter/portalapp/navigations/master']
             .treeModel[currSel]}">
    <f:facet name="nodeStamp">
      <af:commandImageLink id="cil2" text="#{node2.title}"
                           actionListener="#{navigationContext.processAction}"
                           action="pprnav"
                           icon="#{node2.attributes[pageFlowScope.tnBean.iconKey]}"
                           disabled="#{not node2.navigable}"
                           inlineStyle="#{node2.onSelectedPath ? 'font-weight:bold;' : ''}">
        <f:attribute name="node" value="#{node2}"/>
      </af:commandImageLink>
    </f:facet>
  </af:tree>
  <af:spacer id="sp3" height="20px"/>
</af:panelGroupLayout>

Tips for Visualizing Portal Navigation

When visualizing a portal navigation model, consider the following:

  • Use ADF Faces layout components to organize your page or page template, rather than HTML div and span tags. See ADF Faces Layout Components in Developing Web User Interfaces with Oracle ADF Faces.

  • If your portal is public facing, or you want to enable search engine optimization, add navigation visualization using the af:goLink component in conjunction with the goLinkPrettyUrl method. You can also use other variations, such as goButton, goImageLink, and goMenuItem.

    For example:

    <af.goLink
    destination="#{navigationContext.defaultNavigationModel.node['pagePath']
         .goLinkPrettyUrl"} 
    text="mylink" />
  • Manage styling, decorative images, and geometry using skins.

  • Select the page template using the default page template setting in adf-config.xml or using the Render URL in Page Template option for individual navigation links.

  • If you use the af:commandLink component, or one of its variations such as commandButton; commandMenuItem; and so on, to visualize your portal navigation, you must use the following web.xml parameters to force the ADF framework to redirect instead of using PPR navigation:

    oracle.adf.view.rich.pprNavigation.OPTIONS
    oracle.webcenter.navigationframework.REDIRECT_OPTIONS

For more information, see the Oracle WebCenter & ADF Architecture Team blog.

Adding a Floating Toolbar to a Page Template

When users with the Contribute Page Content permission view a page, they will see a floating toolbar with a Contribute option when the page template includes the toolbar.

To add the floating toolbar to a custom page template:
  1. Include the following xml namespace declaration  (if not already present):
  2. Within the xml namespace declaration, include the following reference to the floating toolbar:
    <wcdc:portalToolbar id="ptbdc"/>

    Figure 7-7 shows how the floating toolbar with the Contribute option will appear when the page template includes the toolbar.

    Figure 7-7 The Contribute Button in the Floating Toolbar

    The Contribute button in the floating toolbar.
For more information, see About Content Contribution and Publishing in Building Portals with Oracle WebCenter Portal.

Publishing a Page Template

After creating a page template and editing its JSPX file, the next step is to publish and test the template in WebCenter Portal.

For instructions on how to publish a page template as a shared asset, or to a specific portal as a portal asset, see Publishing WebCenter Portal Assets.

Page Template Tutorials and Examples

The supplementary tutorials and examples listed in this section provide additional information about page templates.