For some time I’ve wanted to refresh the design here at damieng.com which evolved out of the Redoable theme with my own tweaks to colours, typography, images and background until it was almost my own.
Almost, but not quite.
As an engineer I prefer incremental improvement over a complete redesign but I was at the point where the code-base (HTML, CSS and PHP) was unworkable. Partly my fault, partly the sheer complexity of a general-purpose theme with wide-ranging plugin support I didn’t need.
These are the steps that helped me get to a clean minimal code-base that did exactly what I wanted and would like to share the experience for friends about to go through a similar process.
1. Decide on a layout
Getting layouts right across browsers can be tricky.
Thankfully a number of individuals have put together a number of reusable CSS frameworks that provide grid-based approaches to layout, compensating for differences in browser defaults and including some minimalistic styling.
These let you hit the ground running but they are not complete themes unless you’re into minimalistic design.
I’m not a fan of fixed-width sites that contribute to the years of wear on my scrolling mouse finger so settled on the Fluid 960 Grid System which scales a 12 or 16 column grid system out to the full browser width while being incredibly easy to use and tweak.
At this point you’ll want to copy the CSS they provide into your own development folder and take the existing HTML sample page and cut it down to the bare minimum of <head> and its necessary <link…> elements to setup the CSS plus the <body> and any intermediate child elements required to get the basic structure in place.
Now think about how many columns each section needs to cover and whether it should continue taking columns to the right or whether it should start on a new row after the existing section has finished.
Given I wanted the layout shown above I needed just three containers – the primary left area (red) would span 12 columns and would contain the branding, navigation and actual content. The right area (blue) would span 4 columns and contain the sidebar. As I didn’t want my footer too high on pages with small amounts of content I created another section (not pictured) that also spanned 12 columns but would appear after the content in both sections. Simply:
<body> <div class="container_16"> <div class="grid_12"> <a href="//damieng.com/" /> <ul class="nav" /> <div id="maincontent" /> </div> <div class="grid_4" id="sidebar" /> <div class="clear" /> <div class="grid_12" id="footer" /> </div> </body>
2. Add your content
Unless you’re planning on throwing away any of your content (not recommended if you have it), now is the time to drop in actual content, navigation and any chrome. At this stage real static HTML content is best – the combination of PHP, remotely uploading files and hooking in to dynamic content can really slow you down while you are trying to get the basics sorted.
The easiest thing to do here is to just view source a page on your blog and copy out the required blocks. For me this was:
- Two blog posts from the main page, they sit in the maincontent div above, each contained within a new <div class=”article”> so I can provide article-specific styling
- A brand new set of nested navigation elements created by hand based on the page structure – initially two levels deep to support the drop-down CSS menus
- My five sidebar elements – Search, Stay in touch, Topics, My most popular and Interesting finds
Bear in mind that you are going to need to keep the structure and content of your existing pages and articles unless you have the time to either go-back and edit each one or apply some bulk-changes via SQL UPDATE statements. For me, this meant keeping my post sub-headings as <h3> and sticking with my class=”alert”, class=”code” and class=”download” blocks I use for notifications, code snippets and downloads which required bringing some CSS elements in from the old theme.
3. Style the page
Design inspiration can come from many places – here are some best-of designs, portfolios and showcases to draw from:
- CSS Showcase
- 50 New Beautiful Blog Designs
- 70 Fresh and Inspirational Blog Designs
- 70+ Ultimate Round-Up of Free PSD Website Templates
Now you have some basic HTML and CSS displaying real content it’s easy to see what works and what doesn’t with minimal resistance to experimenting.
I was happy with the existing look and I plan on further tweaks now my code-base is easy to understand so for now took the basic colours, background and icons then adjusted the layout, spacing, positioning, wording and elements like the content metadata. This was also an opportunity to experiment with some CSS techniques available but considering CSS3 browser support is limited right now I kept this to:
- @font-face for headings – Font Squirrel have a great set of @font-face kits including fonts with the CSS snippets
- text-shadow for headings and hyperlink hover-overs to achieve a glow effect
- border-radius for curved blocks and navigation bar (also used prior to the redesign)
The result is something that looks quite unique on Safari and Chrome yet still looks good on Internet Explorer 7.
4. Convert to a theme
Now our CSS and HTML looks great as a single page we need to create a theme for the blog engine. This consists of several specially-named files to dynamically construct the page as required.
You can build this from scratch but a basic theme like Starkers ‘naked’ WordPress theme is recommended. Merge the layout and style of your theme with the dynamic tags that drop in content, navigation and titles in from the basic theme. A quick start would be to modify:
- header.php with your HTML up to opening your main content div but:
- remove <link type=”text/css”> elements to the CSS and replace with the one line <link> from the theme
- replace the static navigation elements with a call to a function to dynamically build it such as <?php wp_list_pages(‘depth=3&title_li=’); ?>
- links for shortcut icons and ensure they point to files that exist, you don’t want to be serving up 404 error pages every time
- meta tags – take the dynamic ones with <?php?> elements (content-type, description etc). from the theme and merge them with your sites existing ones if you have any
- sidebar.php with your HTML from closing the main content div through to closing the sidebar div
- footer.php with your HTML footer div (and in my case the preceding clear div) through to the end of the file
- single.php with your HTML that appears around each article with the necessary tags (like <?php the_content(); ?> taken from the naked theme)
- style.css with relative references to your CSS files and your new metadata, e.g.
/* Theme Name: DamienGNew Theme URI: //damieng.com Description: Minimalistic theme based on Fluid 960 Grid. Version: 1 Author: Damien Guard Author URI: //damieng.com */ @import "css/reset.css"; @import "css/grid.css"; @import "css/damieng.css"; @import "css/navigation.css";
Rename the theme folder and upload it to your blog in the right location – for WordPress this is wp-content/themes.
5. Test drive, tweak, rinse and repeat
Now you want to test the theme without interrupting the existing one so don’t go and set it to be the default just yet.
If you are using WordPress a few tips:
- WP Super Cache enabled sites – check Don’t cache pages for logged in users so you don’t see cached pages in the original theme pages or serve up pre-cached new themed pages for other visitors
- Theme Test Drive – lets you specify a new theme and what access level it applies to (e.g. 10 for admin) so you will see it while you are logged in for testing
- Page templates – leave them to last as WordPress will try to use them in the default theme too
- Keep an eye out for error_log files – they contain details of when pages failed
It’s worth testing your site in popular browser and operating system combinations from your own analytics or you don’t have any of your own stats check out usage share of web browsers at Wikipedia. The major engines are:
- Internet Explorer (Windows)
- WebKit (Safari on OS X, Chrome on Windows & Konqueror on Linux)
- Gecko (Firefox cross-platform & Camino on Mac)
- Opera (cross-platform)
Bear in mind that each browser can behave quite differently between versions – Internet Explorer 6 will likely render quite differently to 7 or 8.
Sites like BrowserShots can help by rendering your page on a multitude of browsers for you and present screen-shots (once the theme is live) to compare. Validating your HTML and CSS is a good idea because the errors and warnings it spots are the likely cause for odd rendering problems.
Now you see a single blog post rendered it’s time to go through the rest of the files and apply the same merging process before you sit back, smile and make your new theme the default.
It’s been a few weeks since I upgraded to WordPress 2.5 and whilst the upgrade went well it hasn’t been all plain sailing.
New and changed
Manage files removed
The Manage > Files administration function has been silently removed despite still appearing in the on-line documentation.
If you don’t have FTP access this was the only way to modify your .htaccess and other important files without installing additional software. I can understand such a powerful function could be abused but an option to turn it back on or even a warning about its removal in the upgrade notes/read-me would have been useful.
Hopefully somebody will repackage the old functionality into a plug-in.
New look administration
I’m not sold on the new administration theme look but Dean J Robinson has crafted a plug-in called Fluency that refines the styling.
Generally usability in the administration user interface is better, the write post screen makes a lot more sense and the category & tag management is more logical.
Auto update plug-ins
I love this new feature, it shows you when a new version of a plug-in is available and then lets you automatically update. It isn’t without issue however, specifically it:
- overwrites modified local versions without warning
- may go wrong (it “upgraded” my wp-PostViews to wp-DBManager)
- does not provide a roll-back or revert facility
Still it’s a v1 feature and I’m sure it’ll get some refinement in 2.6.
Live search broken (Redoable theme)
I’m not 100% happy with the output from Sociable right now but that can wait until my new theme is finished.
These weren’t caused by the 2.5 upgrade but once you start messing with one thing there’s always that urge to fix other things you know aren’t right.
Whilst testing my site I found XHTML compliance was broken. It turns out that Joost’s Google Analytics for WordPress incorrectly rewrites the hyperlinks when they parent another element such as an image. Putting on my PHP hacking hat I managed to fix it by editing the plug-in and changing the last line of ga_parse_link to:
return '<a '.$matches.'href="'.$matches.'//' .$matches.'"'.' '.$coolBit.$matches.'>'.$matches.'</a>';
My feed subscriber counts have been bugging me for a while as they jump up and down seemingly at random. In fact, it can be traced down to two things:
- If you base it on less than 5 days of activity you’ll get the weekend dip
Solution: Count 7 days worth of individual subscribers
- Google Reader etc. sometimes stop passing the subscriber count from time to time
Solution: Use single most recent multi-subscriber header for each service/feed in the last 30 days
If you want to do the same you need to edit the Feed Statistics plug-in and change the how_many_subscribers function to:
$q = "SELECT subscribers, CASE WHEN subscribers = 1 THEN identifier ELSE CONCAT(identifier, feed) END AS ident FROM ".$table_prefix."feed_subscribers WHERE ((subscribers = 1 AND date > '".date("Y-m-d H:i:s", time() - (60 * 60 * 24 * get_option("feed_statistics_expiration_days")))."' ) OR (subscribers = 1 AND LOCATE('###',identifier) != 0 AND date > '".date("Y-m-d H:i:s", time() - (60 * 60 * 24 * get_option("feed_statistics_expiration_days") * 3))."' ) OR (subscribers > 1 AND date > '".date("Y-m-d H:i:s", time() - (60 * 60 * 24 * 30 * 3))."' ) ) ORDER BY ident ASC, date DESC";
This should help but it’s not ideal with individual readers counted more than once if they change IP and groups counted as one if they are sharing an IP/NAT.
The change to WordPress from Subtext went without major hitch. This was great considering I was tweaking the design and articles right up to going on holiday (I wouldn’t do this in a professional environment but my blog is a sandpit for such dare-devil risk taking ;-)
Here are my notes on the experience.
Akismet is good but I prefer the invisible captcha that Subtext was using. I’ve gone from dealing with 1 rogue spam a month to 1-2 held for moderation a day.
The WordPress import format doesn’t deal with view counts. I wrote a query against Subtext to list them, a query in MySQL to identify article numbers then manually executed
UPDATE post_meta SET meta_value = meta_value + 123 WHERE meta_key = 'views' AND article_id = 456
For every article replacing 123 with Subtext’s view count and 456 with the WordPress article id. As my blog was previously on Blogger.com which doesn’t provide view counts they are a year or so lower than reality.
I chose a custom permalink format of /blog/%year%/%monthnum%/%day%/%postname% which gives //damieng.com/blog/2007/10/01/first-of-october for posts. This is similar to the old format of http://www.damieng.com/blog/2007/10/01/first-of-october.aspx but obviously has the file extension and www dropped. Apache’s .htaccess file made redirecting the old links a breeze which was important to me as my blog suffered big drops in Technorati and Google when I last moved from Blogger.com to Subtext. The required lines to achieve this, redirect /blog/ and keep the RSS going were:
RedirectMatch permanent ^/blog/archive/(.*).aspx$ //damieng.com/blog/$1 RedirectMatch permanent ^/blog/$ //damieng.com/ RedirectMatch permanent ^/blog$ //damieng.com/ RedirectMatch permanent ^/blog/rss.aspx //damieng.com/feed RedirectMatch permanent ^/blog/Rss.aspx //damieng.com/feed
The default editor is fast and for the most part okay although it lacks the ability to change from the default paragraph tag to headings, pre-formatted blocks, blockquotes etc. It also very annoyingly tries to be helpful by turning carriage returns into new paragraphs which would be fine if it was clever enough to leave <pre> blocks well alone.
There are still a number of things I want to do including further deviating from the Redoable theme. Lightening up the look somewhat perhaps with some soft gradients and alternative typefaces will go a long-way. I’ll also want to do a proper logo at some point as soon as I can decide what it should look like.
Being that WordPress is a higher visibility target Phrixus suggested hiding the wp-admin directory as an extra level of protection against automated vulnerability/brute-force attacks which I shall also try.
I need to speak to GrinGod about the download counting mechanism he mentioned too.
The original Blogger.com content from a year or two ago will be phased out/removed as it would appear it dilutes my page rank having almost-identical content elsewhere not to mention messing up traffic stats etc.
I have been planning on moving my blog off my little Windows Shuttle PC at home onto a hosted service for some time and the latest flurry of activity followed by DSL line meltdown was enough to give me the nudge I needed to get the job done.
Rob Conery provided a useful .NET/Subsonic app to make the transition from Subtext about as painless as possible bar the obvious one of going with a PHP based solution when I know .NET is a better technology.
I simply felt the .NET blogging engines didn’t give me what I want right now and yes, I know I should be contributing to them to get them where I want them but I’m just so busy on various projects that if I was coding a blog in the evenings I wouldn’t be writing on it. Hopefully the great, and no doubt equally busy, guys behind those engines will forgive my little foray into WordPress for a while.
The non-blog parts of the web site (yes, there are some, with downloads, fonts, cursors, little tools and a mini-biography) will be integrated with the site shortly and the theme will probably gradually change to something more me. I also want to add a few extra things, the tag cloud and identicons for a start.
The title of this post also has a second meaning… yes, I’ve put an offer in on a house and will hopefully be taking possession in around 6 weeks providing nothing goes wrong.
Your invite to the house warming party will be in the post…