I love Perch, for some projects it really allows the most flexibility I’ve ever known from a CMS. For those of you not familiar, the crux is, you design a site with content and plug in Perch to make it dynamic, essentially you switch static content areas for perch tags to make them dynamic. Perch then picks up those tags and allows you to add/amend the content in the CMS rather than hard code it.
Anyway aside from the brilliance (and it really is) one thing I didn’t like was the messy urls in the blog app*. Retrieving a blog post on a landing page was fine and the documentation is incredibly clear but once you head into a full post the URL looks something like this:
http://example.com/post.php?s=post-slug
If you’re just plugging in content very quickly it’s okay but it isn’t the best it could be. There are a few ways of doing this and it does depend on your server set up. Feel free to give it a go but be warned, this isn’t a one-size-fits-all solution but it certainly should give you a clue as to what you’ll need to consider on your own install. These few steps also assume your blog page for retrieving posts is called ‘post.php’ as per the Perch examples.
To achieve cleaner urls I made two changes, one to my .htaccess file and one to the perch templates. There are other methods, but in haste this is what I fumbled together.
The aim is to change:
http://example.com/post.php?id=post-slug
to
http://example.com/post/post-slug
Step 1
First We want to get rid of the .php extension by amending the .htaccess file in your site root, if you haven’t got one, open a new file in a text editor and save it as anything you like, close it and rename it .htaccess from the Finder/Explorer window. Open your .htaccess file for editing and add the following:
RewriteEngine on
RewriteRule ^([a-z]+)$ $1.php [L]
This rule says ‘any amount of letters without an extension on the end, add ‘.php’. So now visiting http://host/post actually returns http://host/post.php . The [L] simply says ‘this is the last rule’
Step 2
Now we want to amend any existing hard coded urls on the site – as you’re using Perch you may not have to do much of this but if you have any internal links that point to .php files, take off the extension.
For example: href=“http://example.com/post.php” will now work without the extension ‘.php’ as simply href=“http://example.com/post”
Step 3
Back to the .htaccess rules. This rule handles the blog post urls. We want the user to see the clean URL not the query string so amend your .htaccess file to look like the following:
RewriteEngine on
RewriteRule ^post/(.*)$ post.php?s=$1
RewriteRule ^([a-z]+)$ $1.php [L]
Notice the additional line in the middle. This rule targets the post page directly, if the URL matches /post/some-characters turn it into /post?s=some-characters.
Perch is looking for a parameter called ‘s’ (if you’re using default examples) by doing this rewrite we show the user a clean url but the server still gets the ‘s’ parameter available for Perch. If your blog is run by something other than post.php, amend the reference accordingly.
Now if everything’s okay up until this point you should be able to go to http://example.com/post/post-slug and retrieve a post – if so, the rewrite is working. At this stage our only remaining issue is the Perch template, it’s kicking out links with the full query string, not the clean URL we’d hoped for.
Step 4
The next bit is up to you, we have to change the perch template format so that the template constructs link urls in the clean structure we’ve set up for.
You can either create a copy of the existing templates, write a custom query to retrieve posts and use your amended templates (recommended) or, if you’re not comfortable with that, take a backup of the any templates you edit and amend directly (not recommended but possible).
I would strongly recommend creating a your own templates these changes but if you’re not comfortable, take a back up of any file you change.
For each template you’re using you’ll need to find the element that constructs the url:
e.g in post-in-list.html: <a href="post.php?s=<perch:blog id="postSlug" />" rel="bookmark" class="entry-title">
Change the template structure to use your new clean URL structure:
<a href="post/<perch:blog id="postSlug" />" rel="bookmark" class="entry-title">
The Perch template will now render links in the desired format. Clicking them should direct you through to the post itself.
What we’ve done is abstract the query from the user to give simple and readable urls.
Hopefully you’ve followed along and the few steps described were easy enough to understand, if not please feel free to get in touch and I’ll do my best to guide you through anything you don’t understand.
*Please note I have in the meantime spoken to the guys at Perch and they have mentioned their reasons for including the query string by default and I completely agree with them. All set ups are different and one rule doesn’t fit all. If you’re attempting the changes I’ve described above, do take back ups and avoid doing anything that could break the default methods of the CMS.


