ColdFusion Tag Parameters Can Be Included In Separate Files (Thanks Mark Drew!)

Posted June 17, 2009 at 9:06 AM by Ben Nadel

Tags: ColdFusion

At the New York ColdFusion User Group a few weeks ago, Mark Drew was presenting on Reactor, an ORM framework. In his presentation, he was discussing how the SQL was generated and he had something on a slide that I don't think I had ever seen before. He had a CFQuery tag in which the SQL was defined in an included file (via CFInclude). Now, I've seen that done before (separate SQL); but, what I had not seen before that I can remember is that the included SQL file contained actual CFQueryParam tags.

From what I could remember, things like this were not possible. So, I figured it was time to run some experiments. I took three ColdFusion tags that usually have some sort of child parameter tag and tried moving them to separate include files. I did this with CFQuery (to replicate Mark's idea), CFMail, and CFHTTP.

To start with, I wanted to replicate Mark's demonstration using CFQuery and included CFQueryParam tags:

  • <!--- Create a query to test with. --->
  • <cfset dataTable = queryNew( "id", "cf_sql_integer" ) />
  •  
  • <!---
  • Run query against data table, but build query in
  • secondary file.
  • --->
  • <cfquery name="records" dbtype="query">
  • <cfinclude template="cfquery_params.cfm" />
  • </cfquery>
  •  
  • <!--- Output query data. --->
  • <cfdump
  • var="#records#"
  • label="Query Data"
  • />

... and here is the include file:

  • SELECT
  • id
  • FROM
  • dataTable
  • WHERE
  • id = <cfqueryparam value="1" cfsqltype="cf_sql_integer" />

The above code runs with no ColdFusion errors.

Then, I tried using the CFMail tag:

  • <!--- Send email, but define body elements in included files. --->
  • <cfmail
  • to="ben@bennadel.com"
  • from="blog@bennadel.com"
  • subject="Child Params Test"
  • type="html">
  •  
  • <cfinclude template="cfmail_params.cfm" />
  • </cfmail>

... and here is the include file:

  • <!--- HTML mail data. --->
  • <cfmailpart type="text/html">
  • <strong>HTML data.</strong>
  • </cfmailpart>
  •  
  • <!--- Text-only mail data. --->
  • <cfmailpart type="text/plain">
  • Text-only data.
  • </cfmailpart>
  •  
  • <!--- Include a file. --->
  • <cfmailparam
  • file="#ExpandPath( './cfmail_params.cfm' )#"
  • type="text/plain"
  • />

The above code runs with no ColdFusion errors.

Then, I tried using the CFHTTP tag:

  • <!--- Make HTTP request, but include params in separate file. --->
  • <cfhttp
  • result="httpResponse"
  • method="get"
  • url="http://www.google.com/search"
  • useragent="firefox">
  •  
  • <cfinclude template="cfhttp_params.cfm" />
  • </cfhttp>
  •  
  • <!--- Output http response. --->
  • <cfoutput>
  • #httpResponse.fileContent#
  • </cfoutput>

... and here is the include file:

  • <cfhttpparam
  • type="url"
  • name="q"
  • value="hot sexy female muscle"
  • />

This also executed without any ColdFusion errors.

So, that's pretty cool. I am not sure how often it would make sense to use this kind of strategy; but, I was a bit surprised that it worked. I always thought that these child ColdFusion tags needed to be defined in the direct context of their parent tags, but I guess I was totally wrong. Thanks Mark!



Reader Comments

Jun 17, 2009 at 9:23 AM // reply »
66 Comments

Interesting post Ben. I've actually done something very similar to your CFMail example, but not the CFHTTP or CFQuery ones. Hmm.


Jun 17, 2009 at 10:04 AM // reply »
6 Comments

I've used this in the past with <cfquery> -- it's great for keeping a shared "where" clause separate from the main query.

But, does this work with <cfform> ... <cfinput> ... </cfform> too? That limitation used to be there, and it was the main reason I never started using those tags.

Ben


Jun 17, 2009 at 10:09 AM // reply »
11,238 Comments

@Ben,

I've never really gotten into CFForm, so I can't say. But, it would seem like it should follow the same scheme.


Jun 17, 2009 at 10:24 AM // reply »
15 Comments

I've always equated includes (in any language) as Server-Side copy and paste. When I'm teaching people that are having problems understanding how to use includes, I tell them to just pretend that you copy everything from the include and paste it into the parent document. This falls right in line with that way of thinking, though I didn't know that CF would consider it valid :-).


Jun 17, 2009 at 10:26 AM // reply »
11,238 Comments

@Daniel,

Yeah, I thought it would be a compile-time validation issue. I'll have to do some more playing around.


Jun 17, 2009 at 10:44 AM // reply »
1 Comments

Very interesting. Not sure if there's a chance that I will use it - but very interesting.

Ben, I always find good cf tips on your site.


Jun 17, 2009 at 11:15 AM // reply »
26 Comments

Definitely an interesting technique, but I've been mulling it over for the past several minutes and I can't come up with a situation where you would want to do something like this. Can you see a use for this, Ben?


Jun 17, 2009 at 11:19 AM // reply »
11,238 Comments

@Pat,

Thanks my man :)

@Brian,

The SQL is the only one that really makes much sense to me. I can't really think of another reason to do this... unless you were going to create custom tags that wrapped around the inherent tag functionality... assuming that scenario is even still functional. I'll play around.


Jun 17, 2009 at 11:31 AM // reply »
26 Comments

One possible use that came to mind was building a query testing tool: you'd have a directory of include files with different SQL statements and just loop through them to make sure they worked properly.

The oddness of it just really bothers me for some reason. The normal approach is to create a reusable function and then inject different parameters to get different results, whereas this lets you create reusable parameters to inject into different functions...bit of a mind-bender.


Jun 17, 2009 at 11:35 AM // reply »
11,238 Comments

@Brian,

Yeah, it's a bit interesting, right?


Jun 17, 2009 at 12:10 PM // reply »
45 Comments

I've also done this with nested custom tags in the ColdExt project, with a bit of trickery looking through the list of parent tags you can safely ignore standard CF tags (including cfinclude) and only pass data back to a parent tag that belongs to your own library (using cfassociate), even when the code is in separate files as you've noted here. The built-in CF tags which are generally used as nested tags must treat cfinclude (and other flow control tags) the same way when passing data back to their parent tags :)


Jun 17, 2009 at 1:00 PM // reply »
14 Comments

Whoah. Weird. It shows how literal cfinclude is.


Jun 17, 2009 at 3:17 PM // reply »
27 Comments

I've always considered cfinclude to do just that, take another template and insert it right here.

One exception though and I haven't tested this in a while, but I think that a cfinclude inside of cfoutputs does not recognize that it is inside those. The included template must have its own cfoutput tags.


Jun 18, 2009 at 11:53 AM // reply »
47 Comments

@Matt, I believe you're right, I think the page is executed separately from what I recall.


Jun 18, 2009 at 1:46 PM // reply »
131 Comments

and, yes, this works just fine with CFFORM tags wrapped around something like CFINCLUDE template="_form.cfm" ...



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
May 14, 2013 at 6:57 PM
The UX Of Prototyping: Low-Fidelity Is The New High-Fidelity
@Phillip, I'm not sure I follow what you mean? Are you saying that you looked at the list of widgets provided by the jQuery UI and let that be your style guide? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools