Connecting Mura CMS to an ORM Application
Posted on Jun 17, 2010
Some of you may be wondering, based upon the title of this post, why you would want to connect a Mura CMS application to ColdFusion ORM. Let me give a long-winded explanation. Unless your site is entirely content driven you will often have large portions of your site that are not contained within the CMS (we'll refer to this as an external application). Mura makes it easy to connect the CMS portion of your site to another application (this is especially easy if the other application uses a front-controller framework). However, you may often need to display some portion of data from your non-Mura external application in the content-driven portion of your site. For example, let's imagine a site like Twitter (another clone perhaps) whereby the informational content (i.e. home page, about us, documentation, help and so on) may be CMS-driven but we'd also like to display a list of top tweets on the home page that are pulled from outside the CMS.
So, that's the background on why you might need Mura to speak to an outside application. However, now imagine that outside application has services that rely on ColdFusion 9 ORM. In the case of my Twitter-clone site, I can't just directly call tweetService.getTopTweets() from my Mura driven home page because the Mura application does not have ORM enabled. You could use a remote method and call that via Ajax or a webservice since a remote call would mean the method call is instantiated within the external application's application context (i.e. it has ORM enabled) but that isn't always a desirable solution. Thankfully, as of a recent update, you can easily connect your Mura site to your external ORM application. I will show you how to do this by instantiating the ORM context within Mura thereby allowing you to directly call ORM-dependent service methods like tweetService.getTopTweets().
As of a recent update, Mura CMS added a new, customizable configuration file to add custom Application.cfc variables. The file can be found at /config/cfapplication.cfm. If you open this file for the first time it should only contain a comment. This file allows me to do a number things including adding custom settings to my application using the Application.cfc's this scope. This allows me to do everything I need to enable ORM. As you can see in the code below, there's nothing out of the ordinary for this code, its standard orm-enabling settings, with the minor exception that I'd recommend including the cfclocation setting so that ColdFusion only traverses the specific CFC's of your external application and not all the folders and components within your Mura installation. (note: the settings like LogSQL and flushAtRequestEnd aren't required, they're just how I have mine configured).
<!--- Add Custom Application.cfc Vars Here --->
<cfset this.ormenabled = true />
<cfset this.datasource = "myDSN" />
<cfset this.ormSettings.flushatrequestend = false />
<cfset this.ormsettings.logSQL = true />
<cfset this.ormsettings.autorebuild = true />
<cfset this.ormsettings.cfclocation="/mySubApp/com/" />
That's really all you need to enable ORM. Now if you just reload Mura by appending ?appreload to your URL, you should be able to directly call your ORM-dependent service without getting errors about ORM not being enabled on this application. However, during development, you may run into one other issue. Let's say you make some changes to the ORM model on your external application. You might typically add a url variable to reload ORM by doing an applicationStop(). However, the appreload on Mura does not do this and thus you will suddenly get errors from ORM in the Mura app context not reflecting the changes to your model. In order to handle this I created a simple eventHandler that I plugged into Mura to do an applicationStop() when appreload is called. I called the event handler cfc ormReloader and the code is pretty basic:
<cfcomponent output="false" extends="mura.cfobject">
<cffunction name="onGlobalRequestStart" access="public" output="false" returntype="void">
<cfif (structKeyExists(url, "appreload"))>
<cfset ApplicationStop() />
<cflocation url="#cgi.script_name#" addtoken="false" />
</cfif>
</cffunction>
</cfcomponent>
To enable this eventHandler, just add the following code to the onApplicationLoad event in /[siteID]/includes/eventHandler.cfc.
<cfset var ormReloader = createObject("component","ormReloader") />
<cfset application.pluginManager.addEventHandler(ormReloader,event.getValue("siteID")) />
That's it. Now, when you call ?appreload, it will purge and reload ORM as well.
Comments
Thanks for posting about this. I was just exploring Mura here the other day, and one of my first questions was how to integrate it with an external CF ORM driven app, considering the application centric architecture we have with Hibernate integration.
Posted By Kerr / Posted on 03/07/2011 at 8:50 AM