Converting a Third-Party Theme to a Mura Theme

Mura allows you to change a site's look and feel through the implementation of Themes. You can change a site's theme in the Site Settings "Basic" Tab via the Theme drop-down. While Mura ships with just a single theme, the Merced theme, it's not hard to convert any html/css template into a Mura theme.

For the purposes of this walkthrough we'll be converting the "Deliciously Blue" open source template found at http://www.oswd.org/design/preview/id/2634

Watch a walk-through of this conversion via Adobe Connect

Directory Structure Overview

The SiteID Directory

The siteID directory is the folder just inside your Mura install that has the same name as the siteID you entered when the site was first created. Under the siteID folder:

  • The "assets" directory contains all the files uploaded via FCKeditor.
  • The "cache" directory caches files when caching is turned on (HIGHLY recommended once the site goes live.)
  • The "css" directory contains any root level css files that are shared between themes (e.g. default.css). Best practice suggests that you do NOT modify the default.css file, but rather overwrite and extend it in your theme site.css file.
  • The "images" directory contains any root level image files that are shared between themes.
  • The "js" directory" contains any root level javascript files that are shared between themes.

Themes Directory

The "themes" folder lives inside the "includes" directory. This is where any new themes are installed.

Merced Directory

Now let's take a look at the "merced" theme directory.

The "_static" directory and the "_components" directory contain static html files that ship with the Merced theme so you can get a visual idea of what the Merced theme will look like with content.

The "css" directory contains not just the site.css file for controlling the theme specific styles for layout, navigation and the different Mura Content Objects, it also includes:

  • The editor.css which allows you to pass styles in from the typography css and default.css to the wysiwyg content editor so the content being edited actually looks more like the front end content.
  • The "fckstyles.xml" which adds custom styles in the wysiwyg editor styles drop-down.
  • The ie.css which contains special style rules for the Internet Explorer browser.

New Theme Setup

  1. Create a new folder in the themes directory and name it "mytheme" (or whatever)
  2. Extract the Deliciously_Blue zip into this new folder and rename the resulting "Deliciously_Blue" folder to "_static."
  3. Create 3 new folders named "css," "images" and "templates" at the same level as the "_static" folder.
  4. Copy the editor.css, typography.css, ie.css, and fckstyles.xml files files from the merced/css directory and paste them into your new mytheme/css directory.
  5. Copy the style.css from the mytheme/_static folder and paste it into your new mytheme/css directory. Rename it "site.css"
  6. Copy the images from the mytheme/_static folder and paste them into your new mytheme/images directory
  7. copy the index.html from the mytheme/_static folder and paste it into your new mytheme/templates directory. Rename it two_column_SR.cfm The ".cfm" file extension will let the web server know that this is a coldfusion file that needs to be processed by the Coldfusion application server.

    Note: You could actually name the template anything you wish, but for the purposes of this walkthrough we are giving it a descriptive file name to reflect the fact that the design has two columns with a sidebar on the right.
  8. Copy the blank.cfm, default.cfm, and xml.cfm files from the merced/templates folder and paste them into your new mytheme/templates directory. Also copy the ie_conditional_includes.cfm file from the merced/templates/inc directory and paste into the mytheme/templates directory.

Basic File Edits

default.cfm

Open the mytheme/templates/default.cfm and change:

<cfinclude template="two_column_SL.cfm" />

to the name of the new mytheme template file:

<cfinclude template="two_column_SR.cfm" />
site.css

Open the mytheme/css/site.css, scroll down to the menu styles and change the background url() references to reflect the new location of the menu background images (e.g. background: url("images/tableft10.gif") etc.)

Integrating the Mura Variables

Once the basic setup for the new theme has been completed, it's time to integrate the variables used to output content from Mura. This includes using variables for the paths to the various theme files. These variables generate the paths dynamically so Mura can find them no matter where it is installed, whether in the webroot or a sub directory. Doing this keeps themes portable so they can be deployed into any Mura installation.

Note: For a list of Mura template variables with descriptions and usage examples go to http://docs.getmura.com/index.cfm/developer-guides/front-end-development/template-development/template-variables/

Editing the New Theme Template

