Model-Glue does not require XML, but it's a good idea to use it.

Recently, I've seen a few posts criticizing the use of XML for frameworks. One piece of misinformation they've contained is that Model-Glue requires you to use XML.

[Read more on Joe Rinehart's blog]

In reality, Model-Glue could care less about XML. It just happens that the framework, by default, includes something called the "XMLConfigurationLoader" that reads ModelGlue.xml files.

Why does it include this by default?

When I started writing Model-Glue, I shared the view of many others where I just didn't see why XML should be necessary to use a framework. I mean, I already know ColdFusion, why not just script together the events, listeners, etc? Let the CFCs themselves be the framework.

That soon became a mess:

  1. As the earliest MG application grew, the script became really repetitive. In script form, this MG tag:
    <include name="body" template="foo.cfm" />
    ...requires creating an instance of View.cfc, setting its name and template, and adding it to an instance of EventHandler.cfc. Sure, the CFCs are the framework, but the script is a royal pain to read.
  2. As the framework CFC changed, applications broke! Because I built a framework where the CFCs were the framework, my applications were dependent on the framework API.

So, I soon found myself using an XML file. This solved the problems nicely:

  1. I could create my own syntax that was Model-Glue specific, expressing multiple lines of CFML script in a single tag.
  2. I abstracted my application from the framework's API.
  3. I made more clear the separation of types of code: CFML handled application logic, but XML handled application flow. These two should be separate, and having them in different languages forces this.

Is XML perfect? No, it can be overdone. I really don't like that Fusebox allows pseudo-programming in its XML files, but it seems to work for its users. However, using XML to configure an II framework beats the pants off the alternative. What follows is a re-creation of the Model-Glue application template without using any XML:

<!--- Tell modelglue.cfm where the framework is stored so that it doesn't try loading it --->
<cfset ModelGlue_APP_KEY = "mgnoxml" />
<!--- Tell MG to run in "legacy" mode, where no ColdSpring.xml file exists --->
<cfset _modelglue.compatibilityMode = "Legacy" />

<!--- Model-Glue config: most settings are defaulted --->
<cfset cfg = createObject("component", "ModelGlue.unity.framework.ModelglueConfiguration").init() />
<cfset cfg.setDefaultEvent("page.index") />
<cfset cfg.setReload(false) />
<cfset cfg.setDebug(true) />
<cfset cfg.setViewMappings("/blogsamples/mgnoxml/views") />
<cfset cfg.setGeneratedViewMapping("/blogsamples/mgnoxml/views/generated") />

<!--- Create the framework --->
<cfset mg = createObject("component", "ModelGlue.unity.framework.ModelGlue").init("MG No XML Demo") />
<cfset mg.setConfiguration(cfg) />
<cfset mg.setStateBuilder(createObject("component", "ModelGlue.unity.statebuilder.StateBuilder").init()) />



<!--- Create controllers / listeners --->
<cfset cont = createObject("component", "blogsamples.mgnoxml.controller.Controller").init(mg, "ControllerName") />
<cfset mg.addListener("onRequestStart", cont, "onRequestStart", false) />
<cfset mg.addListener("onQueueComplete", cont, "onQueueComplete", false) />
<cfset mg.addListener("onRequestEnd", cont, "onRequestEnd", false) />

<!--- Create event-handlers --->

<!--- Request start/end/etc. events --->
<cfset eh = createObject("component", "ModelGlue.unity.eventhandler.EventHandler").init() />
<cfset eh.setName("ModelGlue.OnRequestStart") />
<cfset msg = createObject("component", "ModelGlue.unity.eventhandler.Message").init() />
<cfset msg.setName("OnRequestStart") />
<cfset eh.addMessage(msg) />
<cfset mg.addEventHandler(eh) />

<cfset eh = createObject("component", "ModelGlue.unity.eventhandler.EventHandler").init() />
<cfset eh.setName("ModelGlue.OnQueueComplete") />
<cfset msg = createObject("component", "ModelGlue.unity.eventhandler.Message").init() />
<cfset msg.setName("OnQueueComplete") />
<cfset eh.addMessage(msg) />
<cfset mg.addEventHandler(eh) />

<cfset eh = createObject("component", "ModelGlue.unity.eventhandler.EventHandler").init() />
<cfset eh.setName("ModelGlue.OnRequestEnd") />
<cfset msg = createObject("component", "ModelGlue.unity.eventhandler.Message").init() />
<cfset msg.setName("OnRequestEnd") />
<cfset eh.addMessage(msg) />
<cfset mg.addEventHandler(eh) />

<!--- Index event --->
<cfset eh = createObject("component", "ModelGlue.unity.eventhandler.EventHandler").init() />
<cfset eh.setName("page.index") />
<cfset view = createObject("component", "ModelGlue.unity.eventhandler.View").init() />
<cfset view.setName("body") />
<cfset view.setTemplate("dspIndex.cfm") />
<cfset eh.addView(view) />
<cfset eh.addResultMapping("", "view.template", false, "", "", false, true) />
<cfset mg.addEventHandler(eh) />

<!--- Template event --->
<cfset eh = createObject("component", "ModelGlue.unity.eventhandler.EventHandler").init() />
<cfset eh.setName("view.template") />
<cfset view = createObject("component", "ModelGlue.unity.eventhandler.View").init() />
<cfset view.setName("body") />
<cfset view.setTemplate("dspTemplate.cfm") />
<cfset eh.addView(view) />
<cfset mg.addEventHandler(eh) />

<!--- Exception Event --->
<cfset eh = createObject("component", "ModelGlue.unity.eventhandler.EventHandler").init() />
<cfset eh.setName("exception") />
<cfset view = createObject("component", "ModelGlue.unity.eventhandler.View").init() />
<cfset view.setName("body") />
<cfset view.setTemplate("dspException.cfm") />
<cfset eh.addView(view) />
<cfset mg.addEventHandler(eh) />


<cfset application[ModelGlue_APP_KEY] = structNew() />
<cfset application[ModelGlue_APP_KEY].framework = mg />

<cginclude template="/ModelGlue/unity/modelglue.cfm" />

Fun, eh?

TweetBacks
Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
© 2017 Joe Rinehart
BlogCFC was created by Raymond Camden. This blog is running version 5.9.3.006.