Translate

Sunday, September 6, 2015

Using Groovy elements in WCS

One of the new features which were introduced with Oracle WebCenter Sites version 11.1.1.8.0 was use of Groovy within WCS. You can now write code in Groovy elements to perform business logic separately and hence, with proper plan and design, one can develop a site with MVC pattern.

Although there is not much documentation or explanation on how to use it. There are few interesting articles by Oracle expert team which should be helpful:

1. Why to use groovy with WCS?
This article explains not only how WCS product uses groovy element but possible use of it to design MVC pattern within WCS sites.

2. Wrapper-CSElement example using Groovy
Although it's not a simple example as one would like but you get the point once you go through it.

3. Using RUNTAG api
This is far most best example explaining use of groovy to render sites tags. Best part of using groovy is that it can invoke both JSP and XML tags.

4. An useful use case
Setting http-status codes, content-type at runtime and redirect implementation; which may be desirable for many clients.

5. Get Translated asset
Describes the method to get a translation of an asset using Groovy.

6. Groovy CSELement Dispatcher
A good example on how to leverage groovy to generate output in different formats by setting content-type at runtime. This use case is very simple yet very useful and powerful considering that if your clients wants to have WCS site based content output in different formats for e.g. generating different web feed formats (like atom or rss), json object to be consumed by other sites or internally, XML/HTML output of certain webpage, etc.

All of the above examples mentioned are really good in terms of providing knowledge and implementation of groovy element.

Groovy was already used before it was officially being introduced to Sites with GSF framework. Currently, WCS product itself doesn't use many groovy elements but a few. It seems after the introduction of groovy, in future, more of development should occur within product (or sample sites) which shall make full use of groovy language to develop a site or product itself. Henceforth, it is better for any Sites developer to learn groovy and be prepared to use it.

----------------------------------------------------
SUGGESTIONS/COMMENTS ARE INVITED
----------------------------------------------------



Friday, April 3, 2015

Example 14: Searching Assets using Lucene Search API

Hello, this blog corresponds to the chapter - Public Site Search from Oracle WebCenter Sites developer's guide but also applies to FatWire 7.x version too.

Before jumping into example, one should know the architecture behind lucene search used in Sites/FatWire:

There are 2 types of indexes: Global and AssetType. Default attributes present in
1. Global indexes is defaultSearchField which contains all the following: asset type, asset subtype, name, description, status, createdby, updatedby, updateddate, startdate, enddate, fw_uid, id, fw_tags, all asset's flex attributes. Other attributes are also stored as stated in guide. All the indexes are stored under <WCS_Installed_Folder>/shared/lucene/Global
2. AssetType indexes - All the metadata in defaultSearchField and rest attributes in seperate columns as stated in guide. All the indexes are stored under <WCS_Installed_Folder>/shared/lucene/<AssetType>

This indexes can be checked via one tool - LUKE

You should check out this chapter in Admin Guide for configuring lucene indexes and once you know how to configure, you can proceed with coding to search assets via lucene search API.

When to use what?

Global indexes are used for searching against any asset types, hence, then name Global index and Public Site Search. You can search against multiple asset types given that there is a common attribute like name, description, createdby, etc. or even if you have created your flex family in such a way that all the asset types fall under one Attribute type and there is one common attribute among all the definition, that attribute can used for Global/Public site search.
AssetType indexes as you can guess is limited to only one Asset Type search.

Common methods and their description are provided in Guide here. You can also browse through javadoc to see various methods.

Example: The following example can be used to search against AVIArticle for AviSports site which comes along with JSK 11g. Enable AVIArticle lucene index and enable GLOBAL indexes for AVIArticle too. Add the attributes like headline, abstract, postDate, etc. for indexing. Once done, proceed with creation of one template - SearchLayout (type: Page and usage: can be used as Layout and add 2 params in cache-criteria - keyword and form-to-render) and just save. Create one Page asset with nothing in it, just a name should suffice, and assign this template SearchLayout. (You can also place this page under AviSports home page so that it will be visible in top navig)

Copy and paste code form Page/ArticleLayout.jsp to this template - SearchLayout. Delete the main container code from the template which would look like this:
This snippet was taken from HomeLayout template present in 11.1.1.6.0 JSK

Thus, now all the code will be under between container id.

First, just a simple form tag with one input field like text with name="keyword" (keyword search will be performed against headline or abstract field for AVIArticle asset). Replace the <form> tag into <satellite:form> tag (don't forget to include satellite tag lib at the top of your template).

Use the tag: <render:gettemplateurlparameters> to generate URL for this page itself (Same page will be called after the form is submitted) and render all the args name and value inside <satellite:form> as hidden params. Check the tag here.  (don't forget to include string tag lib at the top of your template). It should end up like this:

Once search form is completed, proceed with search lucene search logic as shown.


and then, just load the query and show the results as required:

































You can download the source code from here.

Update: In latest 11g version, you have the ability to configure vanity URLs per asset. So if you have vanity URL enabled, then the above search may not work. There are 2 or more possible solutions, I am listing 3 of them:
1. Apply Patch 2 or greater and replace <satellite:form> with <form> tag. Pass action url in form and remove passing of hidden params via <render:geturltemplateparameters> tag.
2. Another way is to delete vanity URL entry for the page asset. Go to your page asset, search for the URL tab, copy the URL and go to Admin UI -> System tools -> double click URL -> Select "URL" as search criteria, paste the URL which you copied and then search. Select the entry and click delete, this will remove vanity URL for the page asset. Check your search page asset, there should be no vanity URL in URL tab. Above code will work with this configuration.
3.  Don't pass action url, this way you get form but again no vanity url.

Notes:

1. If you want to build global site search, then following changes should be done. Note: There should be at least one common attribute to search against.

IndexSourceMetadata metadata = con.getConfiguration( "Global" );
QueryExpression typeQ = new QueryExpressionImpl(SearchIndexFields.Global.ASSET_TYPE, Operation.EQUALS, "AVIArticle");
typeQ = typeQ.or(SearchIndexFields.Global.ASSET_TYPE, Operation.EQUALS, "AVIImage");

2. If you want to search against Parent assets. For e.g. finding AVIArticles with parent "Skiiing", use filter: FieldCopier to copy parent id in one attribute and enable this attribute for indexing and update your query to search against that indexed attribute name.

3. Similar above steps can be done to search against associated content.


----------------------------------------------------
SUGGESTIONS/COMMENTS ARE INVITED
----------------------------------------------------



Saturday, March 7, 2015

Example 13: Create, update and delete Asset (Asset API Write)

This section of blog lists how to create, update and delete assets (flex, basic and flex parents only) using Asset API. Most of examples are present in Developer's guide which can be accessed here -> http://docs.oracle.com/cd/E29542_01/doc.1111/e29634/asset_api_tutorial.htm#WBCSD2403

All examples for creating, updating and deleting assets are already present.
Although methods are defined in developer's guide, but some are missing, so I have listed those:
1. Updating an asset's attribute of type-asset

a.getAttributeData("<Attribute Name>").setDataAsList(Arrays.<AssetId>asList( new AssetIdImpl( "<ASSET TYPE>", <ASSET ID in LONG>)));

2. Get an asset's locale

data.getAttributeData("Dimension").getData());

3. Avoid getting parent's attribute value if child has no attribute value by setting immediateOnly

query.getProperties().setIsImmediateOnly(true);

4. While querying asset, you can set Site condition as shown:

query.getProperties().setSite(<SITE ID in Long>);

5. While querying asset, you can set locale condition only if you have copied its name to some other custom attribute via flex filter

6. Get parents or immediate parents

java.util.List<AssetId> parents = data.getImmediateParents();
java.util.List<AssetId> parents = data.getParents();

NOTE: Before using those methods mentioned in guide, please note that:
  1. Flex family or Basic asset family should already be created i.e. framework must be ready
  2. For flex -> attributes, flex parent definition, flex content definition and flex filters must be present too.
  3. Considering that you have FSIISite in your installation, examples provided in guide are valid
General steps to follow:
    1. Get a session
    2. Get a handle to AssetDataManager
    3. Use appropriate method to
      • CREATE - AssetDataManager.insert( List<AssetData> data )
      • UPDATE - AssetDataManager.update( List<AssetData> data )
      • DELETE - AssetDataManager.delete( List<AssetData> data )
    4. Use the above API with care and always handle all exceptions with logging

----------------------------------------------------
SUGGESTIONS/COMMENTS ARE INVITED
----------------------------------------------------