Using your favorite editor, open the new mytheme/templates/two_column_SR.cfm file and the merced/templates/two_column_SR.cfm file and arrange them side by side (we will be using the merced two_column_SR.cfm file for reference.)

Add an opening <cfoutput> tag to the very top of your "mytheme" two_column_SR.cfm file and a closing </cfoutput> tag to the very bottom of the file. This insures that the mura variables being added will be parsed by the Coldfusion Server.

Note: If you view your page and you see a lot of hash marks (##) instead of content, it is likely that the variables are not surrounded by the necessary cfoutput tags.

HTML Head

The first section to look at is the HTML head. Notice that the Merced theme stores this in a separate html_head.cfm include. (merced/templates/inc/html_head.cfm) Go ahead and open the merced/templates/inc/html_head.cfm for reference.

Note: If you plan to use the same layout throughout your site there is no need create a separate include for the html head. If you do plan to develop more than one layout, breaking out the code for the html head as well as the header and footer into separate include files will allow you to share the same code between the different layouts.

Meta Data

Add the meta data description to the head using:

<meta name="description" content="#HTMLEditFormat($.getMetaDesc())#" />

#$.getMetaDesc()# outputs Meta Description found on the "Metadata" tab when editing a page or portal.

Add the meta data keywords to the head using:

<meta name="keywords" content="#HTMLEditFormat($.getMetaKeywords())#" />

#$.getMetaKeywords()# outputs Meta Keywords found on the "Metadata" tab when editing a page or portal.

Notes: Unless you specify otherwise on a specific page, Meta data content cascades down to the content nodes below. This means you don't have to set the meta data content on every page unless you specifically want to.

If you wish to add Author Credits meta data use:

<cfif $.content('credits') neq ""><meta name="author" content="#HTMLEditFormat($.content('credits'))#" /></cfif>

#$.content('credits')# outputs the contents of the "Credits" field found on the "Metadata" tab when editing a content node.

The Generator Meta tag is used to declare the name and version number of the publishing tool used to create the page.

<meta name="generator" content="Mura CMS #$.globalConfig('version')#" />

#$.globalConfig('version')# outputs the version of Mura used to publish the page or portal.

Browser Title

Replace the Title tags with:

<title>#HTMLEditFormat($.content('HTMLTitle'))# - #HTMLEditFormat($.siteConfig('site'))#</title>

#$.content('HTMLTitle')# #$.siteConfig('site')# outputs the title specified in the HTML/Browser Title (when editing a node) and the Site Name (found in Site Settings).

Favicon Links

You can link to favicons using:

<link rel="icon" href="#$.siteConfig('assetPath')#/images/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="#$.siteConfig('assetPath')#/images/favicon.ico" type="image/x-icon" />

#$.siteConfig('assetPath')#/ outputs a root relative path to the root of a site, including the context, i.e. if Mura is installed in a subdirectory of your webroot.

To link to a theme-specific favicon::

<link rel="icon" href="#$.siteConfig('themeAssetPath')#/images/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="#$.siteConfig('themeAssetPath')#/images/favicon.ico" type="image/x-icon" />

#themePath#/ outputs a root relative path to the root of a theme, including the context.

Note: If you don't specify the location of a favicon, browsers will look in the root by default.

Linking to Style Sheets

Add a link to the Mura default.css:
<link rel="stylesheet" href="#$.siteConfig('assetPath')#/css/default.css" type="text/css" media="all" />

The default.css includes a general css reset, as well as basic styling applied to the built-in Mura display objects. You want to add it in before any theme css files, especially the site.css so that the theme css files can then be used to overwrite or extend the default.css

Create links to the other css files:
<link rel="stylesheet" href="#$.siteConfig('themeAssetPath')#/css/typography.css" type="text/css" media="all" />
<link rel="stylesheet" href="#$.siteConfig('themeAssetPath')#/css/site.css" type="text/css" media="all" />
<link rel="stylesheet" href="#$.siteConfig('themeAssetPath')#/css/ie.css" type="text/css" media="all" />

If your theme does not include a print.css you can link to the print.css file built into Mura:

<link rel="stylesheet" href="#$.siteConfig('assetPath')#/css/print.css" type="text/css" media="print" />

Include the Internet Explorer conditional styles:

<cfinclude template="ie_conditional_includes.cfm" />

Link to Alternate Content (RSS)

This code dynamically loops through all Local Indexes outputting links to any "public" RSS feeds that might have been created. When these RSS links are available, most browsers will show a small, clickable RSS icon in the location bar.

<cfset rs=$.getBean('feedManager').getFeeds($.event('siteID'),'Local',true,true) />
<cfloop query="rs">
<link rel="alternate" type="application/rss+xml" title="#HTMLEditFormat($.siteConfig('site'))# - #HTMLEditFormat(rs.name)#" href="#XMLFormat('http://#listFirst(cgi.http_host,":")##$.globalConfig('context')#/tasks/feed/?feedID=#rs.feedID#')#" />
</cfloop>

Body Tag & Container Div

The Body Tag

If you look at the <body> tag in the merced/templates/two_column_SR.cfm file, you will notice that there is a Mura variable on the body tag itself. This variable provides an id for the body, based on the top level node that you're on, allowing you to target any top level section in the css with this css hook.

<body id="#$.getTopID()#" class="twoColSR">

Add this id & variable to the new mytheme/templates/two_column_SR.cfm <body> tag:

<body id="#$.getTopID()#">

Note: Beginning with Mura 5.2 you can also use the "mura" scope to reference this variable: #mura.gettopid()#.

<body id="#mura.gettopid()#">

Container Div

Just like the body tag, there is also a Mura variable "class" on the "container" div in the merced/templates/two_column_SR.cfm file.

<div id="container" class="#$.createCSSid($.content('menuTitle'))#">

Add this class & variable to the new mytheme/templates/two_column_SR.cfm "container" div tag (same as above). This class could be added to the <body> tag instead, if that is preferred.

Note: The "createCSSid()" function can be used on any variable to create a CSS-friendly string. Mura generated css hooks make it possible to control virtual all of your site display via css.

Template Header

Site Search Form

Open the themes/merced/templates/inc/header.cfm file. Copy the search form code (starting with <form and ending with </form>) then move back to the mytheme two_column_SR.cfm template  and replace placeholder site search form code with the code you just copied:

<form action="./" id="searchForm">
<fieldset>
<input type="text" name="Keywords" id="txtKeywords" class="text" value="Search" onfocus="this.value=(this.value=='Search') ? '' : this.value;" onblur="this.value=(this.value=='') ? 'Search' : this.value;" />
<input type="hidden" name="display" value="search" />
<input type="hidden" name="newSearch" value="true" />
<input type="hidden" name="noCache" value="1" />
<input type="submit" class="submit" value="Go" />
</fieldset>
</form>

Change class="submit" to class="button"

H1 Site Title

Replace the H1 Site Title (<h1>Deliciously Blue</h1>) with:

<h1><a href="#$.createHREF(filename='')#">#HTMLEditFormat($.siteConfig('site'))#</a></h1>

#$.globalConfig('context')# outputs the sub-directory if Mura is installed in one in the web root.

#$.event('siteID')# outputs the Site ID found in "Site Settings".

#$.siteConfig('site')# outputs the Site Name.

Primary Navigation

Return to the themes/merced/templates/inc/header.cfm file and copy the code for the Primary Navigation including the cf_CacheOMatic tags (from <cf_CacheOMatic through </cf_cacheomatic>) and paste the code into the new template completely replacing the placeholder primary nav (starting with <ul> and ending with </ul>) between the "tabs10" div tags. Then move the <div id="tabs10> div tags and place them so that they wrap/bookend the #renderer.dspPrimary... variable.

<cf_CacheOMatic key="dspPrimaryNav#request.contentBean.getcontentID()#">
<div id="tabs10>#$.dspPrimaryNav(viewDepth="1",id="navPrimary",displayHome="Always",closePortals="true",showCurrentChildrenOnly=false)#</div></cf_cacheomatic>

Note: The cf_CacheOMatic Tag can be used to to cache less frequently updated items that might be very server intensive, especially on a per page basis. However, the "Caching" option must be turned on in "Site Settings" for cf_CacheOMatic to actually be implemented. The key prefix (e.g. "dspPrimaryNav") is used to give context to the unique variable, #$.content('contentID')#, created for the cached item. You can leave the setting empty (="") and not put an id if having an id would interfere with custom styling for the Primary Nav.

Change viewDepth="1" to viewDepth="0" if you don't want any dropdowns display. (viewDepth toggles drop down navigation on and off. It is not recommended to set this greater than 1 or 2 due to the overhead required to parse a node's "current" location and permissions).

Leave displayHome="Always" as is. The displayHome configuration sets the nav to include a link to home page in the primary nav at all times (always), not include the link (never), or include the link only when not on the home page itself (conditional).

Also leave closePortals="true" as is for now. Since, in general, portals are used for content repositories, you could end up with a very very VERY long list of items such as news articles or press releases, etc. This would make your dropdown nav quite awkward and unwieldy. You do have the option of toggling portals to show or not show children in the Primary Navigation. These options are: true, false, or a comma delimited list of content id's (found on the "advanced" tab of any content node) to specify which portals are to be "closed" or "open."

Breadcrumb Navigation

To add Breadcrumb Navigation to the new template, copy the complete render.dspCrumbListLinks ... variable from the merced template and paste it into the new template just under the "content" div.

<div id="content">
#$.dspCrumbListLinks("crumbList","&nbsp;&raquo;&nbsp;")#

This outputs the links in an unordered list (<ul>). The first argument sets the name of the ID for the list and the second dictates the separator to use between each list item.

Main Content

In the new template, delete all the placeholder content under the crumb list (within the "content" div) starting with the <h2> tag through the last paragraph before the closing "content" </div> tag. We will be replacing all these lines of code with a single Mura variable.

In the Merced template, copy the long renderer.dspBody ... variable and paste it into the new mytheme template just under the crumbList variable

#$.dspBody(body=$.content('body'),pageTitle=$.content('title'),crumbList=0,showMetaImage=1)#

The $.dspBody() function contains several named arguments:

  • body - tells Mura where to pull the content from and should not be changed
  • pageTitle - Outputs the page title
  • crumblist - A deprecated argument which outputs the crumblist below the title is set to "1"
  • metaimage - Toggles on and off using 1 & 0.  MetaImage outputs the medium sized image of an image associated with your content. When clicked, the medium-sized image will show the large/full version of that image in the light box.

Note: When you associate an image with a piece of content,Mura will create 3 versions of the image: a thumbnail, a medium sized and the full or large size. (The settings for these are set in Site Settings) Thumbnails are shown in any list view. When you go to the detail page for that content, the medium-sized image is displayed. And when you click on the medium sized image, the large/full sized image is shown in the lightbox. If MetaImage display doesn't make sense for your site, then set this to 0.

Display Regions

Copy the #$.dspObjects(2)# variable from the Merced template and paste it into the mytheme template directly beneath therenderer.dspBody ... variable.

"Display Regions" are used to determine where Mura Content Objects are displayed. (Settings for these can be configured in the Site Settings on the "Display Regions" tab.) You can have up to 8 Display Regions, but whether you use 1, 2 or all 8 display regions, one of them must be designated the "Primary Display Region" so that Mura can know where to insert dynamic dystem content such as Login Forms and Search Results. By default, Mura sets up region number 2 ("$.dspObjects(2)") to be the Primary Display Region.

Sidebar Content

Copy the #renderer.dspObjects(3)# variable from the Merced themplate and paste it within the "sidebar" div of the mytheme template, replacing all the placeholder content.

<div id="sidebar"> #$.dspObjects(3)# </div>

Footer

Open the Merced templates/inc/footer.cfm file and copy the paragraph element containing the variables for copyright (year) and site name.

<p>&copy;#year(now())# #HTMLEditFormat($.siteConfig('site'))#</p>

Paste this within the mytheme template "footer" div, replacing the middle "copyright" section between the pipe center pipe characters.

Tweaking the Primary Nav CSS

The original "Deliciously Blue" used a <span> tag around the Primary Navigation link text as a hook. While Mura generates the Primary Navigation as an unordered list, it does not use the <span> as in the original template. This can easily be addressed in the new mytheme site.css. Under "menu styles" apply the rules from the "span" element to the anchor tag and apply the rules originally on the anchor tag to the list item itself.