Fake SEO Urls with FW/1
I've been playing around with using SEO friendly URLs in FW/1 and hit a problem. What I wanted to is allow the details page for a product to be called with a URI which looks something like this:
http://myapp.com/index.cfm/product/start_me_up_rolling_stones
As FW/1 supports onMissingMethod in the controller I thought I'd be clever and extract the product id from the URL and display the page. Here's what my product controller looked like:
component
{
void function init( fw )
{
variables.fw = fw;
}
void function onMissingMethod( string MissingMethodName, struct MissingMethodArguments )
{
var rc = arguments.MissingMethodArguments.rc;
var slug = LCase( arguments.MissingMethodName );
rc.Product = EntityLoad( "Product", {slug=slug}, True );
if ( !IsNull( rc.Product ) )
{
rc.MetaData.setMetaTitle( rc.Product.getTitle() );
rc.MetaData.setMetaDescription( rc.Product.getSummary() );
variables.fw.setView( "product.detail" );
}
}
}
As you can see I try to load a product from the database using EntityLoad where the product "slug" is the action. So for http://myapp.com/index.cfm/product/start_me_up_rolling_stones, it will look for slug = 'start_me_up_rolling_stones'. This works fine, except that when I have a look at the SQL hibernate is generating, then the following queries are being run:
select * from products where slug = 'startstart_me_up_rolling_stones';
select * from products where slug = 'start_me_up_rolling_stones';
select * from products where slug = 'endstart_me_up_rolling_stones';
This is expected behavious and is mentioned in the https://github.com/seancorfield/fw1/wiki/Developing-Applications-Manual, however I clearly don't want this to happen. I could just check to see if the MissingMethodName starts with "start" or "end", but that won't work if my product URL starts with "start" or "end".
My solution was remove the onMissingMethod function from my product controller and instead, to trap the requested action in FW/1's setupRequest method in Application.cfc.
void function setupRequest()
{
if ( getSection() == "product" )
{
// calling dynamic product URLS
controller( 'product.detail' );
}
}
In the product controller I added a "detail" method, so now my Product.cfc looks like:
component
{
void function init( fw )
{
variables.fw = fw;
}
void function detail( rc )
{
rc.Product = EntityLoad( "Product", {slug=variables.fw.getItem()}, True );
if ( !IsNull( rc.Product ) )
{
variables.fw.setView( "product.detail" );
}
}
}
- Posted in:
- ColdFusion
- FW/1


Set up the following in your Application.cfc:
variables.framework.routes = [
{
'/product/:productslug' = '/product/detail/product/:productslug'
}
];
...and if you enter:
myapp.com/index.cfm/product/start_me_up_rolling_stones
...it will pass the key-value pair "product=start_me_up_rolling_stones" to product.detail.
I've got this running on a production site, and works beautifully.
Comment by Seb Duggan – May 23, 2011
Comment by spills – May 23, 2011
Comment by John Whish – May 23, 2011
Sean rolled out another feature in the last 24 hours - adding a setLayout() method.
Comment by Seb Duggan – May 23, 2011
We handle all of our pages generated like this so that:
/index.cfm?event=dentist.show&staffID=56
renders like this:
/San-Francisco/Dentist/Dr-Steve-Thomas-DDS/56
Much easier on the eyes, and all the "crap" of the index.cfm is removed out. Characters count when you're vying for clicks on google results!!!
Comment by Great Dental Websites – May 23, 2011