Posts tagged Wordpress

Week 118

In retrospect I probably shouldn’t have expected to hit the ground running when travelling with a one year old. Dealing with one’s own jetlag can be bad enough, but dealing with another person’s increases it all exponentially. I’m quite pleased, then, that I got as much done as I did last week. I’m particularly grateful to the proprietors of Sparrows and Madcap for their tolerance of my hours of wifi usage.

The main phase of the big wordpress/government consultation project for Digital Public is wrapped for now. There’ll be a little more work on that after Christmas once it’s been fully put through its paces, but for now it’s good to have that off my plate. Work on the Greenbelt management system is settling down to just tidying up a few loose ends. Drapno launched with a party I sadly had to miss. And I can finally stop and think a bit and do some much needed admin.

That’s why this afternoon involved many console windows. Over the years I’ve become responsible for a lot of servers and I’ve been working hard to reduce the amount of time it takes to manage them. I’ve got a loose assembly of parts that (munin for activity monitoring, god for process monitoring, pingdom for a few key sites, capistrano shell for applying updates, apticron to keep on top of package upgrades) that are working pretty well, but a good chunk of today was spent bringing a few configurations in line and upgrading some packages to make the system hang together better.

The other big activity at the moment is business planning. I’ve never really done much of that, but after a hectic year it seemed sensible to look back through the past months’ projects and accounts and get a better sense of where the work’s coming from, what areas I want to be focussing on, and how best to grow things in 2010. I’ve got some vague ideas but looking at the data may reveal some things I’ve missed.

So between that and some much needed cleaning up of side projects (it’d be good to get on top of all the wordpress plugins I’ve released this year, really put my Palm Pre through its paces, etc) this won’t really be a week off. But it’ll be enough of a change of pace that there won’t be a weekly update next week. Maybe the week after.

Cucumber, wordpress and database_cleaner

I’m up to my usual using-ruby-tools-to-test-other-environments tricks, using cucumber and my wordpress activerecord classes to do acceptance testing against a highly-customised wordpress install.

I’m hoping to write a bit more about that soon, once I’ve put it through its paces a little more and cleaned up some of the code, but I wanted to quickly mention one of the key pain-points and an extremely handy solution.

One of the things I enjoy most about testing in rails is the handy tasks to prepare a blank database and the transactions that ensure the database is returned to that state after each test. Obviously that wasn’t going to work cleanly with wordpress since it doesn’t use ActiveRecord, but Matt kindly pointed me in the direction of Ben Mabey’s database_cleaner gem.

With that installed it’s as simple as adding:

require 'database_cleaner'
require 'database_cleaner/cucumber'
DatabaseCleaner.strategy = :truncation, {:except => %w[wp_options]}

to my

features/support/env.rb

file and my database is reset on each step. Combined with a few hooks to manage the configuration and load in the schema at the appropriate point, it’s turning into quite a nice little testing environment.

Talking to WordPress with ActiveRecord

As mentioned in yesterday’s announcement I’m pulling some content across from this blog (running on wordpress) into the new Ket Lai site (a merb app). I’ve found myself doing similar things a few times lately, such as on Only Connect (on which more, soon) and so have built out a selection of ActiveRecord models to help me talk to a wordpress database from a ruby app.

At Matt‘s urging (he’s been using them to move data from a legacy site), I’ve finally put those models up on github. Being a single file they arguably should have been a gist, but I’m reserving the right to reorganise them in future.

They’re far from complete in that there are lots of validations I could have added in, named scopes that would probably be handy, and loads of convenience methods that some might like, but hopefully they’ll be of use to someone and evolve over time.

(on the subject of wordpress, I’m glad to see the addition of changelogs to the plugin directory – being asked to upgrade plugins without any idea what’s changed has long been a bugbear of mine, so hopefully this will resolve some of that)

WordPress and “Pathless Categories”

I’m working on a wordpress project at the moment, and pushing that blogging engine quite a bit further than I have before. We’re going to be using categories very extensively and one of the first tasks has been to allow category paths without any preceding /category/ or the like. By default, wordpress wants the category with a slug of ‘case-studies’ to live at:

/category/case-studies

but we want it to be simply:

/case-studies

So far, so straightforward. I installed the pathless-category-links plugin and all was well. Until I started using subcategories. All subcategory links started returning 404s. It seems I’m far from alone in that problem, but I’ve not yet seen a solution offered, so a little digging was required.

What was happening with subcategories (at least in my setup) was that the wordpress method that parses the query string was identifying the top-level category name as the category name and the subcategory name as the ‘name’ (ie. the post slug to look for). What was needed was a check to see whether that ‘name’ maps to a category slug and if so, correct wordpress’ assumption.

The code I’m using is:

if (! function_exists('jys_pathless_category_links_query_string')) {
  function jys_pathless_category_links_query_string($qs) {
    parse_str($qs, $query_vars);
    if (isset($query_vars['name']) && get_category_by_slug($query_vars['name'])) {
      $res = array('category_name' => $query_vars['category_name'] . "/" . $query_vars['name']);
      return http_build_query($res);
    }
    return $qs;
  }
}
 
add_filter('query_string', 'jys_pathless_category_links_query_string');

(NB: This will break if you have permalinks set up as recommended by the plugin author (‘/%category%/%postname%’) and a post in your top-level category with the same slug as your subcategory. But hopefully that’s rare enough that we’ll be okay!)

Hacking wordpress to support per-post banner images

post-bannersI seem to be spending a lot of time with wordpress at the moment. It’s become so ubiquitous that it often makes far more sense to set it up and integrate with an existing app than to set up some other blogging system and re-train users. As a result I’ve been writing a few wordpress plugins. Most of them are too specialised to be worth sharing, but one seemed worth opening up…

Implementing a (not quite public yet) design recently I had need of a way to specify a banner image for each post. While wp has pretty good support for adding various media into the body of posts, this needed to sit outside the post body.

I whipped together a quick plugin to handle uploading a banner and storing its details in the metadata for the post. It was a simple process, nicely self-contained, except that the post edit form doesn’t have the appropriate enctype=”multipart/form-data”. I looked around for any hooks that would allow me to cleanly add attributes to the form tag, but in the end resorted to editing wp-admin/edit-form-advanced.php to add it.

I’d hoped that there’d be time to find a cleaner way to do all this before telling people about it—perhaps some javascript that hooks into the existing media selector but allows it to populate a custom data field?—but it hasn’t, so I’m throwing it out there to the wider world as-is. The code is at github. Feel free to take it and use it as-is, to fork it and update it to be a better wordpress citizen, to email me patches to apply to my copy, or even to employ me to spend more time cleaning it up! Either way, it deserves to be out in the open and hopefully it’ll be of us to somebody besides me.