Custom Objects in Mura

Although I only meant to cover how to use Mura's "addToHTMLHeadQueue" function to show you how to load javascript libraries, CSS or whatever else you may need on-the-fly, I ended up covering a lot of ground in the interest of providing something useful, a custom object that uses the aforementioned function and loads internal Mura content dynamically.

Since this post originated as a request in our support forum, we're going to create tabbed navigation for an in-page object/component loading the files into the HTML <head> only when the Display Object is called on a specific page. For content, we're going to use both static and dynamically generated content. We've adapted the tab code from Fabtabulous.

If you'd like to follow along or use Fabtabulous in your Mura site, here are the files:

Step 1: Let Mura know which javascript library you'd like to use

Mura uses Prototype/Scriptaculous jQuery by default, so this step is only really necessary if you'd like to use JQuery Prototype/Scriptaculous or if you'd like to just hard-code the libraries and CSS you need in the templates rather than loading them on-the-fly as we do in this example.

There are two variables that you can set in the local contentRenderer (/[siteid]/includes/contentRenderer.cfc):

  1. jslib: This variable tells Mura which js framework it should use. Set this to jquery.
  2. jsLibLoaded: This tells Mura if it needs to load the js framework into the html head. If you have hard coded jquery into the template set this to true.


<cfset this.jslib=""/>
<cfset this.jsLibLoaded=true>

Step 2: Place files into the appropriate directory

Best practice for adding custom Display Objects suggests you place the files in /[siteid]/includes/display_objects/custom/ so we'll create a new directory there called "fabtabulous", add a couple sub-directories for our javascript and CSS, and drop fabtabulous.js and tabs.css into the js and css sub-directories respectively.

If you take a look at the files included in the you'll see that there are also two other files included, index.cfm, htmlhead.cfm and Mura tag.txt. If not, you can create them and place them in the root of the fabtabulous directory.

index.cfm needs to include the following to initiate the Javascript library and tell Mura where to find the items to be loaded into your document <head>:

<cfset loadJSLib() />
<cfset addToHTMLHeadQueue("custom/fabtabulous/htmlhead.cfm")>

If this were a static component you would also place all necessary HTML for your object following these two lines (be sure to wrap your code/content in <cfoutput>). Since we want our content to be edited from within the Mura admin, we're going to use the "dspObject" function to dynamically place a Mura Component that contains the HTML (and other nested objects) instead.

#dspObject('component','COMPONENT ID',request.siteid)#

The other file we need is htmlhead.cfm. This file is the include that places the calls to your javascript and CSS into the <head> of your page dynamically. You can use actual code here or link to files as we do:

<script src="#$.siteConfig('assetPath')#/includes/display_objects/custom/fabtabulous/js/fabtabulous.js" type="text/javascript"></script>
<link rel="stylesheet" href="#$.siteConfig('assetPath')#/includes/display_objects/custom/fabtabulous/css/tabs.css" type="text/css" media="all">

Step 3: Create Your Mura "Component"

In the Mura Admin, go to "Components" and create a new Component. Give it a title and paste the following into the code view in the editor:

<div id="fabtabs">
<ul id="tabs">
    <li><a href="#tab1">Tab 1</a></li>
    <li><a href="#tab2">Tab 2</a></li>
    <li><a href="#tab3">Tab 3</a></li>
    <li><a href="#tab4">Tab 4</a></li>
<div class="panel" id="tab1">
<h3>This is tab 1</h3>
<div class="panel" id="tab2">[ Mura ]dspObject('feed','60F01591-DC00-15EF-A8D129D0BE512940',request.siteid)[ /Mura ]</div>
<div class="panel" id="tab3">[ Mura ]dspObject('feed','09DA88D4-F2BB-4055-938B52F2D89EFB64',request.siteid)[ /Mura ]</div>
<div class="panel" id="tab4">
<h3>[ Mura ]dspObject('component','60F5C04D-DFC2-6319-19B508376EAC5147',request.siteid)[ /Mura ]</h3>

You'll notice in the panels for tabs 2,3 and 4 I'm using the dspObject function to pass in other Mura objects. In tab2, I've added a "Remote Feed" for Yahoo Sports RSS and in tab3 I've added a "Local Index" with recent posts from a Blog in Mura. In Tab 4 I'm nesting another component inside this one to provide an easy way to edit the content of that tab, reducing the opportunity for the mark-up to break. Tab1 is simply text. You will, of course, need to create create objects before being able to use them. Once you have, you can grab the contentID (the long string of random numbers that is the second argument in my function, the first is the type of object you are calling, the third and last is the specific siteID we're calling it in) by editing the object and copying the feedID out of the URL.

Unfortunately, with fabtabulous, you'll need to manually create each of the actual tabs and it's asscoiated panel/content manually. In the near future, we'll show you how to do a similar thing, but using the powerful JQuery Cycle plug-in which creates navigation for you dynamically, among other cool tings.

Step 4: Placing your new custom object into a page

This last step is a simple one. Using the [mura ] tag and the dspInclude function, we'll place your object into a specific page using the following:

[ Mura ]dspInclude('display_objects/custom/fabtabulous/index.cfm')[ /Mura ]

IMPORTANT: To keep the [ Mura ] tags from rendering in this page, I've added spaces after the first bracket and before the last bracket in the tag in all references above. These spaces will need to be removed for the [ Mura ] tag to render.

Step 5: View the result

This screenshot shows the tab I created for my Local Index.


While I ended up getting a little carried away, the topics covered in this post can be used in many different ways and not only for custom objects. They can be used alone or in combination to provide some very powerful, but easy to maintain results. In addition, some of the concepts covered here will be useful when we release the forthcoming Plug-In Manager. We hope you find this as useful as we do.


Post a Comment

Required Field