Wow, that’s a horribly complex title. Hopefully it makes sense. Anyway, here is the question from reader Doug:
You've covered using custom tags for layout in a couple posts. My struggle is with the head tags.
Say for example, I have 10 different forms in my app, all requiring different jQuery validation scripts. In what manner should I build the head portion of a template to only pull in the specific .js I need?
My current approach just doesn't seem as clean as it could be... I'm cfimporting in a directory of tags, and then including only the ones needed in my head custom tag:
It works, but each of the 10 form validation scripts is stored separately and then called just for the one form that needs it. I guess since the script truly is unique to that form, there's no way around it.
But figured I'd inquire... do you recommend a better approach?
So first off - let me begin by saying that my "custom tag for layout" approach is something I've generally moved away from. Not because I don't like the approach (I think 'wrapping' is one of the few places where custom tags make sense in a modern ColdFusion application), but because I'm generally using a framework that has it's own way of handling layout and page content. (As an aside, I am finding myself using the approach in CFBuilder extensions - but more on that later.) Despite that, there is still a need for this. You could simply include every library your site needs within your main template. But doing so adds unnecessary load and processing to your pages. Does it really matter? Probably not for 99% of our sites, but if we can easily manage what resources (JS frameworks, CSS files) get loaded in a template than there is no reason not too.
The approach I've taken is actually pretty similar to Doug's. I update my template to allow for flags that indicate which libraries to load. As an example, here is a snippet of code from Adobe Groups (built using ColdFusion 9 and Model-Glue).
<cfset loadmce = event.getValue("loadmce",false)>
<cfset loadrsvp = event.getValue("loadrsvp", false)>
<cfparam name="attributes.loadmce" default="false">
<cfparam name="attributes.loadrsvp" default="false">
I kept the flags/names a bit generic. I didn't want my views specifying a particular file to load, like tinymce.1.9.js. I felt that by keeping it generic it would both be easier to read and easier to update behind the scenes.
JQuery has no issues with multiple blocks like this. I also feel it's better to keep code like this closer to the view. It's worth it to break it out of the head so I can see it closer to the rest of my page layout. (If that doesn't make sense, let me know.)
So - does this seem like a sensible approach? It's worked for me - but how about others?