Translate

Monday, November 25, 2013

Example 7: Site Plan

This example illustrates how to render SITE PLAN in different cases.

CASE 1: If you know Page name or asset id.

GENERAL STEPS TO FOLLOW:
  1. Load the page asset (using asset:load tag) 
  2. Get the site node from SitePlanTree table (using asset:sitenode tag) 
  3. Load the node (using siteplan:load tag)
  4. Get ChildList from loaded node (using siteplan:children tag or using siteplan:listpages tag)
  5. Loop through childlist to get Page name/id (using ics:listloop tag) 
a) Using siteplan:children tag

<asset:load name="target" type='Page' field="name" value="Home" site="<%=ics.GetVar("site")%>"/>
<!--  Get site node -->
<asset:getsitenode name="target" output="PageNodeId"/>
<!-- Load Home page as a siteplan node object -->
<siteplan:load name="ParentNode" nodeid='<%=ics.GetVar("PageNodeId") %>'/>
<!-- Obtain Home page's child node, save in list and order them by their rank -->
<siteplan:children name="ParentNode" list="ChildPages" order="nrank" code="Placed" objecttype="Page"/>
<!-- Loop through list to get page names's under Home page node -->
<ics:if condition='<%=ics.GetList("ChildPages") !=null %>'>
<ics:listloop listname="ChildPages">
<ics:listget listname="ChildPages" fieldname="id" output="aid"/>
<asset:load name="ThePage" type="Page" objectid='<%=ics.GetVar("aid") %>' />
<p><asset:get field="name"/></p>
</ics:listloop>
</ics:if>

b) Using siteplan:listpages tag (continue after loading the parent node (using siteplan:load) as shown above)

<!-- Query the SitePlanTree table and then creates a list of pages, starting with the page node that you specify. -->

<siteplan:listpages name="ParentNode" placedlist="placedPages" level="1" />
<!-- Loop through list to get page names under specified page node -->
<ics:if condition='<%=ics.GetList("placedPages") != null %>'>
<ics:listloop listname="placedPages">
<p><ics:listget listname="placedPages" fieldname="PageName"/></p>
</ics:listloop>

</ics:if>



CASE 2: Querying from root node i.e. Publication Node of the site. This is required when you want to extract and display information about the site structure from the top down. You can even list the pages which are placed or unplaced.

GENERAL STEPS TO FOLLOW:
  1. Load the publication (using publication:load tag) 
  2. Get the publication id (using publication:get tag)
  3. Query the SitePlanTree table for a root node of the site plan (using siteplan:root tag)
  4. Loop through list to get publication nid (using ics:listloop tag) 
  5. Load the node (using siteplan:load tag)
  6. Get ChildList from loaded node (using siteplan:children tag)
  7. Again loop through childlist if there child pages are required as shown in CASE 1
<publication:load name="thisPub" field="name" value='<%=ics.GetVar("site") %>'/>
<publication:get name="thisPub" field="id" output="thePubID"/>
<siteplan:root list="PubRoot" objectid='<%=ics.GetVar("thePubID") %>'/>
<ics:if condition='<%=ics.GetList("PubRoot") != null %>'>
<ics:listloop listname="PubRoot">
<ics:listget listname="PubRoot" fieldname="nid" output="rootNodeid"/>
<siteplan:load name="RootNode" nodeid='<%=ics.GetVar("rootNodeid") %>'/>
<siteplan:children name="RootNode" list="RootChildPages" order="nrank" code="Placed" objecttype="Page"/>
<ics:if condition='<%=ics.GetList("RootChildPages") !=null %>'>
<ics:listloop listname="RootChildPages">
<p><ics:listget listname="RootChildPages" fieldname="name"/></p>
</ics:listloop>
</ics:if>
</ics:listloop>
</ics:if>

INFO:
  • Using siteplan tags can be trickier when you want specific information, so please read about them before you use them.
  • While coding for siteplan, always keep in mind what table column we are getting after the query. Read the tags properly, its written there.
  • Keep CS Explorer (FatWire)\ Sites Explorer (Oracle WCS) handy to see which field's/column's value you are retrieving.
----------------------------------------------------
SUGGESTIONS/COMMENTS ARE INVITED
----------------------------------------------------

