In ASP.NET MVC 3, you can have an @section
within a view:
@section SideBar {
<p>Some content</p>
<p>Some more content</p>
}
<p>Body content</p>
Then in the master view, you would use this to render it:
<div id="sidebar">
@RenderSection("SideBar", false)
</div>
@RenderBody()
What would be the ColdFusion equivalent of this in the Model Glue framework? I know I can set simple variables in the view:
<cfset event.setValue("section", "Tables")>
Then use them in the master template like so:
<cfif event.exists("section")><h3>#event.getValue("section")#</h3></cfif>
But this only works well for one-liners and simple strings. What I'd like to do is include an entire HTML block. What is the best way of accomplishing this? I think this would work in theory:
<cfsavecontent variable="sidebar">
<p>Some content</p>
<p>Some more content</p>
</cfsavecontent>
<cfset event.setValue("sidebar", sidebar)>
But I was wondering if there's a better way of doing it.
Edit:
In response to Adam Cameron's answer, Model Glue, from what I can tell, only supports the ability to combine separate files into one template:
SideBar.cfm:
<p>Some content</p>
<p>Some more content</p>
Page.cfm:
<p>Body content</p>
ModelGlue.xml:
<event-handler name="page.text">
<views>
<include name="sidebar" template="SideBar.cfm"/>
<include name="body" template="Page.cfm"/>
<include name="main" template="main.cfm"/>
</views>
</event-handler>
main.cfm:
<cfoutput>#viewCollection.getView("sidebar")#</cfoutput>
<cfoutput>#viewCollection.getView("body")#</cfoutput>
I need to be able to declare the sidebar content within the page.cfm
view. The thought here is that there will be a div somewhere in the main template that allows for a small HTML snippet, say an image with a text description and a link, which any view can populate. It wouldn't make sense to have something like Page1.cfm
and Page1SidebarContent.cfm
, Page2.cfm
and Page2SidebarContent.cfm
, etc...
ModelGlue doesn't support what you want to do out of the box. However its easy enough to achieve using Peter's suggestion and ModelGlue helpers for encapsulation.
Create a new cfc, call it PageFragment.cfc and drop it in to your ModelGlue helpers directory.
// untested!
component name="PageFragment" {
public boolean function exists(string name) {
return structkeyexists(request.subcontent, arguments.name);
}
public string function get(string name) {
if(exists(arguments.name)) return request.subcontent[arguments.name];
return "";
}
public void function set(string name, string value) {
request.subcontent[arguments.name] = arguments.value;
}
}
Then in your views you can do
index.cfm
<cfset helpers.PageFragment.set("sidebar", "<p>My sidebar content</p>") />
main.cfm
<cfif helpers.PageFragment.exists("sidebar")>
<div id="sidebar">#helpers.PageFragment.get("sidebar")#</div>
</cfif>
To avoid having to cfsavecontent all your fragments you could create a customtag that used thistag.generatedcontent and the caller scope to access your helpers.
By using helpers to encapsulate the functionality its really easy to reuse, or to change later without altering your views, for example you may want to add caching.