I have a lot of city pages for my site similar to this folder structure: example.com/colorado/denver.cfm
What I have been doing is to create a template called template-city.cfm that gets included in to each city page such as denver.cfm. So basically denver.cfm is just a tiny shell file and the real guts of the page is located in the template-city.cfm, so the thought is that I only have to change the template-city.cfm once and all the others pages like denver.cfm get updated at once.
But in order to do this I had to create tons of city pages within each state (which I automated with CFfile) but a red flag is going off in my brain telling me this is the wrong way to do it. Is there some virtual way to create these city pages and even state folders?
There are two ways of doing this. The first would be with a server side URL rewriter. Apache has this built in, and you can find options for IIS as well. The URL rewriter would simply map example.com/louisiana/lafayette.cfm to example.com/dyncity.cfm?state=louisiana&city=lafayette.cfm.
If you don't have access to the web server and you are using ColdFusion 8, there is no reason not to use onMissingTemplate in Application.cfc. Here is a simple example:
2 <cfargument name="pageRequested" type="string" required="true">
3 <cfset var city = listLast(arguments.pageRequested, "/")>
4 <cfset var state = listGetAt(arguments.pageRequested, listLen(arguments.pageRequested,"/")-1, "/")>
5 <cfset city = replaceNoCase(city, ".cfm", "")>
6
7 <cfinclude template="dyncity.cfm">
8 <cfreturn true>
9
10 </cffunction>
Given a request of some.com/louisiana/lafayette.cfm, the value passed to pageRequested will be a string I can parse using list functions. I grab the city at the end, and the state at the second to last position. At that point, what you do is up to your model. You would probably call a CFC method that would translate a state/city string to a particular ID value of a city in the database. In my example I just include a file that displays it:
I've included the application as a zip to this blog entry. You should be able to extract it to your web server, and then hit any URL. The only drawback is that .cfm must be in the URL.
If you wanted to support example.com/louisiana/lafayette, then you would need to use the URL rewriters I mentioned above.


Comment 1 written by Dave Dugdale on 9 December 2008, at 12:56 PM
Thanks for answering my question!
I really like your idea of using the onMissingTemplate method.
I have my own dedicated IIS box (with CF8) so the URL re-writer idea gets really complicated since I am not very good at writing regular expressions.
Thanks again.
Comment 2 written by Michael on 9 December 2008, at 1:41 PM
www.example.com/c.cfm/State/City
with c.cfm parsing out State and City off of it
The following function will get the State/City and then I can convert a List with the delimiter of / to an array and get the data off of this.
<cffunction name="getRHS">
<cfset path = cgi.PATH_INFO>
<cfset filename = cgi.script_name>
<cfif not findnocase(filename,path) >
<cfif len(path) gt 1>
<cfset path = right(path,len(path)-1)>
<cfelse>
<cfset path = " ">
</cfif>
<cfelse>
<cfif len(path) gt len(filename)>
<cfset path = right(path,len(path)-len(filename))>
<cfelse>
<cfset path = "">
</cfif>
</cfif>
<cfreturn path>
</cffunction>
Comment 3 written by TJ Downes on 9 December 2008, at 1:47 PM
Also, IIS7 has a built-in URL Rewrite. Finally.
Comment 4 written by Dave Dugdale on 9 December 2008, at 4:20 PM
I just added the files to my server and it worked perfectly.
Now I have to remember how the hierarchy works for the Application.cfc since i placed your files in a sub folder.
Comment 5 written by ajm on 9 December 2008, at 5:15 PM
Comment 6 written by Raymond Camden on 9 December 2008, at 5:18 PM
Comment 7 written by Matt Ondrey on 9 December 2008, at 7:22 PM
When the template can't find any relevant content it sends a 404 via cfheader statuscode so that the search engines don't think I'm running a spam doorway site.
Comment 8 written by Steve Withington on 9 December 2008, at 11:48 PM
Comment 9 written by Anthony on 10 December 2008, at 3:00 AM
Comment 10 written by Raymond Camden on 10 December 2008, at 5:53 AM
So sure, the non short version of the URL isn't so bad. I'm no SEO expert of course. I will say that it is less typing to do /state/city and it is something a non-techy would easier be able to remember.
Comment 11 written by Beth on 10 December 2008, at 7:10 AM
Comment 12 written by Raymond Camden on 10 December 2008, at 7:16 AM
Comment 13 written by Dave Dugdale on 11 December 2008, at 12:21 AM
For some reason I am having a tough time transferring my old Application.cfm to the new Application.cfc so I can use your cool onMissingTemplate idea for my URL structure.
The first thing I am trying to transfer over is the variables that are shared among all pages and all visitors of my site.
So I thought onApplicationStart function would be the best use for my global variables such as company name, but I can't get it to work.
Application.cfc file:
<cfcomponent output="false">
<cffunction name="onApplicationStart" returnType="boolean" output="true">
<cfset Application.companyname = "Joes Diner">
<cfreturn true>
</cffunction>
</cfcomponent>
Normal template:
<cfoutput> #Application.companyname#</cfoutput>
But I get this error when running the page:
Element COMPANYNAME is undefined in APPLICATION.
Sorry I am so confused on this, I have used CFC before in the past with much success.
Dave
Comment 14 written by Raymond Camden on 11 December 2008, at 6:57 AM
You should read the docs on Application.cfc. It will definitely help.
Comment 15 written by Raymond Camden on 11 December 2008, at 7:02 AM
http://www.coldfusionjedi.com/index.cfm/2007/11/9/...
http://www.coldfusionjedi.com/downloads/applicatio...
Comment 16 written by Dave Dugdale on 11 December 2008, at 2:53 PM
For testing I set it to 5 seconds and now I see how it is working.
Question do I have to use the "Application" prefix on all my Application variables such as <cfset Application.coname = "Daves Diner"> or can I do it like <cfset coname = "Daves Diner">?
Comment 17 written by Raymond Camden on 11 December 2008, at 2:54 PM
Comment 18 written by Dave Dugdale on 11 December 2008, at 3:06 PM
I am using your standard application file that you pointed me to earlier and finding very useful.
[Add Comment] [Subscribe to Comments]