20 Coding Elements for Templates and CSElements

Elements provide the code that identifies, extracts, and displays your content. Since in a WebCenter Sites system, your content is stored as assets, much of the XML or JSP code in your elements is dedicated to identifying the appropriate asset for the appropriate context, then extracting and displaying that asset's data.

Topics:

For information about creating the assets themselves, see Creating Template, CSElement, and SiteEntry Assets.

About Dependencies

To function properly, your WebCenter Sites system tracks and relies on approval and compositional dependencies. Code your element in a way that the code logs compositional dependencies accurately, and, if you are designing a static site, it sets approval dependencies appropriately, as well.

  • Approval dependenciesare conditions that determine whether an approved asset can be published.

    The approval system calculates the approval dependencies for an asset when it is approved. If there are dependent assets that also have to be approved, the parent asset is not published.

  • Compositional dependencies, that is, page composition dependencies are dependencies between assets and the pages and pagelets that they are rendered on that determine whether a page needs to be regenerated.

    The WebCenter Sites servlet logs compositional dependencies when it renders pages. CacheManager consults the dependency log to determine when to regenerate the cached pages. The Export to Disk publishing method consults the dependency logs to determine when an exported page file must be regenerated.

See these topics:

The Publishing System and Approval Dependencies

The publishers, editors, and content providers who work on your management system approve assets to be published to a target destination. The publishing system then publishes the approved assets automatically, as a background process, according to the schedule that your administration team set up for your WebCenter Sites system.

An asset can be published only if it meets all specified approval dependencies, that is, all associated assets must have been either approved or previously published. If not, the asset is held from being published until the dependencies are met: the dependent (related) assets must themselves be approved for publishing to the same destination.

This approval process frees your content and editorial team from the responsibility of manually checking asset dependencies and then publishing a large number of related assets. It also ensures that there can be no broken links on your online site after assets are published.

If an asset is subsequently changed, the asset is no longer considered to be approved, and it must be approved again before it can be re-published.

This section includes the following topics:

Calculating Approval Dependencies

Approval dependencies are recorded at the time the asset is approved. They are written to the ApprovedAssetDeps table in the WebCenter Sites database.

The approval status of an asset is determined by its dependency relationships, which include the approval status of all asset items associated with a particular asset item, and the dependency relationships of those associated items.

The dependency calculation is based on the publishing method:

  • For Export to Disk, the approval system renders the asset using either the template that is assigned to it or, if there is one specified, the default approval templates for assets of this type. The tags in the template code set approval dependencies that determine the appropriate dependents for the approved asset. The dependent assets must be in an appropriate approval state before the current asset can be published.

  • For Mirror to Server or Export Assets to XML, the approval process examines the data relationships between asset types. Basic assets have associations. Flex assets have family relationships. Both of these relationships create approval dependencies for these publishing methods. For example, if you approve a flex asset, it will be held from a publishing session unless its parent assets are in an appropriate approval state.

Exists vs. Exact vs. None

Approval dependencies can be exists, exact, and none. This section defines each kind of approval type.

You cannot change the approval dependency type for CSElements and SiteEntry assets, embedded links and pagelets, or the Oracle WebCenter Sites: Engage visitor data assets. With the exception of flex attributes, whose dependency type you set when you create the attribute, you also cannot change the approval dependency type for the flex family asset types. For basic asset types, you set the type of approval dependency for their associated assets when you configure the association fields.

When your publishing method is Export to Disk, the tags that set compositional dependencies when pages are rendered also create approval dependencies when the approval system calculates whether an asset can be published. When your code sets approval dependencies on pagelets generated for other assets, you can set the approval type to exists, exact, or none.

Note:

For information about the types of approval dependencies created by the relationships between assets of the various types, see Managing Publishing in Administering Oracle WebCenter Sites.

Exists

With an exists dependency, the dependent asset must merely exist on the target, the version of the asset does not matter. An exists dependency means that an approved parent asset can be published even if a child asset changes (which means that the child asset is no longer approved), if the child asset was previously approved and published to that same destination.

For example, in the following sequence, a collection asset has an exists relationship with its ranked children:

  • A collection and all of its ranked articles are approved and published to a target.

  • One of the ranked articles is edited again, but not approved.

  • The collection itself is edited again, approved, and published to the destination.

    The collection is not held back from publishing by the changed but unapproved article, because a prior version of the article exists.

However, in the following example, a collection with an exists dependency relationship to its articles cannot be published:

  • A collection and all of its ranked articles are approved but not published.

  • One of the ranked articles is edited again.

Because the edited article was never published to the destination, it does not yet exist for that destination, which means that the collection cannot be published. The collection asset is held and both the collection and the edited article must be approved before the collection can be published.

The exists approval type is generally useful for links.

Exact

With an exact dependency, the dependent asset must be the exact version on the target. No other previously approved version will do. An exact dependency means that the parent asset cannot be published if the version of the parent and child assets on the destination do not match.

In the following example, a page asset has an exact dependency with its article assets:

  1. A page asset and all of its article assets are approved and published to a destination.

  2. One of the articles is edited again, but is not re-approved.

  3. The page asset is edited and is re-approved.

    The page asset is held, and the resulting form in the WebCenter Sites interface displays a link that points to a list of the assets that must be approved before the page asset can be published. This list shows the article that was edited but not re-approved.

  4. The edited article is approved.

    The page asset has been approved and can now be published because the version stamps of the article and the page asset match.

  5. Another article asset associated with the page asset is edited.

  6. Both the page asset and the edited article asset must be re-approved because the version stamps of the two do not match:

    • The article must be re-approved because it was edited but not yet re-approved.

    • The page asset must be re-approved because it was previously approved with a dependency on a different version of the article.

The exact approval type is generally useful for embedded content.

None

A none dependency means that the approved asset can be published no matter what approval state the dependent asset is in. You can set the approval dependency type to none by adding the DEPTYPE parameter to a tag that sets an approval dependency and setting that parameter to none.

Note that setting DEPTYPE to none affects the approval dependency only. When the Export to Disk process generates the page and invokes the tag, a compositional dependency is logged. But when the approval system invokes the tag during its calculation, no approval dependency is logged.

Approval Templates for Export to Disk

When assets are approved for a publishing destination that uses the Export to Disk publishing method, the approval system examines the template assigned to the asset to determine its dependencies.

However, when Export to Disk actually publishes the asset, it does not necessarily use the template that is assigned to the asset. Why? Because the code in another element could determine that a different template is used for that asset in certain cases.

Consider a site that has an asset which can be rendered by several different templates, depending on the context. So when you approve this asset for publishing, which template should the approval process use to determine the dependencies for it? The one that contains the most representative set of dependencies for all of the templates. You may decide to create a special template that contains all the possible dependencies for assets of each type.

What if the template that contains the most representative set of dependencies is not the template that you want to assign to the asset? Set it as the Default Approval Template for assets of that type.

You can set Default Approval Templates for each asset type and for each publishing destination. This feature is located in the tree by selecting the Admin tab, then selecting Publishing, then Destinations, then MyStaticDestinationName, and then Set Default Templates.

Note:

If you specify a default approval template for an asset type on a destination that uses the Mirror to Server publishing method, that template is used when you preview the asset on the Asset Status screen, but not when the asset is approved or published.

Subtypes, Flex Definitions, and Approval Templates

If you are using flex assets for a static site, you can assign multiple default approval templates to the flex asset type in the family. You can designate a different default approval template for each flex definition.

For basic assets, the Subtype feature provides a way to further categorize assets of a single asset type. You can use this feature to assign multiple default approval templates for assets of a specific type, based on some other organizing construct.

For example, perhaps the approval template for sports articles should be different than the approval template for world news articles. You can create a sports subtype and a world news subtype for the article asset type and then assign different approval templates for each subtype of the asset type.

You create subtypes for basic assets either in the asset descriptor file when you create the asset type or by using the Asset Types option under the Admin node in the General Admin tree if you decide you need subtypes after the asset types were created. You assign a subtype to an asset by using the New and Edit asset forms. As mentioned, flex assets have subtypes: their flex definitions.

For more information about configuring subtypes for basic assets, and about subtypes in general, see Designing Basic Asset Types.

Page Generation and Compositional Dependencies

Compositional dependencies are recorded in different ways:

  • When the Export to Disk publishing method renders a page, it logs compositional dependencies to the appropriate publishing tables. Then, when it's time to publish again, Export to Disk can determine which pages need to be regenerated based on which assets are being published, it generates all the pages that have logged the assets as compositional dependents.

  • When WebCenter Sites renders and caches a page, it logs the dependencies in EhCache at the time a page is rendered and cached. Each row in this table holds the ID of an asset and the cache key or ID of the generated page that the asset was rendered on.

CacheManager and the Page Caches

The CacheManager maintains the WebCenter Sites page caches in EhCache. As assets are changed, it informs EhCache to do flushing and regenerating the appropriate pages basing on the asset dependency. After it makes changes to the WebCenter Sites page cache, the CacheManager communicates that information to all the Satellite Servers participating in your WebCenter Sites system, the co-resident Satellite Server and any remote Satellite Servers that are installed in your system. The Satellite Server applications then update the Satellite page caches.

Note:

If you have the appropriate permissions, you can examine the data using the System Tools for Cache in the Admin tree.

CacheManager and Dynamic Publish Sessions