Saturday, November 16, 2013

Example 11: Basic Guidelines for using TAGS


Hi All, I would be adding here tips & tricks for using tags which are used in FatWire/Oracle WebCenter Sites. This post would be always be alive and I would be adding new findings as I learn more.
  1. Never hardcore assettypes and specifically, assetids in tags i.e. don't write them as they are present in FatWire. This is very important because after publishing your site from environment to other, assetids changes and hence, hardcording is never an option. Use tags to retrieve assetids. (Faced one such issues while working with 11g) For eg: If you want assetid of  a Page Asset, just load the Page asset using <asset:load> by providing name/value pair and retrieve assetid or use Template/CSElement mapping (render:lookup tag). This helps when 2 assets have same name but you have mapped the correct required one in the MAP.
  2. Read what tag does before you use them. This is really important as I have seen people in past using tags without reading them and suffering from long hours of resolving many issues. For eg: Retrieving a flex asset using asset:load is NOT recommended. Site would work with no issues even if you use asset:load to retrieve flex assets, but later on when you site grows, you will face many performance issues. Hence, use correct tags to retrieve assets.
  3. Check the attributes which are included while using tags. For eg: use of 'scoped' attribute while calling CSElement via render:callelement tag. Please read documentation before using any tags to leverage their full use. Another thing which I noticed in performance was using some tags attributes properly. For e.g. Using <ics:listloop> tag; suppose you want only 2 results, use maxrows argument so that loop does not iterate over full list, its just like adding break in for loop.
  4. This may be new to many. XML tags and JSP tags can perform different in functionality. You may get some attributes/tags which are available in XML but not in JSPs and vice versa.
  5. Use tags which sets compositional dependencies for cache management automatically. FatWire is all about Caching and Designing. If your design (creation of minimal flex family and basic family, less number of templates, proper use of subtype dispatching, etc. ) is proper and Caching strategies are well prepared, your site would be very fast and fluid. Some tags are unaware of what type of assets they are going to be deal with and hence, those tags generates undeterminable dependencies , which may again lead to performance issues. Eg: use <render:unknowndeps> when you querying for large number of assets. Please read about dependencies from documentation, it is very necessary to know about them.
  6. Retrieving One attribute vs Multiple attributes: This may seems like very easy but again when your site grows large, you may face performance issues. For eg: Consider asset:load tag to retrieve basic asset. After using this tag, if you code to get every attribute of its asset using asset:get tag, it tries to fetch info every-time from db which is very performance costly, so use asset:scatter which will retrieve the required attributes in one go. Similarly is the case with flex assets. Check out assetset:getattributevalues and assetset:getmultiplevalues in tag reference.
  7. Search tags: Searching assets via asset:search or asset:list is very costly than using searchstate tags for large amount of data. Check the use of searchstate tags explained in one of my blogs.
  8. Always perform NULL checks and make use of  ics:geterrno to check if your tags threw any error. For eg: After retrieving attributes of flex assets in list, we should always check if the list is empty or not.
  9. Flush the variables which are not required using ics:removevar or ics:removessvar. This may seem like waste of line of code but let me give you one example of its use. Suppose, you are looping through list of assets and retrieving their attributes and setting in HashMap, we can make use of one variable to assign that value and remove its variable after putting in Map for the next data to be set. Eg: If we have list of username set in Map with no values and you want their ages to be set in values, so rather than calling a particular template repeatedly, its better to use loop. For eg:                                                                                                    <%for(Entry<String,String> entry: userMap.entrySet())                                                                                        { %> <render:callelement elementname='GetAge' scoped="global" >                                               <render:argument name="name" value='<%= entry.getKey() %>'/></render:callelement>                             <%  if(Utilities.goodString(ics.GetVar("age"))){userMap.put(entry.getKey(),ics.GetVar("age"));} ics.RemoveVar("age");}%>
  10. Use CatalogManager tags wisely, they have ability to delete/edit database tables.
  11. Passing arguments: Developers often tend to forget to include the arguments in cache criteria, when we pass any argument to call other template from current template. 
  12. Passing multiple values: Pass as comma separated values as one string while passing through arguments in tags. Less arguments - less dependencies. Avoid large number of arguments as possible.
  13. Use tags for date formatting, decimals, currency and string provided by Fatwire rather than using Java classes.
  14. You might use same variable in one template, either remove that variable after its use or use the variable as - Variables.assettype:fieldname
  15. Use ics.RegisterList("IList Name",null) to de-register the list which would avoid any clashing between two lists on same page with same name.
  16. Sometimes, we require asset name, page name or their asset ids which are not associated with our assets or page and hence, these can not be generated on template or CSElement dynamically. For eg: Suppose you want to load homepage on your template for generating siteplan, so you end up using asset:load to load the page either with its name or id, which is again hardcoding values. So to avoid that, use "Map" functionality in CSElement or Template where you can provide key-value and bind the page asset with template, ensuring intended asset is called dynamically. Use render:lookup tag for this.
  17. Variables: GLOBAL vs LOCAL - Global variables (including reserved variables) have more precedence than Local variables. For e.g. "site" variable which is present in URL act as Global variable. So suppose you want to pass site names to some particular element to get some value and if you are using variable - "site", you are in trouble because using "site" variable will provide you same value which is present in URL in the calling template.
  18. Try to minimize loading of assets. For e.g. Rather than using asset:load tag and then using asset:children tag to get association, don't use asset:load. You can directly load association by providing asset id and asset type info to <asset:children> tag (Check how in tag reference)
  19. If you want to know metadata attributes of flex or basic asset, use <asset:load> and <asset:scatter> tag. <asset:scatter> tag has ability to scatter all the metadata attributes of the loaded asset using asset:load tag.

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

Example 8: Satellite forms

Satellite Forms: Can be used via tag - satellite:form, which emits an HTML <form> tag suitable for using in a Satellite Server, Sites, or mixed Sites-Satellite Server environment. It eliminates the need to have to specify the action parameter, and by doing so, gives control over the action URL to the Satellite Server tags. Forms generated using satellite:form tag can be used to replace all input forms.

GENERAL STEPS TO FOLLOW:
  1. Replace <form> tag with <satellite:form> tag 
  2. Import the satellite and string tld
  3. Use <render:gettemplateurlparameters> to generate the URL where you want to submit the form
  4. Loop through outlist generated by above tag inside form as hidden parameter
  5. Also include one hidden parameter for eg: ftp (form-to-process) which would be passed along with other hidden parameters in packedargs variable.
  6. Process/Pass the arguments starting from Wrapper -> Layout -> (Subtype Dispatching) Specific form processing Template or CSElement to required output template. Use render:unpackarg tag to retrieve variables from packedargs strings
  7. Don't forget to add the parameters in cache criteria of corresponding Template/SiteEntry.
CASE 1: A very simple login form

</render:gettemplateurlparameters outlist="args" 
tid='<%=ics.GetVar("eid")%>' slotname="loginForm"
site='<%=ics.GetVar("site")%>'
c='<%=ics.GetVar("c")%>'
cid='<%=ics.GetVar("cid")%>'
wrapperpage="<Wrapper_Name>"  
tname="/<Layout_Name>" >
</render:gettemplateurlparameters>

<satellite:form  method="GET" >
     <label>Enter Username and Password</label>
     <input type="text" name="username" value=""/>
     <input type="password" name="password" value=""/>
     <input type="hidden" name="ftp" value="loginForm"/>
     <input type="submit" name="login" value="login" class="submit"/>
     <ics:listloop listname="args">
          <input type="hidden" name='<string:stream list="args" column="name"/>'                                              value='<string:stream list="args" column="value"/>' />
     </ics:listloop>
</satellite:form>

INFO:
  • In render:gettemplateurlparameters tag, we need to specify which page we want to submit the request. Hence, the value should be c='Page' and cid='<AssetId of the page>'. Please note don't hardcore assetid, use <asset:load> tag to load page asset and get the assetid.
  • Method can be GET/POST. URL assemblers are only invoked on GET requests. They are not invoked on POST requests. For example, when accessing a page with a GET request, the URL assembler is invoked to disassemble the URL. It then provides the appropriate parameters that Content Server requires to open that page (such as c, cid, and pagename) by adding them to the definition (if they do not already exist in the definition). However, when a request is POSTed, such as a form with method=post, the URL assembler is not invoked to disassemble the URL. Example for a proper POST form given in CASE 2.
  • JavaScript validations which applies to HTML <form> are also applicable for <satellite:form> tag.
  • In above example, WebCenter Sites shows the username and password in the URL after submitting the form which is very threat to user sensitive information, so the parameters Content Server requires to open the page must be part of the post request itself and hence, we need to pass them as show below.

