Douglas asked the following question this morning:
Is it possible to use a header file include inside an onRequestStart function in Application.cfc but prevent the header file from loading into select templates, or to define multiple header files and define the templates which are to use them. I know I can just include them in each template but I have a site with multiple templates using the same header and a select few using a different header. How would you approach this?
So first off - yes, you can include a file on onRequestStart. If you wanted to not load it on certain templates, don't forget that ColdFusion passes in the template name to onRequestStart, so you always have access to the template that is about to load.
However - you asked how I would approach this. I do not use onRequestStart to handle layout. Instead, I use a custom tag approach and wrap my pages like so:
<cfmodule template="/mysite/tags/layout.cfm" title="About Me">
stuff
</cfmodule>
While this means more work for me, I like having the finer control. I find this nicer than having logic dictating when and when not to use a header. If I don't need a header, then I simply don't use the custom tag. So for example, a popup may have something like so:
<cfmodule template="/mysite/tags/popup.cfm" title="About Me">
stuff
</cfmodule>
Another reason I like this is that I immidiately know what layout my pages are doing. If the logic was in onRequestStart, or even in the custom tag itself, when I worked on foo.cfm I wouldn't know what layout was being used for the page.
Archived Comments
Hmmm. This causes me to make this leap of speculation, to wonder when we will see Jedi, the CF Framework designed by Ray Camden!
Also note, it's typically noted as a best practise to not put any display layer code in application.cfm or application.cfc. Consider your app eventually extending services to Flex, Flash, or Ajax clients. Then this could make a terrible mess of that well crafted XML response, eh?
DK
James: Probably never. :) I'm very happy with Model-Glue.
Douglas: Absolutely.
A layout.cfc works nicely for this too.
Will
Will ..
Can you elaborate on this layout.cfc.. ?
Toku
I might have a layout.cfc with showHeader(), showLeftMenu(), showFooter(), etc.
You pass in title, keywords, etc. as arguments.
Will
Ray,
Thanks for posting this for discussion.
A Couple of guys wrote this book named WACK that I picked that up in (-;
Douglas, I was unaware that presentation should be left out of application.cfc/.cfm. I try to keep presentation and logic separated as much as possible and thought this was a step in the right direction.
Will, I like your component approach, showHeader() might take template name as an argument which would set the condition whether to use headerA or headerB (unsure as to how the template name will be accessed in the .cfc). As Ray mentioned above CF passes the template name to onRequestStart, how do we control where the template name gets passed? - Thanks Ray, this was a key question that I was realizing today related to accessing a particular template.
Ray, your custom tag approach is confusing to me because I am not familiar with what you would be doing in layout.cfm. Would layout.cfm be working similar to Will's layout.cfc approach?
D.
Doug, I'd just use the custom tag like so:
<cf_layout title="Foo">
Content
</cf_layout>
Custom tags can be run in both "start" and "end" modes, so it is possible to build wrappers like this.
Ray, thought I would crack this one open again as I did not fully understand. The first question which arised was <cfmodule>? Found this useful for beginning to understand: http://www.netbenefit.com/T...
In your code above:
<code>
<cfmodule template="/mysite/tags/layout.cfm" title="About Me">
stuff
</cfmodule>
</code>
I am understanding that cfmodule is referencing the template layout.cfm which contains the custom tag(s).
Related to your post above using <cf_layout title="Foo"> I interpret <cf_layout> as the custom tag "wrapper" titled "Foo" which might be contained within layout.cfm.
Do I have that straight?
Doug, you are mostly right - but the file itself (layout.cfm) _is_ the custom tag. THere are multiple tags in it. So my code, and your code, runs the same file twice. ColdFusion knows if it is in 'startmode' or 'endmode', and that variable is present in the ThisTag scope.
I promise a Custom Tag presentation soon. :)
It appears that custom tags work similarly as that of CFCs. ThisTag scope is defined in app.cfc - Correct?
How do we call individual functions out of the custom tag?
Is the increased overhead of custom tags resulting from the file being run twice or is that just a result of the context of the tag we are discussing for header() footer()?
Once I get the theory side correct I will work on the content and try to write a simple header() and post back.
D.
Nope. Tags are very different. You are confusing the This scope in CFCs with the ThisTag scope in custom tags.
Custom tags do not have functions like CFCs. Custom tags are executed, in ways, a lot like a simple cfinclude.
The overhead is in creating the blackboxing for tags. To be honest, I don't think it is something to normally worry about
.
Ok - that settles it. A custom tag presentation will be on the books.
I have an idea, why don't I go and read some more about custom tags so I can get a clue. Thanks for your patience.
Looking forward to your CT presentation (-;.
I will post back after some research.
D.
Here is a good article - Wonder who that author is?
http://www.adobe.com/devnet...
Ray,
How does the following relationship work?
header.cfm (Tag page)
<cf_header> (calling tag)
Obviously "header" is the identifier. I recall some discussion here in other posts about <cf_foo>, I think in comparison to <_foo> (something like that anyway).
D.
Aha, I see what you mean, the opening tag can contain a custom tag call as well as the closing tag can contain a closing tag call. When CF reads the file the second time the closing tag is called (this epiphony realized by <cfimport>.
By defining ThisTag scope with "start/end" attributes we can control when a tag is called and use <cfmodule>.
layout.cfm (Custom Tag for header/footer)
<!--- Custom tag layout.cfm --->
<cfif ThisTag.ExecutionMode="start"><cfoutput>THIS IS MY HEADER</cfoutput></cfif>
<cfif ThisTag.ExecutionMode="end"><cfoutput>THIS IS MY FOOTER></cfoutput></cfif>
<!--- Tag Call --->
<html>
<head>
<title>MyPage</title>
</head
<body>
<cf_layout><!--- Tag Start Mode Header --->
<h1>MY Page</h1>
</cf_layout><!--- Tag End Mode Footer --->
</body>
</html>
Do I have the basics?
Pretty much yes. Your terminology is a bit off - but you got it.
Doug: Would you believe I had completely forgotten about this article?
Cool - Please correct me.
I can imagine that, that was back in 98, that has been a bit.
Thanks, this was a good study.
D.
Well, to be anal, the opening tag doesnt contain a custom tag call - it IS the custom tag call. The ThisTag scope doesn't control the tag being called, it just gives info about HOW the tag is being used.
But now I'm just being picky.
NP, helps me to understand greater detail.
Opening tag IS and Closing Tag IS (are) the call.
Threw me off with "how" in this context I was understanding "when".
How else can we use ThisTag? (short version)
D.
Maybe too general of a question cause just defining scope. Can be used however see fit.
The ThisTag has a few other values. ThisTag.HasEndTag - can be used to force people to use your tag as a wrapper. ThisTag.GeneratedContent - only makes sense in the closing tag - let's you get the crap on the inside. I already mentioned executionMode. Lastly, assocAttribs, which lets you examine data from "child" tags. (Don't let that throw you.)
I'm going to post a survey (well, just a question) to my blog for the September Jedi UG - to see if folks would rather a security meeting or a custom tags meeting - but even if tags lose, I'll do it the next month. (But it may be November since October has MAX.)
assocAttribs - relative to nested ("child") tags? I began reading on those last night after our discussion. I will read up on the ThisTag values this eve.
Can't thank you enough!
I like the Samsung choice I wish I could do it. Avatar - The last Airbender... Absolutely the best series going. Also like Oban Star Racers (didn't see that one on your list). My son and I watch those all the time.
I will send something your way.
Here is a correction to my syntax:
<!--- Custom tag layout.cfm --->
<cfif ThisTag.ExecutionMode IS "start"><cfoutput>THIS IS MY HEADER</cfoutput></cfif>
<cfif ThisTag.ExecutionMode IS "end"><cfoutput>THIS IS MY FOOTER</cfoutput></cfif>
Forgot about the =. Noticed in Livedocs that they were using a single quote around start/end. Seems to not make a difference though.
Douglas: child tags are pretty rarely used. I use it in my "datatable" tag, which is a simple tag set I built to let me quickly show tables of data. If you download any of my apps you will see an example of this.
As for your custom tag example, I'd write it a bit different. Forgive the lack of less than/greater than signs, too lazy to ecape
cfif thistag.executionmode is "start"
content
cfelse
content
/cfif
I will look through BlogCFC to see if I can find an instance of your "datatable" tag to review.
As for my custom tag, if adapted to your cfelse example I understand:
<cfif thistag.executionmode is "start">
<cfoutput>THIS IS MY Header</cfoutput>
cfelse
<cfoutput>THIS IS MY FOOTER</cfoutput>
/cfif
By using the cfelse I interpret this as implying end mode.
Hope I see that correctly.
Thanks,
D.
Yep, you got it.
Would it be bad practice to do a <cfinclude> inside of the tag?
What I was thinking is making this tag a snippet where I only need to add the header/footer.cfm templates as an include. That way for different sites I could just insert the snip and include the site-specific templates.
This tag thought process is quickly leading me toward a UDF study.
I wouldn't do it. I mean, if you have different sites, why not just use different custom tags? You can have a layout.cfm for site A, and another one for site B.
Ya, it is very little extra coding and I can still create the generic snippet and tailor it for each site. I have been studying your "datatable" tag, it is complex to me at this point but as I iterate through it some things are beginning to come clear. Have you ever written any articles about this tag in particular? I was searching your blog but did not find anything.
D.
No, I haven't. When I do my custom tag preso in a few months I'll cover it. Although as a warning, I may slack a bit during the holidays.