Translate

Saturday, November 16, 2013

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
----------------------------------------------------

2 comments:

Anonymous said...

Hi,
Where exactly the values are storing and How can we retrieve those value??
Thanks

Guddu said...

Hi,
Could you be specific which values are you talking about?

If you are talking about the input values after the submission of form, then there can be many cases which depends upon client's requirement. For eg: Client may request to submit all the user input values from registration form in their database, in this case, you need to write business logic to update client's database after the form submission.

If you just want to update default database (HSQLDB) which is used with FatWire JSK, then you have create your own table using catalogmanager tags. Read about various tables under this section - "The Content Server Database". Check the catalogmanager tags for all the CRUD operations.

Cheers!!