The CacheManager interacts with the publishing system during Mirror to Server publishing session. When a Mirror to Server publishing session ends, the publishing system provides a list of all the IDs of all the assets that were included in the publish operation to the CacheManager servlet on the destination system.

The CacheManager compares that list to the compositional dependencies logged for the pages in the cache to determine which pages and pagelets need to be flushed from the page cache and regenerated. It updates the WebCenter Sites page cache accordingly, and then sends the list of pages to the co-resident and remote Satellite servlets so they can flush those same pages and get new versions from the WebCenter Sites page cache.

CacheManager and the Preview Function

When you preview an asset (on the development or management system), the WebCenter Sites interface executes the page name of the template for the asset. ContentServer renders the page, caches the page, and logs the compositional dependencies between the rendered page and the asset.

The CacheManager updates the cached versions of previewed pages when assets are saved. That is, when someone clicks Save, CacheManager compares the object ID of that asset to the compositional dependencies logged for the pages in the cache. It then clears and refreshes the appropriate pages in the page cache and communicates the information about the changed pages to the Satellite servlets.

About Coding to Log Dependencies

In your element, remember to include code that logs dependencies accurately. Several tags can log compositional dependencies. On processing a tag, WebCenter Sites logs a dependency between the rendered page and the asset.

For a static site using the Export to Disk publishing method, the tags that log compositional dependencies can also log approval dependencies. When an asset is approved, the approval system renders that asset to determine whether it can be published. It logs the results of these tags to the ApprovedAssetDep table unless the tag sets the approval dependency type to none. See Exists vs. Exact vs. None.

The topics that follow present the tags that log dependencies in alphabetic order. For more information about these and any other tag, see the Tag Reference for Oracle WebCenter Sites Reference.

Topics:

ASSET.LOAD and asset:load

When WebCenter Sites executes an ASSET.LOAD tag (or asset:load), it automatically logs a compositional dependency for the asset that is loaded. For example:

<ASSET.LOAD TYPE="Page" NAME="target" FIELD="name" VALUE="Home"/>

This line of code marks a compositional dependency between the page asset named Home and the rendered page that is displaying this asset.

Setting the Approval Dependency Type

When an asset is approved for an Export to Disk destination and the approval system renders this tag, the tag also logs an approval dependency between the assets that are in play.

By default, the approval dependency for ASSET.LOAD is set to exact. You can set the dependency to exists or to none by using the DEPTYPE parameter. For example:

<ASSET.LOAD TYPE="Page" NAME="target" FIELD="name" VALUE="Home" DEPTYPE="exists"/>

The ASSETSET (assetset) Tag Family

You use the ASSETSET tag family to create a set of one or more flex assets. The following tags create assetsets and define compositional dependencies for the assets in the set:

ASSETSET.SETASSET and assetset:setasset
ASSETSET.SETEMPTY and assetset:setempty
ASSETSET.SETLISTEDASSETS and assetset:setlistedassets
ASSETSET.SETSEARCHEDASSETS and assetset:setsearchedassets

When an asset from the assetset is rendered, the compositional dependency is logged.

The first three tags define the following compositional dependencies:

  • A dependency between each flex asset in the assetset and the rendered page.

  • A dependency between the flex asset's parents and the rendered page. Because flex assets inherit values from their flex parent assets, a change to a parent can mean a change to the flex asset and that means the pages that hold the asset may no longer be accurate.

The fourth tag, assetset:setsearchedassets, creates an assetset from the results of a search state. Search states are queries, which means there is no way to predict the identities of the assets in the set. Therefore, the ASSETSET.SETSEARCHEDASSETS tag defines the compositional dependency as unknown. When a compositional dependency is unknown, it means the page must be regenerated during each Export to Disk publishing session and updated in the page caches after each Mirror to Server publishing session, whether it needs it or not.

If you have a search state that describes a fixed set of assets whose identities will not change, you instruct WebCenter Sites to set compositional dependencies for the assets in the assetset by setting the optional fixedlist property to true.

For example:

<assetset:setsearchedassets name=as assettypes=Products constrain=ss fixedlist=true />

This example defines that there is a compositional dependency between each product asset in the assetset named as and the rendered page.

See Assetsets and Searchstate Objects.

Setting the Approval Dependency Type

If you are using flex assets for a static site, be aware that when the approval system invokes an assetset tag, the approval dependency type is set to none by default.

To change this value to exists or exact:

  • Use the deptype parameter. For example:

    <assetset:setsearchedassets name=as assettypes=Products constrain=ss fixedlist=true deptype=exists />
    

    Setting an approval type for the assetset:setsearchedassets tag is meaningful only if the fixedlist parameter is set to true.

RENDER.GETPAGEURL and render:getpageurl

The RENDER.GETPAGEURL tag creates a URL for assets that are not blobs. This tag logs an exists approval dependency, but not a compositional dependency, between the asset being approved (rendered) and the asset referred to by the tag. This means that it creates a dependency only when your publishing method is Export to Disk.

In this example, the template assigned to article ABC has the following code in it:

<RENDER.GETPAGEURL PAGENAME="<site_name>/Page/Home"
cid="Variables.pageid"
c="Page"
OUTSTR="referURL"/>

That code fragment both creates a URL (that is returned in the variable created by the OUTSTR parameter) and logs an exists approval dependency between the asset identified in the cid variable and article ABC.

Then, when article ABC is approved, the page identified by the cid variable must either be approved or must have been published or article ABC is held from being published.

RENDER.LOGDEP (render:logdep)

There are several situations in which your code can obtain an asset's data without actually loading the asset. When this is the case, be sure to log the compositional dependency yourself with the render:logdep tag.

Example 1

When you call a CSElement from a Template asset or other CSElement asset, you do not load the asset to determine the identity of the element file to execute. Instead, you use the RENDER.CALLELEMENT or render:callelement tag and invoke the element directly by name. For example:

<render:callelement name=<site_name>/Common/HeaderText/>

Because you didn't use the asset:load tag to access the CSElement, the compositional dependency between the CSElement asset and the page it is being rendered on is not automatically logged for you. Instead, you must set it yourself.

At the beginning of the element for each CSElement asset, you include the following line of code:

<render:logdep cid="Variables.eid" c="CSElement"/>

At the beginning of the element for a Template asset, the render.logdep statement would be as follows:

<render:logdep cid="Variables.tid" c="template"/>

Note that if you use the CSElement form or the template form in the WebCenter Sites interface to start coding the element, WebCenter Sites automatically includes an appropriate render:logdep statement in the stub code that it seeds into the element for you.

Example 2

For basic assets, when you use an ASSET.LOAD tag on a parent asset (basic asset) and then use an ASSET.CHILDREN tag, you have access to the children assets' data without having to load it. In this case, you should include a RENDER.LOGDEP statement to log the compositional dependency.

For example:

<ASSET.CHILDREN NAME="PlainListCollection" LIST="theArticles"
OBJECTTYPE="Article" ORDER="nrank" CODE=-/>
<LOOP LIST="theArticles">
<RENDER.LOGDEP cid="theArticles.id" c="Article"/>
...
Setting the Approval Dependency Type

When an asset is approved for an Export to Disk destination and the approval system invokes this tag, the tag also creates an exact approval dependency between the asset and the rendered page.

  • You can change the approval dependency type to exists or none by setting the DEPTYPE argument, as in the following example:

    <RENDER.LOGDEP cid="theArticles.id" c="Article" DEPTYPE="exists"/>

RENDER.FILTER and render:filter

You use the RENDER.FILTER tag for lists of assets created by queries. This tag filters out any unapproved assets from a list or a query. It also sets a compositional dependency of unknown.

You use this tag when you do not want an approved asset that has an approval dependency on the results of a query (a collection or query asset, for example) to be held from being published when there are unapproved assets in the list that is returned by the query. For example, say that the element is coded to provide appropriate formatting for any number of article assets that are passed to it so it doesn't matter if only two of the five articles included in a collection cannot be published. Because this tag tells Export to Disk to filter out the unapproved assets, a page using the query can be published while the unapproved assets remain unpublished.

You might use this tag in the following places:

  • Templates for query assets

  • Templates for collection assets

  • SELECTTO statements and EXECSQL queries

For example:

<RENDER.FILTER LIST="ArticlesFromWireQuery" LISTVARNAME="ArticlesFromWireQuery" LISTIDCOL="id"/>

RENDER.UNKNOWNDEPS and render:unknowndeps

The RENDER.UNKNOWNDEPS tag signals that there are dependent assets but that there is no way to predict the identities of those assets because they came from a query or change frequently. This tag logs a compositional dependency of unknown for the rendered page. This tag does not set an approval dependency for the Export to Disk publishing method.

When a compositional dependency is set to unknown, it means the page must be regenerated during each Export to Disk publishing session and updated in the page caches after each Mirror to Server publishing session, whether it needs it or not.

Note:

You must use this tag carefully because the more pages that must be regenerated, the longer it takes to publish your site.

You use this tag to cover those coding situations in which you truly cannot determine what the dependent assets might be. For example, queries are dynamic and can retrieve a different resultset every time they are run. When you use queries of any kind, query assets, SELECTTO statements, EXECSQL, and so on, you should use the RENDER.UNKNOWNDEPS tag.

About Invoking CSElement and SiteEntry Assets

