Blog

Mapping Events in Mura

I recently added a new way to map events in Mura.  You can now simply directly add objects with the new application.pluginManager.addEventHandler() method;

application.pluginManager.addEventHandler([component intance],'[siteid]')application.pluginManager.addEventHandler('[component path]','[siteid]',[persist])

So there are two ways where this can come in handy.

Using addEventHandler() in the Local EventHandler.cfc

Every site in Mura has it's own eventHandler.cfc where you can define event handling methods without needing to bind it to an actual plugin.  You can find this file at:

/[siteid]/includes/eventHandler.cfc

The problem is that it's only one file and if you need to define a large number of events or if you need your handler to persist between requests you run into problems.  The application.pluginManager.addEventHandler() method solves this issue.  You can now do this:

1. Create Your Event Handler.

For example purposes I'm just going to put a simple handler in the sites includes directory next to the local eventHandler.cfc

EXAMPLEHANDLER.CFC
/[siteid]/includes/exampleHandler.cfc

<cfcomponent extends="mura.cfobject"><cfset hits=0><!--- Mura uses on[name], onGlobal[name] and standard[name] for binding event ---><cffunction name="onExample" output="true" returntype="any"><cfargument name="$"><cfset hits=hits+1><cfset $.event("hits","<strong>Number of Hits:" & hits & "</strong>")></cffunction></cfcomponent>

 

2. Load the Event Handler

Now that the custom handler has been defined you still need to create code to register it so that the  plugin manager can listen for it's defined events. This can be done in the local eventHandler.cfc.

EVENTHANDLER.CFC
/[siteid]/includes/eventHandler.cfc

<cfcomponent extends="mura.cfobject"><cffunction name="onApplicationLoad" output="true" returntype="any"><cfargument name="$"><cfset var exampleHandler=createObject("component","exampleHandler")><cfset $.getBean('pluginManager').addEventHandler(exampleHandler,$.event("siteID"))></cffunction></cfcomponent>

 

3. See It in Action

Since the example handler that we created doesn't have any official Mura events you can use the Mura tag in a test page to see it in action.

(Remove spaces in Mura tags )

[mura ]$.announceEvent('onExample')[/mura ][mura ]$.event('hits')[/mura ]

Now reload your Mura instance and view the page an should see the number of times that the onExample event has been fired since the application was last loaded.

Using addEventHandler() in a Plugin

As an example plugin I stumbled upon a blog post by Steve Good about using jquery to dynamically turn links to mp3 files into a simple flash player. You can read it here.  Here are the main elements of the plugin so you can see how you can map events.

CONFIG.XML
Notice that there's only one handler for onApplicationLoad defined in the XML.

<plugin><name>Simple MP3 Player</name><package>MP3Player</package><directoryFormat>packageOnly</directoryFormat><version>1.0</version><provider>Blue River/Steve Good</provider><providerURL>http://blueriver.com</providerURL><category>Application</category><settings/><eventHandlers><eventHandler event="onApplicationLoad" component="cfcs.eventHandler" persist="true"/></eventHandlers><displayobjects location="global"/></plugin>

PLUGIN.CFC
Every time the plugin is updated or installed it tells Mura to reload.

<cfcomponent output="false" extends="mura.plugin.plugincfc"><cffunction name="install" returntype="void" access="public" output="false"><cfset application.appInitialized=false></cffunction><cffunction name="update" returntype="void" access="public" output="false">    <cfset application.appInitialized=false></cffunction></cfcomponent>

EVENTHANDLER.CFC
Here you can see that the onApplicationLoad() uses the variables.pluginConfig.addEventHandler() to register the entire component and all of it's defined events for all of the plugin's assigned sites.

<cfcomponent extends="mura.plugin.pluginGenericEventHandler"><cffunction name="onApplicationLoad">    <cfargument name="$">   <cfset variables.pluginConfig.addEventHandler(this)></cffunction><cffunction name="onRenderStart" output="false" returntype="any">    <cfargument name="$">    <cfset var renderer=$.getContentRenderer()>    <cfset renderer.showMetaList=listAppend(renderer.showMetaList,"mp3")>    <cfset $.loadJSLib()>    <cfset variables.pluginConfig.addToHTMLHeadQueue("htmlhead/htmlhead.cfm")></cffunction></cfcomponent>

The main thing here is that you can just add an event handler without explicitly mapping events that it's listening for.

If you would like to download this plugin to play around you can download it here.

Anyway, hopefully this makes sense and people find it easy to use. Please feel free to ask questions either here or in the forum. Make sure to update your Mura instance's Core verison to the lastest code before working through these examples.

Comments

Steve Good

Interesting news on the event handling.

The code example out of my blog post went straight into a component that was added to the top level cascade. Thought I definitely see how this could be better. One thing that might be interesting to take this a step further would be to parse the content, determine if there are links to mp3 files and if there are then inject the script that inserts the player.

I'll definitely have to play around with this. Thanks for the reference too!

November 7, 2009, 4:17 AM
Reply
Flag as Spam
Hatem Jaber

Matt, just to make sure that I am reading this correctly, by adding the onApplicationLoad() and passing "this" to the addEventHandler(), any event added to that cfc will be added without having to explicitly doing addEventHandler() call for each one? In your example you have onRenderStart(), so that will be added without having to make the call? So if I had an onRenderEnd() that too will be added?

I just want to make sure I understood this correctly.

Thanks,

Hatem

March 30, 2010, 4:32 AM
Reply
Flag as Spam
Hatem Jaber

One more thing that I just thought of, will a custom method also be added to the list of events as well, let's say for example I have onSomeCustomEvent()... ?

Thanks again

March 30, 2010, 5:34 AM
Reply
Flag as Spam
Matt Levine

The addEventHandler() method looks through the keys in the component that has been submitted and registers methods named either:

on[Something]

standard[Something]

You can have any event that you want. If it's not part of the normal Mura event model it just won't ever be called.

However, in your plugin you could have an eventHandler with onCustomProcess method defined that you could in turn call with:

<cfset getPluginManager().announceEvent("onCustomProcess",event)>

or even just:

getPluginManager().announceEvent("CustomProcess",event)

March 30, 2010, 7:35 AM
Reply
Flag as Spam
Post a Comment

Required Field