24 Creating Templates and Wrappers

This chapter presents information on how templates and wrappers are typically used when implementing websites.

This chapter contains the following sections:

24.1 Working with Templates

In this section, we examine the difference between the three types of templates and their practical use in actual implementations.

24.1.1 Layout Templates

A layout template is a template asset where the Usage field is set to Element is used as a layout. A layout template can be typed or typeless (see Section 23.4, "Creating Template Assets" for details on typed versus typeless asset).

A layout template has three main characteristics:

This section provides details for each of these characteristics and presents use-case scenarios that we will use across multiple sections to demonstrate various concepts. This section also presents Use Case 1: Building a Layout Template for Article Assets.

24.1.1.1 A layout template can be invoked from a browser

Given a layout template's pagename, a web page is obtained by calling the Satellite servlet and passing the pagename along with the asset type (c) and asset id (cid) of the content to render:

http://localhost:8080/cs/Satellite?pagename=
  <template_pagename>&c=Article&cid=1234567

The pagename corresponding to any given template can be found by inspecting a template asset and looking at the SiteCatalog Pagename column in the Site Entries field. In the screen capture below, the pagename is avisports/HelloLayout.

Description of a-1-siteentries.png follows
Description of the illustration a-1-siteentries.png

24.1.1.2 A layout template can be assigned to an asset

Every content asset has template metadata which is viewable by selecting the Content tab. This field stores a template name, the possible values include all layout templates applicable to the asset type and subtype.

Description of a-new_article.png follows
Description of the illustration a-new_article.png

How does WebCenter Sites use the template field? Basically, when inspecting or editing an asset in Web Mode of the Contributor interface, WebCenter Sites uses the assigned layout template as the default template to render the asset (this is also the case when simply previewing an asset). In practice, this means that only layout templates can be used to work with assets in Web Mode. Note that previewing does not require a layout template. See Section 23.7.5, "Previewing Template, CSElement, and SiteEntry Assets" for more information.

When working in Web Mode, the default layout template can also be assigned by using the Change Layout functionality (either from the toolbar or menu bar), and selecting a layout template visually, using the template picker. In either case, the value of the asset's template field is modified.

Description of l_changelayout_small.png follows
Description of the illustration l_changelayout_small.png

24.1.1.3 A layout template typically renders an entire web page

A standard web page is built with HTML code using <DIV> elements to define divisions within the document, typically a header, footer, side bar, and main area as shown in the diagram below.

Description of a-4-page.png follows
Description of the illustration a-4-page.png

The HTML structure used by the avisports sample site is used in the example below of a standard web page with a header, footer, side bar, and main area.

<!DOCTYPE html>
<html>
<head>
</head>
<body class="inner">
  <div id="main">
    <div id="header">
      <!--contains the top menu bar -->
    </div>
    <div id="container">
      <div class="content">
        <!--contains the main area -->
      </div>
      <div class="side-bar">
        <!--contains the side nav bar -->
      </div>
    </div>
    <div id="footer">
      <!--contains the footer -->
    </div>
  </div>
</body>
</html>

An actual JSP page would include tag library directives, an opening and closing <cs:ftcs> tag, and the <render:logdep> tag, used by the cache manager. See Chapter 4, "Programming with Oracle WebCenter Sites" for more information.

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld" %>
<%@ taglib prefix="render" uri="futuretense_cs/render.tld" %>

<cs:ftcs>
<!DOCTYPE html>

<%
// The render:logdep tag is mandatory. It allows the cache manager
// to automatically flush any page/pagelet generated using this 
// template ("tid" is automatically populated with the Template
// asset id)
%>

<render:logdep cid='<%=ics.GetVar("tid")%>' c="Template" />

<html>
<head>
</head>
<body class="inner">
  <div id="main">
    <div id="header">
      <!--contains the top menu bar -->
    </div>
    <div id="container">
      <div class="content">
        <!--contains the main area -->
      </div>
      <div class="side-bar">
        <!--contains the side nav bar -->
      </div>
    </div>
    <div id="footer">
      <!--contains the footer -->
    </div>
  </div>
</body>
</html>
</cs:ftcs>

The document must be enclosed within <cs:ftcs> tags. This tag creates the WebCenter Sites context, alerting WebCenter Sites that code contained within the opening and closing <cs:ftcs> tags will contain WebCenter Sites tags. WebCenter Sites is unaware of any code which falls outside of these tags. See Section 4.5, "WebCenter Sites Tags" for more information on the <cs:ftcs> and <render:logdep> tags.

24.1.1.4 Use Case 1: Building a Layout Template for Article Assets

