19 Creating Templates and Wrappers

You need templates to address several different scenarios: to apply to content assets, to render an entire website or a page fragment, to preview content, and so on. WebCenter Sites provides three types of templates: Layout, Pagelet, and Page. Wrappers are SiteEntry assets that contain business logic to be processed before rendering the actual layout template. You use wrappers to access session data for implementing security checks, to determine which locale should be set, to disassemble a friendly URL, and so on.

Topics:

19.1 Working with Templates

You have three types of templates in WebCenter Sites: Layout, Page, and Pagelet. Layout and Page templates can be invoked directly from a browser, but not Pagelet template. Only Layout template can be assigned to an asset. You use Layout template to render an entire website, Page template to preview content, and Pagelet template to render page fragments.

See these topics:

19.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.

A layout template has three main characteristics:

This topic provides details for each of these characteristics and presents use-case scenarios that we will use across multiple sections to demonstrate various concepts. It also explains how you can build a layout template for article assets.

19.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.

19.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.

Figure 19-1 Content Asset with Template Metadata

Description of Figure 19-1 follows
Description of "Figure 19-1 Content Asset with Template Metadata"

WebCenter Sites uses the Template field when inspecting or editing an asset in Web Mode of the Oracle WebCenter Sites: 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 Previewing Template, CSElement, and SiteEntry Assets.

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.

Figure 19-2 Change Page Layout Dialog

Description of Figure 19-2 follows
Description of "Figure 19-2 Change Page Layout Dialog"
19.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.

Figure 19-3 Sample Layout Template

Description of Figure 19-3 follows
Description of "Figure 19-3 Sample Layout Template"

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 Website Development with Tag Technologies.

<%@ 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. For information about <cs:ftcs> and <render:logdep> tags, see Understanding WebCenter Sites Tags.

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

Let’s 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

  2. Use the following JSP code.

    Note that we are reusing some components written for avisports 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>
  3. Open any article asset in a new tab.
  4. Assign the HelloArticleLayout template to the asset. You should get a web page like this:

    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.

  5. Add code to the layout template so it renders actual content. This code renders the headline, post date, related image and body fields.
    <%@ 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>
    
  6. Viewing our asset in Web Mode of the Contributor interface, using HelloArticleLayout, should render a web page with the article detail as shown in the following figure. Note that the side bar is intentionally empty.

    Figure 19-5 Sample Web Page Showing Article Detail

    Description of Figure 19-5 follows
    Description of "Figure 19-5 Sample Web Page Showing Article Detail"

19.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:

19.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).

19.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.

19.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 shown in this figure:

Figure 19-6 Sample Article Summary Block

Description of Figure 19-6 follows
Description of "Figure 19-6 Sample Article Summary Block"

Layout templates can then be used to assemble multiple page fragments to produce a complete web page. 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).

19.1.2.4 Use Case 2: Using Pagelet Templates

See 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

  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>

19.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.

19.1.3.1 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.

19.1.3.2 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.

19.1.3.3 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.

19.2 Working with Wrappers

A wrapper contains business logic to be executed before rendering the actual layout template. It’s used when performing actions such as accessing some session data to implement security checks, determining which locale should be set, disassembling a friendly URL, and so on. A wrapper usually does not render any markup, and it’s usually uncached.

See these topics on wrappers:

19.2.1 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 Creating SiteEntry Assets.

19.2.2 Previewing Wrappers

Depending on the implementation, it might be necessary to execute a wrapper before rendering an asset with a layout template. When you preview an asset, or when you are 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.

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, you can define a preview wrapper, setting extra arguments as required, and then proceed by rendering the layout template. The page name 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>
...