Enhancing the WebCenter Portal ADF Template – 3 easy steps for front-end developers.

Here are a few tips for creating new ADF Templates for WebCenter Portal.
These tips are for front end developers applying a branded template or who are integrating their own custom Javascript enhancements.

There are 2 approaches widely used – the first option is to use pure ADF for everything – the second and one which I follow is the hybrid approach to use HTML and JSTL tags only for templating; as I feel its easier for web designers to skin and maintain a light weight frontend without the need to learn ADF techniques.

Read on for tips on templating -

Lets Start off with a clean ADF Page Template first -

The first thing to do is add the files to be included in the generated template <head></head>.

So first lets add  a generic CSS file ie global.css this is not the ADF Skin and should not contain any ADF skinning syntax ie af|panelGroupLayout {} or hacks like .af_panelGroupLayout {} or compressed CSS adf classes ie – .xyz {}.

This af:resource tag will put either JavaScript or CSS files based on the attribute type into the DOM <head></head> of the generated template.

If your like me – I like to modularise my CSS files into multiple maintainable files like this -

So you can see global.css acts as a CSS Module container importing the rest of the files. This allows me to maintain and update the CSS files individually ie Normalise, bootstrap, iscroll etc.

What’s also really useful is that with the requireJS library – when I move the files from DEV to SIT OR Live requireJS will compress and pull all those modules into a single global.css removing the imports improving load times.

Next lets add some base scripts to load first  in the head before the rest of the page loads.

So first lets discuss plugins.js

This defines an empty method if the object console is not defined.
For more info on JS console and debugging javascript (Chrome Dev Tools) || (FireFox FireBug)

I often leave console.info, log, error methods in my javascript which makes it easier to debug when doing early development – these echo methods will be stripped out when compressed and moved to SIT/Live with the use of requireJS or will be ignore if console is not defined.
(more to come on requirejs in next post) 

- this is common for browser like IE and FireFox without firebug enabled – any console objects found would create a JS error if it the above script was not included.

 JS Method Chaining and initialisation.. ..

This is important as I use requireJS library as a module loader at the footer of the template. RequireJS asynchronously loads in my dependency libraries ie Jquery, mustache templates and my own custom JS Libs as-well as providing a great tool for optimising and merging of the  libraries into 1 file like the CSS above.

After loading the dependencies the chain method is initialised.

(Why load JS files at the footer and not in the <head></head> with af:resource?
Read this - why it is best practise for scripts to load here by yahoo) ( btw – Modernizr needs to load in the <head></head>)

The chain method above allows me to have multiple portlets that can chain their methods to only initialise once all the dependencies have been loaded on the page. ie. If you imagine an onReady event that only initialises when page has loaded and all scripts in the footer of the page have asynchronously loaded – then and only then initialise all methods from the page or portlets or containers that are wrapped in the chain method that require Jquery for example… Without this if I  were to use the Jquery method in the portlet body but initialised the jquery script in the footer the page would send a JS error as the portlet jquery method would be unaware of the Jquery API – as it has not yet loaded.

How to setup inline methods -
in the template or portlet body that can access a library method after it async loads in the footer - 

This way you could write out FB.Base.chainPSA multiple times throughout your template to store all the required methods that need to be initiated after the page has loaded..

How to Initialise chainPSA
after all libs have loaded.

So first check that chainPSA exist then execute all methods; that’s all there is too it.

An alternative solution which I often use is to setting a global JS variable flag – this enables me to contain and compress the forum portlet scripts in a single file that reads the configuration and data attributes from the portlet after all the JS dependencies have loaded if my main script in the footer – Once loaded it will then search to see if the variable flag exist and then asynchronously load all the required portlet files and dependencies ie

Portlet contains inline JS or JS script
which will be injected into the head - 

<af:resource type=”javascript”>

</af:resource>

Footer Script
initiases the following after page load

 

Setting up Global reusable variables using JSTL

Sometimes there are values from WebCenter that you wish to use ie Space Name or User Name – the easiest way is to escape these values with JSTL into a javascript Object within the page template. I’ve put a quick example above you can strip it out if you don’t need any values but it makes it easier to pull in values to other JS libs calling the key value pair from the object like this for user display name -

Setting RequireJS to load my dependencies via base bootstrap script
(Read this - For more info on module loading and using requirejs)  

Now as you can use html in JSF templates and I don’t want my scripts in the head – which af:resource enables I write out the <script> tag. A word or warning and you may have spotted <jsp:text/> this prevents the script tags from being self closed and breaking. This will happen if you are editing the page templates direct at runtime from the browser. This is the same for any empty container ie <div></div> would become <div/> self closing; this is fine with xml but not fine with browser interpreting html mark-up in the DOM..

Also you may want to consider putting this into the login template to pre-load and cache the initial scripts before the portal page loads all of the ADF JS lib dependencies.

The final template

** I haven’t added a navigation structure to this template only the Content Composer facet.

Designing for mobile with Responsive Design.

When learning about responsive design the first thing to do is add the following meta viewport tag into the head defining the required content params for mobile ie -

Now unfortunately there is no ADF tag to add meta tags into the header and although you could add this html to the <body></body> its not really ideal.

What you should do is add this meta viewport into the Page Style not the Page Template.
This will allow you to add the following trinidad tag to generate the meta tag into the  <head></head> of the generated template as the facet metaContainer specifies this region to generate into.

The metaContainer facet should be held within the <af:document></af:document> tags

You could also add other meta tags ie keywords and add a dynamic value like this -

A word of warning you must make sure you add this to the page style before you create a page. Existing pages will ignore any updates to Page Styles that were used to create a page unlike Page Templates which allow you to tweak and update on the fly.

In the next post I’ll be writing up how to use requireJS properly with WebCenter to Asynchronously load in your libraries, templates and request additional libraries or templates when required by the page.

4 thoughts on “Enhancing the WebCenter Portal ADF Template – 3 easy steps for front-end developers.

  1. Hi, I loved your tutorial on skinning. Do you have any actual sites to view? Are you using Bootstrap or anything else to style the components or is it being used to make the site responsive? These are some of the challenges I have been having. Most of the Dev’s here want to do everything via ADF, which really limits what you can do visually.

    • Hi Chris;

      Any business components (ADF) should use adaptive design but any content can use responsive design. I would never recommend using responsive design with ADF it will be more of a challenge and time consuming than using Adaptive Design.

      Depending on clients requirements and skillset we have used Bootstrap and foundation for creating responsive templates and page styles.

      A great public portal example you should check out is baesystems.com although it is not using responsive design.

      Are you going to be at Collaborate at Vegas – if so drop by the Fishbowl booth I will be there and we can discuss or feel free to email Fishbowl and get in contact.

  2. Hi John,

    Is there any approach to use skin file which contain adf tags like af|panelGroupLayout etc.. as external css like how you used global.css. We r using external CSS to achieve RWD through mediaqueries.

    Thanks in advance.

Leave a Reply