In this section we define a layout template for article assets.

  1. Using Eclipse with the WebCenter Sites Developer Tools plug-in, create a new template in the avisports sample site with these characteristics:

    • Site: avisports

    • Name: HelloArticleLayout

    • Asset Type: AVIArticle

    • Subtype: Article

    • Element Usage: Element is used as a Layout.

    • Element Type: JSP

    • Root Element: AVIArticle/HelloArticleLayout

    • Storage Path: AVIArticle/HelloArticleLayout.jsp

      Description of a-5-newtemplate.png follows
      Description of the illustration a-5-newtemplate.png

  2. Use the following JSP code.

    Note that we are reusing some of the components already written for avisports in order to render the standard avisports header and footer, and head section, which allows us to import the avisports stylesheets:

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld" %>
<%@ taglib prefix="render" uri="futuretense_cs/render.tld" %>

<cs:ftcs>
<!DOCTYPE html>

<render:logdep cid='<%=ics.GetVar("tid")%>' c="Template" />

<html>
<head>
<!--inserts the standard avisports head -->
<render:calltemplate 
  tname="/Head" 
  args="c,cid" 
  style="element" />
</head>
<body class="inner">
  <div id="main">
    <div id="header">
      <!--inserts the avisports navbar -->
      <render:satellitepage
        pagename="avisports/navbar" />
    </div>
    <div id="container" style="height: 350px">
      <div class="content">
        <!--contains the main area -->
      </div>
      <div class="side-bar" style="height: 300px">
        <!--contains the side nav bar -->
      </div>
    </div>
    <div id="footer">
      <!--inserts the avisports footer -->
      <render:callelement 
        elementname="avisports/footer" />
    </div>
  </div>
</body>
</html>
</cs:ftcs>

  1. Open any article asset in a new tab.

  2. Assign the HelloArticleLayout template to the asset. You should get a web page like the following:

    Description of a-6-articleasset.png follows
    Description of the illustration a-6-articleasset.png

Note that we added some temporary style to the container and side-bar <DIV> elements so they are visible. We will remove them when those contain actual content.

  1. Add code to the layout template so it renders actual content. This code renders the headline, post date, related image and body fields. See Chapter 11, "Data Design: The Asset Models" for information on attribute values.

    <%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
    <%@ taglib prefix="ics" uri="futuretense_cs/ics.tld"%>
    <%@ taglib prefix="render" uri="futuretense_cs/render.tld"%>
    <%@ taglib prefix="assetset" uri="futuretense_cs/assetset.tld"%>
    <%@ taglib prefix="dateformat" uri="futuretense_cs/dateformat.tld"%>
    
    <cs:ftcs>
    <!DOCTYPE html>
    
    <render:logdep 
      cid='<%=ics.GetVar("tid")%>' 
      c="Template"/>
    
    <%
    // load article content
    %>
    <assetset:setasset
      name="article"
      type='<%=ics.GetVar("c") %>'
      id='<%=ics.GetVar("cid") %>' />
    
    <%
    // fetch the headline, relatedImage, and postDate attributes
    // from the database
    %>
    <assetset:getmultiplevalues 
      name="article" 
      prefix="article">
        <assetset:sortlistentry 
          attributename="headline"
          attributetypename="ContentAttribute" />
        <assetset:sortlistentry 
          attributename="relatedImage"
          attributetypename="ContentAttribute" />
        <assetset:sortlistentry 
          attributename="postDate"
          attributetypename="ContentAttribute" />
    </assetset:getmultiplevalues>
    
    <%
    // fetch the body attribute
    // body has to be fetched separately, since it is a 'text'
    // attribute, and the getmultiplevalues tag does not support
    // 'text' attributes
    %>
    <assetset:getattributevalues 
      name="article" 
      listvarname="bodyList"
      attribute="body" 
      typename="ContentAttribute" />
    
    <%
    // read the related AVIImage asset id
    %>
    <ics:listget 
      listname="article:relatedImage" 
      fieldname="value"
      output="imageId" />
    
    <%
    // read the date value and format it
    %>
    <ics:listget 
      listname="article:postDate" 
      fieldname="value"
      output="postDate" />
    
    <dateformat:create 
      name="df" 
      datestyle="long" />
    
    <dateformat:getdate 
      name="df" 
      varname="formattedDate"
      valuetype="jdbcdate" 
      value='<%=ics.GetVar("postDate") %>' />
    
    <html>
    <head>
    <!--inserts the standard avisports head -->
    
    <render:calltemplate 
      tname="/Head" 
      args="c,cid" 
      style="element" />
    </head>
    
    <body class="inner">
      <div id="main">
        <div id="header">
          <render:satellitepage
            pagename="avisports/navbar" />
        </div>
        <div id="container">
          <div class="content">
            <div class="top-section section-title">
              <h1>
                <ics:listget
                  listname="article:headline"
                  fieldname="value" />
              </h1>
              <span class="date">
                <ics:getvar name="formattedDate" />
              </span>
            </div>
            <div class="article post">
              <render:getbloburl 
                outstr="imageURL" 
                c="AVIImage"
                cid='<%=ics.GetVar("imageId")%>'
                field="largeThumbnail" />
              <img class="photo left"
                src='<%=ics.GetVar("imageURL")%>' />
              <render:stream list="bodyList" column="value" />
            </div>
          </div>
          <div class="side-bar" style="height: 300px">
            <!--contains the side nav bar -->
          </div>
        </div>
        <div id="footer">
          <render:callelement elementname="avisports/footer" />
        </div>
      </div>
    </body>
    </html>
    </cs:ftcs>
    
  2. Viewing our asset in Web Mode of the Contributor interface, using HelloArticleLayout, should render a web page with the article detail as shown below. Note that the side bar is intentionally empty.

    Description of l_viewing-asset_small.png follows
    Description of the illustration l_viewing-asset_small.png

