21 Coding Templates for In-Context and Presentation Editing

Content contributors and editors look for flexibility in the way they can create and manage content. For example, adding content in Web mode instead of using forms, controlling the presentation through page and content layouts, and so on. You give them this flexibility by making attribute data type fields editable and writing appropriate code.

For information on new tags used in this chapter, see the Tag Reference for Oracle WebCenter Sites.

21.1 Coding Templates for In-Context Content Editing

You can instrument templates in such a way that content people can create and edit content in the context of their website, instead of using the standard content forms. In-context refers to the Web Mode of the Oracle WebCenter Sites: Contributor interface.

This topic modifies the HelloDetail template introduced in Creating Templates and Wrappers. See these previous topics that build on the HelloDetail template:

See these topics:

21.1.1 Attribute Data Types

Asset types are defined by one or more attributes, which can be of the following types:

  • string: A short string (normally 255 characters max)

  • text: A long string. Typically mapped to a CLOB database type (maximum size depends on the underlying database).

  • date: A date field

  • binary: A BLOB attribute. Typically meant to store binary files such as image files, PDFs, etc.

  • asset: A reference to another asset

  • number: An integer, float, or money data type

21.1.2 Making String Fields Editable

You can make string fields editable. These fields are restricted in length (usually 255 characters) and are best suited to hold content metadata such as article headlines, author, and so on.

The following steps modify the HelloDetail template introduced in Creating Templates and Wrappers to make the article headline field editable.

You can use the ics:listget tag to print the value of the headline field (which is stored in the value column of the article:headline list).

<h1>
<ics:listget
  listname="article:headline"
  fieldname="value" />
</h1>
  1. To make this field editable in-context, add the following taglib directive:
    <@ taglib prefix="insite" uri="futuretense_cs/insite.tld" %>
    

    and replace the previous code with the code snippet below:

    <h1>
    <insite:edit
      field="headline"
      list="article:headline" column="value"
      assetid='<%=ics.GetVar("cid")%>'
      assettype='<%=ics.GetVar("c")%>' />
    </h1>
    

    where:

    • The field parameter designates which field of the asset is edited.

    • The list and column parameters designate where the current field value is stored.

    • The assetid and assettype parameters designate the edited asset.

    The syntax can be simplified as follows:

    <h1>
    <insite:edit 
      field="headline"
      list="article:headline" 
      column="value" />
    </h1>
    

    Because the edited asset is designated by the asset type (c) and asset id (cid) variables, WebCenter Sites performs the retrieval of these values directly from the ICS scope.

    Examining any asset in Web Mode of the Contributor interface, using HelloArticleLayout will not show any noticeable differences from the previous display. In fact, when in preview or inspect view, the insite:edit tag behaves exactly like the ics:listget tag we just replaced.

  2. Selecting Edit View makes all editable areas active; in this case, the headline field as shown in the figure below.

    Figure 21-1 Sample Web Mode Page with Editable Area Active

    Description of Figure 21-1 follows
    Description of "Figure 21-1 Sample Web Mode Page with Editable Area Active"
  3. Editorial users are now able to edit the headline field in the context of the article detail web page and click Save to make this change permanent. This action is equivalent to going to the article asset form, editing the Headline field of the article, as shown in the figure below, and then clicking Save.

    Figure 21-2 Sample Article Asset Form (Content Tab)

    Description of Figure 21-2 follows
    Description of "Figure 21-2 Sample Article Asset Form (Content Tab)"

21.1.2.1 Variants of the <insite:edit/> Tag

The value of an edited field is stored in a list. This is how the assetset tags work; they query the database and return attribute values in a list object whether attributes are single-valued or multivalued.

In some cases, the value might be made available in a variable. The following variant of insite:edit can then be used:

<h1>
<insite:edit 
  variable="headlineVar"
  field="headline" />
</h1>

In a case where the field value is not available in a variable or a list, it is possible to specify the value directly using the value attribute in the insite:edit tag.

<%String headline = getHeadlineValueFromSomewhere(); %>
<insite:edit 
  value="<%=headline%>"
  field="headline" />

The insite:edit tag also supports the property and ssvariable attributes, in case the field value is available in, respectively, a WebCenter Sites property file or a session variable. These variants are rarely used.

21.1.3 Making Text Fields Editable

You can make text fields editable. This topic builds on the HelloDetail template introduced in Creating Templates and Wrappers.

In a similar way as for string fields, you can replace the render:stream tag in the HelloDetail template with the insite:edit tag. See Making String Fields Editable for an example of working with string fields in the HelloDetail template:

Previously, this was the render:stream tag:

<render:stream 
  list="bodyList" 
  column="value" />

To make this field editable:

  1. Change the render:stream tag: to an insite:edit tag.

    In this example, the body is defined as the field and ckeditor as the editor type.

    <insite:edit
      list="bodyList"
      column="value"
      field="body"
      editor="ckeditor" />
    
  2. Clicking on the body text displays the CKEditor widget as shown in the figure below.

    Figure 21-3 Sample CKEditor Widget

    Description of Figure 21-3 follows
    Description of "Figure 21-3 Sample CKEditor Widget"
  3. You can pass additional arguments to CKEditor, as follows:
    <insite:edit
      list="bodyList"
      column="value"
      field="body"
      editor="ckeditor"
      params="{width: '500px', height: '350px', 
               toolbar: 'MyToolbar'}" />
    

21.1.4 Making Date Fields Editable

You can make date fields editable. This information builds on the HelloDetail template introduced in Creating Templates and Wrappers.

Date fields are made editable in-context using the same insite:edit tag used for string or text fields. However, when dates have to be formatted, a few extra steps are required. The value of date fields when initially retrieved from the database is in JDBC format, which is, 2012-01-01 00:00:00.0. This format is unsuitable for rendering on a website where dates are generally rendered as a readable string, such as January 1, 2012.

In addition, the date is interpreted in the server's time zone, which we can display in a different time zone. We first get the time zone ID by using the java.util TimeZone API. We then format the date by using the long date format (which is a predefined format).

Note:

For more about predefined date formats, see:

http://docs.oracle.com/javase/tutorial/i18n/format/dateFormat.html

If you choose to format the date, you can use one of the date formatting APIs, described in the next section. Depending on your decision, the resulting date and calendar widget will look like one of the samples in the figure below.

Figure 21-4 Date and Calendar Widget

Description of Figure 21-4 follows
Description of "Figure 21-4 Date and Calendar Widget"

21.1.4.1 Date Formatting APIs

The HelloDetail template uses the formattedDate variable to display the date. See Use Case 1: Building a Layout Template for Article Assets.

<span class="date">
  <ics:getvar name="formattedDate" />
</span>

The formattedDate variable must be set by using one of the date formatting APIs: fmt:formatDate or the WebCenter Sites dateformat API.

The formattedDate can be rendered with a timestamp if you add the time style parameter. It can also be rendered with a specific time zone if we add a parameter for time zone. If the time zone parameter is omitted, the date is interpreted and rendered in the server's time zone. Following is a description of the APIs:

  • The fmt:formatDate (which supports EL expression) is one such API, which takes the date in java.util.Date() in String format and takes the timeZone parameter as shown below:

    <fmt:formatDate value="${asset.postDate}" dateStyle="long"
      type="both" timeStyle="long" var="formattedDate"
      timeZone="US/Eastern" />
    
  • The WebCenter Sites dateformat API has an additional parameter named timezoneid and may be used in place of fmt:formatDate:

    <dateformat:create name="dateFormat" datestyle="long"
      timestyle="long" timezoneid="US/Eastern" />
    

    If timestamp is needed, we use dateformat:getdatetime:

    <dateformat:getdatetime name="dateFormat" value='<%=postDate%>'
      valuetype="jdbc" varname="formattedDate"/>
    

    If timestamp is not needed, we use dateformat:getdate:

    <dateformat:getdate name="dateFormat" value='<%=postDate%>'
      valuetype="jdbc" varname="formattedDate"/>
    

    The WebCenter Sites dateformat API takes millis or jdbc in the valuetype argument.

21.1.4.2 Enabling Date Fields for Editing in Web Mode

A formatted date can be used in the insite:edit tag. Do the following steps to enable date fields for editing in Web Mode:

  1. Because the insite:edit tag passes the formatted value, an appropriate formatLength parameter is required in the params argument. In our example, formatLength is set to set to long, as shown below. In addition, if we choose to display the timestamps and time zone in date fields, we would set two additional parameters; timePicker:true and timeZoneID:'US/Eastern', also shown below:
    <span class="date">
      <insite:edit
      field="postDate"
      value="formattedDate"
      params="{constraints:{formatLength: 'long'},
        timePicker:true, timeZoneID:'US/Eastern'}" />
    </span>
    

    Note:

    The date widget in edit mode will function correctly only if we pass a properly formatted date. The datestyle and timestyle arguments in dateformat:create or fmt:formatdate APIs must be consistent with the formatLength params argument in the insite:edit tag. In our example, the datestyle and timestyle arguments in the date formatting API must all be long. If the formattedDate is constructed using the time zone parameter, then the same time zone ID must be used in the insite:edit tag. If the formattedDate is constructed with timestamp using dateformat:getdatetime, then the timePicker:true parameter must be set in the insite:edit tag. And if it is constructed without timestamp using dateformat:getdate, then there is no need to set the timePicker:true parameter.

  2. The date will now be rendered according to how we specified its format:
    • With timestamp and timeZoneID:'US/Eastern':

      SEPTEMBER 7, 2011 10:41:14 AM EDT

    • Without timestamp and timeZoneID::

      SEPTEMBER 7, 2011

  3. The date field is now editable. Click the date field while viewing an article in the Contributor interface in the Web Mode / Edit View. One of the calendar popup widgets opens.

The date format is passed to the insite:edit tag using the params attribute. The params attribute is used to pass extra configuration settings to the Dojo widgets, formatted as a JSON string. In this case:

{constraints: {formatLength: 'long'}, timePicker : true,
  timeZoneID:'US/Eastern' }

For details on available widget settings, refer to the Dojo documentation at http://dojotoolkit.org/.

21.1.5 Making Binary Fields Editable

Binary fields are typically database BLOB or CLOB fields. Binary fields typically store images, or downloadable documents. By default, the insite:edit tag will make binary fields editable through a file upload component.

Note:

This section also applies to WebCenter Sites URL columns. That is, URL columns storing a reference to a file which is stored on the file system.

The HelloDetail template renders the largeThumbnail field of the related AVIImage asset.

To make this field editable in-context:

  1. Retrieve the value of this field, which contains a BLOB ID (not the actual BLOB value):
    <assetset:setasset
      name="image"
      type="AVIImage"
      id='<%=ics.GetVar("imageId")%>' />
    <assetset:getattributevalues
      name="image"
      attribute="largeThumbnail"
      typename="ContentAttribute"
      listvarname="largeThumbnail" />
    
  2. Generate a URL to the largeThumbnail field image:
     <render:getbloburl
      outstr="imageURL"
      c="AVIImage"
      cid='<%=ics.GetVar("imageId")%>'
      field="largeThumbnail"  />
    
  3. Insert the <img> tag between the opening and closing insite:edit tag:
     <insite:edit
      field="largeThumbnail"
      assetid='<%=ics.GetVar("imageId")%>'
      assettype="AVIImage"
      list="largeThumbnail"
      column="value" >
    
         <img class="photo left" src='<%=ics.GetVar("imageURL")%>' />
    </insite:edit>
    

When hovering over the image, content contributors are now shown a tooltip, giving access to the upload component, and allowed to clear the largeThumbnail field.

Note:

The HelloDetail template allows contributors to edit two distinct assets on the same page (the headline, date, body, relatedImage fields of the AVIArticle asset, and the largeThumbnail field of the related AVIImage asset). Generally, it is possible to render multiple assets on the same page, and make them editable simultaneously.

21.1.6 Making Asset Fields Editable

Asset fields store references to other assets. You can make asset fields editable.

This procedure builds on the HelloArticleLayout template created in Use Case 1: Building a Layout Template for Article Assets of Creating Templates and Wrappers.

You can enhance the HelloArticleLayout template and populate the side bar by rendering the article assets related to our article through the relatedStories field.

Note:

Although relatedStories is a multivalued field, it is treated in this section as a single-valued field. That is, the field holds only one related article content asset. Code samples shown in this section are therefore applicable to any single-valued field. For information about handling multivalued fields, see Multivalued Fields.

  1. Create a pagelet template called HelloSideBar, applicable to the AVIArticle asset type and Article subtype, which renders the associated article asset using the avisports Summary/SideBar article template using the following code:
    <%@ 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"%>
    
    <cs:ftcs>
    
    <render:logdep 
      c="Template" 
      cid='<%=ics.GetVar("tid")%>' />
    
    <assetset:setasset 
      name="article" 
      type="AVIArticle"
      id='<%=ics.GetVar("cid")%>' />
    
    <assetset:getattributevalues 
      name="article"
      attribute="relatedStories" 
      listvarname="relatedStories"
      typename="ContentAttribute" />
    
    <%-- we are getting the first item in the list --%>
    <ics:listget 
      listname="relatedStories" 
      fieldname="value"
      output="articleId" />
    
    <render:calltemplate
      tname="Summary/SideBar" 
      c="AVIArticle" 
      cid='<%=ics.GetVar("articleId")%>' />
    
    </cs:ftcs>
    
  2. Modify the HelloArticleLayout template to invoke the HelloSideBar pagelet template inside the side-bar div element:
    <div class="side-bar">
        <render:calltemplate tname="HelloSideBar" args="c,cid" />
    </div>
    

    Assuming that relatedStories contain one asset reference (Cold Snap Back on the Scene in the next figure), the related article is now rendered in the side bar using the Summary/SideBar template, as dictated by the template code.

    Figure 21-5 Sample Related Stories Reference

    Description of Figure 21-5 follows
    Description of "Figure 21-5 Sample Related Stories Reference"

    The next figure shows how the related story is rendered.

    Figure 21-6 Related Story Rendered in Sidebar

    Description of Figure 21-6 follows
    Description of "Figure 21-6 Related Story Rendered in Sidebar"

    Previously, the render:calltemplate tag was used in the HelloSideBar pagelet:

    <render:calltemplate
      tname="Summary/SideBar" 
      c="Article" 
      cid='<%=ics.GetVar("articleId")>' />
    
  3. The relatedStories asset field can be made editable in-context, by turning the area occupied by the asset into a drop target. That is, an area which will accept assets dragged from other parts of the UI (such as the search result pane or the content tree). To do this, add the following taglib directive:
    <%@ taglib prefix="insite" uri="futuretense_cs/insite.tld" %>
    

    and replace the render:calltemplate tag in the HelloSideBar pagelet with the insite:calltemplate tag:

    <insite:calltemplate 
      tname="Summary/SideBar"
      c='AVIArticle'
      cid='<%=ics.GetVar("articleId")%>'
      field="relatedStories"
      assetid='<%=ics.GetVar("cid")%>'
      assettype='<%=ics.GetVar("c")%>' />
    ...
    

    where:

    • The tname (template), c (asset type) and cid (asset id) variables behave exactly as in the render:calltemplate tag and have the same meaning.

    • The assetid and assetype variables designate the asset being edited (in our example, an article asset).

    • The field variable designates which field of the asset is being edited (in our example, relatedStories).

    The syntax can be simplified as follows:

    <insite:calltemplate
      tname="Summary/SideBar"
      c='AVIArticle'
      cid='<%=ics.GetVar("articleId")%>'
      field="relatedStories" />
    

    This simplified structure can be used because the edited asset is the asset designated by the c and cid variables. Thus, WebCenter Sites retrieves the variable values by looking them up directly in the ICS context.

  4. If the field is initially empty (in which case the articleId variable is null), viewing the asset in Web Mode of the Contributor interface shows an empty content-editable slot (provides a droppable zone for the user).
  5. It is now possible to drag and drop an article asset to the content-editable slot, by selecting an asset in the content tree, or from the docked search panel.

21.1.6.1 Editing an Association

When an asset association is used instead of a flex attribute of data type asset, the field attribute needs to be specified, as follows:

Association-named:<associationName>

For example, for an association called topStory the code would be:

<insite:calltemplate 
  field="Association-named:topStory"
  ...
/>

21.1.6.2 Editing a Parent Asset

It is also possible to edit a flex asset's parent asset. The syntax for the field attribute is as follows:

Group_<parentDefinitionName>

For example, in the case of avisports, article assets have a Category parent definition:

<insite:calltemplate
  field="Group_Category"
  ...
/>

21.1.7 Number Fields

When dealing with number attributes (such as, integer, double, and money), raw values are retrieved from the database, and are typically formatted according to the current locale.

For example, assuming that price is a money attribute, a JSP reading the attribute value and rendering it as a formatted string could be written as follows:

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld" %>
<%@ taglib prefix="assetset" uri="futuretense_cs/assetset.tld" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<cs:ftcs>

<assetset:setasset 
  name="theAsset" 
  type='<%=ics.GetVar("c")%>' 
  id='<%=ics.GetVar("cid")%>' />

<assetset:getattributevalues 
  name="theAsset" 
  attribute="price" 
  listvarname="pricelist" 
  typename="ContentAttribute" />

<ics:listget 
  listname="pricelist" 
  fieldname="value" 
  output="price" />

<fmt:formatNumber 
  type="currency" 
  value='<%=ics.GetVar("price")%>' 
  var="formattedValue" 
  currencySymbol="&eur;" /> 

The price is: ${formattedValue}
</cs:ftcs>

Assuming that the raw value is 123456, it would be rendered as €123,456 (en_US locale). The value is made editable using the insite:edit tag as follows:

<%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld" %>
<%@ taglib prefix="assetset" uri="futuretense_cs/assetset.tld" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<cs:ftcs>

<assetset:setasset 
  name="theAsset" 
  type='<%=ics.GetVar("c")%>' 
  id=''<%=ics.GetVar("cid")%> />

<assetset:getattributevalues 
  name="theAsset" 
  attribute="price" 
  listvarname="pricelist" 
  typename="ContentAttribute" />

<ics:listget 
  listname="pricelist" 
  fieldname="value" 
  output="price" />

<fmt:formatNumber 
  type="currency" 
  value='<%=ics.GetVar("price")%>' 
  var="formattedValue" 
  currencySymbol="&eur;" /> 

The price is: <insite:edit field="price" 
                value="${formattedValue}"
                params="{currency: 'EUR'}" />
</cs:ftcs>

Note that the editing widget is passed the formatted value (containing the currency symbol). For this reason, the currency ISO code is specified using the params field.

For more configuration options, refer to the Dojo documentation at http://dojotoolkit.org/.

21.1.8 Multivalued Fields

For multivalued fields, beyond editing the existing values, you need to use editors for tasks such as these:

  • Adding a new value

  • Removing an existing value

  • Reordering existing values

For this reason, multivalued text fields and multivalued asset fields have to be treated specifically.

21.1.8.1 Example 1: Editing Multivalued Text Fields

  1. Page assets of the AVIHome subtype have a multivalued text field (see attribute value teaserText in the assetset:getattributevalues tag below). Create a test layout template, rendering only the value of this field.
    <%@ taglib prefix="cs" uri="futuretense_cs/ftcs1_0.tld"%>
    <%@ taglib prefix="ics" uri="futuretense_cs/ics.tld"%>
    <%@ taglib prefix="assetset" uri="futuretense_cs/assetset.tld"%>
    <%@ taglib prefix="render" uri="futuretense_cs/render.tld"%>
    
    <cs:ftcs>
    
    <render:logdep
      cid='<%=ics.GetVar("tid")%>' 
      c="Template" />
    
    <assetset:setasset 
      name="page" 
      type="Page" 
      id='<%=ics.GetVar("cid")%>' />
    
    <assetset:getattributevalues 
      name="page" 
      attribute="teaserText"
      listvarname="teaserList"
      typename="PageAttribute" />
    
    <div style="width: 500px; font-size: small">
      <ics:listloop listname="teaserList">
        <render:stream list="teaserList" column="value" />
      </ics:listloop>
    </div>
    </cs:ftcs>
    

    This figure shows a sample text layout template:

    Figure 21-7 Sample Text Layout Template

    Description of Figure 21-7 follows
    Description of "Figure 21-7 Sample Text Layout Template"
  2. Modify this template to make the multivalued teaserText field editable.

    Add the insite taglib directive:

    <%@ taglib prefix="insite" uri="futuretense_cs/insite.tld" %>
    

    and replace the original code:

    <ics:listloop listname="teaserList">
      <render:stream list="teaserList" column="value" />
    </ics:listloop>
    

    with the following code:

    <ics:listloop listname="teaserList">
      <ics:listget
        listname="teaserList"
        fieldname="#curRow" 
        output="currentRowNb" />
      <insite:edit
        assetid='<%=ics.GetVar("cid")%>'
        assettype='<%=ics.GetVar("c")%>'
        field="teaserText"
        list="teaserList"
        column="value"
        index='<%=ics.GetVar("currentRowNb")%>'
        editor="ckeditor" />
    </ics:listloop>
    

    The syntax for the insite:edit tag can be simplified as follows:

    <ics:listloop listname="teaserList">
      <ics:listget 
        listname="teaserList" 
        fieldname="#curRow" 
        output="currentRowNb" />
      <insite:edit
        field="teaserText"
        list="teaserList"
        column="value"
        index='<%=ics.GetVar("currentRowNb")%>' 
        editor="ckeditor" /> 
    </ics:listloop>
    
  3. In the Contributor interface, change to Web Mode / Edit View. You are now able to edit each of the existing values using CKEditor.

