Sunday, January 3, 2016

Using controllers for development

Welcome to Oracle WebCenter Sites 12c development! After the introduction of MVC framework in Oracle WebCenter Sites, it is now very very easy to perform CRUD operations on assets as OOTB Controller assets are sufficient to carry out nearly 99% of your WCS development. Developers now need to learn little bit of groovy but its okay even if you know JAVA and jstl programming. But still in current release of 12c, legacy tags and asset api can also be used.

If you browse through Samples site, all new concepts are described aptly in the site's sections itself so its redundant to write the same thing in this post. I just wanted to list down few simple cases which are not present or not explained in detail in Samples or Avisports site.

1. Debugging using watchers:

Debugging is little bit difficult when it comes to WebCenter Sites; if not aware of various core functions which are used in background. And seems like that hasn't changed much as it is same case while using controllers. Whenever there is error thrown from controller, you get detailed error log in sites.log but sometimes it may be difficult to decipher the root cause. Thus, the role of watchers is very useful not only during debugging but also gives detail on output of your data in the model object. For every function, you can just add your own watchers and print them in your JSP code.

Syntax to define in controller: watch("__my_watch__")
Syntax to print output in JSP: $("__my_watch__")

Watchers are very useful when you just want to check output from your controller's method. For e.g. Create one controller and add any method which is defined in Samples site and then create one template (applies to various asset type, can be called from browser, uncached) and assign your controller. In template code, just add the following line of code within <cs:ftcs> opening and closing tag, which is basically default watcher: ${__$WATCH$__}
Now, call your template directly from browser using following url: <hostname>:<port>/sites/Satellite?pagename=<sitename where template was created>/<template name>&c=Page&cid=<Some random id> --> which should print the output of your controller's method. Note: Output will be from the asset of what c and cid is used in controller.

2. Accessing attribute values:

To fetch attributes of data type: string, text, number, float, date, int, money ; use the following syntax in JSP template or CSElement:
${asset.YOUR_ATTRIBUTE_NAME} or ${asset["YOUR_ATTRIBUTE_NAME"]}  
where asset is the model object containing the map values which was defined in controller.

To fetch asset of type blob, use the following syntax:  
${asset._bloblink_} or ${asset.YOURATTRIBUTENAME_bloblink_}

To fetch hyperlink for an asset: ${asset._link_}

To fetch attribute of type - asset: ${asset.YOURATTRIBUTENAME} but it will just provide your associated asset id. So to get detail/summary/link template fragment of this associated asset, fetch id in your controller using following syntax: models.asset.YOURATTRIBUTENAME whose output is basically an arraylist. Loop through list and get each id values. Create one empty List<Fragment> and add as TemplateFragment or SiteEntryFragment or ElementFragment to it to be used in Template or CSElement code. For eg: Suppose product assets are associated to one attribute: RelatedProducts and you want to show them using Summary template, then your code will be as followed:

 
and jsp code as followed (don't forget to include jstl core library at top of your element):

<c:if test="${not empty relatedProducts}">
   <c:forEach begin="0" end="${relatedProducts.size()-1}" var="product">
      <fragment:include name="relatedProducts" index="${product}"/>
   </c:forEach>
</c:if>

3. Formatting date is now very simple using jstl fmt:formatDate tag. Just pass ${asset.DATE_ATTRIBUTE_NAME} and desired format to get the formatted date.

4. Apart from watchers, you can directly log the desired output using already defined logger for controller:  
log.info("AssetMap: " + assetMap) OR log.info(JsonOutput.prettyPrint(JsonOutput.toJson(assetMap)))

5. Although methods related to search are explained but fails to provide info on how to sort and search against locale/dimension content. Following code searches against Page of only particular locale - en_US, sorts by updateddate descending and sets only the latest updated page into model object.

That's all for now, will share as I explore more.

Need help? Click here.

6 comments:

  1. Nice Article.... really useful for me.

    Thanks,
    AjayKishore

    ReplyDelete
  2. Hi,

    how to retrieve flex attributes while doing the filter search
    ex: def results = newSearcher().from("Site_News_C").selectAll().search()
    the models.results --- it is showing only meta attributes,not the flex attributes.
    How to solve this please let me know if you have any clue on this.

    ReplyDelete
    Replies
    1. Use SearchHelper for better results

      Delete
    2. searcher with filter also getting the results now...

      Delete
  3. This comment has been removed by the author.

    ReplyDelete
  4. I have a page attribute of blob type. How do i render its values in my template.

    ReplyDelete