24.1.2 Pagelet Templates

A pagelet template is a template asset for which the Usage field is set to Element is used within an HTML page.

A pagelet template has the following characteristics:

In the following section, we detail each characteristic and continue enhancing our use-case example. This section also presents Use Case 2: Using Pagelet Templates.

24.1.2.1 A pagelet template cannot be invoked directly from a browser

Although a pagelet template has a pagename, attempting to access a pagelet template directly from a browser using a WCS URL will return a 403 HTTP error code (forbidden).

24.1.2.2 A pagelet template cannot be assigned to an asset

Only layout templates are available in the asset's template field. This means that, these assets cannot be directly previewed using a pagelet template. However, it is possible to set up preview templates, that would give editorial users a simple way to preview pagelet templates (see Section 24.1.3, "Page Templates" for more information).

24.1.2.3 A pagelet template renders a page fragment

A page template renders a web page fragment, not an entire web page. Ideally, a pagelet template represents a reusable page fragment. For instance, a pagelet template could render an article summary block such as the following:

Description of l_pagefragement_small.png follows
Description of the illustration l_pagefragement_small.png

Layout templates can then be used to assemble multiple page fragments in order to produce a complete web page. In order to maximize reusability, pagelet templates should provide neutral fragments from a look and feel point of view, with CSS stylesheet rules effectively controlling the visual result (based on where a given fragment is used, it would render differently, only by applying a distinct set of stylesheet rules).

24.1.2.4 Use Case 2: Using Pagelet Templates

See Section 24.1.1.4, "Use Case 1: Building a Layout Template for Article Assets" for previous steps.

If the code rendering the article detail is meant to be reused in multiple context, it makes sense to extract the code from the layout template, and turn it into a pagelet template.

Let's create the corresponding template asset with the following characteristics:

  1. Using Eclipse with the WebCenter Sites Developer Tools plug-in, create the corresponding template in the avisports sample site with these characteristics:

    • Site: avisports

    • Name: HelloDetail

    • Asset Type: AVIArticle

    • Subtype: Article

    • Element Usage: Element is used within an HTML page.

    • Element Type: JSP

    • Root Element: AVIArticle/HelloDetail

    • Storage Path: AVIArticle/HelloDetail.jsp

      Description of a-9-templatearticle.png follows
      Description of the illustration a-9-templatearticle.png

  2. Let's extract the code responsible for looking up and rendering the article field values inside the <div class="content"> element and turn it into a separate JSP:

    <%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
    <%@ taglib prefix="assetset" uri="futuretense_cs/assetset.tld"%>
    <%@ taglib prefix="ics" uri="futuretense_cs/ics.tld"%>
    <%@ taglib prefix="render" uri="futuretense_cs/render.tld"%>
    <%@ taglib prefix="dateformat" uri="futuretense_cs/dateformat.tld"%>
    
    <cs:ftcs>
    
    <render:logdep 
      cid='<%=ics.GetVar("tid")%>' 
      c="Template" />
    
    <assetset:setasset 
      name="article" 
      type='<%=ics.GetVar("c") %>'
      id='<%=ics.GetVar("cid") %>' />
    
    <assetset:getmultiplevalues
      name="article" prefix="article">
        <assetset:sortlistentry 
          attributename="headline"
          attributetypename="ContentAttribute" />
        <assetset:sortlistentry 
          attributename="relatedImage"
          attributetypename="ContentAttribute" />
        <assetset:sortlistentry 
          attributename="postDate"
          attributetypename="ContentAttribute" />
    </assetset:getmultiplevalues>
    
    <assetset:getattributevalues
      name="article" 
      listvarname="bodyList"
      attribute="body" 
      typename="ContentAttribute" />
    <ics:listget
      listname="article:relatedImage" 
      fieldname="value"
      output="imageId" />
    <ics:listget 
      listname="article:postDate" 
      fieldname="value"
      output="postDate" />
    <dateformat:create 
      name="df" 
      datestyle="long" />
    <dateformat:getdate 
      name="df" 
      varname="formattedDate"
      valuetype="jdbcdate" 
      value='<%=ics.GetVar("postDate") %>' />
    
        <div class="top-section section-title">
          <h1>
            <ics:listget 
              listname="article:headline" 
              fieldname="value" />
          </h1> 
          <span class="date">
            <ics:getvar name="formattedDate" />
          </span>
        </div>
    
        <div class="article post">
          <render:getbloburl 
            outstr="imageURL" 
            c="AVIImage"
            cid='<%=ics.GetVar("imageId") %>' 
            field="largeThumbnail" />
          <img class="photo left"
            src='<ics:getvar name="imageURL" />' />
          <render:stream list="bodyList" column="value" />
        </div>
    </cs:ftcs>
    
  3. Our layout template can then be modified by simply relying on HelloDetail, invoked using the <render:calltemplate> tag:

    <html>
    <head>
      <render:calltemplate 
        tname="/Head" 
        args="c,cid" 
        style="element" />
      </head>
    <body class="inner">
      <div id="main">
        <div id="header">
          <render:satellitepage 
            pagename="avisports/navbar" />
        </div>
        <div id="container">
          <div class="content">
            <render:calltemplate 
              tname="HelloDetail" 
              args="c,cid" />
          </div>
          <div class="side-bar" style="height: 300px">
            <!-contains the side nav bar -->
          </div>
        </div>
        <div id="footer">
          <render:callelement
            elementname="avisports/footer" />
        </div>
      </div>
    </body>
    </html>
    