The only noticeable difference with a single-valued field, is that we only added an index attribute which notifies WebCenter Sites the index of the value being edited.

At this point we are only able to edit existing values. See the next section on how to add, remove, or reorder existing values.

21.1.8.2 Example 2: Modifying Multivalued Text Fields

This example builds on Example 1: Editing Multivalued Text Fields and includes adding, removing, and reordering values.

  1. Modify the previous code sample as follows:
    <insite:list 
      field="teaserText" 
      editor="ckeditor" 
      assetid='<%=ics.GetVar("cid")%>'
      assettype='<%=ics.GetVar("c")%>'>
    
        <ics:listloop listname="teaserList">
          <insite:edit list="teaserList" column="value" /> 
        </ics:listloop>
    </insite:list>
    

    The insite:edit tag is now nested inside an insite:list tag. The nested insite:edit tags do not specify the field, assetid, assettype or editor attributes since they are specified at the parent tag level, and each nested insite:edit tag is, by default, inheriting those values when not locally specified. This is also applicable to the params attribute of the insite:edit tag.

    The index attribute is no longer required. In this case, the insite:list tag is keeping track of the current index. The tag assumes that the order in which the insite:edit tag appear matches the order of the multivalued field, that is, the first insite:edit tag edits value #1, and so on. If that is not the case, the index has to be specified. See Specifying a Different Ordering.

    Like the insite:edit tag, the syntax for the insite:list tag can be simplified if the asset being edited is the asset designated by the c (asset type) and cid (asset id) variables; in which case the assetid and assettype attributes can be omitted.

    <insite:list field="teaserText" editor="ckeditor" >
      <ics:listloop listname="teaserList">
        <insite:edit list="teaserList" column="value" /> 
      </ics:listloop>
    </insite:list>
    
  2. Now that the insite:list tag was added, a toolbar is displayed whenever the mouse pointer hovers over the area showing the field values.

    When you click that area, a popup gets rendered, allowing you to add, edit, remove, or reorder field values.

    This topic builds on Example 1: Editing Multivalued Text Fields and Example 2: Modifying Multivalued Text Fields.

    In the case of asset reference fields, we will use the insite:slotlist tag instead of the insite:list tag. In this case, rather than nested insite:edit tags, we will have nested insite:calltemplate tags.

    Instead of rendering a single related article, this example goes through the whole list and renders each of them.

  3. Modify the previous code sample as follows (for the time being, this code omits any in-context editing capabilities):
    <%@ 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"%>
    
    <cs:ftcs>
    
    <assetset:setasset 
      name="article" 
      type="AVIArticle" 
      id='<%=ics.GetVar("cid")%>' />
    
    <assetset:getattributevalues 
      name="article" 
      attribute="relatedStories" 
      listvarname="relatedStories" 
      typename="ContentAttribute" />
    
    <ics:listloop listname="relatedStories">
      <ics:listget 
       listname="relatedStories" 
       fieldname="value" 
       output="articleId" />
      <render:calltemplate 
        tname="Summary/SideBar" 
        c="AVIArticle" 
        cid='<%=ics.GetVar("articleId")%>' />      
    </ics:listloop>
    </cs:ftcs>
    

    This figure shows the field with three values.

    Figure 21-8 Related Stories with Three Examples

    Description of Figure 21-8 follows
    Description of "Figure 21-8 Related Stories with Three Examples"

    The SideBar will now show those three articles.

    Figure 21-9 Related Stories Displayed in SideBar

    Description of Figure 21-9 follows
    Description of "Figure 21-9 Related Stories Displayed in SideBar"
  4. To make the article list editable, make the following changes:
    <%@ 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="insite" uri="futuretense_cs/insite.tld"%>
    
    <cs:ftcs>
    <render:logdep c="Template" cid='<%=ics.GetVar("tid")%>' />
    
    <assetset:setasset
      name="article"
      type="AVIArticle"
      id='<%=ics.GetVar("cid")%>' />
    
    <assetset:getattributevalues
      name="article"
      attribute="relatedStories"
      listvarname="relatedStories"
      typename="ContentAttribute" />
    
    <insite:slotlist field="relatedStories">
      <ics:listloop listname="relatedStories">
        <ics:listget 
          listname="relatedStories" 
          fieldname="value" 
          output="articleId" />
        <insite:calltemplate
          tname="Summary/SideBar"
          c="AVIArticle"
          cid='<%=ics.GetVar("articleId")%>' />
      </ics:listloop>
    </insite:slotlist>
    </cs:ftcs>
    

    Every item of the list becomes a content-editable slot (droppable zone):

    In addition, since the insite:slotlist tag was used in the example, when hovering over the relatedStories area, you see a toolbar similar to the previous example.

21.1.8.3 Specifying a Different Ordering

In the previous example, the articles are rendered in a sequence, the first nested insite:calltemplate tag renders article #1, the second insite:calltemplate tag renders article #2, and so on:

<div class="top-stories">
  <div>article #1</div>
  <div>article #2</div>
  <div>article #3</div>
  <div>...</div>
</ul>

Your structure might be different depending on the structure of the HTML markup used in your site. For example, you might want articles to be displayed in a column layout such as this:

article #1  article #2
article #3  article #4
etc.

The underlying HTML markup might be similar to this:

<div class="left-column">
  <div>article #1</div>
  <div>article #3</div>
  ...
</div>
<div class="right-column">
  <div>article #2</div>
  <div>article #4</div>
  ...
</div>