From a coding point of view, you are not interested in the CSElement or SiteEntry as an asset, but in the element or page entry that the asset represents. So, write a code that directly invokes the element or page entry with the appropriate tag.

If a CSElement does not have a corresponding SiteEntry asset (which means its output is cached according to the cache criteria set for the calling page), or, if you don't need a separate pagelet at this invocation, you invoke it by name with the RENDER.CALLELEMENT (render:callelement) tag. For example:

<render:callelement name="FiscalNews/Common/SetHTMLHeader"/>

When CSElement does have a corresponding SiteEntry asset, you invoke the element by calling the page name of its SiteEntry asset with the RENDER.SATELLITEPAGE (render:satellitepage) tag. For example:

<render:satellitepage pagename="FiscalNews/Pagelet/Common/SiteBanner"/>

Note:

When you use Oracle WebCenter Sites Explorer to examine SiteCatalog and ElementCatalog entries, they are presented as folders and subfolders that visually organize the pages and pagelets. However, these entries are simply rows in a database table, there is no actual hierarchy. Therefore your code must always call a page entry or an element entry by its entire name. You cannot use a relative path.

Additionally, the chain of called elements should not be more than 20 levels deep. Otherwise, the system will perform poorly when displaying the assets.

Also, if you edit using Oracle WebCenter Sites Explorer, save the asset in the asset's editorial form (in the WebCenter Sites interface) to ensure that the cache is updated to reflect your edits. (Oracle WebCenter Sites Explorer does not automatically update the cache.)

Coding Elements to Display Basic Assets

Get a deeper understanding of how the asset type—for whose template you’re writing an element code—is designed. With just a preliminary understanding of data and site design, you may find it hard to re-code templates that display updated assets.

To help you develop a thorough understanding, this topic discusses:

  • What you should keep in mind when you code templates for basic asset types.

  • Code fragments and examples for various situations. One situation is managing dependencies between assets for correctly calculating approval for static sites, and clearing the page cache for dynamic sites, when it’s appropriate.

Before you begin, be sure to read the chapters in the Programming Basics section of this book, especially Website Development with Tag Technologies.

For information about the tags used in the code examples, see the Tag Reference for Oracle WebCenter Sites Reference.

See Template Element Examples for Basic Assets.

Topics:

Assets That Represent Simple Content

Template elements for content assets generally extract one specific article, advertising copy, special offer, image, and so on from the database, then obtain information from the relevant fields such as headline, body, and byline (for example), and then display that information online.

Consider the following simple template element designed for an article asset:

<?xml version="1.0" ?> 
<!DOCTYPE FTCS SYSTEM "futuretense_cs.dtd"> 
<FTCS Version="1.1"> 
<!-- Article/VeryBasic 
- 
- INPUT 
- Variables.c - asset type (Article) 
- Variables.cid - id of the asset to display 
- Variables.tid - template used to display the page(let) 
- OUTPUT 
- 
--> 
<!-- log the template as a dependent of the pagelet being rendered, so changes to the template will force regeneration of the page(let) --> 

<IF COND="IsVariable.tid=true"> 
<THEN> 
<RENDER.LOGDEP cid="Variables.tid" c="Template"/> 
</THEN> 
</IF> 
<!-- asset load will mark the asset as an 'exact' dependent of the pagelet being rendered --> 

<ASSET.LOAD NAME="anAsset" TYPE="Variables.c" OBJECTID="Variables.cid"/> 

<!-- get all the primary table fields of the asset --> 

<ASSET.SCATTER NAME="anAsset" PREFIX="asset"/> 

<!-- display the description --> 
<ics.getvar name=asset:description/>

<!-- display the contents of the urlbody file --> 

<ics.getvar name="asset:urlbody" encoding="default" 
output="bodyvar"/>
<RENDER.STREAM VARIABLE="bodyvar" /><br/> 

</FTCS>

The code in this template does the following things:

  • Logs a compositional dependency between the Template asset and the page being rendered with the element with the RENDER.LOGDEP tag.

  • If the approval system is evaluating this code for an Export to Disk target, logs an approval dependency.

  • Loads the article asset with an ASSET.LOAD tag, which logs a compositional dependency between the article asset and the page being rendered.

  • Extracts all the values from all the fields of the article with an ASSET.SCATTER tag.

  • Displays the contents of the description column with a CSVAR tag. The description column corresponds to the Headline field in the New or Edit article forms in the WebCenter Sites interface.

  • Displays the contents of the urlbody column with the ics.getvar and RENDER.STREAM tags. The urlbody column corresponds to the Headline field in the New or Edit article forms in the WebCenter Sites interface.

Notice the difference in the code that displays the value from the description column and the code that displays the value from the urlbody column. The urlbody column can contain embedded links and whenever a field can contain embedded links, you ensure that the links are rendered correctly by using the RENDER.STREAM tag rather than the CSVAR tag.

Associations

You identify the assets that are associated with other assets through association fields with the ASSET.CHILDREN tag. To specify which associated asset, you use the CODE parameter to specify the association field.

For example, say that the following code fragment is inserted right before the </FTCS> tag in the preceding example:

<!-- display the Main Image --> 
<ASSET.CHILDREN NAME="anAsset" LIST="associatedImage"
CODE="MainImage"/> 
<IF COND="IsList.associatedImage=true"> 
<THEN> 
<RENDER.SATELLITEPAGE PAGENAME="FiscalNews/ImageFile/TeaserSummary" ARGS_cid="associatedImage.oid"/> 
</THEN> 
</IF> 

The code in this fragment does the following things:

  • Extracts the imagefile asset that is specified in the Main Image field for this article asset (named anAsset) with the ASSET.CHILDREN tag and the CODE parameter set to MainImage.

  • Passes the identity of that imagefile to the page entry for the TeaserSummary template with the RENDER.SATELLITEPAGE tag. The page entry is identified with the PAGENAME parameter and the imagefile is identified with the ARGS_cid parameter. The TeaserSummary template than renders the imagefile into a pagelet and passes the pagelet back to this page, where it is displayed with the article.

ImageFile Assets or Other Blob Assets

The imagefile asset type stores uploaded image files. In other words, the imagefile asset type is a binary large object (blob), served from the WebCenter Sites database. You use the BlobServer servlet to serve and display imagefiles and other blobs.

A template element for an imagefile or other blob can use the RENDER.SATELLITEBLOB tag to create and return an HTML tag that tells the browser how to access the blob and how to format and display it. If you need a BlobServer URL only, without it being embedded in an HTML tag, you can use the RENDER.GETBLOBURL tag.

For more information about coding links to blobs, see Creating URLs for Hyperlinks.

Basic Assets That Can Have Embedded Links

The Body field of the Article asset and other assets that have fields with a data type of TEXTAREA allow editors to create embedded hyperlinks within the text field. To ensure that these links are rendered properly, you can use the RENDER.STREAM tag to retrieve the contents of the field, as shown in the following example:

<asset:load name="TestArticle" type="<%=ics.GetVar("c")%>"
 objectid='<%=ics.GetVar("cid")%>' />
<asset:scatter name="MainArticle" prefix="articleAsset" />
<!-- display the contents of the urlbody file --> 

<ics:getvar name="articleAsset:urlbody" encoding="default"
 output="bodyvar"/>
<render:stream variable="bodyvar"/><br/>

If Web Mode is enabled on your management system, note that the insite:edit tag also manages embedded links appropriately when it retrieves the contents of a field that has embedded links in it.

Collections

Templates for collection assets typically extract the assets in the collection from the database with an ASSET.CHILDREN tag. For example:

<ASSET.LOAD TYPE="Variables.c" OBJECTID="Variables.cid"
NAME="PlainListCollection"/>
<ASSET.SCATTER NAME="PlainListCollection" PREFIX="asset"/>
<ASSET.CHILDREN NAME="PlainListCollection" LIST="theArticles"
OBJECTTYPE="Article"/>

After the children are identified, the template code can then display parts of these assets in a list on a rendered page.

Sometimes the template for a collection is coded to handle the first item in the collection differently than the rest. You can single out the highest ranking asset in a collection by coding the element to order the items in the list according to their rank, as shown here:

<ASSET.CHILDREN NAME="HomePageStories" LIST="theArticles"
OBJECTTYPE="Article" ORDER="nrank"/>

This section includes the following topics:

Collection Templates and Approval Dependencies

When your publishing method is Export to Disk, you can use the RENDER.FILTER tag in your collection templates. This tag filters out any unapproved assets from the collection both when the approval dependencies are calculated and when the publish process renders the site.

The following code fragment illustrates this tag:

<ASSET.LOAD TYPE="Variables.c" OBJECTID="Variables.cid"
NAME="StoryListCollection"/>
<ASSET.SCATTER NAME="StoryListCollection" PREFIX="asset"/>
<ASSET.CHILDREN NAME="StoryListCollection" LIST="theArticles"
ORDER="nrank" CODE="-"/>

<!-- Get only the articles that are approved for export -->

<RENDER.FILTER LIST="theArticles"
LISTVARNAME="ApprovedArticles" 
LISTIDCOL="oid"/>

<!-- Display only the articles that are approved-->

