Making jQuery Mobile templates even easier - with ColdFusion

This post is more than 2 years old.

Earlier today I read an interesting blog entry on jQuery Mobile and Rails. Now - let me start off with saying I'm not a huge fan of Ruby's syntax. I've got nothing against it and Rails. I did notice though that some of the template examples in the post seemed unnecessarily complex and verbose when it came to HTML. A few folks on Twitter informed me that was more his use of HAML than Ruby. Fair enough. That being said, the author did some very interesting things with his templates and I thought I'd work on a ColdFusion version. Credit for the coolness though goes squarely to the original author, Ken Collins.

So - creating a ColdFusion custom tag to handle layouts is not something new. You've been able to build custom tag wrappers since version 4, approximately 200 years ago. But if you look at Ken's code, even if you can't read the Ruby/HAML, you will see two very cool things he is doing with his templates. First - he is simplifying the creation of page IDs. jQuery Mobile requires your pages to use unique IDs. His template makes that automatic. I decided for my code I'd make it automatic, but let you supply one if you wanted. Secondly - jQuery Mobile pages loaded after the initial request do not need to return the entire HTML block. Ie the HTML tag, BODY, etc. His code intelligently checks for Ajax requests and minimizes what is returned when it can. That quick little tweak will add just a bit more speed to your pages and is easy enough to add in our code as well. Here's my first custom tag, page.cfm.

<!--- Courtesy Dan Switzer, II: ---> <cffunction name="isAjaxRequest" output="false" returntype="boolean" access="public"> <cfset var headers = getHttpRequestData().headers /> <cfreturn structKeyExists(headers, "X-Requested-With") and (headers["X-Requested-With"] eq "XMLHttpRequest") /> </cffunction>

<cfif thisTag.executionMode is "start">

&lt;cfparam name="attributes.title" default=""&gt;
&lt;cfparam name="attributes.customscript" default=""&gt; 
&lt;cfif not structKeyExists(attributes, "pageid")&gt;
	&lt;!--- Make a page based on request. ---&gt;
	&lt;cfset attributes.pageid = replace(cgi.script_name, "/","_","all")&gt;
&lt;cfparam name="attributes.theme" default=""&gt; 

&lt;cfif not isAjaxRequest()&gt;
&lt;!DOCTYPE html&gt; 
	&lt;meta charset="utf-8"&gt; 
	&lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt; 
	&lt;link rel="stylesheet" href="" /&gt; 
	&lt;script src=""&gt;&lt;/script&gt; 
	&lt;cfif len(attributes.customscript)&gt;
		&lt;srcript src="#attributes.customscript#"&gt;&lt;/script&gt;
	&lt;script src=""&gt;&lt;/script&gt; 

&lt;cfoutput&gt;&lt;div data-role="page" id="#attributes.pageid#" data-title="#attributes.title#" &lt;cfif len(attributes.theme)&gt;data-theme="#attributes.theme#"&lt;/cfif&gt;&gt;&lt;/cfoutput&gt;



&lt;cfif not isAjaxRequest()&gt; 


For the most part I'm going to assume this is easy enough to read. If you've never seen a custom tag "wrapper" before, check out this blog entry I wrote back in 2007. Basically ColdFusion passes to your custom tag whether or not the execution is at the beginning or end of the tag. Notice the check for the pageid value. If it doesn't exist, we create it based on the request path. Again, this is based on Ken's template. The other interesting part is the isAjaxRequest UDF. It's taken from code Dan Switzer wrote (and something I blogged about in the past as well). If we detect an Ajax request, we will suppress everything but the code div. Finally - I added support for passing in the URL to a custom script and a theme selection as well. Here's an example of how you could call this:

<cf_page title="Home Page"> </cf_page>

Or you can use cfimport:

<cfimport prefix="jqm" taglib="jqm">

<jqm:page title="Home Page">


Next up - I decided to quickly add support for 3 main jQuery Mobile UI items - header, footer, and content. This allows me to complete a page like so:

<cfimport prefix="jqm" taglib="jqm">

<jqm:page title="Home Page">


	This is my main page content. Go to &lt;a href="test2.cfm"&gt;next&lt;/a&gt;.

&lt;jqm:footer&gt;Copyright &copy; 2014&lt;/jqm:footer&gt;


Each of these three new tags are the exact same, so I'll share one of them here (content.cfm):

<cfif thisTag.executionMode is "start"> <cfparam name="attributes.theme" default="">

&lt;div data-role="content" &lt;cfif len(attributes.theme)&gt;data-theme="#attributes.theme#"&lt;/cfif&gt;&gt;




And here is another example:

<cfimport prefix="jqm" taglib="jqm">

<jqm:page title="Home Page" id="page2" theme="e">


	This is my second page content. Go to &lt;a href="index.cfm"&gt;home&lt;/a&gt;.

&lt;jqm:footer theme="b"&gt;Copyright &copy; 2014&lt;/jqm:footer&gt;


By the way, I'm not normally a cfimport fan myself. I use it every now and then when the mood hits me. If it scares you, here's the above example with just cf_ syntax.

<cf_page title="Home Page" id="page2" theme="e">


	This is my second page content. Go to &lt;a href="index.cfm"&gt;home&lt;/a&gt;.

&lt;cf_footer theme="b"&gt;Copyright &copy; 2014&lt;/cf_footer&gt;


I did some quick testing with my Chrome Net panel open, and can confirm that when I requested my second page (and clicked the link back home), the template correctly noted it as an Ajax request and suppressed the unnecessary HTML. If you want to play with these custom tags I've included them as a zip to this blog entry.

Download attached file.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA

Archived Comments

Comment 1 by John Farrar posted on 8/26/2011 at 10:10 PM

Sweet, nice to see more Custom Tag content used where it should be. There was a day we missed the target and used them too much. This is a great use case of the right way to do it and a great blog post. Keep up the awesomeness Ray!

Comment 2 by Jaana Gilbert posted on 8/26/2011 at 10:27 PM

I love it! Can't make a page creation any easier than that :)

Comment 3 by Connor Middleton posted on 8/27/2011 at 12:12 AM

This is pretty sweet Ray. I'll probably put this to use on a project I am just spooling up. Thanks

Comment 4 by David McGraw posted on 8/27/2011 at 12:26 AM

Interesting take, and cool routine. Thanks!

Comment 5 by Phillip Senn posted on 8/27/2011 at 5:43 AM

What could be next? A Dreamweaver template? Just kidding.

Comment 6 by Misty posted on 1/31/2012 at 12:41 PM

Hi ray, Good post.

My Question here is

1. Can I cfinclude the templates in the pages - i think i can
2. Is the new way to write jquery mobile applications pertaining to their own attaibute usage like ui-hidden-theme classes or data-role="something"

3. silly question but let me ask - can i add my application.cfm or application.cfc - i think i can

Comment 7 by Raymond Camden posted on 1/31/2012 at 5:35 PM

1) Um, well yeah, thats kinda the point. ;) You aren't cfincluding it though, you are using it as a custom tag.

2) No idea at all what you mean here.

3) Yes.