On several occasions I have had the need to modify a page's <TITLE> tag after
it has already rendered. Most commonly, this occurs when a Content
Management System is generating the template. For example, a news article site:
index.cfm
<cfparam name=”url.id” default=”” />
<cfquery name=”getNewsArticle” datasource=”myDSN”>
SELECT id,title,body FROM NewsArticles
WHERE id = <cfqueryparam value=”#url.id#” type=”CF_SQL_VARCHAR” />
</cfquery>
<cfoutput>
<h1>#getNewsArticle.title#</h1>
<p>#getNewsArticle.body#</p>
</cfoutput>
In this example, a news story ID is passed into index.cfm and a story is displayed. With this code, every page will still have the same thing in the <title></title> tag of the template. Of course, I could go into the template and add conditional code to detect the ID and display a different title based on the ID. However, you don't always have access to the template, and in many CMS cases, the template will not run ColdFusion – it may be stored in a database or html file.
So, I wrote this custom tag to reset a page title anywhere in the code.
resetpagetitle.cfm
<cfif thistag.executionmode IS “start”>
<cfscript>
pageContent = getPageContext().getOut().getString();
getPageContext().getOut().clearBuffer();
pageContent = ReReplaceNoCase(pageContent,”<title>.*</title>”, “”, “ALL”);
writeOutput( pageContent );
</cfscript>
<cfhtmlhead text = “<title>#htmleditformat(attributes.newTitle)#</title>”>
</cfif>
An modification of the example above that changes the page title:
index.cfm (modified)
<cfparam name=”url.id” default=”” />
<cfquery name=”getNewsArticle” datasource=”myDSN”>
SELECT id,title,body FROM NewsArticles
WHERE id = <cfqueryparam value=”#url.id#” type=”CF_SQL_VARCHAR” />
</cfquery>
<cf_resetpagetitle newTitle=”#getNewsArticle.title#” />
<cfoutput>
<h1>#getNewsArticle.title#</h1>
<p>#getNewsArticle.body#</p>
</cfoutput>
This will examine the buffer, strip out the existing title tags, then replace them with your new title tag and continue processing the page.
Great code, thanks so much :). I saw your blog post in my RSS reader last week and found a need for this today. I made some adjustments to your code to better suit our coding style here at work:
title.cfm:
.*“, “”, “ALL”) />
#pageContent#
This allows you to execute it like so:My Page Title . That makes it more HTML coder friendly. Again, nice work, and thank you.
Dan
How about… no title for the base template, and then you can use to add the title anywhere in your code later.
@Henry – Yes, that works, but it assumes that you have control of the template and the template is not being used for other purposes. That is not always the case. Sometimes the designer controls the template… and sometimes the template might have a title for use on general pages, but you are developing a database-driven page that needs to have dynamic page titles. This tag overcomes those issues by removing the existing title.
I can see how this would be useful if, as you said maybe you don’t have control of the template. However, I don’t really see this as being a common problem so here is in my opinion a better alternative for those who do have control over there template.
In the template custom tag you can write a attribute for the title tag. With the default title tag in the area where it say’s default. This would go in the top of the custom tag.
Then later on in your custom tag where you would put the title put something like this…
#attributes.pagetitle#
What this does basically is check to see if you’ve specified a page title through one of the custom tag attributes, if you haven’t it will default to the default page title if you have it will feed in the page title through the custom tag.
Usage Example
My Webpage Content
Thanks to both the original author and Dan. Nice efficient way of getting the job done.