<IF COND="IsList.ApprovedArticles=true">
<THEN>
<LOOP LIST="ApprovedArticles">
<RENDER.SATELLITEPAGE 
PAGENAME="<site_name>/Article/Summary"
ARGS_cid="ApprovedArticles.oid" 
ARGS_p="Variables.p"/>
</LOOP>
</THEN>
</IF>
Collection Templates and Compositional Dependencies

In the preceding code example that illustrates the RENDER.FILTER tag, the ID of each of the child assets in the collection is passed to the Summary template.

The first line of code in the Summary template is an ASSET.LOAD statement, which means that the dependency between article asset that it loads and the page that is rendered with the Summary template is logged.

If the code in the template for the collection also formats the child articles, you must carefully consider the code and determine whether you have to log the dependency with the RENDER.LOGDEP tag.

For example, when you use the OBJECTYPE parameter in an ASSET.CHILDREN tag, the resulting list is a join of the AssetRelationTree table and the asset table for the type specified and includes information from both tables, as in the following example:

<ASSET.CHILDREN NAME="StoryListCollection" LIST="theArticles"
OBJECTTYPE=Article ORDER="nrank" CODE="-"/>

You can then access the children asset's information without using subsequent ASSET.LOAD tags. If you do, be sure to include the RENDER.LOGDEP tag for each child so that the compositional dependencies between those assets and the rendered page can be tracked correctly.

For another example, see Coding Links to the Article Assets in a Collection Asset.

Query Assets

Query assets can execute SQL code or they can run an element that contains query code. You use them in such applications as collections and page assets.

  • You build a collection by running a query in the Build Collection form and then selecting and ordering the assets you want from the resulting list. The collection is a static list of assets selected from the query's resultset.

  • You select queries for a page asset either through unnamed relationships or through associations. You select queries for assets like articles through associations.

    In these cases, the page or article assets do not themselves invoke the query; you code the query template element to invoke a standard WebCenter Sites element called OpenMarket/Xcelerate/AssetType/Query/ExecuteQuery. This element runs the query asset when the page asset or article asset is rendered.

Elements for query templates invoke the ExecuteQuery element and typically include code that loops through the items returned in the list object that the query created, extracts bits of information from those items, and then displays it.

The following example loads a query asset and passes it to the ExecuteQuery element:

<ASSET.LOAD TYPE="Query" NAME="Wirefeed" OBJECTID="Variables.id"/>
<CALLELEMENT NAME="OpenMarket/Xcelerate/AssetType/Query/
ExecuteQuery">
<ARGUMENT NAME="list" VALUE="ArticlesFromWireFeed"/>
<ARGUMENT NAME="assetname" VALUE="WireFeed"/>
<ARGUMENT NAME="ResultLimit" VALUE="-1"/>
</CALLELEMENT>

Queries and Compositional Dependencies

The first line of code in the ExecuteQuery element is a RENDER.UNKNOWNDEPS tag, which alerts the Export to Disk publishing method and the CacheManager on a dynamic delivery system that the assets that will be retrieved by the query cannot be predicted and, therefore, no dependencies can be calculated and logged.

If you are using any other kind of query, for example, a SELECTTO statement, CALLSQL, or EXECSQL, you should include the RENDER.UNKNOWNDEPS tag.

Additionally, in the element that a query-generated list of assets is returned to, you must use the RENDER.FILTER tag if you are using the Export to Disk publishing method, as in the following example:

<CALLELEMENT NAME="OpenMarket/Xcelerate/AssetType/Query/ExecuteQuery">
<ARGUMENT NAME="list" VALUE="ArticlesFromTheQuery"/>
<ARGUMENT NAME="assetname" VALUE="PlainListQuery"/>
<ARGUMENT NAME="ResultLimit" VALUE="5"/>
</CALLELEMENT>

<!-- On export - filter out un-approved assets -->
<RENDER.FILTER LIST="ArticlesFromTheQuery" LISTVARNAME="ArticlesFromTheQuery" LISTIDCOL="id"/>

<if COND="ArticlesFromTheQuery.#numRows!=0">
<then>
<LOOP LIST="ArticlesFromTheQuery">
<RENDER.GETPAGEURL PAGENAME="FiscalNews/Article/
Variables.ct"
cid="ArticlesFromTheQuery.id"
c="Article"
p="Variables.p"
OUTSTR="referURL"/>
<A class="wirelink" HREF="Variables.referURL"
REPLACEALL="Variables.referURL"><ics.listget listname=ArticlesFromTheQuery fieldname=subheadline/>
</A><P/>

For another example, see Coding Templates for Query Assets.

Page Assets

Templates for page assets generally contain the following kinds of code:

  • The framework for the page asset when it is a rendered page

  • The logic for obtaining the content for the rendered page

  • The logic for links to other rendered pages

The templates for content assets contain the formatting code for individual pieces of content. The page templates invoke the templates for the other assets, receive formatted assets from those template elements, and then place the formatted assets into the context of the page framework.

The following is the code for a simple template that formats a page asset:

<?xml version="1.0" ?> 
<!DOCTYPE FTCS SYSTEM "futuretense_cs.dtd"> 
<FTCS Version="1.1"> 
<!-- Page/CollectionsAndQuery 
-
- INPUT 
- Variables.c - asset type (Page) 
- Variables.cid - id of the asset to display 
- Variables.tid - template used to display the page(let) 
- OUTPUT 
- 
--> 

<!-- log the template as a dependent of the pagelet being rendered, so changes to the template will force regeneration of the page(let) -->

<IF COND="IsVariable.tid=true"> 
<THEN> 
<RENDER.LOGDEP cid="Variables.tid" c="Template"/> 
</THEN> 
</IF>

<!-- asset load will mark the asset as an 'exact' dependent of the pagelet being rendered --> 

<ASSET.LOAD NAME="anAsset" TYPE="Variables.c"
OBJECTID="Variables.cid"/> 

<!-- get all the primary table fields of the asset --> 

<ASSET.SCATTER NAME="anAsset" PREFIX="asset"/> 

<!-- get a list of id's of the child assets in the collection in order of their rank --> 

<!-- get the WireFeed query --> 

<ASSET.CHILDREN NAME="HomeTextPage" LIST="WireFeedStories"
CODE="WireFeed"/> 
<IF COND="IsList.WireFeedStories=true"> 
<THEN> 
<RENDER.GETPAGEURL PAGENAME="<site_name>/Query/WireFeedFrontText" 
cid="WireFeedStories.oid" 
c="Query" 
p="Variables.asset:id" 
OUTSTR="referURL"/> 
<P> 
<A HREF="Variables.referURL" 
REPLACEALL="Variables.referURL">From the Wires...</A>
 
</P> 
<RENDER.SATELLITEPAGE PAGENAME="<site_name>/Query/WireSummaryText" 
ARGS_cid="WireFeedStories.oid" 
ARGS_ct="WireStoryText" 
ARGS_p="Variables.asset:id"/> 
</THEN> 
</IF> 
</FTCS> 

The code in this example does the following:

  • Logs a compositional dependency between the Template asset and the page being rendered with a RENDER.LOGDEP tag.

  • Loads the page asset with an ASSET.LOAD tag, which logs a compositional dependency between the article asset and the page being rendered.

  • Extracts the WireFeed query with an ASSET.CHILDREN tag and the CODE parameter set to WireFeed.

  • Obtains a URL for a page that will display the stories from the WireFeed query with the RENDER.GETPAGEURL tag. The PAGENAME parameter specifies the page entry of the template to use to create that page and also determines part of the URL. The OUTSTR parameter creates a variable named referURL to hold the URL that RENDER.GETPAGEURL creates.

  • Uses the URL from the referURL variable to build an <A HREF> link to the page.

  • Passes the identity of the query asset to the page entry for the WireSummaryText template. The WireSummaryText template then creates a pagelet that displays the summary text from each article returned by the Wire Feed query and passes the pagelet back to this page, where it is displayed.

About Coding Elements that Display Flex Assets

WebCenter Sites provides ASSETSET and SEARCHSTATE tag families for coding elements that display flex assets.

When you code templates for basic assets, you use the WebCenter Sites ASSET tag family. For example, when you want to extract and display a basic asset, you use the ASSET.LOAD tag, a tag that extracts data from the primary storage table for that asset type. But, the database schema for flex assets is different than that for basic assets, so WebCenter Sites provides these tag families for flex assets that you use in place of the ASSET tags:

  • ASSETSET. You use this tag family to specify a set of one or more flex assets.

  • SEARCHSTATE. You use this tag family to create search constraints that filter the assets in an assetset.

    Note:

    The ASSET.LOAD tag will load a flex asset for you. However, using the ASSET.LOAD tag with flex assets is not supported: the code cannot be upgraded, and extracting the asset in this way is slower by orders of magnitude than using the ASSETSET tag family.

When you use the flex asset model to represent your content, your online site will use a mixture of flex and basic assets because the page asset type (which you are likely to use) is a basic asset type.

Topics:

Assetsets

An assetset is a group of one or more flex assets or flex parent assets. You use the ASSETSET tags to create the set of assets and to extract the attribute values that you want to display.

You can retrieve the following information from an assetset:

  • The values for one attribute for each of the flex assets in the assetset.

  • The values for multiple attributes for each of the flex assets in the assetset.

  • A list of the flex assets in the assetset.

  • A count of the flex assets in the assetset.

  • A list of unique attribute values for an attribute for all flex assets in the assetset.

  • A count of unique attribute values for an attribute for all flex assets in the assetset.

You can create assetsets that include flex assets of multiple types, but only if those flex assets use the same flex attribute asset type.

The most commonly used ASSETSET tags are:

ASSETSET.SETASSET 
ASSETSET.SETSEARCHEDASSETS 
ASSETSET.GETMULTIPLEVALUES 
ASSETSET.GETATTRIBUTEVALUES 
ASSETSET.GETASSETLIST 
ASSETSET.SORTLISTENTRY ... 

All of the ASSETSET tags are described in the Tag Reference for Oracle WebCenter Sites Reference and several of them are used in the code samples in this chapter. For information about compositional dependencies and the assetset tags, see The ASSETSET (assetset) Tag Family.

Searchstate Objects

With searchstate objects, you can obtain the IDs of the flex assets that you want to display.

A searchstate is a set of search constraints based on the attribute values held in the _Mungo table for the flex asset type. You apply searchstates to assetsets.

You build a searchstate by adding or removing constraints to narrow or broaden the list of flex assets that are described by the searchstate. For example, if you have a Lighting site whose purpose is to sell lighting supplies, you can use searchstates to create drill-down searching features that visitors use to browse through the site's product catalog.

An unconstrained searchstate applied to an assetset creates an unfiltered list of all the assets of that type. For example, the following code sample would create an assetset that contains all the products in the Lighting site's product catalog:

<SEARCHSTATE.CREATE NAME=nolimits/>
<ASSETSET.SETSEARCHEDASSETS NAME=unconstrainedAssetSet
CONSTRAINT=nolimits ASSETTYPES=Products/>

To narrow the number of products in the assetset, you add constraints. For example, the following code sample would create an assetset that contains only the 40-watt light bulbs from the catalog:

<SEARCHSTATE.CREATE NAME=lightbulbs/>
<SEARCHSTATE.ADDSIMPLESTANDARDCONSTRAINT NAME=lightbulbs
 ATTRIBUTE=wattage VALUE=40/>
<ASSETSET.SETSEARCHEDASSETS NAME=40WattLightbulbs
CONSTRAINT=lightbulbs ASSETTYPES=Products/>

A constraint is a filter (restriction) that can be based on the value of an attribute or it can be based on another searchstate, which is called a nested searchstate.

A searchstate can search either the _Mungo table for the asset type database or the attribute indexes created by a search engine for that asset type. This means that you can mix database and rich-text (full-text through an index) searches in the same query. To apply a constraint against a search engine index, use the SEARCHSTATE.ADDRICHTEXTCONSTRAINT tag.

Note:

Using SQL to query the flex asset database tables instead of using the SEARCHSTATE tag family is not supported.

The most commonly used SEARCHSTATE tags are as follows:

SEARCHSTATE.CREATE 
SEARCHSTATE.ADDSTANDARDCONSTRAINT 
SEARCHSTATE.ADDSIMPLESTANDARDCONSTRAINT 
SEARCHSTATE.ADDRANGECONSTRAINT 
SEARCHSTATE.ADDRICHTEXTCONSTRAINT 
SEARCHSTATE.TOSTRING 
SEARCHSTATE.FROMSTRING 

All of the SEARCHSTATE tags are described in the Tag Reference for Oracle WebCenter Sites Reference and several of them are used in the code samples in this chapter.

Assetsets, Searchstates, and Flex Attribute Asset Types

Because searchstates filter select assets based on attribute values, and assetsets are created by applying searchstates to the assets in the database, only those flex asset types that share the same attribute asset type can be included in the same assetset.

For example, if a site has a content attribute that is shared by two flex asset types such as a flex article asset type and a flex image asset type, then you can create an assetset with both flex articles and flex images in it. However, if the site also has a product asset type that uses a product attribute instead of the content attribute, you could not create an assetset that contains both flex articles and product assets or both flex images and product assets.

Scope

The scope of assetsets and searchstates is local; that is, they exist only for the current element (rendered page).

When you want to maintain the existing searchstate, you can use the SEARCHSTATE.TOSTRING tag to convert it to a string and then include that string as an argument in the URL for the next page.

For example:

<SEARCHSTATE.TOSTRING NAME=ss VARNAME=stringss/>
<RENDER.SATELLITEPAGE 
pagename= SiteName/Products/Example 
ARGS_search=Variables.stringss/>

And then, in the root element of this example page that receives the string, you code another searchstate:

<SEARCHSTATE CREATE NAME=ss/>

And unpack the string that was passed to the example element with a SEARCHSTATE.FROMSTRING tag:

<SEARCHSTATE.FROMSTRING NAME=ss VALUE= Variables.search/>

Coding Templates That Display Flex Assets

Are you coding templates for an online site’s flex asset model? Your primary concern should be flex attributes’ values. And these values are assets themselves. A flex asset (a product, for example) or flex parent asset is really an abstraction of attribute values in this context.

You use searchstates to obtain the identity of the flex assets that you want to display, filtering the assets under consideration by their attribute values. The result is an assetset of flex or flex parent assets, and it’s based on attribute values. You can display the attribute values for the assets in the assetset.

Be sure that you understand the data model of the flex family (or families) that you are using before you begin coding template elements for your flex assets. See Understanding the Asset Types and Asset Models and Designing Flex Asset Types.

Topics:

Example Data Set for the Examples in This Section

The code examples in this section start with simple assetsets and searchstates that interact with a small, example data set (product flex family in these examples). The product family data set used in these examples is as follows:

Flex Asset Type External Name (as displayed in the WebCenter Sites interfaces) Internal Name (as used in the WebCenter Sites database)*

flex attribute

product attribute

PAttributes

flex asset

product

Products

flex parent

product parent

ProductGroups

Always use the internal name of the asset type when you use the ASSETTYPES parameter for an ASSETSET tag.

n/a

n/a

The example products in this data set are pairs of blue jeans that have the following attributes:

Attribute Data Type Number of Values

sku

string

single

color

string

multiple

price

integer

single

style

text

single

There are four pairs of blue jeans, defined as follows:

sku color price style

jeans-1

blue

35

wide

jeans-2

blue,black

30

straight

jeans-3

black,green

25

straight

jeans-4

green

20

wide

Examples of Assetsets with One Product (Flex Asset)

The code samples in this section do the following:

  • Create an assetset that contains one pair of jeans, identified by its sku number

  • Log a dependency between the product asset and the rendered page(let)

  • Get and display the value for the price attribute and display it

  • Get and display the values for the color attribute and display them

  • Get and display the values for both the price and color attribute with the same tag (ASSETSET.GETMULTIPLEVALUES)

This section includes the following topics:

Create a Searchstate and Apply It to an Assetset

This line of code creates an unfiltered searchstate named ss:

<SEARCHSTATE.CREATE NAME="ss"/>

Next, we can narrow the unfiltered searchstate named ss so that it finds a specific product in the sample data set, by providing the sku of the product:

<SEARCHSTATE.ADDSIMPLESTANDARDCONSTRAINT NAME="ss" TYPENAME="PAttributes" ATTRIBUTE="sku" VALUE="jeans-2"/>

Now we can create an assetset named as, applying the searchstate named ss to it:

<ASSETSET.SETSEARCHEDASSETS NAME="as" ASSETTYPES="Products"CONSTRAINT="ss" FIXEDLIST="true"/>

Since the value of the sku attribute is unique for each product asset, there is only one product in the assetset: the one whose sku value is jeans-2.

Because this searchstate was created by querying for a hard-coded attribute value (a sku value of jeans-2) we know the exact contents of the assetset. That is why we set the FIXEDLIST parameter to true. Now the ASSETSET.SETSEARCHEDASSET tag logs a compositional dependency for the product asset.

Get the Price of the Product

Next, let's extract the price of this pair of jeans:

<ASSETSET.GETATTRIBUTEVALUES NAME="as" ATTRIBUTE="price" TYPENAME="PAttributes" LISTVARNAME="pricelist"/>

Notice that even though price is a single-value attribute (which means the product only has one price), the ASSETSET.GETATTRIBUTEVALUES tag returns the value of the price attribute as a list variable (LISTVARNAME=pricelist).

Display the Price of the Product

Now the following line of code can display the price of the jeans-2 product:

Price: <ics.listget listname=pricelist fieldname=value/>
And this is the result:
Price: 30
Get the Colors for the Product

Next, let's determine which colors this pair of jeans is available in.

As specified above, the color attribute is a multiple-value attribute. Because the ASSETSET.GETATTRIBUTEVALUES tag works the same whether an attribute is a single-value or a multiple-value attribute, we use the tag exactly as we did for single-value price attribute:

<ASSETSET.GETATTRIBUTEVALUES NAME="as" ATTRIBUTE="color" TYPENAME="PAttributes" LISTVARNAME="colorlist"/>
Display the Colors of the Product

Now the following code can display the colors for the jeans-2 product, and, because this product can have multiple colors, the code loops through the list:

Colors: <LOOP LIST="colorlist">
<ics.listget listname=colorlist fieldname=value/>
&nbsp;
</LOOP>

And this is the result:

Colors: black blue
Create a List Object for the ASSETSET.GETMULTIPLEVALUES tag

In general, you should not use the ASSETSET.GETATTRIBUTEVALUES tag when you want to get the value for multiple attributes.