In this example, articles are rendered in an order that doesn’t not match the ordering of the field (#1, #3, #5, then #2, #4, #6, and so on.). If this is the case, WebCenter Sites needs to be aware of the ordering. To do that, you have to explicitly indicate the index of the list item being edited, by using the index attribute as shown in Multivalued Fields.

21.1.8.4 Editing Mode and Caching

Caching is not disabled when you are working in Web Mode / Edit View. Therefore, templates that are configured to be cached will still be cached when rendered in Edit View.

When you are working with assets, WebCenter Sites automatically handles cache flushing provided that the correct dependencies are logged. For example, modifying the definition of a particular attribute (for example, changing the allowed types of an asset reference field) automatically flushes all pagelets whose rendering depends on this particular attribute.

However, the page cache has to be manually flushed in these cases:

  • Modifying the definition of an association field

  • Removing a role from WebCenter Sites, if this role is directly referenced from an insite:calltemplate tag, through the roles attribute

  • Removing asset types or subtypes from WebCenter Sites, if this asset type or subtype is referenced from an insite:calltemplate tag through the clegal attribute

21.2 Coding Templates for Presentation Editing

Content contributors like to present their content in different layouts to appeal the site visitors. So, you can let them control the page and content presentation. For example, let them choose which page layout should render an entire web page, which content layout should render an asset in a part of a page, and which arguments should be sent to a pagelet template.

The following information covers context and how to make a presentation change local (that is, visible only on a given web page), or global (that is, changing the presentation on one page can propagate the same change to multiple pages on the site).

This section builds on the HelloDetail template introduced in Creating Templates and Wrappers and the examples in Coding Templates for In-Context Content Editing.

See these topics:

21.2.1 Selecting a Different Layout for the Entire Web Page

Editorial users can assign a layout template to assets in two ways:

Selecting a layout template for an asset will make this template the default choice when working with an asset in Web Mode of the Contributor interface, or when previewing the asset.

To enable content contributors to control the page layout used to render a given asset on a live site, the value of the template field should be looked up and used to calculate asset hyperlinks, as in the following example.

<asset:list
  type='<%=ics.GetVar("c")%>'
  list="asset"
  field1="id"
  value1='<%=ics.GetVar("cid")%>' />

<ics:listget
  listname="asset"
  fieldname="template"
  output="template" />

<render:gettemplateurl
  outstr="pageURL"
  tname='<%=ics.GetVar("template")%>'
  args="c,cid" />

21.2.2 Selecting a Different Layout for a Page Fragment

This information builds on the HelloArticleLayout template used in Coding Templates for In-Context Content Editing. For information about working with fragments, see Developer's Samples Website in Website Development the MVC Framework and APIs.

Previously, in the HelloArticleLayout layout template, the main area of the article page was rendered using the HelloDetail template as shown in this code snippet:

<div id="container">
  <div class="content">
    <render:calltemplate tname="HelloDetail" args="c,cid" />
  </div> 
  <div class="side-bar">
    ...
  </div>
</div>

This template renders output as shown in the figure.

Figure 21-11 Article Page Rendered Using Template

Description of Figure 21-11 follows
Description of "Figure 21-11 Article Page Rendered Using Template"

Note:

The syntax used in the code sample:

<render:calltemplate tname="HelloDetail" args="c,cid" />

is a shortcut for (and is strictly equivalent to):

<render:calltemplate   tname="HelloDetail"   c='<%=ics.GetVar("c")%>'   cid='<%=ics.GetVar("cid")%>' />

The avisports sample site also provides a Detail template for article assets. The Detail pagelet template is functionally equivalent to the HelloDetail template, in that it provides a detailed view of the article, and is meant to be rendered in the main area of the page, as shown in the figure.

Figure 21-12 Rendering with Detail Pagelet Template

Description of Figure 21-12 follows
Description of "Figure 21-12 Rendering with Detail Pagelet Template"

21.2.2.1 Defining a Slot for Presentation Editing

To allow non-technical users to choose which presentation (that is, which pagelet template) to use to render a particular article page, you must define a slot.

The previous code in the HelloArticleLayout layout template rendered the main area of the article page using the HelloDetail template:

<div id="container">
  <div class="content">
    <render:calltemplate 
      tname="HelloDetail" 
      args="c,cid" />
  </div> 
  <div class=side-bar>
    ...
  </div>
</div>
...

To define a slot:

  1. Add the insite taglib directory.
    <%@ taglib prefix="insite" uri="futuretense_cs/insite.tld" %>
    
  2. Replace the previous render:calltemplate tag with an insite:calltemplate tag and add the slotname and variant attributes:
    <div id="container">
      <div class="content">
        <insite:calltemplate 
          slotname="HelloSlot"
    
          tname="HelloDetail"
          variant="HelloDetail|Detail"
          args="c,cid" />
      </div> 
      <div class=side-bar>
        ...
      </div>
    </div>
    ...
    

    By adding the slotname attribute, you are defining a slot, called in the example HelloSlot. The slotname attribute value can be any string, but it must be unique across all templates of a given site. See Understanding the Context System Variable.

  3. Run this template again.

    Initially there are no noticeable changes. The article is still rendered using the HelloDetail template, as directed by the tname attribute.

  4. Switch to Edit View and hover over the main div section. The changes are as follows:
    • The page fragment inside the main div is now marked with a blue overlay.

    • The slot name is indicated in the top right corner.

    • Clicking the blue overlay also brings up a toolbar.

  5. Click the Change Content Layout icon.

    Figure 21-13 Change Content Layout Icon

    Description of Figure 21-13 follows
    Description of "Figure 21-13 Change Content Layout Icon"

    The Change Content Layout Dialog opens.

    Using the Change Content Layout option enables you to select a different content layout to render the asset in the main area of the page.

  6. The template picker shows the HelloDetail and Detail pagelet templates, specified by the variant attribute. Select the Detail template and click Apply to render the web page.

    Figure 21-14 Output Page with Change Content Layout Dialog

    Description of Figure 21-14 follows
    Description of "Figure 21-14 Output Page with Change Content Layout Dialog"

    The slot defined in Figure 21-14 is only meant for presentation editing and is not a content-editable slot (not a droppable zone).

    The reasons for this behavior follows:

    • The insite:calltemplate tag does not define any field attribute. That is, the content of the slot is not the value of an asset reference field.

      The tag is explicitly providing values for c (asset type) and cid (asset id). In this particular case, we want the article asset specified by the incoming c and cid request parameters to be rendered in this location.

      In addition, if the variant attribute had been omitted, the slot layout would not have been editable, since the insite:calltemplate tag specifies an explicit value for the tname attribute (which acts as a default template for all assets dropped in this slot).

      Note:

      The variant attribute can contain any regular expression. For example; variant="Detail.*" would restrict available templates to any pagelet template whose name starts with Detail.

21.2.2.2 Adjusting the Slot Title

Rather than showing the value of slotname in the blue overlay, which is typically a technical string meaningful only to developers, you can replace the value with any string.

To do this:

  • Add a title attribute to the insite:calltemplate tag as shown in this code:

    <insite:calltemplate 
      slotname="HelloSlot" 
      tname="HelloDetail" 
      args="c,cid" 
      variant="HelloDetail|Detail" 
      title="Article Detail Area" /> 
    

    Defining the title attribute overrides the default slot title.

21.2.2.3 Controlling Template Arguments

This section provides an example of controlling template arguments. We modify the HelloDetail template to accept an extra argument called image-align which will be used to align the article image left or right.

The process is as follows:

  • The image-align argument has to be registered as a legal argument for the HelloDetail template. If this step is skipped, contributors are not able to set its value from the editorial UI.

  • To ensure caching works properly, the new argument has to be declared as a cache criteria.

  • Finally, the template code is modified to use the newly defined argument.

    Note:

    On Using Eclipse with the WebCenter Sites Developer Tools plug-in: When editing a Template asset from the Admin interface, if this Template is also opened in WSDT at the same time, you must remember to synchronize your changes to the WSDT workspace. Template metadata stored in the WSDT workspace will otherwise override the values entered from the web interface.

  1. Declare image-align as a legal argument of our HelloDetail template asset.

    1. From the Admin interface, edit the HelloDetail template asset.

    2. For Legal Arguments, enter image-align and click Add Argument.

    3. Select Required.

    4. For Argument Description enter: Image Alignment.

    5. For LegalValues, add the following descriptions:

      • For value left, enter Value Description: Aligned Left.

      • For value right, enter Value Description: Aligned Right.

    6. Click Save.

  2. Remember to sync the change made in WebCenter Sites with the WSDT workspace.

  3. Use the WebCenter Sites Developer Tools plug-in to add image-align to the set of cache criteria.

    1. Right-click the HelloDetail Template in the WebCenter Sites workspace.

    2. Select Properties.

    3. In the Cache Criteria field, append image-align to the end of the list. For information about Cache Criteria values, see Creating Template, CSElement, and SiteEntry Assets.

    4. Click Submit.

  4. Optionally, a default value could be defined by using the Additional element parameters field and specifying the following value, for instance: image-align=right.

  5. Modify the HelloDetail pagelet template code:

    <insite:edit
      field="largeThumbnail" 
      assettype="AVIImage"
      assetid='<%=ics.GetVar("imageId")%>' >
    
        <img class='photo <ics:getvar name="image-align"/>'
          src='<ics:getvar name="imageURL" />' />
    </insite:edit>
    ...
    

Note that, in this particular case, the value of the parameter is used to set a different CSS class.

When you go to the slot properties panel, assuming HelloDetail is the currently selected layout, the Advanced tab now shows the alignment options.

21.2.3 Editing Presentation and Content Simultaneously

The insite:calltemplate tag allows editorial users to edit associated content and edit the layout. This section explains the difference between a content-editable slot and a presentation-editable slot and how to combine the functionality of both to allow editorial users to edit both the associated content and the template used to render the content.

This section includes the following topics:

21.2.3.1 Understanding Content-Editable Slots and Presentation-Editable Slots

Content-editable slots allow users to edit associated content by providing a droppable zone for the user. Presentation-editable slots allow users to select a different template to render the content.

To create a content-editable slot (creates a droppable zone for the user) the insite:calltemplate tag is used with the following defined parameters:

  • assetid: The edited asset ID.

  • assettype: The edited asset type.

  • field: The edited field.

  • cid: The ID of the asset to be rendered by the called template.

  • c: The asset type to be rendered by the called template.

  • tname: The pagelet template used to render the associated asset.

This code defines a content-editable slot that creates a droppable zone for the user:

<insite:calltemplate
  assetid=" "
  assettype=" "
  field=" "
  cid=" "
  c=" "
  tname=" " 
/>

To create a presentation-editable slot (allows users to select a different template to render content) the insite:calltemplate tag is used with the following defined parameters:

  • slotname: This attribute defines an identifier for the slot that is being filled with the called template. It should be reasonably easy to understand and should be unique across all templates.

  • cid: The id of the asset to be rendered by the called template.

  • c: The asset type to be rendered by the called template.

  • tname: The default pagelet template to be called.

This code defines a presentation-editable slot that allows users to select a different template to render the content:

<insite:calltemplate
  slotname=" "
  cid=" "
  c=" "
  tname=" " 
/>

21.2.3.2 Combining Content-Editable Slots and Presentation-Editable Slots

You can combine the functionality of a content-editable slot and a presentation-editable slot to allow editorial users to edit both the associated content and the template used to render the content.

To combine the functionality of both content-editable slots and presentation-editable slots, the insite:calltemplate tag is used along with all the attributes required for both a content-editable slot and a presentation-editable slot.

  • These attributes are required for a content-editable slot (creates a droppable zone for the user):

    field, assetid, assettype
    
  • This attribute is required to define a presentation-editable slot (allows users to select a different template to render the content):

    slotname
    

This code combines the attributes for a content-editable slot and a presentation-editable slot:

<insite:calltemplate
  slotname=" "
  assetid=" "
  assettype=" "
  field=" "
  cid=" "
  c=" "
  tname=" " 
/>

Combining a Content-Editable Slot and a Presentation-Editable Slot

This section builds on the HelloSideBar template created in Coding Templates for In-Context Content Editing.

Previously, the HelloSideBar template was coded as shown:

<%@ 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="insite" uri="futuretense_cs/insite.tld"%>

<cs:ftcs>

<render:logdep cid='<%=ics.GetVar("tid")%>' c="Template"/>
<assetset:setasset name="article" 
  type='<%=ics.GetVar("c") %>' id='<%=ics.GetVar("cid") %>' />
<assetset:getattributevalues name="article"
  listvarname="relatedStories" attribute="relatedStories"
  typename="ContentAttribute" />

<insite:slotlist field="relatedStories">
  <ics:listloop listname="relatedStories">
    <ics:listget listname="relatedStories" fieldname="value"
      output="articleId" />

    <insite:calltemplate 
      tname="Summary/SideBar" 
      c="Article"
      cid='<%=ics.GetVar("articleId") %>' /> 

  </ics:listloop>
</insite:slotlist>
</cs:ftcs>
...

In this template, the related articles are made editable with content-editable slots (drop zones). That is, they are rendered using the Summary/SideBar template, without any possibility for editorial users to select a different template. However, they cannot change how the related article should be rendered. For this to happen, the HelloSideBar template needs to be modified as follows:

<%@ 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="insite" uri="futuretense_cs/insite.tld"%>

<cs:ftcs>

<render:logdep cid='<%=ics.GetVar("tid")%>' c="Template"/>
<assetset:setasset name="article" 
  type='<%=ics.GetVar("c") %>' id='<%=ics.GetVar("cid") %>' />
<assetset:getattributevalues name="article"
  listvarname="relatedStories" attribute="relatedStories"
  typename="ContentAttribute" />

  <insite:slotlist 
    slotname="RelatedStoriesSlot"
    field="relatedStories">

    <ics:listloop listname="relatedStories">
      <ics:listget listname="relatedStories" fieldname="value"
        output="articleId" />

      <insite:calltemplate 
        tname="Summary/SideBar" 
        c="Article" 
        cid='<%=ics.GetVar("articleId") %>' 
        variant="Summary.*" /> 

    </ics:listloop>
  </insite:slotlist>
</cs:ftcs>

This is the same code used previously, except that we have specified a slotname attribute, and a variant attribute (in this case, the list of available templates is restricted to all pagelet templates starting with Summary).

Because slotname was included inside the insite:slotlist tag, it is not required to add it for the inner insite:calltemplate tag. The value is automatically inherited, as is the value of tname and field.

For example:

<insite:slotlist slotname=" " field=" ">
  <insite:calltemplate tname=" " c=" " cid=" " /> 
</insite:slotlist>

The Summary/SideBar now behaves as a default template for the related articles. By right-clicking any related article and selecting the Change Content Layout feature, it now becomes possible to select alternate templates.

21.2.4 Understanding the Context System Variable

In WebCenter Sites templates, context is a system variable maintained internally. Its value is retrieved by using the ics:getvar JSP tag or the ics.GetVar() method.

For example:

<ics:getvar name=context/>
ics.GetVar(context)

The value of context is determined by default. It is initially set to an empty string. Then, for every template called using render:calltemplate or insite:calltemplate, the value of context changes in the called template following this logic:

if parent_context is empty
  context = <c>:<cid>:<tname>
otherwise
  context = <parent_context>;<c>:<cid>:<tname>

This section includes the following topics:

21.2.4.1 About Defining the Scope of the Slot

When defining a slot, it is possible for template developers to decide the scope of the slot. Typically, whether any presentation change made in this slot should be local or global.

  • local: visible only on the currently edited web page

  • global: spanning across multiple web pages in a site (possibly, ALL web pages in a site)

This is done by manipulating the value of the context variable and will be explained in the following sections.

21.2.4.2 Using the Context Variable in Action

WebCenter Sites stores presentation changes by recording the newly selected template against these items:

  • Slot name

  • Current site name

  • Context

To modify the slot content layout:

  1. Assign the HelloArticleLayout template to two avisports articles (for example,

    All 25 Nevada resorts serving great snow and Cold snap back on the scene).

  2. Observe both of these articles in Web Mode of the Contributor interface.

    The main slot is rendered with the default template HelloDetail as this is the template specified as the default template in the JSP code.

  3. Assign the Detail template to all 25 Nevada resorts serving great snow article using the Change Content Layout option.
  4. Refresh the web page with the Cold snap back on the scene article. The presentation of the main slot has also been modified on this web page as it is also using the Detail template.

Consequently, when we modified the slot content layout from HelloDetail to Detail, the following presentation data was recorded:

  • site: avisports

  • slotname: ArticleDetail

  • context: (empty)

  • tname: Detail

Context is empty since, when the HelloArticleLayout template is executed, context is initially empty, and is never modified when the slot gets rendered. Thus, any web page of avisports rendered using the HelloArticleLayout template will match the recorded presentation data above. Consequently, the Detail template is now used for all article pages.

21.2.4.3 Initializing the Context Value

The behavior observed in the previous section may be the intended behavior, but in some cases, editorial users will have to be able to make local presentation changes, that is, changes visible only on the current web page being edited.

To do this, the context variable has to be set to a value which will uniquely identify a given web page. In our case, it is enough to initialize context with, for example, the template name, and the identifier and type of the rendered asset:

<ics:setvar
  name="context"
  value='<%=ics.GetVar("c")
  + ":" + ics.GetVar("cid")
  + ":HelloArticleLayout"%>' />

Other parameters can be added to initialize the context, depending on the intended result. We can add the line above to the HelloArticleLayout template and verify that presentation changes are local to each article page.

21.2.4.4 Overriding Context

Both the render:calltemplate tag and the insite:calltemplate tag have an optional context attribute, which can be used to override the current context.

21.2.4.5 Caching Context

Context is useful only when presentation editing capabilities are enabled on your site.

If that is not the case, context can be removed from every template's cache criteria (avoiding the creation of unnecessary duplicates in the page cache).

21.2.5 Using Slots with CSElement and SiteEntry Assets

In our previous examples, slots were used to hold content. In this section, we look at using slots to hold functionalities such as a navigation bar, a login box, a code snippet showing the last ten published articles in a site, and so on. These types of functionalities can be made available as a CSElement or SiteEntry asset.

By allowing CSElement or SiteEntry assets to be dropped in slots, non-technical users are given the ability to modify the behavior of a particular web page without having to modify code.

This section includes the following topics:

21.2.5.1 Defining a Slot Containing a CSElement Asset

A slot meant to contain a CSElement asset is typically defined as:

<insite:calltemplate 
  slotname="Navbar" 
  clegal="CSElement" 
/>

Or can be defined in this manner if the slot is meant to show the same content across all pages of the site:

<insite:calltemplate
  slotname="Navbar" 
  clegal="CSElement" 
  context="Global" 
/>

There is no need to specify a tname attribute in this case, since the CSElement and SiteEntry assets are directly referring to the JSP element in charge of rendering them.

To see SiteEntry or CSElement in the list of allowed asset types for the slot, you have to ensure both asset types have their Can Be Child Asset flag set to True (which means that this asset type can be the child asset type in an association field for another asset type.). See Configuring the Asset Type in Creating Basic Asset Types.

Note:

To see SiteEntry or CSElement in the list of allowed asset types for the slot, you have to ensure both asset types have their Can Be Child Asset flag set to True (which means that this asset type can be the child asset type in an association field for another asset type.). See Designing Basic Asset Types.

21.2.5.2 When to Use CSElement or SiteEntry Assets

A SiteEntry asset does not hold any code, but simply points at a CSElement asset. The only difference between one case and the other is that, when using a SiteEntry, the element is invoked through the cache engine. Consequently, the same result can be achieved by dropping a SiteEntry asset or dropping its related CSElement asset.

The decision to use SiteEntry or CSElement is therefore implementation-dependent. Exposing a functionality as a SiteEntry only will ensure that caching is used to render this particular code snippet.

21.2.5.3 About Defining Legal Arguments

Like templates, it is possible to define legal arguments for CSElement assets. Once a CSElement has been dropped in a slot, the legal arguments are accessible from the slot properties panel.

The same applies to dropping a SiteEntry asset except that the legal arguments shown in the slot properties panel are the legal arguments of the related CSElement asset. (SiteEntry assets do not have their own legal arguments.)

21.2.5.4 Consideration About Using Nested Slots

When you drop an asset in a content-editable slot, the template rendering this asset can potentially define other slots. To avoid too many controls and slots being rendered in a given area, the behavior of nested slots is automatically degraded to a simple droppable area (without a toolbar and overlay). It is generally recommended to avoid nested slots, to keep the Contributor interface simple and usable for users.

21.2.6 Constraining Asset Types

By default, WebCenter Sites allows the following asset types to be dropped into a slot:

  • if field is defined (content-editable slot): any legal asset types given by the field definition.

  • if field is not defined (presentation-editable slot): any asset type for which the Can Be Child Asset flag is set to True. See Designing Basic Asset Types.

It is also possible to further restrict allowable asset types, using the clegal attribute:

<insite:calltemplate
  slotname="Main"
  clegal="Article,Product"
  ... 
/>

The following syntax allows to additionally restrict by asset subtypes:

<insite:calltemplate
  slotname="Main"
  clegal="type1:subtype1,type2:subtype2"
  ... 
/>

Note:

Using "type:*" (with asterisk as wildcard) is also valid, and behaves as the "type" value.

21.2.7 Preventing CSS and JavaScript Conflicts

The in-context UI is injecting styles and JavaScript into web pages, when rendered in the Contributor interface in Web Mode / Edit View (and only in this case).

This may possibly result in:

  • CSS conflicts: for instance, slots are improperly displayed due to a site CSS rule applying to them)

  • JavaScript conflicts: the web page has JavaScript which conflicts with the JavaScript injected in the page in the editing view. As a result, either the editorial UI or the page itself do not work properly.

CSS conflicts are typically solved by adding extra CSS rules, which are loaded only when the template is rendered inside the editorial UI, in editing mode. This is done by using the insite:ifedit tag, which allows to execute JSP code only when the JSP template is ran in editing mode:

<insite:ifedit>
<%-- This stylesheet import will only occur in editing mode.
  -- It will not have any impact on the actual rendering of the
  -- live site.
  --%>
  <link rel="stylesheet" 
   type="text/css" 
   href="/css/editorial.css" />
</insite:ifedit>

Extra CSS classes can be added to slots by using the cssstyle attribute of the insite:calltemplate tag, to specify specific CSS rules for slots.

CSS conflicts typically when rendering slots around elements which are floated: in this case, the blue or green overlay which is marking the slot area is likely to not have the proper dimension.

JavaScript conflicts are normally solved by degrading the behavior of the web page in editing mode only, to let the scripts injected by the editorial UI function properly. This may mean disabling some page functionality in Web Mode / Edit View of the Contributor interface.

21.3 Enabling Content Creation for Web Mode

All you need to do is provide a Start Menu item of type insite, at least one layout template applicable to the asset type the contributors are using, editing-specific presentation logic. You can make more changes according to what the contributors need.

See these topics:

21.3.1 Defining a Start Menu for In-Context Creation

