Example template with tree menu

From OpenCms Wiki
Jump to: navigation, search

Here is an example of a page template, which has a navigational menu generated as a tree from folder structure.

Contents

Location of template

A new module for a site

I create a new module for every web site. That allows me to treat the site as a unit, I can easily export the module for backup, or transfer the site to another instance of OpenCms.

For example, let's say I am creating the site www.example.com.

First I create a new folder /sites/example, set its "Title" (it is displayed then in workplace as the name of the site), edit opencms-system.xml to add mapping for it, restart tomcat.

Then I create the module. I go to Administration - Module management, click New module, fill Package name as com.example.site, check all checkboxes for creating folders.

Then I go to Module Resources and I add a new resource /sites/example so that the site pages are part of the module.

Template and resources location

The template then should be located in the /system/modules/com.example.site/templates/ folder. It will appear automatically in the list of page templates in file properties.

Other JSP files should be located in the /system/modules/com.example.site/elements/ folder. If you put them into the templates folder, they will appear in the list of templates and may confuse users.

The images, CSS and JavaScript files it uses should be located in the /system/modules/com.example.site/resources/ folder. It is good to set the export property on that folder to true, so they are exported from database to a static file to improve speed.

Page title and index.html files

I was solving the problem of index.html and navigation in OpenCMS for years and here is my solution.

The problem is that when you have a folder set for navigation, it can have a Title, NavPos and NavText properties. But it should also contain a file index.html which can also have a Title, NavPos and NavText properties. These can be inconsistent with the setting of the folder.

My solution is that I set only Title and NavPos on the folder, and I do not set any of the properties on the index.html.

In the page template, I use

<title> <cms:property name="Title" file="search" escapeHtml="true" /></title>

The file="search" causes that the title of the index.html file is inherited from the parent folder, so it cannot be incosistent.

The code for generating menu below uses Title for text in menu, but it can be overriden with NavText if the property is set. This way, the users creating a new file or folder need only to set the Title and check the Add to navigation checkbox.

Template structure

A basic page template then may look like this:

<%@page buffer="none" session="false"  %>
<%@ taglib prefix="cms" uri="http://www.opencms.org/taglib/cms" %>
<cms:template element="head">
<html>
<head> 
    <title><cms:property name="Title" file="search" escapeHtml="true"/></title>
    <cms:editable/>
</head>
<body>    
 <h1><cms:property name="Title" file="search" escapeHtml="true"/></h1>
</cms:template>
<cms:template element="body">
        <cms:include element="body" editable="true"/>
</cms:template>
<cms:template element="foot">
</body>
</html>
</cms:template>

This page has no menu, but it does have a header, a footer, a body with a h1 heading matching the page title, and an area for body content. The cms:editable tag allows the Direct edit button to appear on the page.

Tree menu

Add the line

 <cms:include file="../elements/treemenu.jsp" />

to the place where you want your menu. The menu will be just a tree of nested unsorted lists, you can style it however you want, use fo example CSS Library Horizontal CSS Menus.

Then create the file treemenu.jsp in the /system/modules/com.example.site/elements/ directory. Its content should be:

<%@ page import="org.opencms.jsp.*" %>
<%@ page import="org.opencms.file.*" %>
<%@ page import="java.util.*" %>
<%!
//recursive function
    @SuppressWarnings({"unchecked"})
    static void showFolder(CmsJspActionElement cms, JspWriter out, CmsJspNavBuilder nav,
                           List<CmsJspNavElement> filesInFolder, String indent)
            throws java.io.IOException {
 
        for (CmsJspNavElement sub : filesInFolder) {
            String name = sub.getResourceName();
            if (name.endsWith("index.html") || name.endsWith("index.jsp")) continue;
            String navText = sub.getProperty(CmsPropertyDefinition.PROPERTY_NAVTEXT);
            if (navText == null) navText = sub.getTitle();
            out.print(indent + "<li><a href=\"" + cms.link(name) + "\">" + navText + "</a>");
            if (sub.isFolderLink()) {
                List<CmsJspNavElement> filesInSub = nav.getNavigationForFolder(sub.getResourceName());
                if (filesInSub.size() > 0) {
                    out.println("\n"+indent + " <ul>");
                    showFolder(cms, out, nav, filesInSub, indent + "  ");
                    out.print(indent + " </ul>\n"+indent);
                }
            }
            out.println("</li>");
        }
    }
%><%
    CmsJspActionElement cms = new CmsJspActionElement(pageContext, request, response);
    CmsJspNavBuilder nav = cms.getNavigation();
 
%>
<ul id="cssmenu1">
<% showFolder(cms,out,nav,nav.getNavigationForFolder("/"),"  "); %>
</ul>

The code will generate nested lists like:

<ul id="cssmenu1">
  <li><a href="/cms/about/">About us</a>
   <ul>
    <li><a href="/cms/about/mission.html">Mission</a></li>
    <li><a href="/cms/about/news/">News</a></li>
    <li><a href="/cms/about/events/">Events</a></li>
     <ul>
      <li><a href="/cms/about/events/other/">Other</a></li>
      <li><a href="/cms/about/events/community/">Community</a></li>
     </ul>
    </li>
   </ul> 
  </li>
  <li><a href="/cms/projects/">Projects</a></li>
  <li><a href="/cms/intranet/">Intranet</a></li> 
</ul>

The code gets the NavText property, if is is empty, it uses Title.

Breadcrumb

Breadcrumb or breadcrumb trail is a navigation aid used in user interfaces. It gives users a way to keep track of their locations within programs or documents. The term comes from the trail of breadcrumbs left by Hansel and Gretel in the popular fairytale.

Put the line

 <cms:include file="../elements/breadcrumb.jsp" />

to the place in the page template where you want your breadcrumb. Then create the file breadcrumb.jsp in the /system/modules/com/example.site/elements directory. Its content should be something like:

<%@ page import="org.opencms.jsp.*" %>
<%@ page import="org.opencms.file.*" %>
<%@ page import="java.util.*" %>
<%
    CmsJspActionElement cms = new CmsJspActionElement(pageContext, request, response);
    CmsJspNavBuilder nav = cms.getNavigation();
    List<CmsJspNavElement> breads = nav.getNavigationBreadCrumb();
    boolean first=true;
    for(CmsJspNavElement ne : breads) {
       String navText = ne.getProperty(CmsPropertyDefinition.PROPERTY_NAVTEXT);
       if (navText == null) navText = ne.getTitle();
       if(first) { first= false; } else { out.print("&raquo;"); }
       %> <a href="<%=cms.link(ne.getResourceName())%>"><%=navText%></a>
<%
    }  
%>

It will generate breadcrumb trail like Home » First level » Second level. Just define the Title or NavText for all folders including the main folder of the site.

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox