Dissecting a Real World MeshCMS Theme

Themes are one of the most important parts of any CMS. They let users define how pages must be shown to visitors, so I want to show you how the theme of my website is written, with the hope that this can give you some hints on how to add value to your pages with MeshCMS.

First of all, a doctype is declared:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

I import user information since I want to display a different footer for logged users:

<jsp:useBean id="userInfo" scope="session" class="org.meshcms.core.UserInfo" />

The tag library is imported as usual:

<%@ taglib uri="meshcms-taglib" prefix="cms" %>

Setting a default locale is always a good idea, even if you're going to use the multilanguage feature as in this case:

<cms:setlocale defaultValue="en" />

Let the HEAD begin:

<html xmlns="http://www.w3.org/1999/xhtml">

Additional CSS files are included using the common LINK tag:

    <link rel="stylesheet" type="text/css" href="<cms:themepath />/layout.css" media="screen,projection,tv" />
    <link rel="stylesheet" type="text/css" href="<cms:themepath />/print.css" media="print" />

I build a custom title adding breadcrumbs:

    <title><cms:pagetitle /><cms:breadcrumbs current="false" separator=" &raquo; " pre=" [" post="]" /></title>

Load some META tags using values from configuration:

    <meta name="description" content="<cms:info id="description" />" />
    <meta name="keywords" content="<cms:info id="keywords" />" />
    <meta name="author" content="<cms:info id="author" /> (<cms:info id="authorurl" />)" />

The default charset can be specified this way:

    <meta http-equiv="Content-Type" content="text/html; charset=<cms:info id="charset" />" />

Load the theme CSS:

    <cms:defaultcss />

I can't live without jQuery!

    <script type='text/javascript' src="<cms:adminpath />/scripts/jquery/jquery.pack.js"></script>

Load the contents of the HEAD from the page, but drop style definitions (I have some old pages that include their own styles):

    <cms:pagehead dropStyles="true" />