To enable a particular asset type for in-context creation, a start menu of type insite has to be provided. That is, the New Insite option has to be selected in the Type drop-down menu.

In addition, if the asset being created has one or more required fields, default values have to be provided in the start menu, using the Default Values menu.

If required values are missing, the user will be directed to the asset form.

When a user selects a New Insite start menu, the editorial user is first prompted to select a layout template and a name for the newly created asset.

Once you click Continue, if no workflow is configured, a new asset is created in the background and then rendered using the selected layout template.

21.3.2 Providing Layout Templates for In-Context Creation

The same layout templates used for editing can be used for in-context creation. However, extra care must be taken to make sure the template will render properly with an empty asset.

This typically requires the following:

  • Style adjustments, so the various elements on the page are rendered in the appropriate positions, although no values are rendered

  • Meaningful help text (no value indicators), displayed to users when an editable field is empty

  • Additional presentation logic, only executed when the template is ran in editing mode, on the editorial platform

This section includes the following topics:

21.3.2.1 Adjusting Stylesheets

When the stylesheets have to be specifically adjusted for creating or editing content, the corresponding import statements can be enclosed in an insite:ifedit tag:

// import "delivery" stylesheets
<link type="text/css" rel="stylesheet" href="somecss.css" />
...

// then import "editing only" stylesheets. using the insite:ifedit
// tag ensures that only those stylesheets will be imported
// when rendering the template in create/edit mode.

