Fragment API in Oracle WebCenter Sites 12c - A Better Way to Render

image

The Fragment API was introduced in WebCenter Sites 12c (WCS) to better handle how the HTML markup blocks are included on a web page.  Working alongside the new Controller infrastructure in 12c, the Fragment API provides a Java API and a tag library that works in conjunction to allow for separation between business logic around generating the HTML block versus rendering these blocks. 

The Fragment API is used in lieu of the ‘render’ JSP or XML tags to render the resultant pagelet of a template, element or site entry.  An example will be used to illustrate the difference between these.  This example will simulate an article layout template that renders the header as a site entry, an article detail template and the footer as an element.

The first code sample below demonstrates the article layout template implemented using the render JSP tags in a JSP template:

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

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

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

<cs:ftcs>

       <render:satellitepage pagename="Header">

              <render:argument name="authLevel" value="public"/>

       </render:satellitepage>

       <render:calltemplate tname="ArticleDetail" c='<%=ics.GetVar("c")%>' cid='<%=ics.GetVar("cid")%>'  style="embeded">

              <render:argument name="style" value="grid"/>                    

       </render:calltemplate>

       <render:callelement elementname="Footer"/>

</cs:ftcs>

The structure of the above tags could be different for different pieces depending on whether you are calling an element or site entry or template, what arguments are needed and how that item needs to be cached.  Thus, developers building this would need to be familiar with WCS and the WCS API to ensure that the correct tag, attributes, and appropriate values are being used.

To implement the same example using the Fragment API, a controller is created that uses the Java API to execute the element or site entry or template to generate a fragment object that is added to the model.  Then, the tag library is used to render the fragments in the article layout template.  The next code sample shows the controller that generates the fragments.

package com.test.controller

import com.fatwire.assetapi.data.*

import com.openmarket.xcelerate.asset.*

import com.fatwire.assetapi.fragment.*


public class ArticleExample1Controller extends BaseController

{

       @RequiredParams(query="c,cid")

       public void doWork(Map models)

       {
              Fragment header = newSiteEntryFragment().usePage("Header").addArgument("authLevel","public")             

              models.put("Header", header)

              Fragment detail = newTemplateFragment().useTemplate("ArticleDetail").useArguments("c","cid").useStyle(Fragment.Style.EMBEDDED).addArgument("style","grid")

              models.put("ArticleDetail", detail)

              Fragment footer = newElementFragment().useElement("Footer")

              models.put("Footer", footer)

       }

}

The code shown below depicts the re-written article layout template to use the fragment tags instead of the render tags:

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

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

<cs:ftcs>

        <fragment:include name="Header"/>

        <fragment:include name="ArticleDetail"/>

        <fragment:include name="Footer"/>

</cs:ftcs>

The Fragment API provides an interface that allows elements, templates, and site entries to be handled in a uniform manner.  The tag library hides the WCS domain details and allows the developer to handle HTML blocks generated in the same way irrespective of whether it is generated by an element, template, or site entry, how it is cached, or what arguments it needs.

The Fragment API also incorporates in-context editing and the ability to manage a list of fragments.  This will be illustrated in the next example, where we have an article page with a list of related article links.  The article can be managed using WCS’s drag and drop (in-context) interface.  The code below shows the controller code for this example:

package com.test.controller

import com.fatwire.assetapi.data.*

import com.openmarket.xcelerate.asset.*

import com.fatwire.assetapi.fragment.*

import java,util.*

public class ArticleExample2Controller extends BaseController

{

       @RequiredParams(query="c,cid")

       public void doWork(Map models)

       {
    

              EditableTemplateFragment<?> articleFragment = newEditableTemplateFragment().useTemplate("Detail").setEmptyText("[ Drop Article ]").forAsset(getAssetId()).editField("article")                                                                                                                             

              models.put("articleFragment", articleFragment)   

              List<AssetId> articleList = null

              // some code that populates articleList with a list of Articles as AssetId objects.

              List<Fragment> linkFragments = new ArrayList<Fragment>()

              if (articleList != null){

                      for(AssetId asset: articleList){

                             Fragment f = newTemplateFragment().useTemplate("Link").forAsset(asset.getType(), asset.getId()).useStyle(Fragment.Style.EMBEDDED)

                             if(f != null){

                                    fragmentList.add(f)

                             }

                      }

              }

              models.put("linkFragments", linkFragments)

       }
}  

The following shows the JSP template to render the fragments for the above controller.

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

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

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<cs:ftcs>

        <fragment:include name="articleFragment"/>

        <c:forEach items="${linkFragments}" varStatus="count">

              <fragment:include name="linkFragments" index="${count.index}"/>

         </c:forEach>

     
</cs:ftcs>

 

The two Fragment API code samples demonstrate how different cases are handled in a similar fashion.  The same fragment tag is used to render the HTML block whether it uses in-context editing or not or whether the block is rendered by an element, template, or site entry.

The new Fragment API brings several benefits over the traditional render tag library.  These benefits include:

  • Handling elements, templates, and site entries in a uniform manner making coding easier.
  • Not requiring any WCS related arguments or parameters in the JSP tag library.  This allows developers with very little WCS knowledge to create the templates that contain the HTML markup. 
  • Having separated the business logic for the execution of the elements, templates, and site entries in the controller and the rendering of them in the JSP generates cleaner code and allows the opportunity for different people, each with their own expertise, to work on each piece independently. This would potentially allow a user experience developer to focus on coding the templates with the markup, and a WCS developer to focus on creating the controllers.

Not only does the Fragment API provide a better way to render pagelets, but it also offers better prospects for parallel development activities between WCS and user experience developers.

Subscribe to Our Newsletter

Stay In Touch