The ASSETSET.GETMULTIPLEVALUES tag gets and scatters the values from multiple attributes, for all the assets in an assetset. Because the tag makes only one call to the database for all the attribute values, it performs the query more efficiently than using multiple ASSETSET.GETATTRIBUTEVALUES tags.

Before you can use this tag, however, you must use the LISTOBJECT tags to create a list object that describes the attributes that the ASSETSET.GETMULTIPLEVALUES tag will return. The list object needs one row for each attribute that you want to get.

This next line of code creates a list object named lo that has columns named attributetypename, attributename, and direction.

<LISTOBJECT.CREATE NAME="lo"
COLUMNS="attributetypename,attributename,direction"/>

Then, this line adds a row to the list object for each attribute, color and price:

<LISTOBJECT.ADDROW NAME="lo" attributetypename="PAttributes" attributename="color" direction="none"/>
<LISTOBJECT.ADDROW NAME="lo" attributetypename="PAttributes" attributename="price" direction="none"/>

The next line of code converts the list object to a list variable name lolist:

<LISTOBJECT.TOLIST NAME="lo" LISTVARNAME="lolist"/>
Get the Value for Both Price and Color with ASSETSET.GETMULTIPLEVALUES

And now we can get the values for both the price and the color attribute from our original assetset, named as:

<ASSETSET.GETMULTIPLEVALUES NAME="as" PREFIX="multi" LIST="lolist" BYASSET="false"/>
Display the Value of Price and Color for the jeans-2 Product

Now that the values are stored in the list variable (lolist), the following code can display all the values for all the attributes:

<LOOP LIST="lolist">
<ics.listget listname=lolist fieldname=attributename output=attrName/>
<ics.getvar name=attrName/> is
<LOOP LIST="multi:Variables.attrName">
<ics.listget listname=multi:Variables.attrNamefieldname=value/>&nbsp;
</LOOP><P/>
</LOOP>

This code sets up a nested loop that loops through all the attributes in the lolist variable, and then loops through all the distinct attribute values for each of the attributes in the lolist list variable.

And this is the result:

color is blue black
price is 30

Special Cases: Flex Attributes of Type Text, Blob, and URL

To display the values held in flex attributes of type text or blob, use the methodologies described in this section.

This section includes the following topics:

About Flex Attributes of Type Text

The ASSETSET.GETMULTIPLEVALUES tag does not retrieve the values for attributes of type text. This means that you must include a separate ASSETSET.GETATTRIBUTEVALUES tag for attributes of this type.

For example, if the color attribute in the sample data set used in these examples were an attribute of type text rather than type string, we could not have retrieved its values with the ASSETSET.GETMULTIPLEVALUES tag in the preceding examples.

About Flex Attributes of Type Blob

The _Mungo table for a flex asset type stores the attribute values for the flex assets of that type and the ASSETSET tags query the asset type's _Mungo table for attribute values.

Attributes of type blob are an exception:

  • WebCenter Sites stores all the values of all the attributes of type blob in the MungoBlobs table.

  • A row in the _Mungo table (Products_Mungo, for example) for an attribute of type blob stores only the ID of the row in the MungoBlobs table that holds its value. That is, the blob column in a _Mungo table is a foreign key to the MungoBlobs table.

This means that for an attribute of type blob, the ASSETSET.GETATTRIBUTEVALUES and ASSETSET.GETMULTIPLEVALUES tags return the ID of the blob attribute's value, but not the actual value.

Once the ID of the attribute's value has been identified, you can do one of two things with it:

  • Use the ID to obtain a BlobServer URL.

  • Use the ID to extract the actual value of the blob.

Creating a BlobServer URL

To obtain a BlobServer URL for the value of the flex attribute blob, you do the following:

  • Use the BLOBSERVICE tags to programmatically identify the MungoBlobs table and the appropriate columns in it.

  • Pass that information to a RENDER.SATELLITEBLOB tag, if you want the URL in an HTML tag, or to a RENDER.GETBLOBURL tag if you need only the URL without the HTML tag.

  • Use the BLOBSERVICE tags to programmatically identify the MungoBlobs table, as shown in the following example. By obtaining the value with the BLOBSERVICE tags rather than hard coding the name of the table into your code, your code will function properly even if the table name is changed in a future version of the product.

    To illustrate the following blob examples, let's add the following attribute to the jeans products in our sample data set:

    Attribute Data Type Number of Values

    description

    blob

    single

    • First, let's create the assetset and log the dependency between the jeans-2 product and the rendered page:

      <SEARCHSTATE.CREATE NAME="ss"/>
      <SEARCHSTATE.ADDSIMPLESTANDARDCONSTRAINT NAME="ss" TYPENAME="PAttributes" ATTRIBUTE="sku" VALUE="jeans-2"/>
      <ASSETSET.SETSEARCHEDASSETS NAME="as" ASSETTYPES="Products" CONSTRAINT="ss"/>
      <ASSETSET.GETASSETLIST NAME="as" LISTVARNAME="aslist"/>
      <RENDER.LOGDEP cid="aslist.assetid" c="aslist.assettype"/>
      The next line of code gets the ID of the jeans-2 asset's description attribute (that attribute of type blob) and stores it in a list variable called descFile
      <ASSETSET.GETATTRIBUTEVALUES NAME="as" TYPENAME="PAttributes" ATTRIBUTE="description" LISTVARNAME="descFile"/>
      
    • The next lines of code use the BLOBSERVICE tags to obtain the table name and column names from the WebCenter Sites table that stores the attribute values for blob attributes and store them in variables named "uTabname", "idColumn", and "uColumn":

      <BLOBSERVICE.GETTABLENAME VARNAME="uTabname"/>
      <BLOBSERVICE.GETIDCOLUMN VARNAME="idColumn"/>
      <BLOBSERVICE.GETURLCOLUMN VARNAME="uColumn"/>
      
    • Now we can pass the list variable named descFile and the uTabname, idColumn, and uColumn variables to a RENDER.SATELLITEBLOB tag, which returns a BlobServer URL in an HTML tag:

      <RENDER.SATELLITEBLOB
      BLOBTABLE="Variables.uTabname" 
      BLOBWHERE="descFile.value" 
      BLOBKEY="Variables.idColumn" 
      BLOBCOL="Variables.uColumn" 
      BLOBHEADER="application/pdf"
      /> add service=a href ... download link... 
      

      The RENDER.SATELLITEBLOB tag returns a BlobServer URL in an HREF tag.

Getting and Displaying the Value of a Blob Flex Attribute

To obtain and display the contents or data in the blob flex attribute after its ID has been returned, you use a BLOBSERVICE.READDATA tag, which loads the file name and URL data of the blob.

  • Under the same assumptions about the data set used for the preceding blob example, create the assetset, log the dependency between the jeans-2 asset and the rendered page, and get the ID of the description attribute's value:

    <SEARCHSTATE.CREATE NAME="ss"/>
    <SEARCHSTATE.ADDSIMPLESTANDARDCONSTRAINT NAME="ss" TYPENAME="PAttributes" ATTRIBUTE="sku" VALUE="jeans-2"/>
    <ASSETSET.SETSEARCHEDASSETS NAME="as" ASSETTYPES="Products" CONSTRAINT="ss"/>
    <ASSETSET.GETASSETLIST NAME="as" LISTVARNAME="aslist"/>
    <RENDER.LOGDEP cid="aslist.assetid" c="aslist.assettype"/>
    <ASSETSET.GETATTRIBUTEVALUES NAME="as" TYPENAME="PAttributes" ATTRIBUTE="description" LISTVARNAME="descFile"/>
    

    This time, get and then display the value (data) of the description attribute, using the BLOBSERVICE.READDATA tag:

    <BLOBSERVICE.READDATA ID="descFile.value" LISTVARNAME="descData"/>
    <ics.listget listname=descData fieldname=@urldata/>

Examples of Assetsets with Multiple Products (Flex Assets)

The code samples in this section do the following:

  • Create an assetset that holds all the products (pairs of jeans) in the sample data set being used in this chapter.

  • Get and display a count of the number of jeans in the assetset.

  • Get and display all the values for the color attribute for all the pairs of jeans in the assetset.

  • Get and display all the values for both the color and the style attributes for the jeans in the assetset.

  • Get and display, in a table, all the attribute values for the jeans in the assetset.

  • Add a search constraint that filters the assetset for the jeans whose price falls into a specific range.

  • Replace the range constraint on the price attribute with a search constraint that filters the assetset for the jeans that are available in any color that begins with the letter b.

  • Replace that color constraint with one that filters the assetset for the jeans that are available in either of two specific colors: blue or black.

This section includes the following topics:

Creating a Searchstate and Apply it to an Assetset

This line of code creates an unfiltered searchstate named ss:

<SEARCHSTATE.CREATE NAME="ss"/>

When you apply the unfiltered searchstate to an assetset, you get all the flex assets of the type specified (in this case, product assets):

<ASSETSET.SETSEARCHEDASSETS NAME="as" CONSTRAINT="ss" ASSETTYPES="Products"/>
Displaying the Number of Assets in the Assetset

These lines of code return and display a count of the number of assets in the assetset, which at this point represents the entire sample catalog:

<ASSETSET.GETASSETCOUNT NAME="as" VARNAME="count"/>
How many products are in the catalog? 
<ics.getvar name=count/>

And this is the result:

How many products are in the catalog? 4
Displaying the Colors That the Jeans Are Available In

The next lines of code get and display the different colors for the jeans. In other words, the distinct values of the color attribute:

<ASSETSET.GETATTRIBUTEVALUES NAME="as" ATTRIBUTE="color" TYPENAME="PAttributes" LISTVARNAME="colors"/>
What are the possible colors for any pair of jeans?<BR/>
<LOOP LIST="colors">
<ics.listget listname=colors fieldname=value/>
</LOOP><p/>

And this is the result:

What are the possible colors for any pair of jeans?
black blue green
Displaying Both the Colors and the Styles for the Jeans in the Assetset

Next, let's extract and display the values for both the color and the style attribute for the jeans in the assetset. This time we use the ASSETSET.GETMULTIPLEVALUES tag.

First, however, we have to create a list object for the resultset that the ASSETSET.GETMULTIPLEVALUES tag returns. The list object needs one row for each of the attributes, as follows:

<LISTOBJECT.CREATE NAME="lo" COLUMNS="attributename,attributetypename,direction"/>
<LISTOBJECT.ADDROW NAME="lo" attributename="color" attributetypename="PAttributes" direction="none"/>
<LISTOBJECT.ADDROW NAME="lo" attributename="style" attributetypename="PAttributes" direction="none"/>

The next line of code converts the list object to a list variable named lolist:

<LISTOBJECT.TOLIST NAME="lo" LISTVARNAME="lolist"/>

Now we can extract the attributes and store them in the list variable named lolist:

<ASSETSET.GETMULTIPLEVALUES NAME="as" LIST="lolist" PREFIX="distinct" BYASSET="false"/>

Notice the BYASSET parameter in the preceding line of code. Because there are multiple assets in the assetset and we want to know the distinct values for the attribute rather than all the attribute values for each asset in the assetset, BYASSET=false. This way, we get only the unique attribute values and not every single attribute value.

The next lines of code loop through the list and display the unique values for each attribute:

Here are all the possible colors:
<LOOP LIST="distinct:color">
<ics.listget listname=distinct:color fieldname=value/>
</LOOP><P/>

Here are all the possible styles:
<LOOP LIST="distinct:style">
<ics.listget listname=distinct:style fieldname=value/>
</LOOP><P/>

And this is the result:

Here are all the possible colors: green blue black
Here are all the possible styles: wide straight
Creating a Table That Displays All the Jeans and Their Attribute Values

You can also use the ASSETSET.GETMULTIPLEVALUES tag to obtain the attribute values that are distinct for each asset in the assetset. It creates a list of all the products and the values for their attributes that we can use to create a grid or table that displays all the products in the example catalog.

In this case, we have to do two additional things:

  • Because we want the attribute values grouped by the asset that they belong to, the BYASSET parameter must be set to true.

  • Because we need the IDs of the assets in this case, we have to use the ASSETSET.GETASSETLIST tag to obtain them.

First, this code creates a list object:

<LISTOBJECT.CREATE NAME="lo" COLUMNS="attributename,attributetypename,direction"/>
<LISTOBJECT.ADDROW NAME="lo" attributename="color" attributetypename="PAttributes" direction="none"/>
<LISTOBJECT.ADDROW NAME="lo" attributename="style" attributetypename="PAttributes" direction="none"/>
<LISTOBJECT.ADDROW NAME="lo" attributename="price" attributetypename="PAttributes" direction="none"/>
<LISTOBJECT.ADDROW NAME="lo" attributename="sku" attributetypename="PAttributes" direction="none"/>
<LISTOBJECT.TOLIST NAME="lo" LISTVARNAME="lolist"/>

Next, we can get the attribute values:

<ASSETSET.GETMULTIPLEVALUES NAME="as" LIST="lolist" PREFIX="grid" BYASSET="true"/>

And then we use the ASSETSET.GETASSETLIST tag.

<ASSETSET.GETASSETLIST NAME="as" LISTVARNAME="aslist"/>

It returns a list with these columns:

  • assettype

  • assetid

By using both lists, we can create a grid that shows all of the products and all of their attribute values:

<TABLE>
<LOOP LIST="aslist">
<TR>
<TD><CSVAR NAME="grid:aslist.assetid:sku.value"/></TD>
<TD><CSVAR NAME="grid:aslist.assetid:price.value"/>
   </TD>
<TD><CSVAR NAME="grid:aslist.assetid:style.value"/>
</TD>
<TD>
<IF COND="IsList.grid:aslist.assetid:color=true"><THEN>
<LOOP LIST="grid:aslist.assetid:color">
<CSVAR NAME="grid:aslist.assetid:color.value"/>&nbsp;
</LOOP>
</THEN></IF>
</TD>
</TR>
</LOOP>
</TABLE>

And this is the result:

Table 20-1 Table That Displays All Jeans and Their Attribute Values

SKU Price Style Color

jeans-1

35

wide

blue

jeans-2

30

straight

black blue

jeans-3

25

straight

black green

jeans-4

20

wide

green

Searching for Jeans Based on a Range of Prices

Up until now, we have been using the same assetset (NAME=as) that was created in the second line of code in this section. Next, let's filter the assetset by the price attribute, using a range constraint.

This line of code adds a range constraint to our original searchstate (NAME=ss) that was created in the first line of code in this section:

<SEARCHSTATE.ADDRANGECONSTRAINT NAME="ss" ATTRIBUTE="price" TYPENAME="PAttributes" LOWER="0" UPPEREQUAL="30"/>

The range is from 0 to 30. Let's apply the modified searchstate against our assetset:

<ASSETSET.SETSEARCHEDASSETS NAME="as" CONSTRAINT="ss" ASSETTYPES="Products"/>

And check whether it worked, by obtaining and displaying a count of the jeans that are now in the assetset:

<ASSETSET.GETASSETCOUNT NAME="as" VARNAME="count"/>
How many jeans products are less than or equal to $30?
<ics.getvar name=count/>

Here's the result:

How many jeans products are less than or equal to $30? 3
Searching for Jeans with a Wildcard for Color

Now let's replace the range constraint on the price attribute with a search constraint that filters the assetset for the jeans that are available in any color that begins with the letter b.

First this line of code deletes the range constraint for price:

<SEARCHSTATE.DELETECONSTRAINT NAME="ss" ATTRIBUTE="price"/>

And this line of code adds a new constraint for color, using the percentage (%) character as a wildcard with the VALUE parameter:

<SEARCHSTATE.ADDSIMPLELIKECONSTRAINT NAME="ss" ATTRIBUTE="color" TYPENAME="PAttributes" VALUE="b%"/>

The VALUE="b%" statement means any color that begins with the letter b. Lets apply the modified searchstate against our same assetset (as):

<ASSETSET.SETSEARCHEDASSETS NAME="as" CONSTRAINT="ss" ASSETTYPES="Products"/>

And check whether it worked by obtaining and displaying a count of the number of jeans that are in the assetset now:

<ASSETSET.GETASSETCOUNT NAME="as" VARNAME="count"/>
How many jeans have a color that begins with the letter b? 
<ics.getvar name=count/>

Here's the result:

How many jeans have a color that begins with the letter b? 3
Searching for Jeans with Specific Colors

Finally, let's change the color constraint that filters the assetset for the jeans that are available in either of two specific colors: blue or black.

This line of code deletes the color constraint from the searchstate:

<SEARCHSTATE.DELETECONSTRAINT NAME="ss" ATTRIBUTE="color"/>

Next, because we want to filter based on two values for the color attribute, we have to create a list object with those values:

<LISTOBJECT.CREATE NAME="lo" COLUMNS="value"/>
<LISTOBJECT.ADDROW NAME="lo" value="blue"/>
<LISTOBJECT.ADDROW NAME="lo" value="black"/>
<LISTOBJECT.TOLIST NAME="lo" LISTVARNAME="colorlist"/>

Now we can use the list variable named colorlist to create the searchstate:

<SEARCHSTATE.ADDSTANDARDCONSTRAINT NAME="ss" ATTRIBUTE="color" TYPENAME="PAttributes" LIST="colorlist"/>

The LIST=colorlist statement is the equivalent of the VALUE statement in the preceding example. It means attribute values that match any of the colors in the list named colorlist. Let's apply the modified searchstate to our same assetset:

<ASSETSET.SETSEARCHEDASSETS NAME="as" CONSTRAINT="ss" ASSETTYPES="Products"/>

And check whether it worked by obtaining and displaying a count of the number of jeans that are in the assetset now:

<ASSETSET.GETASSETCOUNT NAME="as" VARNAME="count"/>
How many products have a color that is black or blue?
<ics.getvar name=count/>

Here's the result:

How many products have a color that is black or blue? 3

Creating URLs for Hyperlinks

Your site may be dynamic or static, but its content changes regularly. So, you can’t hard code URLs into hyperlinks. At the time of rendering, your pages must be able to determine the identity of the assets they are providing links to.

WebCenter Sites provides three tags (each with an XML and a JSP version) that you can use to create your URLs:

  • For URLs for assets that are not blobs, use RENDER.GETPAGEURL tag.

  • For URLs for assets that are blobs, use either the RENDER.SATELLITEBLOB tag or the RENDER.GETBLOBURL tag.

See these topics:

RENDER.GETPAGEURL (render:getpageurl)