<insite:ifedit>
  <link type="text/css" rel="stylesheet" href="edit.css"  />
  ...
</insite:ifedit>

21.3.2.2 Adjusting Stylesheets for Slots

When you adjust styles for the rendering of slots, the cssstyle attribute of the insite:calltemplate tag can be used to specify additional class names, which can then be used in CSS rules.

<insite:calltemplate 
  slotname="mySlot" 
  ...
  cssstyle="myClassName" 
  ...
/>

For example, if we wanted to force mySlot to have a 50px height when it is empty, we could provide the following CSS rule:

.myClassName .emptyIndicator {height: 50px !important;}

CSS rules can be grouped inside a specific stylesheet, and then imported conditionally, only when the template is executed in the context of Web Mode / Edit View of the Contributor interface, using the insite:ifedit JSP tag.

21.3.3 Providing Empty Value Indicators

For slots, use the emptytext attribute of the insite:calltemplate tag:

<insite:calltemplate
  slotname="mySlot"
  emptytext="Drag an Article here"
  ...
/>

For other editing fields, use the noValueIndicator parameter of the insite:edit tag:

<insite:edit 
  field="headline
  params="{noValueIndicator: 'Enter Headline Here'}"
  ...
/>

21.3.4 Providing Editing-Specific Presentation Logic

In some cases, the presentation logic will be slightly different in delivery mode, compared to create/edit mode.

For example, in create/edit mode, when rendering an in-context editable list of articles, you would want to always display 5 extra empty slots. In that case, the logic has to account for both delivery and edit mode. It could be written as follows:

<% 
// assuming that "relatedArticles" contains a list of 
// related articles
%>
<insite:slotlist field="someAssetField">
  <ics:listloop listname="relatedArticles">
    <ics:listget 
      listname="relatedArticles" 
      fieldname="value" 
      output="articleid" />
    <div class="post">
      <insite:calltemplate 
        tname="Summary" 
        c="Article" 
        cid='<%=ics.GetVar("articleid")%>' />
    </div>
  </ics:listloop>
</insite:slotlist>

<% 
// in this example, we add five extra empty slots 
%>
<insite:ifedit>
  <% 
    // To not disrupt rendering in delivery, this code is 
    // added inside the insite:ifedit tag 
  %>
  <c:forEach begin="0" end="4">
    <div class="post">
      <%
      // no c, cid specified, this renders an empty slot
      %>
      <insite:calltemplate tname="Summary" />
    </div>
  </c:forEach>
</insite:ifedit>

Obviously, the code could be adjusted to accommodate for any particular logic. For instance, to display a maximum of 5 slots, empty or not. In that case, the last part of the code snippet could be written as follows:

<% 
// get how many articles are in the list 
%>
<ics:listget 
  listname="relatedArticles" 
  fieldname="#numRows" 
  output="nbArticles" />

<c:forEach 
  begin='<%=Integer.valueOf(ics.GetVar("nbArticles"))%>' 
  end='4'>
  <div class="post">
    <insite:calltemplate tname='Summary" />
  </div>
</c:forEach>