24.1.3 Page Templates

Page templates are Template assets for which the Usage field is set to Element defines a whole HTML page and can be called externally.

A page template has the following characteristics:

In this section we discuss each of these characteristics and then demonstrate a practical application of page templates.

A page template can be invoked from a browser

Like layout templates, a page template can be used to render a web page in a browser by invoking its pagename through the Satellite servlet.

A page template cannot be assigned to an asset

Only layout templates are assignable. Practically speaking, this means that editorial users cannot work in Web Mode of the Contributor interface with a page template, they have to use a layout template.

A page template can be used for previewing

Previewing an asset is different from using Web Mode in the Contributor interface, in the sense that it only allows editorial users to view an asset, there are no editing capabilities involved. When previewing an asset, WebCenter Sites will use, by default, the layout template set in the asset's template field.

When bringing up the Change Preview Template dialog, the template picker shows the following as valid options:

  • All layout templates applicable to the current asset

  • All page templates applicable to the current asset

Unlike the Change Layout template picker, selecting a different preview template does not assign this template to the asset's template field. It simply renders the current asset with the selected preview template.

24.2 Working with Wrappers

A wrapper is usually not rendering any markup. Instead, a wrapper is usually uncached, and contains business logic meant to be executed before rendering the actual layout template. This is useful when performing such actions as accessing some session data in order to implement security checks, determining which locale should be set, disassembling a friendly URL, etc.

This section presents the following information on wrappers:

Creating a Wrapper Page

A wrapper is a normal SiteEntry asset, for which the Wrapper page flag is set to Yes. This specifies that the asset you are creating is a wrapper page. Selecting the No flag displays the Pagelet only field. See Section 23.6, "Creating SiteEntry Assets" for more information.

Description of a-10-rootelement.png follows
Description of the illustration a-10-rootelement.png

Wrappers and Previewing

Depending on the implementation, it might be necessary to execute a wrapper before rendering an asset with a layout template. When previewing an asset, or when working in Web Mode of the Contributor interface, WebCenter Sites will systematically run a wrapper if there is at least one wrapper enabled on the current site.

If a default preview wrapper has been configured for the current editorial site, WebCenter Sites will use this wrapper. Otherwise, it will use the first wrapper available in the list. If several wrappers are available, a different wrapper can be modified by selecting View and then Preview with Wrapper.

Description of a-11-view.png follows
Description of the illustration a-11-view.png

In preview mode, wrappers are especially useful in situations where a layout template requires extra arguments to properly render a web page (for example, a locale argument might be expected) since by default, WebCenter Sites generate a minimal preview URL mainly setting the pagename, with the asset type (c) and asset id (cid) parameters with, respectively, the template pagename, and the type and identifier of the asset to render.

In this case, a preview wrapper can be defined, setting extra arguments as required, and then proceeding by rendering the layout template. Note that the pagename to call is made available in the childpagename variable.

<cs:ftcs>

<%
// establish appropriate values for required template arguments
%>
<ics:setvar name="foo" value="bar" />

<render:satellitepage 
  pagename='<%=ics.GetVar("childpagename")%>' 
  args="c,cid,foo" />

</cs:ftcs>
...