Sunday, August 28, 2016

Generating page urls which reflects folder structure

In Oracle WebCenter Sites 11.1.1.8.0 and above, it is very easy to generate vanity urls with help of webroots. With introduction of Vanity URLs concept, editors have control over urls without help of developers once URL Pattern is set and thus, removing the need of developing/updating URL assembler for generating urls. Furthermore, editors have ability to create 301 and 302 redirects as well.
Admin/Developer's Guide details about setup of webroots and URL pattern with examples, hence, it is redundant to explain the same in this post.

Although, there is facility to generate desired short urls, there is one particular case which mostly every client wants to have i.e. to generate urls for page assets that reflects the pages placed in SitePlan tree (/locale/level-1-page/level-2-page/..).
For e.g. Consider FirstSiteII sample site, there are 4 home pages for all each language: en, fr, de, es and there are few pages placed under FSIIHome (en language version of pages), thus, any client will like to have url the following way:

FSIIHome --> /en/home
       FSIIAbout --> /en/home/about-us
       FSIIProducts --> /en/home/products
       .....
Home (es) --> /es/home
Home (fr) --> /fr/home
Home (de) --> /de/home

As Editors keep on adding/editing and updating pages' position in SitePlan, it has become very necessary for clients that pages' URL update automatically. Also, editors mostly desire to decide their own url string, for e.g. for Home (fr), url string would be accueil, thus url should be --> /fr/accueil

Keeping in the mind above requirements, there are 3 easy ways (there can be other ways too) to achieve hierarchical urls for Page assets. First of all, it is very clear that editors want to enter their own url string (page url string which would be part of url); thus, create one attribute which would hold this url string value which editors can edit.

1. URL Assembler: It is widely used by various developers to generate page urls which reflects page path in SitePlan. As this post is about generate vanity urls without use of Assembler, it is out of scope of this post.
A simple idea would be to find page's path in one element and then pass this calculated path as argument to <render:gettemplateurl> tag with inclusion of assembler attribute which would be used to generate urls while assembling. Developer's Guide details on how to generate url assembler and is quite explanatory.

2. Flex Filter: Flex filter can be used for finding page's path and save the path in some custom attribute (say URLPath) so that this custom attribute can be used for defining Page's URL Pattern.  Thus, while creating Page URL Pattern, pattern can be similar to following: ${locale}/${f:spaceToDash(URLPath.toLowerCase())}

Although, it is quite a flexible solution but if any changes are required, have to update and deploy flex filter which may not be desirable in few situations like restarting WebCenter Sites, saving all page assets, etc. Furthermore, I have experienced that updating URLPath attribute's value with page path doesn't always reflect immediately in page's vanity url. Sometimes, its required to edit & save page assets 2 times. I faced this issue in my local 11.1.1.8.0 JSK but may be latest patch includes the fix.

3. Custom Function: All the Functions which are available while defining vanity url pattern are present in OpenMarket/Xcelerate/Util/GetUrlExpressions element. You can update this element and add your own custom function as required and generate vanity url for assets. Please note, functions within this element do not support Asset API or REST API but it does allow use of ICS object. Thus, with this key information, we can use ICS object to call a CSElement which can generate url path string and then, use this calculated url path string to generate hierarchical urls for Pages.

For creating the custom function, just start by creating one CSElement with name: OpenMarket/Xcelerate/Util/GetUrlExpressions and click on Element Tab, automatically existing code should be visible as it should already exist in ElementCatalog. Include the following custom function which accepts id and locale as input and calls a CSElement. This CSElement is responsible for generating url path and set the url path in ics scope to be used by the custom function.

Sample code for finding URL Path (URLString is the page attribute where editors can input desired URL string for the page asset):

And, then just define page vanity url pattern using the above custom function. Add attribute: URLString to all page assets, update values in all Page assets and save. Vanity URLs should be present for all the page assets.

Following snapshots are for FirstSiteII Page URL Pattern as example:

FSIIPageURLPattern
FSII Page Vanity URLs

Thus, by using custom function defined in GetUrlExpressions groovy element and CSElement, one can update business logic as many times required without restarting WebCenter Sites and deployment issues.

CAVEATS:
  • There is no escape from editing and saving children page assets when URLString attribute's value is updated in parent page. For e.g. updating FSIIHome's URLString attribute value from home to fsii-home does updates the vanity url for FSIIHome page from /en/home to /en/fsii-home but does NOT updates the children page's vanity url for e.g for FSIIAbout vanity url from /en/home/about-us to /en/fsii-home/about-us. All the children pages are required to be edited & saved for updating vanity urls. This is where URL Assembler can be helpful if there are many URLString attribute value changes but considering that most companies are very strict about SEO and google page ranking, page urls will not be changed frequently. Also, one can plan to generate vanity urls for Page assets when there is release, thus, it would be only one time edit & save for generating vanity urls for Page assets. Finally, it all falls to business decision.
  • During upgrade or applying patch, one needs to take care that GetUrlExpressions element has your custom function otherwise you many loose all the vanity url for pages and have to generate again.
DisclaimerThe code and/or the configurations posted are not official recommendations and should be used at sole's discretion with proper testing before deploying on live WebCenter Sites systems. Cheers!!

A simple code compare functionality

One of the most important aspect of any development cycle is deployment and while deployment, it is very important to note the changes don...