Entering the BODY (don't forget the <cms:editor> tag!):


    <script type="text/javascript" src="<cms:themepath />/layout.js"></script>

The page title again...

      <h1 id="title">
        <cms:pagetitle />

... and the site name...

      <h2 id="siteDescription">
        <cms:info id="name" />

This is a typical code to insert a module. The external <cms:ifmodule> drops the whole enclosed HTML if the module is not used. The <h3> tag will not be created if the module title is empty.

      <cms:ifmodule location="top">
        <div class="content">
          <cms:moduletitle location="top" pre="<h3>" post="</h3>" />
          <cms:module location="top" alt="" />

The main page content:

      <div class="content">
        <cms:pagebody />

Another couple of modules:

      <cms:ifmodule location="bottom">
        <div class="content">
          <cms:moduletitle location="bottom" pre="<h3>" post="</h3>" />
          <cms:module location="bottom" alt="" />

      <cms:ifmodule location="bottom2">
        <div class="content">
          <cms:moduletitle location="bottom2" pre="<h3>" post="</h3>" />
          <cms:module location="bottom2" alt="" />

Now I'm going to insert a fixed module for comments. I want this module to appear in most pages, but not all. Inserting the module in every single page is painful, so I enclosed the module in some other tags to allow me to discriminate better.

First of all, I exclude pages that are not in the site map (I have some, for example my CV):


Then, I exclude pages that use the mail form, since I don't want to have comments and the contact form in the same page:


Finally, I exclude pages where the bottom2 module is used. This allows me to exclude comments from some pages. If I don't need to really use that module, but I still want to exclude comments, I can just define an empty module, like the Include one without argument.

          <cms:ifnotmodule location="bottom2">

Now the module begins. I want to include a title, but it must be different depending on the page language. Here the <cms:iflang> tag comes handy:

            <div class="content">
              <cms:iflang id="en">
              <cms:iflang id="it">

This is a fixed module definition:

              <cms:module location="bottom2alt" name="comments:(none)" date="full"
              parameters="math=false,captcha=true,notify=luciano@virgilio.it" />

Some closing tags:


This is the good old mail form tag. You can use the Mail Form module instead, but I preferred to insert this one too:

        <div class="content">
          <cms:iflang id="en"><h3>Mail Form</h3></cms:iflang>
          <cms:iflang id="it"><h3>Modulo per messaggi</h3></cms:iflang>
          <cms:mailform />

A language menu is compulsory being a bilingual website:

      <div id="languages">
        <cms:iflang id="en"><h3>Languages</h3></cms:iflang>
        <cms:iflang id="it"><h3>Lingue</h3></cms:iflang>
        <cms:langmenu pre="<ul><li>" separator="</li><li>" post="</li></ul>" flags="true" />

My theme has two menus. The first one lists the top level items:

      <div id="firstLevelMenu">
        <cms:iflang id="en"><h3>Top Level Menu</h3></cms:iflang>
        <cms:iflang id="it"><h3>Menu di primo livello</h3></cms:iflang>
        <cms:listmenu items="firstlevel" currentStyle="current"
        currentPathStyle="current" />

I'd like to find breadcrumbs in all sites I visit, so here they are:

      <div id="breadcrumbs">
        <cms:iflang id="en">
          <cms:breadcrumbs mode="links" pre="Path: " separator=" &raquo; " />
        <cms:iflang id="it">
          <cms:breadcrumbs mode="links" pre="Percorso: " separator=" &raquo; " />

The second menu will change according to the visited page; I use page hiding in the blog, since there's no reason to list all blog pages in the menu:

      <div id="sectionMenu">
        <cms:iflang id="en"><h3>Section Menu</h3></cms:iflang>
        <cms:iflang id="it"><h3>Menu di sezione</h3></cms:iflang>
        <cms:listmenu allowHiding="true" currentStyle="current" />

An additional module that will be shown on the left in the page layout:

      <cms:ifmodule location="left">
        <div class="secondaryContent">
          <cms:moduletitle location="left" pre="<h3>" post="</h3>" />
          <cms:module location="left" alt="" />

A fixed module to display some news in all pages:

      <div class="secondaryContent">
        <cms:iflang id="en">
          <cms:module location="news" name="en/news" date="normal" />
        <cms:iflang id="it">
          <cms:module location="news" name="it/news" date="normal" />

A button for donations to MeshCMS; rarely used, I must admit :(

      <div class="secondaryContent">
        <cms:iflang id="en"><h3>Donate to MeshCMS</h3></cms:iflang>
        <cms:iflang id="it"><h3>Donazioni per MeshCMS</h3></cms:iflang>
        <p align="center">
          <a href="http://sourceforge.net/donate/index.php?group_id=126684"><img
          src="http://images.sourceforge.net/images/project-support.jpg" width="88"
          height="32" border="0" alt="Support This Project" /></a>

MeshCMS does not include a function to search the site. To overcome this, I opened an account on FreeFind and started using it on my site. This is not strictly needed, since it is quite easy to add a form to search the site using Google. This form is site-independent, since the domain name is gathered from the configuration. Here's the preliminary code:

        <div id="search">
          <cms:iflang id="en"><h3>Search This Site</h3></cms:iflang>
          <cms:iflang id="it"><h3>Cerca in questo sito</h3></cms:iflang>

Now the Google search form:

          <form id="searchform" action="http://www.google.com/search" method="get">
              <label for="google_search"><cms:iflang id="en">With</cms:iflang><cms:iflang id="it">Con</cms:iflang>
              <a href="http://www.google.com/">Google</a>:</label><br />
              <input type="hidden" name="as_sitesearch" value="<cms:info id="host" />" />
              <input type="text" id="google_search" class="search" name="as_q" size="14" />
              <input type="submit" class="button" value="<cms:iflang id="en">Go</cms:iflang><cms:iflang id="it">Vai</cms:iflang>" />

For completeness, this is the FreeFind search form:

          <form action="http://search.freefind.com/find.html" method="get">
              <label for="freefind_search"><cms:iflang id="en">With</cms:iflang><cms:iflang id="it">Con</cms:iflang>
              <a href="http://www.freefind.com/">FreeFind</a>:</label><br />
              <input type="hidden" name="id" value="98736023" />
              <input type="hidden" name="pageid" value="r" />
              <input type="hidden" name="mode" value="all" />
              <input type="hidden" name="n" value="0" />
              <input type="text" id="freefind_search" name="query" size="14" />
              <input type="submit" value="<cms:iflang id="en">Go</cms:iflang><cms:iflang id="it">Vai</cms:iflang>" />

Closing the search div:


I chose to hide the CMS menu and show it to logged users only:

        <div id="cmsMenu">
          <cms:iflang id="en"><h3>CMS Menu</h3></cms:iflang>
          <cms:iflang id="it"><h3>Menu del CMS</h3></cms:iflang>
          <ul class="menu">
            <li><cms:adminmenu separator="</li><li>" /></li>

Two modules for the right column:

      <cms:ifmodule location="right">
        <div class="extraContent">
          <cms:moduletitle location="right" pre="<h3>" post="</h3>" />
          <cms:module location="right" alt="" />

      <cms:ifmodule location="right2">
        <div class="extraContent">
          <cms:moduletitle location="right2" pre="<h3>" post="</h3>" />
          <cms:module location="right2" alt="" />

In the footer I used a small piece of code to display the heap usage, but only for administrators:

      <div id="footer">
          if (userInfo != null && userInfo.canDo(org.meshcms.core.UserInfo.CAN_DO_ADMINTASKS)) {
            Runtime runtime = Runtime.getRuntime();
        Used Memory: <%= (runtime.totalMemory() - runtime.freeMemory()) *
              100 / runtime.maxMemory() %>% |

Then, for all users, the last modification time of the page...

        <cms:iflang id="en">
          <cms:lastmodified pre="Last modified: " post=" |" />
        <cms:iflang id="it">
          <cms:lastmodified pre="Ultima modifica: " post=" |" />

... and the copyright notice

        &copy; <a href="<cms:info id="authorurl" />"><cms:info id="author" /></a> |
        Powered by <a href="http://cromoteca.com/en/meshcms/"><cms:info id="meshcms" /></a>

Time to close everything:


Of course you will want to apply some CSS to make things look better.


Nov 11, 2011 2:37 PM

where can i found pre packaged themes ???

Luciano Vernaschi

Nov 14, 2011 10:48 AM

There are some themes in the distribution file, unfortunately nothing else. Anyway, converting a free theme from HTML is not that hard.

Comments are closed.