Blog

Mura Plugins Boot Camp: Day 3 - Display Objects

May 19, 2015 by Grant Shepert

The easiest way for plugins to display content in a Mura CMS site is by using display objects, widgets you can place on a page, even multiple times. What's even better is that you can configure each instance through what we call configurators.

If you use Mura CMS, you've probably already encounterd configurators. Whenever you add a content index to a page, for instance, a box will pop up letting you choose which fields you want displayed, the image size, and so on. This fine-grain configuration of what would otherwise be a generic list gives you great control over how the content will be displayed. Let's look at how we can leverage that same control over a plugin display object.

In our previous example, we had a display object that would list some basic information about an event:

<cfoutput>
<cfif $.content().getValue('allowRegistration') eq true>
<ul class="er-eventinfo">
<li>
<b>Attendee Limit: </b> #$.content().getValue('attendeeLimit')#
</li>
<li>
<b>Location: </b> #$.content().getValue('location')#
</li>
</ul>
</cfif>
</cfoutput>

What if we wanted to add some custom information to this display object every time we added it to a page? Well, it's actually pretty easy to do!

The Plugin Configuration

First, let's modify our plugin config.xml.cfm so that our display object knows there is a configurator attached to it.

<plugin>
...
<displayobjects>
<displayobject
name="Event Info"
displayobjectfile="display_objects/display_eventinfo.cfm"
 configuratorJS="configurator/configurator.js"
configuratorInit="initMyConfigurator"
persist="false" />
 </displayobjects>
...
</plugin>

I've added a couple new values to our standard display object definition. First, configuratorJS identifies the path to our configurator javascript file. This file will contain some basic configuration information so the pop-up configurator can talk to Mura. Note that the base of the path for the file is going to start from the plugin's folder.

Next we identify the name of the configurator function within the javascript file, in this case initMyConfigurator.

The Configurator

I've created a folder in my plugin called "configurator", which is where I'm going to place 3 files. The first is an Application.cfc file that contains mappings to important Mura files (because the configurator is a pop-up interstitial, it won't have any ties to Mura other than the ones we explicitly define). You can download the plugin to see the contents of this file. This file can be used for multiple configurators, at it doesn't contain any configurator-specific information (other than a "safe list" that identifies the names of the configurator files, which you can edit manually).

The next file in this folder will be the configurator.js file itself:

function initMyConfigurator(data) {
initConfigurator(data,{
url: '../plugins/eventregister-configurator/configurator/configurator.cfm'
, pars: ''
, title: 'Event Register Configurator'
, init: function(){}
, destroy: function(){}
, validate: function(){
// simple js validation
if ( !jQuery('#myMessage').val() ) {
var response = alert('Please say something!');
return false;
}
return true;
}
});
return true;
};

This file contains the basic configuration and validation information for our configurator. Of note are the:

  • url: which maps from the admin directory (hence the "../" at the beginning) to the configurator.cfm file in our plugin folder
  • validate: is a validation function you can add to your configurator. It can return either true (validates) or false (a pop-up warning will appear)

Finally there is the configurator form itself:

<cfscript>
$ = StructKeyExists(session, 'siteid') ?
application.serviceFactory.getBean('$').init('session.siteid') :
application.serviceFactory.getBean('$').init('default');
params = IsJSON($.event('params')) ? DeSerializeJSON($.event('params')) : {};
defaultParams = {
myMessage = ''
};
StructAppend(params, defaultParams, false);
</cfscript>
<style type="text/css">
#availableObjectParams dt { padding-top:1em; }
#availableObjectParams dt.first { padding-top:0; }
</style>
<cfoutput>
<div id="availableObjectParams"
data-object="plugin"
data-name="Event Info"
data-objectid="#$.event('objectID')#">
<div class="row-fluid">
<!--- Message --->
<div class="control-group">
<label for="size" class="control-label">My Welcome Message</label>
<div class="controls">
<input type="text"
name="myMessage"
id="myMessage"
class="objectParam span12"
value="#params.myMessage#">
</div>
</div>
</div>
</div>
</cfoutput>

Most of this is just basic configuration/setup information for Mura CMS, like grabbing the Mura Scope. An important bits to note is that the div block with the data-... attributes is used by Mura when the display object is saved. Make sure the data-name value matches the name of your display object

The form itself (highlighted above) is what will be displayed to the user whenever this display object is added to a page.

You'll note that the value I've set for the "myMessage" form field is #params.myMessage#. This is because configurators store their data in a variable called "params". We will be using this very same variable in our display object as well.

The Display Object

Lets open up our display object from the previous blog post and add a few lines of code:

<cfsilent>
<cfset local.params = arguments.$.event('objectParams') />
</cfsilent>
<cfoutput>
<cfif structKeyExists(local.params,'myMessage') and len(local.params.myMessage)>
<p>#local.params.myMessage#</p>
</cfif>
<cfif $.content().getValue('allowRegistration') eq true>
<ul class="er-eventinfo">
<li>
<b>Attendee Limit: </b> #$.content().getValue('attendeeLimit')#
</li>
<li>
<b>Location: </b> #$.content().getValue('location')#
</li>
</ul>
</cfif>
</cfoutput>


I've added a call at the top of the display object to retrieve the "params" variable. You don't need to go through this extra step, but I did it here for clarification. Next, I've checked to ensure the variable "myMessage" exists, and if so I display it at the top of the display object.

In Conclusion

Configurators can be a very powerful too for adding custom configuration information to your display objects. Often times you will do this in the code itself, pulling out Class Extension variables or generating data based upon the url/etc., but when you need to do per-instance configuration on the fly, configurators can make your life much easier.

Look for Plugin Bootcamp Day Four soon; in it I'm going to move our basic plugin into the FW/1 framework using our MuraFW1 starter plugin. Until then, hope you enjoy playing with configurators!

EventRegister Example Plugin

Additional Resources

Mura CMS Documentation: Plugins http://docs.getmura.com/v6/back-end/plugins

This Mura CMS Blog entry is part of the "Mura Plugins Boot Camp" series by Grant Shepert:

Comments

Nicole Bencomo

These articles are extremely helpful.

May 21, 2015, 6:48 AM
Reply
Flag as Spam
Post a Comment

Required Field