To obtain URLs for regular assets (that is, assets that are not blobs), use the RENDER.GETPAGEURL tag.

The RENDER.GETPAGEURL tag processes arguments passed in from the element that invokes it into a URL-encoded string that it returns as a variable that you name with the OUTSTR parameter. By convention, the name of that variable is referURL.

If rendermode is set to export, it creates a static URL (unless you specify that it should be dynamic). If rendermode is set to live, it creates a dynamic URL.

For example:

<RENDER.GETPAGEURL PAGENAME="FiscalNews/Article/Full
cid="Variables.cid"
c="Article"
p="Variables.p"
OUTSTR="referURL"/>

You can now use the value in the referURL variable to create a hyperlink with an <A HREF> tag.

See the Tag Reference for Oracle WebCenter Sites Reference.

RENDER.SATELLITEBLOB (render:satelliteblob)

Binary large objects (blobs) that are stored in the WebCenter Sites database are served by the BlobServer servlet rather than the WebCenter Sites servlet. The RENDER.SATELLITEBLOB tag returns an HTML tag with a BlobServer URL in it.

This tag takes a set of arguments that define the blob and an additional set of arguments that determine how to format the blob. For example, you can use it to create an <IMG SRC> tag or an <A HREF> tag, as follows:

<RENDER.SATELLITEBLOB 
BLOBTABLE=ImageFile 
BLOBKEY=id 
BLOBCOL=urlpicture 
BLOBWHERE=Variables.asset:id 
BLOBHEADER=Variables.asset:mimetype 
SERVICE=IMG SRC 
ARGS_alt=Variables.asset:alttext 
ARGS_hspace=5 ARGS_vspace=5/>

Note that there are additional coding steps if you are creating a URL for a flex attribute of type blob. See About Flex Attributes of Type Blob.

Even if you are not using Satellite Server, you should still use the RENDER.SATELLITEBLOB tag because the tag can create a BlobServer URL in an HTML tag even when Satellite Server is not present.

See the Tag Reference for Oracle WebCenter Sites Reference.

RENDER.GETBLOBURL (render:getbloburl)

If you need a BlobServer URL only, without it being embedded in an HTML tag, use the RENDER.GETBLOBURL tag.

For example, the following element named SetHTMLHeader uses the RENDER.GETBLOBURL element to obtain a BlobServer URL (stored as a variable named referURL) that it then passes on to JavaScript code that runs on the client side to determine which browser the visitor is using. In this case, the client-side JavaScript creates the HTML tag based on the browser it discovers, so it needs the BlobServer URL without an HTML tag.

SetHTMLHeader is the element for a CSElement. You could examine it in two ways:

  • Use the WebCenter Sites interface to search for the path-name/SetHTMLHeader CSElement and then inspect it.

  • Use Explorer to open the path-name/SetHTMLHeader element.

If you are creating a URL for a flex attribute of type blob, there are additional coding steps. See About Flex Attributes of Type Blob.

See the Tag Reference for Oracle WebCenter Sites Reference.

Using the referURL Variable

The RENDER.GETPAGEURL, RENDER.GETBLOBURL, and RENDER.SATELLITEBLOB tags were introduced in the 3.6.x version of this product. Older versions of the product used elements named GetPageURL and GetBlobURL to obtain URLs; they are coded to return URLs in a variable named referURL.

By convention, all of the sample code in the sample sites that use the tags that replaced the GetPageURL and GetBlobURL elements use a referURL variable for the value of the URL.

Do not append or add any text to the value held in the referURL variable or any other variable returned by a RENDER.GETPAGEURL or RENDER.GETBLOBURL tag. URLs in this kind of variable are complete (whole). If you change the URL returned by the tag, you are likely to break it.

If you have to include additional arguments in a URL, use the RENDER.PACKARGS tag to URL-encode them (pack them) and then pass those encoded arguments to the RENDER.GETPAGEURL or RENDER.GETBLOBURL tag with the PACKEDARGS parameter.

See the Tag Reference for Oracle WebCenter Sites Reference.

Handling Error Conditions

Can your element code check for error conditions? Decide which conditions are serious and, when necessary, code a solution or alternate action. Sometimes the solution is to write a meaningful error message. Additionally, you can also include a code that stops a broken page from being cached.

Note:

While debugging your code, you can use the commons-logging.properties and loggingconfig.xml files to enable loggers. Error and debugging messages are then written to the WebCenter Sites log file. For information about the debugging properties, see the Property Files Reference for Oracle WebCenter Sites.

Topics:

Using the Errno Variable

The errno variable, a standard WebCenter Sites variable, holds error numbers that the WebCenter Sites XML and JSP tags report. When a WebCenter Sites tag cannot successfully execute, it sets errno to the value that best describes the reason why it did not succeed. For example, an errno value of -13004 means a CURRENCY tag couldn't read a number because it was not in the correct currency format. For a complete list of all the errno values and their descriptions, see the error conditions section in the Tag Reference for Oracle WebCenter Sites Reference.

The tags that are delivered with the WebCenter Sites modules and products clear errno before they execute so you do not have to set errno to 0 when you want to check for errors from these tags. However, it is recommended that you clear error numbers before executing a tag. Here's a code example that determines whether an ASSET.LOAD was successful before attempting to load the child assets:

<ASSET.LOAD NAME="topArticle" TYPE="Article" 
OBJECTID="Variables.cid"/>
<IF COND="IsError.Variables.errno=false">
<THEN>
<ASSET.CHILDREN NAME="topArticle" 
LIST="listOfChildren/>
</THEN>
</IF>

To check the results of the tags that are delivered by WebCenter Sites, you should include code that clears the value errno before the tag whose results you want to check. For example:

<SETVAR NAME=errno VALUE=0/>

The following code sample shows an error message that you could use while you are in the process of developing your templates:

<IF rendermode=preview>
<THEN>
<IF COND=IsError.Variables.errno=true>
<THEN>
<FONT COLOR=#FF0000>
Error <ics.geterrno/>
while rendering <ics.getvar name=pagename/> 
with asset ID <ics.getvar name=cid/>.
</FONT>
</THEN>
</IF>
</THEN>
</IF>

Ensuring that Incorrect Pages Are Not Cached

If you can determine that the output from an element is incorrect, there is probably no need for WebCenter Sites or Satellite Server to cache the page. You can stop the page that is being generated from being cached with the ics.disablecache tag.

Example 1: Error Condition

To continue with the first example in Using the Errno Variable, if the article asset could not be loaded, there would also be no reason to cache the page. You could add the following ELSE statement to the IF condition in that code sample:

<ASSET.LOAD NAME="topArticle" TYPE="Article" 
OBJECTID="Variables.cid"/>
<IF COND="IsError.Variables.errno=false">
<THEN>
<ASSET.CHILDREN NAME="topArticle" 
LIST="listOfChildren/>
</THEN>
<ELSE>
<ics.disablecache/>
</ELSE>
</IF>

Example 2: Clear the Page From Cache if the Asset's Status is VO (Basic Assets Only)

The CacheManager on the destination system regenerates all the pages and pagelets that were affected by a publishing session. Affected pages includes those whose dependent assets were deleted.

Deleted assets have their status set to VO. The ASSET.LOAD and asset:load tags do not check the status of an asset before they execute which means they can and will load a deleted asset. Typically this isn't a problem. Why? Because an asset cannot be deleted until all links to it from other assets are removed. Therefore, when the site is regenerated there are no longer any links to a page or pagelet that would display the deleted asset. But there is no need to leave a page or pagelet that displays a deleted asset in the cache.

The following code sample stops the page from being cached if the asset cannot be loaded or if the asset's status is deleted:

<ASSET.LOAD TYPE="Variables.c" OBJECTID="Variables.cid" NAME="WireStoryTextArticle"/>
<!-- if the asset cannot be loaded, then flush the pagelet from cache -->
<if COND="IsError.Variables.errno=true">
<then>
<ics.disablecache/>
</then>
</if>
<ASSET.SCATTER NAME="WireStoryTextArticle" PREFIX="asset"/>
<!-- if the asset is marked as void, then flush the pagelet from cache -->
<if COND="Variables.asset:status=VO">
<then>
<ics.disablecache/>
</then>
</if>

Note that you do not have to include code that checks the status of flex assets. The SEARCHSTATE and searchstate tags do not return assets that have a status of VO and the ASSETSET and assetset tags do not include assets that have a status of VO in the assetsets that they create.

Encoding Page Arguments

The encodeParameter element is called to encode arguments. In the excludeParametersLst argument value field you can include the arguments you don’t want to encode. Use this method as a best practice for secure coding, for any arguments passed into a template via URL or any other way.

 <ics:callelement element="UI/Utils/encodeParameters"> 
 <ics:argument name="excludeParametersLst" 
 value="<list_of_comma_seperated_args>"/> 
  </ics:callelement> 

For example:

 <ics:callelement element="UI/Utils/encodeParameters"> 
 <ics:argument name="excludeParametersLst" value="attributes, 
 displayData,browseUrl,chartParams"/> 
 </ics:callelement> 

What You May Need to Know About Securing Your Site Against XSS Attacks

Have you sanitized custom and system parameters in the custom element you’ve written for your site?

To avoid cross site scripting (XSS) attacks, first you should identify the vulnerable parameters, and then encode or sanitize them according to their business logic.