Best Practices from Oracle Development's A‑Team

Dynamic Page Styles Using Dynamic Declarative Components


In WebCenter Portal (WCP), once a page is created with a particular style, any subsequent changes to that style are not applied to those existing pages.  Internally, the page style definition is copied when the page is created, so there is no link back to those pages when the page style is updated.  The impact of this design approach is that changes to a page style can be expensive, since all existing pages have to be manually edited to conform to the updated page style appearance.  This cost only increases as the number of pages increases, and as the number of modifications increases over time.

This blog post describes a technique for making page styles more dynamic, by using dynamic declarative components (DDCs) in the page style itself.  The instantiation of a DDC in a page style includes a reference to a separate resource that contains the definition of the DDC.  Pages are still created with a copy of the page style, but that copy includes the DDC instantiation.  Since the DDC definition is in a separate resource, such as a Java Server Faces Fragment (JSFF) file, that DDC definition can be changed without requiring that the existing pages be modified.  So, the page style of existing pages can be modified dynamically, using the separation allowed by DDCs.

Main Article

Page styles can be powerful and useful building blocks of an application.  Once a page style is selected for a new page, however, that style becomes part of the page.  The page with that style stays the same, even if the page style definition is subsequently updated.  This presents quite a dilemma for sites with a large number of pages that were created with a particular style. Any changes to the style would require manually modifying all of those existing pages.

While using DDCs in page styles does not completely resolve the issue, this approach does allow for more dynamic page styles after pages have been created.

DDC Definition

A DDC is typically defined in a JSFF file. The fragment includes Application Development Framework (ADF) tags for componentDef, component, facet, and attribute.  The fragment would also include ADF tags for presenting the DDC facets, such as a panelGridLayout tag.  Since the DDC definition is separate from the page style, how the DDC facets are presented can be changed without changing anything in the existing pages that have that DDC.

DDC Instantiation

In this approach, DDCs are instantiated in the page style.  This is where the ADF declarativeComponent appears, along with any facet and attribute values.  The real value of this approach comes from making the instantiation flexible, such as simply putting a panelCustomizable tag as the content of the facet.


This example uses a copy of the blank page style, with a DDC that defines and instantiates three facets representing three areas on the screen.  Each facet consists of a panelCustomizable tag, and the facets are presented in a panelGridLayout tag.  The content is simply default images, to show how the definition can be updated to rearrange the locations of the images. This example uses WebCenter Portal, and a portal has been created with a Metadata Services (MDS) globally unique identifier (GUID) of s5095653a_590c_4ba4_a76d_09fc5beec61a.

Initial DDC Definition

The DDC definition is in a file named three_areas.jsff under a layouts folder.  This file is inserted into the MDS repository, using the location of the current portal.  In this example, the path of the current portal is:


So, the command to import the file into the MDS repository would be:

importMetadata(application='webcenter',server='WC_Spaces', fromLocation='/home/oracle/mds',docs='/oracle/webcenter/page/scopedMD/s5095653a_590c_4ba4_a76d_09fc5beec61a/layouts/three_areas.jsff')

Documentation on MDS importing can be found at Managing the Metadata Repository.

This is the content of the three_areas.jsff file:

<?xml version='1.0' encoding='UTF-8'?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"           xmlns:f="http://java.sun.com/jsf/core"           xmlns:af="http://xmlns.oracle.com/adf/faces/rich" version="2.1">   <af:componentDef var="attrs">     <af:xmlContent>       <component xmlns="http://xmlns.oracle.com/adf/faces/rich/component">         <description>This component will display images in areas.</description>         <facet>           <facet-name>area1</facet-name>           <description>First area</description>         </facet>         <facet>           <facet-name>area2</facet-name>           <description>Second area</description>         </facet>         <facet>           <facet-name>area3</facet-name>           <description>Third area</description>         </facet>       </component>     </af:xmlContent>     <af:panelGridLayout id="dc_pgl2">       <af:gridRow marginTop="5px" marginBottom="5px" height="auto" id="dc_gr1">         <af:gridCell marginStart="5px" width="50%" id="dc_gc1">           <af:facetRef facetName="area1"/>         </af:gridCell>       </af:gridRow>     <af:gridRow marginTop="5px" marginBottom="5px" height="auto" id="dc_gr2" >         <af:gridCell marginStart="5px" marginEnd="5px" width="50%" id="dc_gc2">           <af:facetRef facetName="area2"/>         </af:gridCell>       </af:gridRow>     <af:gridRow marginTop="5px" marginBottom="5px" height="auto" id="dc_gr3" >         <af:gridCell marginStart="5px" marginEnd="5px" width="50%" id="dc_gc3">           <af:facetRef facetName="area3"/>         </af:gridCell>       </af:gridRow>     </af:panelGridLayout>   </af:componentDef> </jsp:root>

Note that the panelGridLayout tag has three rows, meaning that the facets will appear on the left side of the screen, listed vertically. Later in this example, this definition will be updated to put the three cells in a single row, listed horizontally.

Page Style DDC Instantiation

The first step is to copy an existing page style and modify the contents.  A page style can be created from scratch, but requires additional configuration.

This image shows where the new StyleThreeAreas page style is created:


This is the content of the new StyleThreeAreas page style, with blank lines added to highlight the DDC:

<?xml version='1.0' encoding='UTF-8'?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:pe="http://xmlns.oracle.com/adf/pageeditor" xmlns:cust="http://xmlns.oracle.com/adf/faces/customizable" xmlns:f="http://java.sun.com/jsf/core" xmlns:trh="http://myfaces.apache.org/trinidad/html" xmlns:af="http://xmlns.oracle.com/adf/faces/rich" version="2.1">    <jsp:directive.page deferredSyntaxAllowedAsLiteral="true"/>    <jsp:directive.page contentType="text/html;charset=utf-8"/>    <f:view>       <af:document title="#{pageDocBean.title}" id="docrt">          <f:facet name="metaContainer">             <trh:meta name="keywords" content="#{bindings.SEO_KEYWORDS}"/>          </f:facet>          <af:form usesUpload="true" id="f1">             <af:pageTemplate value="#{bindings.shellTemplateBinding.templateModel}" id="T">                <f:facet name="content">                   <pe:pageCustomizable id="pcl1">                      <af:panelGroupLayout id="pgl1" layout="scroll" styleClass="replace_with_scheme_name" inlineStyle="replace_with_inline_style">                         <cust:panelCustomizable id="hm_pnchdr" rendered="#{bindings.showHeader}" layout="vertical" showTabAction="true"/>                         <af:panelGroupLayout id="pgl2" layout="vertical" styleClass="AFStretchWidth">                            <af:declarativeComponent id="layout" viewId="layouts/three_areas.jsff">                               <f:facet name="area1">                                  <cust:panelCustomizable id="a_pnc1" layout="scroll" showTabAction="true"/>                               </f:facet>                               <f:facet name="area2">                                  <cust:panelCustomizable id="a_pnc2" layout="scroll" showTabAction="true"/>                               </f:facet>                               <f:facet name="area3">                                  <cust:panelCustomizable id="a_pnc3" layout="scroll" showTabAction="true"/>                               </f:facet>                            </af:declarativeComponent>                         </af:panelGroupLayout>                         <cust:panelCustomizable id="hm_pncftr" rendered="#{bindings.showFooter}" layout="vertical" showTabAction="true"/>                      </af:panelGroupLayout>                      <f:facet name="editor">                         <pe:pageEditorPanel id="pep1"/>                      </f:facet>                   </pe:pageCustomizable>                </f:facet>             </af:pageTemplate>          </af:form>       </af:document>    </f:view> </jsp:root>

Note that the DDC merely lists the facets, without specifying how those facets are arranged.  This is instantiating the DDC in the page style. The actual arrangement of the facets is handled in the JSFF, which is identified by the viewId="layouts/three_areas.jsff" entry.  Since the view ID value is a relative path, this DDC could be used in other portals, as long as the corresponding JSFF file was imported into the MDS repository under that portal's GUID.

Page Creation

Creating the page is as easy as selecting the new StyleThreeAreas page style.  In this example, the panelCustomizable tags were populated with simple images.

The resulting page looks like this:


Note that the default images are listed vertically down the left side of the page.

Dynamic page style modification

To demonstrate how the page style can be dynamically updated, the three_areas.jsff file was modified to have the panelGridLayout tag contain a single row.

This is a snippet of just the modified panelGridLayout tag, with the rest of the file unchanged:

    <af:panelGridLayout id="dc_pgl2">       <af:gridRow marginTop="5px" marginBottom="5px" height="auto" id="dc_gr1">         <af:gridCell marginStart="5px" width="33%" id="dc_gc1">           <af:facetRef facetName="area1"/>         </af:gridCell>         <af:gridCell marginStart="5px" marginEnd="5px" width="33%" id="dc_gc2">           <af:facetRef facetName="area2"/>         </af:gridCell>         <af:gridCell marginStart="5px" marginEnd="5px" width="33%" id="dc_gc3">           <af:facetRef facetName="area3"/>         </af:gridCell>       </af:gridRow>     </af:panelGridLayout>

This updated file was imported into the MDS repository using the same command described above.

A simple refresh of the existing page shows the updated page style:


Note that nothing on the page itself was changed, and that the same change in page style would appear on any other existing pages created with that DDC in the page style.  Also note that the panelCustomizable tag can be populated with much more than just an image.


This approach does not change the underlying implementation of page style definitions being copied when a page is created.  This means that the instantiation of the DDC in a page style becomes part of the created page.  While the DDC definition can be subsequently modified for existing pages, the instantiation can only be changed by manually updating existing pages.  If, for example, a DDC instantiation has two facets, any created page(s) would only ever have those two facets, since the DDC instantiation is in the page style and the page style is copied when a page is created.


Here is a summary of the steps:

  1. 1. Define the DDC in a JSFF layout file.
  2. 2. Identify the path and GUID of the current portal.
  3. 3. Import the JSFF file into the MDS repository using the path and GUID of the current portal.
  4. 4. Create a page style containing the declarativeComponent instantiation, with the view ID pointing to the JSFF file in the MDS repository.
  5. 5. Create and edit pages using the new page style.
  6. 6. To dynamically update the page style, change the layout in the JSFF file.
  7. 7. Import the updated JSFF file into the MDS repository using the same path as before.
  8. 8. View the existing pages and note the updated layout.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha

Recent Content