I recently performed a minor update to my Embed Video Plugin for Mura CMS. One of the things this update addressed was a judge's comment from the Mura Plugin ColdFusion Throwdown contest, which basically pointed out that I didn't provide documentation for how the EmbedVideo tag could be used within a component (a Mura display component, not a CFC). Well, the original version actually couldn't be used within a Mura component. So I decided to do something about it and figured this would be a good opportunity to demonstrate how you can intercept and modify output in Mura using a plugin or your site's custom eventhandler.
In the original plugin's event handler (EmbedVideo.cfc), the magic happens in the "onRenderStart" event (which was declared in the config.xml of the plugin). The event fires prior to when the page rendering process starts.
<cffunction name="onRenderStart" output="false" returntype="void"> <cfargument name="event"> <cfset var body = "" /> <cfif pluginConfig.getSetting( "isEnabled" ) eq "yes"> <cfset body = event.getContentBean().getBody() /> <cfset body = parseTags( body ) /> <cfset event.getContentBean().setBody( body ) /> </cfif> </cffunction>
So, first there is a check to see if the plugin is enabled. If so, it grabs the content bean from the event object and assigns the body of the content to the variable "body." The parseTags function basically looks for any EmbedVideo tags in the body, parses their attributes, and replaces the tags with the appropriate video embedding code. The contentBean's body is then replaced with the modified copy before it is rendered and then displayed.
Notice, though, that we intercepted the content of the "body" property of the contentbean. This property contains the content which is entered into the content field of the page via the WYSIWYG editor when the page is created/edited. Because I did it this way, the EmbedVideo tag will only be parsed if it was entered into this field, but not if it was included in a display component (or any other custom display object). In fact, I'm not sure that this would work if the tag was put into the "Summary" field of the page either.
So in order to enable the plugin to parse the tag no matter where it appeared in the page output, I needed to be able to to access a variable which contained the entire page output (not just the body property). It turns out that there is a way to access it in an event property called "__MuraResponse__" (that's 2 underscores on either side). This property is available in the "onRenderEnd" event, which apparently fires after all the content is rendered but before it is actually displayed. So the new version of the plugin, I replaced the "onRenderStart" method with this "onRenderEnd" method:
<cffunction name="onRenderEnd" output="false" returntype="void"> <cfargument name="event"> <cfset var output = "" /> <cfif pluginConfig.getSetting( "isEnabled" ) eq "yes"> <cfset output = event.getValue( "__MuraResponse__" ) /> <cfset output = parseTags( output ) /> <cfset event.setValue( "__MuraResponse__", output ) /> </cfif> </cffunction>
Not much has changed except for now I'm looking within "__ MuraResponse__" for the tag and parsing that. Now the tag works within the page, body, summary, components, display objects, and probably within other plugins as well (although I haven't tested that yet).
I hope this has been useful in showing how you can intercept content in Mura and modify it before it is actually displayed in the browser. It is worthwhile to note that while I used a plugin as an example, this can also be done outside of a plugin by putting custom events in your local eventHandler cfc and programmatically registering these events, as is explained in this entry in the Mura blog.
2-16-2010
2-12-2010
1-11-2010
1-4-2010
1-4-2010