SURF Part 2 – Pages and Navigation

February 19, 2009

During part 1, the process of creating a simple web page using the SURF framework was discussed detailing creating a basic template and various components.  Next I will look at adding additional pages and building some simple navigation utilising SURF’s “Page Association” features.

Setup

If you have not got the basic home page up and running from part 1, download the sample web application here and deploy to your local Tomcat (or any other web app server).  Once installed and started you should be able to hit the home page using http://localhost:8080/surf/page?p=index as long as you are using your local machine and have not renamed the web app folder.  You should then get the HTML template home page as follows:

Overview

The process of creating a new page is relatively simple.  It basically involves creating a new “page” item, and the relevant components that will make up that page as covered in part 1.  In this example I am also going to introduce a new template so that we have a different layout for our new page.  Here is an overview of the steps involved:

  • Create the new FTL template file (for the different layout)
  • Create the new “template instance” so that the new template can be referenced from a page component
  • Create the new page component

I will then move on the introduce some simple navigation using the Page Association item.

Templates and Pages

As noted, the process for creating the new template and page is identical to that covered in part 1 and therefore I will not describe the code in detail.  If you are in any doubt, refer to Part 1 accordingly.

I have decided to introduce a new template so that we can use a different page layout from that of the home page.  I have called this template “content.ftl” as it is a generic page for displaying any type of content.

Start by preparing a basic HTML page that will be used as a generic “content” page.  If you downloaded an HTML template for part 1, perhaps a second content page was also provided.  If not, you can take a copy of the current home page template.  It does not really matter at this stage what it looks like, as long as you can see it is different from your current home page layout.  You can always come back later and make CSS and other layout changes.  If you are using the template that is included as part of the download, you can use the following example content.ftl page:

<@region id="top" scope="global" />
<body>
<div id="content">
<@region id="header" scope="global" />
<div id="left">
<ul>
<li><a href="#">Example list item</a></li>
<li><a href="#">Example list item</a></li>
<li><a href="#">Example list item</a></li>
<li><a href="#">Example list item</a></li>
</ul>
</div>
<div id="right">
<h2>Aliquam metus turpis, luctus ac, sagittis eget</h2>
<div id="line"></div>
<p>Suspendisse egestas fringilla odio. Donec lacinia tristique ante. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam </p>
</div>
<@region id="footer" scope="global" />
</div>
</body>
</html>

You will note above that I have included the different components that we have available using the <region> tag.  This just allows us to re-use the global components we require e.g. header and footers.

  • Create the new content.ftl file in the /WEB-INF/classes/alfresco/templates directory.
  • Copy in your source HTML for your new layout, or the above example code into the new content.ftl file.
  • Add in your global components where needed e.g. headers and footers using the <region> tag.
  • Create a new template instance file in /WEB-INF/classes/alfresco/site-data/template-instances named content.xml.  You can copy the current “index.xml” file and remember to amend the <template-type> to point to the new content template.
  • Now create the new page.  Lets create a page called “products“.  Create the page xml item within /WEB-INF/classes/alfresco/pages named products.xml.  Remember to reference the new content template instance.

Once this is complete, you should be able to manually request the page to test it using http://localhost/surf/page?p=products. Here is my example products page using the “content.ftl” template:

You can now go ahead and componentise the new page as you wish.  Perhaps separate the main content from the left pane and create web scripts to return the HTML where required.

Is is important that the navigation pane is componentised, as this is what we will be working with.  The image below shows the navigation component:

Here are the steps involved to create the navigation component:

  • Create the new component in /WEB-INF/classes/alfresco/site-data/components.  I have named my example global.nav.xml as this will be a globally scoped/used component.
  • Create a new web script FTL and descriptor file within /WEB-INF/classes/alfresco/site-webscripts.  Remember to match the same URL references as defined within the component.
  • Chop out the HTML for the header navigation into the web script FTL file.
  • Include the component using the region tag into both the index and content template files:


<@region id="nav" scope="global" />

  • Test the pages so that the new nav component is being included correctly on both the index and the products pages.

We can now go ahead and create some dynamic navigation using Page Associations.

Page Association

From the Alfresco Wiki pageThe Page Association objects allows you to link two pages together. Most commonly, this link is of type child and is meant to depict a fixed structure like a navigation tree. However, other types are possible and there is no requirement to use Page Associations as a means to support only a single fixed tree.

Using associations, multiple trees are possible. The nature of the associations, when expanded beyond child, is very similar to that of classifiers, categories, or tags. In other words, Pages may be associated to other pages, but they may also be laterally associated to other elements. This allows for implementations of faceted navigation and tag clouds.

In this example, we will create a very simple navigation to link the Home page (index) to the new Products page.  To do this we will create a page association item.

  • Create a new Page Association item within /WEB-INF/classes/alfresco/site-data/page-associations named index-products.xml
  • Add the following code.  Note the source and destination id’s relate the pages together:

<?xml version='1.0' encoding='UTF-8'?>
<page-association>
<source-id>index</source-id>
<dest-id>products</dest-id>
<assoc-type>child</assoc-type>
<order-id>1</order-id>
</page-association>

Once the association file is in place, we now need to modify the global nav web script to process the relationships and display the menu.  You should already have in place the nav.get.desc.xml file and nav.get.html.ftl (or files of similar name and purpose) web script files which currently just return the example menu HTML code, nothing dynamic.

In order to process the menu items, we will need to include some logic making use of a JavaScript file as part of the web script.

  • Create a nav.get.js (or relative name if your nav web script is named differently) file within the web scripts directory – /WEB-INF/classes/alfresco/site-webscripts.


// renderer attribute
var renderer = instance.properties["renderer"];
if(renderer == null)
{
renderer = "horizontal";
}
model.renderer = renderer;


// set up rendering attributes
model.rootpage = sitedata.getRootPage();
model.linkbuilder = context.getLinkBuilder();

This code makes use of an example basic navigation component with horizontal and vertical renderers.  This is included as part of the surf starter war.

  • Edit the nav.get.html.ftl file and remove the static HTML content.  Add the following code:

<#if renderer == "horizontal">
<@horizontal page=rootpage showChildren=true/>
</#if>
<#macro horizontal page showChildren>
<ul id="menu">
<li>
<#assign href = linkbuilder.page(page.id, context.formatId)>
<#assign classId = ''>
<#if page.id == context.page.id>
<#assign classId = 'current'>
</#if>
<a href='${href}' id='${classId}'>${page.title}</a>
</li>
<#-- Children of Home Page -->
<#list sitedata.findChildPages(page.id) as parentPage>
<li>
<#assign href = linkbuilder.page(parentPage.id, context.formatId)>
<#assign classId = ''>
<#if parentPage.id == context.page.id>
<#assign classId = 'current'>
</#if>
<a href='${href}' id='${classId}'>${parentPage.title}</a>
</li>
</#list>
</ul>
</#macro>

The above code makes use of the findChildPages(sourceId) Surf API call which simply finds all child page objects for the given top level page id.  It also demonstrates usage of the linkBuilder facility which dynamically creates the URL.  You will also notice that a style is being applied if we are viewing the current page i.e. parentPage.id == context.page.

This example could easily be extended for second level navigation simply by passing in the parent item id:

<#-- Children of Home Page -->
<#list sitedata.findChildPages(page.id) as parentPage>
<#-- Sub Pages -->
<#list sitedata.findChildPages(parentPage.id) as childPage>

This is a simplified version of the navigation code used within the Green Energy site which is part of the Alfresco Surf Code Camp material.  Jeff Potts has kindly made this available for download, and I would recommend taking a look to learn more about Surf in general (including an example of second level navigation).

You should now have working navigation showing the Home page and the Products page:

Summary

Here we have just created a new template (so we can alter the style of the page), and created a new page using the new template.  We then created a simple page association so that the navigation item could build the links. You can probably start to see how useful Web Studio will be, allowing new pages and navigation to be created using a GUI rather than hand coding each new page.

Next I will look at using Alfresco WCM with Surf, along with some deployment options.

Download

The completed web application is available for download here – SURF Part 2 – Pages and Navigation.

See also – SURF Part 1 – Getting Started and SURF Part 3 – Alfresco WCM Content

{ 1 trackback }

SURF Part 1 - Getting Started
02.20.09 at 10:13 am

{ 4 comments }

sbarcena 02.20.09 at 3:00 pm

Hi,

I would build my site, as explained in your example, but using JSP templates, do you know how should I start?

Thank you.

admin 03.09.09 at 7:34 pm

Hi,
I have not tried it but you should be able to use JSP templates instead of Freemarker, so just drop them into \WEB-INF\classes\alfresco\templates. Reference the components using the tag instead of the FTL @region directive. The JSP custom tag library mirrors the FTL custom directives.

Ben.

maya.zh 06.21.09 at 9:24 pm

Hi,
thank you for the great tutorial.I have followed it step-by-step but I have reach a point from where I cannot continue. When I create the page association, the navigation section changes, but all that is written is “Home”, without “Products”. And when i press ‘Home” the default page of alfresco.studio appears telling me that “This is an unconfigured page.It does not have a presentation template. Associate a Presentation Template”.And even from the Home page of my site, hitting “Home” tab, sends me to the same default page.
I have been looking through the web-scripts and the site-data files, but since I am not very experienced with HTML and webSite creation, I just cannot figure it out.

Thank you.

Amethyst 10.20.10 at 3:21 pm

I’m trying to follow this guide but struggling… Will keep trying though. Thanks, it is proving somewhat needed and useful currently.

Comments on this entry are closed.