CASE 2: A complex POST form which works with assembler. POST request require both, action in form and rendering of hidden parameters to work with URL assembler.

<asset:load name="PageName" type="Page" field="name" value="ProcessLogin" site='<%=ics.GetVar("site") %>'/>
<asset:get name="PageName" field="id" output="pageId"/>



<render:gettemplateurl
outstr="outLink"
site='<%=ics.GetVar("site") %>'
wrapperpage="<Wrapper_Name>"
tname='ProcessLogin'
tid='<%=ics.GetVar("tid") %>'
ttype='CSElement'
c='Page'
cid='<%=ics.GetVar("pageId")%>'
slotname="processlogin"
assembler='<assemblerShortName>' >
</render:gettemplateurl>

<render:gettemplateurlparameters 
outlist="args" 
tid='<%=ics.GetVar("tid")%>'
slotname="loginform"
site='<%=ics.GetVar("site")%>'
c="Page"
cid='<%= ics.GetVar("pageId") %>' 
tname="<Layout>"
wrapperpage="<Wrapper_Name>">
</render:gettemplateurlparameters>



<satellite:form  method="POST" action='<%=ics.GetVar("outlink")%>'>
     <label>Enter Username and Password</label>
     <input type="text" name="username" value=""/>
     <input type="password" name="password" value=""/>
     <input type="hidden" name="ftp" value="loginForm"/>
     <input type="submit" name="login" value="login" class="submit"/>
     <ics:listloop listname="args">
          <input type="hidden" name='<string:stream list="args" column="name"/>'                                              value='<string:stream list="args" column="value"/>' />
     </ics:listloop>
</satellite:form>

After submit, page should go through ProcessLogin template.
ProcessLogin Template may contain code like (After skipping the obvious importing tld codes):


<%     if((ics.GetVar("ftp")!=null && ics.GetVar("ftp").equals("loginForm"))    
{          //Get username, password and check if credentials are valid and redirect to correct page     
} else {          
// Redirect to login page with showing some error if login info was wrong or ftp variable did not exist in variable pool    

%>


INFO:
  • For form to work with POST request we require both action and hidden url parameters to be passed to work with Assembler (UPDATE: If you are using vanity URLs, then you don't need to pass hidden params generated via <render:gettemplateurlparameters> and have to pass action url in satellite:form tag which will be generated via <render:gettemplateurl> tag. Also include your assembler short name while generating action url, if no assembler, then pass assembler="query")
  • You may/may not require to pass argument while generating url parameters depending upon how your assembler is coded
  • action in form is generated via <render:gettemplateurl> and hidden parameters are passed using <render:gettemplateurlparameters>. Please read about this tags before using them.
  • In Case 2 example, we are submitting the form to other template (ProcessLogin) which processes the login request. For processing, we have passed one hidden parameter (ftp - form-to-process), so that we can check its value in ProcessLogin template and decide on what to do and respond accordingly.
  • Many other points are to be taken care while creating forms, as form processing may undergo JavaScript validation, ajax call for verification of login info (in our case) with 3rd party APIs, processing of some hidden variables passed in Wrapper, keeping the user in session after successful login or showing error if failed, creating/handling cookies, visitor tracking via Engange module (Personalization), etc. All this could vary from site to site and obviously depends on customer requirements.
  • There is introduction of vanity URLs in new WCS 11g (11.1.1.8.0 onwards) where in every asset can have vanity URLs if configured (Its done for avisports in JSK). If you have configured vanity url for a page asset and if you are searching by passing page asset id and template to generate action url, above search may not work. Hence, to resolve this you can do one of the following: EITHER delete the vanity url for this page asset (by doing so, there is no conflict of urls but you will not get vanity url on search which is not desirable) OR use <form> tag rather than using <satellite:form> & pass action url, don't pass hidden params which are generated via <render:gettemplateurlparamaters> tag (by doing so, you are just forward request to a particular page and if there are any params, then those will also be passed along with it) 
  • It seems you cannot pass query params (more than 1) if you are using vanity urls and hence, you will have to apply PATCH 2 or higher so that you can pass query param strings like param1=val1&param2=val2
----------------------------------------------------
SUGGESTIONS/COMMENTS ARE INVITED
----------------------------------------------------

Example 10: Presentation Editing

Insite Editing (PRESENTATION-EDITING): Describes how to render insite tags so that user can choose templates while editing. This section also deals with how to render content so that IN-CONTEXT and PRESENTATION-EDITING can be combined.

* How templates can be coded to allow non-technical users to control presentation of content. This section presents information on “context” and on how to make a presentation change local (i.e. visible only on a given web page), or global (i.e. changing the presentation on one page can propagate the same change to multiple pages on the site). Controlling presentation includes being able to select which page layout to select to render an entire web page, being able to select which content layout to select to render an asset in a given portion of a web page, and being able to select arguments sent to a pagelet template.

1. DEFINING A SLOT FOR PRESENTATION EDITING

* If you want to allow non-technical users to choose which presentation (i.e. which pagelet                              template) to use in order to render a particular page (say an article page), you must define a SLOT, TITLE (slot name) and add the templates in VARIANT attribute (Add multiple templates using variant="Detail.*")

 <insite:calltemplate slotname="HelloSlot"  title="Article Detail Area" tname="HelloDetail"                                variant="HelloDetail|Detail" args="c,cid" />

* The slot defined in our example above is only meant for presentation editing and is not a
 content-editable slot (not a droppable zone).

2. CONTROLLING TEMPLATE ARGUMENTS
* If you want any argument(for eg: image-align to align an image on the page) to be passed, we have to do following:

• The "image-align" argument has to be registered as a legal argument for the
 HelloDetail template. If this step is skipped, contributors will not be able to set its
 value from the editorial UI.
• In order to make sure that caching works properly, the new argument has to be
 declared as a cache criteria.
• Finally, the template code is modified in order to use the newly defined argument.

1. Declare "image-align" as a legal argument of our HelloDetail template asset.
a. From the Admin interface, edit the HelloDetail template asset.
b. For Legal Arguments, enter “image-align” and click Add Argument.
c. Select Required.
d. For Argument Description enter “Image Alignment”.
e. For LegalValues, add the following descriptions:
- For Value: left enter “Value Description: Aligned Left”.
- For Value: right enter “Value Description: Aligned Right”.
f. Click Save.
2. Remember to sync the change made in WebCenter Sites with the WSDT workspace.
3. Use the WebCenter Sites Developer Tools plug-in to add image-align to the set of
  cache criteria.
a. Right-click the HelloDetail Template in the Sites workspace.
b. Select Properties.
c. In the Cache Criteria field, append image-align to the end of the list.
d. Click Submit.
4. Optionally, a default value could be defined by using the "Additional element
  parameters" field and specifying the following value, for instance: "imagealign=right".
5. Modify the HelloDetail pagelet template code

<insite:edit field="largeThumbnail" assettype="AVIImage"                                                                                         assetid='<%=ics.GetVar("imageId")%>' >
<img class='photo <ics:getvar name="image-align"/>' src='<ics:getvar name="imageURL" />' />
</insite:edit>

* When going to the slot properties panel, assuming HelloDetail is the currently selected
layout, the Advanced tab now shows dropdown to select the legal arguments (left or right)

3. EDITING PRESENTATION AND CONTENT SIMULTANEOUSLY
* The insite:calltemplate tag allows editorial users to edit associated content and edit the layout.
 This section explains the difference between a content-editable slot and a presentation-editable                     slot and how to combine the functionality of both to allow editorial users to edit both
 the associated content and the template used to render the content.

1. Understanding CONTENT-EDITABLE Slots and PRESENTATION-EDITABLE Slots

  * Content-editable slots allow users to edit associated content by providing a “droppable zone” for the             user. Presentation-editable slots allow users to select a different template to render the content.

  * To create a CONTENT-EDITABLE slot (creates a “droppable zone” for the user) the                                 insite:calltemplate tag is used with the following defined parameters:
• assetid: The edited asset ID.
• assettype: The edited asset type.
• field: The edited field.
• cid: The ID of the asset to be rendered by the called template.
• c: The asset type to be rendered by the called template.
• tname: The pagelet template used to render the associated asset.
  * This code defines a content-editable slot that creates a “droppable zone” for the user:
<insite:calltemplate 
assetid=" "
assettype=" "
field=" "
cid=" "
c=" "
tname=" " >
</insite:calltemplate>

  * To create a PRESENTATION-EDITABLE slot (allows users to select a different template to                        render content) the insite:calltemplate tag is used with the following defined parameters:
• slotname: This attribute defines an identifier for the slot that is being filled with the
   called template. It should be reasonably easy to understand and should be unique
   across all templates.
• cid: The id of the asset to be rendered by the called template.
• c: The asset type to be rendered by the called template.
• tname: The default pagelet template to be called.
  * This code defines a presentation-editable slot that allows users to select a different template to                        render the content:
<insite:calltemplate
slotname=" "
cid=" "
c=" "
tname=" ">
</insite:calltemplate>

2. Combining CONTENT-EDITABLE Slots and PRESENTATION-EDITABLE Slots

  * To combine the functionality of both content-editable slots and presentation-editable slots,
    the insite:calltemplate tag is used along with all the attributes required for both a
    content-editable slot and a presentation-editable slot.
• These attributes are required for a content-editable slot (creates a “droppable zone” for the                            user):
- field, assetid, assettype
• This attribute is required to define a presentation-editable slot (allows users to select a
 different template to render the content):
- slotname

  * This code combines the attributes for a content-editable slot and a presentation-editable slot:
    <insite:calltemplate
slotname=" "
assetid=" "
assettype=" "
field=" "
cid=" "
c=" "
tname=" ">
</insite:calltemplate>

for eg:
<insite:slotlist field="relatedStories" slotname="relatedStoriesSlot">
<ics:listloop listname="relatedStories">
<ics:listget listname="relatedStories" fieldname="value" output="articleId" />
<insite:calltemplate tname="Summary/SideBar" c="AVIArticle"                                                                        cid='<%=ics.GetVar("articleId")%>' variant="Summary.*"/>
</ics:listloop>
</insite:slotlist>

  * This is the same code used previously, except that we have specified a slotname attribute,
    and a variant attribute (in this case, the list of available templates is restricted to all pagelet
    templates starting with Summary). Because slotname was included inside the insite:slotlist tag, it                      is not required to add it for the inner insite:calltemplate tag. The value is automatically inherited, as is the value of tname and field.
For example:
<insite:slotlist slotname=" " field=" ">
<insite:calltemplate tname=" " c=" " cid=" " />
</insite:slotlist>
                     The Summary/SideBar now behaves as a default template for the related articles. By right                              clicking any related article and selecting the Change Content Layout feature, it now becomes                        possible to select alternate templates.

INFO:
  • Insite Editing topic is a very big topic and one has to seriously read developer guide and work on it.
  • Other topics like: Understanding the CONTEXT System Variable and Enabling Content Creation for Web Mode are needed for developers to understand to make full use of insite editing.
----------------------------------------------------
SUGGESTIONS/COMMENTS ARE INVITED
----------------------------------------------------

Example 9: In-Context Content Editing

Insite Editing (IN-CONTEXT) : Describes how to render insite editing tags for different attribute types with different formatting.

1. STRING: 
<insite:edit field="attribute_name" value="value from variable"/>
or 
<insite:edit field="headline" list="from list" column="value" />

2. TEXT with CkEditor:
<insite:edit list="bodyList" column="value" editor="ckeditor" field="body" params="{width:                               '500px', height: '350px'}" />

3. DATE:
* Insite editing for date is little bit tricky as it depends on how we are formatting date
* With timezone and timezoneID:
************** First, format the date **************
<dateformat:create name="df" datestyle="long" timestyle="long" timezoneid="IST"/>
<dateformat:getdate name="df" varname="formattedDate" valuetype="jdbcdate"                                                    value='<%=ics.GetVar("postDate") %>' />

* If TIMESTAMP is needed, then use
<dateformat:getdatetime name="df" varname="formattedDate" valuetype="jdbcdate"                                      value='<%=ics.GetVar("postDate") %>' />

************** Render date using insite tag **************
<insite:edit field="postDate" value='<%=ics.GetVar("formattedDate") %>' params="                                        {constraints:{formatLength: 'long'} , timePicker:true, timeZoneID:'IST'}"/>

* Without timezone and timezoneID, just remove timestyle, timezoneid while formatting and while                     rendering remove timepicker and timezoneid.

4. BINARY FIELDS:
* We require imageID and list where it would be saved as followed:
<assetset:setasset name="image" type="AVIImage" id='<%= ics.GetVar("imageId")%>'/>
<assetset:getattributevalues name="image" listvarname="largeThumbnailList"                                                              typename="ContentAttribute" attribute="largeThumbnail"/>

* Render image using insite tag:
<render:getbloburl outstr="imageURL" c="AVIImage" cid='<%=ics.GetVar("imageId") %>'                               field="largeThumbnail" />
<insite:edit field="largeThumbnail" assetid='<%=ics.GetVar("imageId")%>'                                                         assettype="AVIImage" list="largeThumbnailList" column="value">
<img class="photo left" src='<%=ics.GetVar("imageURL")%>' />
</insite:edit>

* Following options are available on hovering with toolbaar:
• Upload
• Edit with Clarkii (displays the Clarkii image editor)
• Clear

5. ASSET FIELDS(Single Valued):
* Instead of calling templates with render:calltemplate use insite:template; provide proper                                  c,cid,fieldname
* fieldname values can change for
- type:asset subtype:AVIArticle --> fieldname="attribute_name"
- association --> fieldname="Association-named:<associationName>"
- parent asset --> fieldname="Group_<parentDefinitionName>"

6. NUMBER FIELDS(i.e. integer, double and money):
* For example: attribute_name=price
* Create currency object and display with insite edit as followed:
<currency:create name="curname" isocurrency="USD" separator="comma|dot|default"/>
<currency:getcurrency varname='curout' name="curname" value='<%=price %>'/>

<insite:edit field="price" value='<%=ics.GetVar("curout")%>' params="{currency:'USD'}"/>

7. MULTIVALUED FIELDS
* When dealing with multivalued fields, beyond editing the existing values, editors need to access                       more features such as:
• adding a new value
• removing an existing value
• reordering existing values

a) Editing Multivalued Text Fields (having CKEDITOR)
* Editing all the text fields (attribute type - text (MULTIPLE))
* Following code just enables to edit every text list

<ics:listloop listname="teaserList">
<ics:listget listname="teaserList" fieldname="#curRow" output="currentRowNb" />
<insite:edit assetid='<%=ics.GetVar("cid")%>' 
assettype='<%=ics.GetVar("c")%>'
field="teaserText"
list="teaserList"
column="value"
index='<%=ics.GetVar("currentRowNb")%>'
editor="ckeditor" />
</ics:listloop>

* Following code includes adding, removing, and reordering values

<insite:list field="teaserText"
editor="ckeditor"
assetid='<%=ics.GetVar("cid")%>'
assettype='<%=ics.GetVar("c")%>'>
<ics:listloop listname="teaserList">
<insite:edit list="teaserList" column="value" />
</ics:listloop>
</insite:list>

* In the case of asset reference fields, we will use the insite:slotlist tag instead of the insite:list tag.
 In this case, rather than nested insite:edit tags, we will have nested insite:calltemplate tags.
 
<insite:slotlist field="relatedStories">
<ics:listloop listname="relatedStories">
<ics:listget listname="relatedStories" fieldname="value" output="articleId" />
<insite:calltemplate tname="Summary/SideBar" c="AVIArticle"                                                                          cid='<%=ics.GetVar("articleId")%>' />
</ics:listloop>
   </insite:slotlist>

INFO:

  • This examples were simple taken from Oracle WebCenter Sites developer guide.
  • All asset types, examples and attributes were used from AVISPORTS site.
  • User was given all sites privileges and roles to AVISPORTS site.
----------------------------------------------------
SUGGESTIONS/COMMENTS ARE INVITED
----------------------------------------------------

Example 4: Rendering Blobs

This post illustrates how to render blobs (BINARY LARGE OBJECTS)

GENERAL STEPS TO FOLLOW:
  1. Load the flex asset (using assetset tags) 
  2. Get the value of imagefile attribute in list (using assetset:getattributevalues tag) 
  3. Retrieve information using blobservice tags 
CASE 1: If we are using normal upload functionality for images while creating asset and if you know asset type(c) and asset id (cid). This is used to render image asset as shown below:

<ics:if condition='<%=ics.GetVar("c")!=null && ics.GetVar("cid")!=null%>'><ics:then>
<!-- Use assetset tags to load FLEX ASSETS. CheckOut tagReference for further details. -->
<assetset:setasset name='Media' type='<%=ics.GetVar("c") %>' id='<%=ics.GetVar("cid")%>' />
<assetset:getattributevalues name='Media' immediateonly='true' typename='FlexAssetAttributeType' attribute='ImageFile' listvarname='mediaImageList' />
                 
<!-- 
BLOB attributes are to be rendered differently and uses BlobServer servlet.
Don't forget to include tld in your template/CSElement for BlobService -> taglib prefix="blobservice" uri="futuretense_cs/blobservice.tld"
 -->                  
<ics:if condition='<%=ics.GetList("mediaImageList")!=null && ics.GetList("mediaImageList").hasData()%>'>
<ics:then>        
      <ics:listloop listname='mediaImageList'>
<ics:listget listname='mediaImageList' fieldname='value' output='media_image' />
      
 <blobservice:gettablename varname="uTabname"/>
 <blobservice:getidcolumn varname="idColumn"/>
 <blobservice:geturlcolumn varname="uColumn"/>
 
 <render:getbloburl 
 blobtable='<%=ics.GetVar("uTabname")%>' 
 blobcol='<%=ics.GetVar("uColumn")%>'
 blobheader="image/jpeg"
 blobkey='<%=ics.GetVar("idColumn")%>'
 blobwhere='<%=ics.GetVar("media_image")%>' 
 outstr="imageURL"/> 
    </ics:listloop>
   
<img  src='<%=ics.GetVar("imageURL")%>' >
  
      </ics:then></ics:if>   
          
</ics:then></ics:if>

INFO:
  • Media is just a name used in Assetset tag
  • This code in template should be created once and called from various template/cselement as required by passing c and cid to render blobs.
  •  FlexAssetAttributeType is attribute type (For eg: It would be something like Media_A if you have created flex family using Media_* where *=CD, C, PD, P, A and F)
  • Always do a null check and use log messages to capture errors.

CASE 2: This case may be trickier. If you have stored your images under some folder say "image" in Shared directory, then you can obtain url value of blob, we can use blobservice.readdata as followed and render the image:

<ics:if condition='<%=ics.GetVar("c")!=null && ics.GetVar("cid")!=null%>'><ics:then>
<!-- Use assetset tags to load FLEX ASSETS. CheckOut tagReference for further details. -->
<assetset:setasset name='Media' type='<%=ics.GetVar("c") %>' id='<%=ics.GetVar("cid")%>' />
<assetset:getattributevalues name='Media' immediateonly='true' typename='FlexAssetAttributeType' attribute='ImageFile' listvarname='mediaList' />
<%if (ics.GetList("mediaList") != null && ics.GetList("mediaList").hasData()) { %>
<ics:listget listname='mediaList' fieldname='value' output='mediaFile' />
<%} %>
<%if (ics.GetVar("mediaFile") != null ) { %>
<blobservice:readdata id='<%=ics.GetVar("mediaFile") %>' listvarname="mediaInfo"/>
<%} %>
<% if (ics.GetList("mediaInfo") != null && ics.GetList("mediaInfo").hasData()) 
{
ics.SetVar("mediaURL", "/media/" + ics.GetList("mediaInfo").getValue("urldata").replace("\\", "/"));
}
%>

<img src='<%= ics.GetVar("mediaURL") %>' >

INFO:
  • Create one folder "media" in Shared directory and place all your images.
  • Add this property in server.xml if you are using apache tomcat which is located in conf directory:     <Context path="/media" docBase="<installed location of fatwire>/Shared/ccurl" reloadable="true" debug="1" crossContext="true"/>
----------------------------------------------------
SUGGESTIONS/COMMENTS ARE INVITED
----------------------------------------------------