how stuff works - smackfoo style.

As promised, I’ll cover some of the techniques used in the design, handling of URIs and the tricky htaccess rules all used to glue the whole concept of ’smackfoo’ together.

The weekend as a whole has been a massive learning experience - while there have been some frustrating moments, the results are far far better than I had originally hoped.

If seeing naked code makes you uncomfortable however, you might want to skip the rest of this post. Given that the wordpress community has it’s foundations in open source, I hope that sharing some of the code used will help others who choose to push the boundaries of what WP can do.

This is also another long post - don’t say I didn’t warn you. :)

Under the bonnet

There were some major hurdles to cross during cutting code for the new design1- not the least of which was breaking out of the problems changes to wordpress 2.1a. brought to the table.

To set the scene, I wished to pull just one post for the front page, 7 for paged and 10 for archives.

I was able to make use of the $wp_query tag, that has become quite a favoured tool in handling various WP db queries. In current use is the following query, where the post count is dictated by variable $count, which is set based on which page is in use:

<?php // set up the loop
$wp_query->set('posts_per_page', $count);
$wp_query->set('posts_per_archive_page', 10);
$posts_per_page = $count; $posts = $wp_query->get_posts();
if ( have_posts() ) : while (have_posts() ) : the_post(); ?>

This was a relatively simple way to ’set’ how many posts to display - if it’s an archive page then display 10 posts, else display $count. Initially $count was pre-set, using usual PHP markup, ie:

This meant archive pages provided 10 posts and the front page displayed one post.

Handling scenarios such as which page I am actually on, such as /page/2/ and context sensitive post loops proved to be quite the challenge however. For example, due to structural changes in WP 2.1a code, is_paged() and associated query’s such as $_GET['paged']; don’t quite work as expected (or indeed at all). You see, /page/2/ is not considered a page or an archive as far as the is_paged() tag is concerned.

It’s at that point I turned to the #wordpress IRC channel for some suggestions to the problem2. Charles Stricklin had also found similar issues when working on his page-jump plugin, which he thankfully had found a solution to.

Armed with his work-around I was able to construct a query to identify pagination and set the count accordingly:

<?php // set up the count variable
($count=1); $this_page = get_query_var('paged');
if ($this_page > 1) $count = 7; ?>

Voila - the count is set correctly prior to the $wp_query kicking in, i.e. if home - 1 post, if paged - 7 posts and if archive - 10 posts.

Handling the domain move

Part of the transition from dreamhost involved a domain name change - which in itself isn’t a massive task. Wordpress 2 sports a backup function and access to phpmyadmin made moving the db a relatively easy affair. One simply exports the SQL data out to a text file via the wordpress backup tool, ready to then import via phpmyadmin into the new host’s db.

With the database under control, it was time to focus on just how to redirect HTTP requests from the old host, to the new (mt) media temple based domain. Apache’s rewrite module is a potent beast that can direct requests in all manner of directions - directing requests from incoherently.net to smackfoo.com was handled by 301 redirect .htaccess rules:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !smackfoo.com$ [NC]
RewriteRule ^(.*)$ http://www.smackfoo.com/$1 [L,R=301]

The rules above filter the request to ensure the domain isn’t already smackfoo.com, stripes the old domain name, then passes the entire remaining URI to the new domain - for example http://incoherently.net/archives/123 would be rewritten as http://www.smackfoo.com/archives/123.

This works incredibly well as it triggers a 301 (Redirect Permanently)3 to the new domain. It maintains the whole URI, and helps stop 404’s that would occur if I simply did a standard non-rewrite redirect4.

However, to complicate matters I really wanted to better categorize sections of the blog. When I implemented the above, the redirect created a URI that didn’t exist, as I have implemented a new URI naming convention. Thus when a redirect occured: http://incoherently.net/archives/2006/04/15/designarama/ became: http://www.smackfoo.com/archives/2006/04/15/designarama/ which was invalid.

Through trial and error, I hit apon using a ‘filter’ to capture specific URIs, in this case the archives, and re-direct those alone to the new structure. If the URI is an archive, rewrite the base URI and redirect, else redirect as is. The result is the following rewrite rules:

RewriteEngine On
RewriteBase /
RewriteRule ^archives/(.+)$ http://www.smackfoo.com/chronology/$1 [R=301,L]
RewriteCond %{HTTP_HOST} !smackfoo.com$ [NC]
RewriteRule ^(.*)$ http://www.smackfoo.com/$1 [L,R=301]

Upshot

I’m still bedding things down and chances are pages will break temporarily while I re-organise.. however the results so far are very promising and to be honest, this is one of the better moves I have made. Wordpress makes database moves a synch and (mt) media temple have already proven to be very quick to respond to requests.

Colour me a happy chappy. :)

  1. This is by no means a how-to of template generation ()
  2. irc://freenode.net/wordpress is the place to be, boys and girls ()
  3. which will seamlessly redirect any lookup, including search engine results and RSS feeds ()
  4. RSS feeds are particularly sensitive to a non re-write redirect and will break ()

≡ This is a journal entry relating to the topics of , , , , , , .

Brendan Borlase is a Systems and Network Administrator living in Adelaide, Australia, having lived, worked and breathed Information Technology for over 12 years. Learn more.

Feedback is encouraged. If you would like to read more, consider subscribing to the regularly updated RSS Feed.