framework

Automated backups to S3

Wrapping python-boto in scriptable magic to back up your websites to S3

Simon Willison put together an excellent short-and-simple backup script over a year ago now, and I've used it intermittently to make backups. It takes files, whole directories, or the output of shell commands, and wraps it all up into a datestamped gzip file, before sending the whole thing up to an Amazon S3 account. It's a nice little piece of kit, in other words.

I found that it worked mostly fine, although it was (a) fiddly to run as a cron and (b) threw occasional errors which I wanted to fix. These two things together meant I wanted to do some proper development on the script and keep track of it.

I wrote a wrapper to help setting up cronjobs, which means it can be scripted using config files in the user's home directory and . I then decided on a whim to commit all of this to github , which is the online home for a community that's been set up around the git versioning tool. As befits a DVCS tool, git has spawned a community which is multithreaded and agile and most of all very friendly, with all free repositories available to the public and everyone able to fork off everyone else.

The repository was still a bit empty, as out of respect for the original coder I didn't commit backup_to_s3.py with everything else. Then, very kindly, Simon agreed to let me bundle his script with everything else, so you can now check out (clone) the "Configured S3 Backups" repository and follow the README to get scripted backups up and running fairly speedily.

I'd love for people to give it a try and offer some feedback. I definitely want to squash bugs and would also welcome new functionality. But the joy of git and github is that if I don't want to implement any extras, then other programmers can go ahead and

In summary? Configured S3 Backups: give the script a try. Git: give DVCS a try. And github: give DVCS-based online community building a try. Message ends.

Render any block in Drupal 5

Blocks are a bit neglected in Drupal: here's one way to use them more flexibly

Blocks aren't what you might call "first-class citizens" in Drupal 5 or 6 (or 7, as far as I'm aware). Block functionality is provided by a range of functions and database tables, but ultimately there's no thingness, no Ding an sich tying them together as an object the way that a node of content or a user might be.

Annoyingly, there's no function in Drupal 5 to grab a block and render it. You can render a region, a block container which then makes a number of decisions for you about what blocks should appear in it. Blocks can in principle be uniquely identified by (a) the module which provides the block through its implementation of hook_block() and (b) the "delta", the unique (potentially non-numeric) ID for each block in a given module. Yet there are no functions in the core block module to handle this.

One option is to move to Panels, which I'm doing for this site. Yet if your existing site is heavily based around blocks and regions, implementing Panels can be a lot of overhead just to render a single block in a template.

Here's a function which returns a single block, given the module name and block delta. It's an abstraction from block_list(), the function which returns all the blocks in a given region. You can put this in a shell module with an info file (see the previous post on theme preprocess hooks in Drupal 5 for how to quickly set up an otherwise empty module) or if you're not comfortable with that you can always name it accordingly and put it in template.php

/**
 * Get a single block for themeing
 */
function mymodule_get_block($module, $delta) {
  // User roles mean blocks are still invisible if the user
  // isn't permitted to see them
  global $user;
  $rids = array_keys($user->roles);
  $placeholders = implode(',', array_fill(0, count($rids), '%d'));
 
  // This is still cropped from block_list() , but newlines added
  // for legibility and blogposting
  $result = db_query(
      "SELECT DISTINCT b.* "
    . " FROM {blocks} b LEFT JOIN {blocks_roles} r "
    . "   ON b.module = r.module AND b.delta = r.delta "
    . " WHERE (r.rid IN ($placeholders) OR r.rid IS NULL) "
    . "   AND b.module = '%s' "
    . "   AND b.delta = '%s' "
    . " ORDER BY b.region, b.weight, b.module", 
    array_merge($rids, array($module,$delta)));
 
  // Assemble block info from the module
  while ($block = db_fetch_object($result)) {
    // Invoke the block hook in the supporting 
    // module and convert the return array
    $array = module_invoke($block->module, 'block', 'view', $block->delta);
    if (isset($array) && is_array($array)) {
      foreach ($array as $k => $v) {
        $block->$k = $v;
      }
    }
 
    // Swap in any user-defined title in admin interface
    if ($block->title) {
      $block->subject = $block->title == '<none>' ? '' : check_plain($block->title);
    }
 
    return $block;
  }
}

Once this is safely out of the way you can grab and render a block. The following code grabs the fourth block that you ever created through the block admin interface (the "block" module is the "maintainer" of those blocks, and the blocks are numbered starting at zero, hence "3"):

<?php print theme('block', mymodule_get_block('block', 3)); ?>

This is a bit unsafe, though. What if you disable mymodule? The template will break, and depending on your server configuration your visitors might see a pretty ugly error. So use the theme preprocess hooks trick. If you want the block to show in node.tpl.php then you're going to have to bite the bullet and put the bigger code snippet above in a module. Then, in the same module, you can write a hook_preprocess_node as follows:

function mymodule_preprocess_node(&$vars) {
  $vars['myblock'] = theme('block', mymodule_get_block('block', 3));
}

Then you can put just the bare variable in your node.tpl.php, which is much safer:

<?php print $myblock ?>

Turn off mymodule, and this just prints an empty string.

So, ta-da, blocks are now better exposed in your Drupal backend, for you to use in different places in your themeing. Unfortunately that still doesn't make them first-class citizens: they can't be categorized or given an "owner" i.e. an associated user ID; they can't be made to link to nodes in the same robust way that nodes can link to each other with node reference; they certainly can't have any CCK fields hung off them. But, humble though blocks are, they've still got some life left in them yet.

Blog category:

Basic theme preprocess hooks in Drupal 5

You can move much of your theme logic out of template.php in Drupal 5, by following Drupal 6 code patterns

One of the useful aspects of Drupal 6's themeing is theme preprocessing. This occurs in between a module (or Drupal core) calling theme() and rendering the actual template file (or function), and arbitrarily alter the variables passed between the module layer and the theme layer. In this way preprocess hooks act much like Django's context preprocessors, providing ways for modules to "communicate" at the point of themeing.

Drupal 5 doesn't have any preprocess hooks, unfortunately. All it has is the function _phptemplate_variables() in your theme's template.php. That's the sole instance of theme preprocessing in D5, and this bottlenecking means that the function quickly becomes the dumping ground for all of your site's pre-theme logic. Even if you're a module developer, of any level of experience, there's no incentive to factor this code out elsewhere: you just replace it with whatever the module function's called anyway, and your site becomes more brittle because of it.

With that in mind, here's how to free up your D5 theme preprocessing in a reasonably Drupalish manner. We'll use a helper module, and call a single function, safely from within your template.php. That function will replicate the basics of D6's theme preprocessing and let you start writing D5 modules with preprocess logic in them.

helpd6.info

First your helper module needs a .info file. It doesn't need to have very much details in it, but here's a sample file:

name = D6 forward-compatibility functions
description =  D6 functions, like theme preprocessing

helpd6.module

Next, here's the module in its entirety. Once you've saved this and the .info file into a directory called helpd6, in your site's modules directory, you should be able to enable the module in your Drupal administrative pages.

<?php
/**
 * Implementation of basic theme preprocessing
 */
function helpd6_implement_preprocess(&$vars, $hook) {
  // module_invoke_all passes by value
  // So assemble function name and invoke ourselves to pass by reference
  foreach(array('preprocess', "preprocess_$hook") as $stub) {
    foreach(module_implements($stub) as $mod) {
      $fn = $mod . "_$stub";
      $fn($vars, $hook);
    }
  }
}

Note we omit the closing PHP tag. And note also that we put an ampersand by $vars. This means we get the "real" theme variables object to play with, not a copy, so that all our logic can modify that "real" variables object and it's reflected by the time Drupal gets round to themeing.

template.php (excerpt)

Finally, this snippet ties everything together: it calls your helper module from the theme's template.php. Put it at the very end of the _phptemplate_variables() function:

function _phptemplate_variables($hook, &$vars = array()) {
  // ...
 
  // Finally, run preprocess hook functions
  function_exists('helpd6_implement_preprocess') 
    && helpd6_implement_preprocess($vars, $hook);
 
  // Now return variables
  return $vars;
}

You'll see that it checks the function exists first. You could check with module_exists('helpd6') too, but we're aiming for as robust a setup as possible, so best check the function exists rather than the general module.

We also return the variables. In practice, referring to &$vars in the function declaration means they get merged in situ, but in principle the function's definition on api.drupal.org requires the variables array to be returned. So changes inthe PHPTemplate engine might stop the &$vars trick working in the future.

Implementation

You can now implement either hook_preprocess or hook_preprocess_TYPE hooks e.g. hook_preprocess_page. These behave pretty much exactly the same as Drupal 6 preprocess hooks.

As an example, let's say that some nodes on your site have an "author" field. This might be different from Drupal's concept of node author e.g: the node might be created by an admin user, but contain information for a book or other publication; the book itself has an author, who could be anybody in the world, alive or dead. Our site also contains a biography node for each author, so we'd like to have the relevant biography present in the theme layer, to list the biography alongside the book.

Here's a "module"---again, just a single function---that accomplishes just that with the aid of our helpd6 module. It should be self-explanatory, but have a look at the comments for more details.

<?php
/**
 * Implementation of hook_preprocess_node
 */
function authorbiog_preprocess_node(&$vars) {
  // Two possible sources for a biography node:
  // 1. the author is a site user - CCK user ref field
  // 2. otherwise, use a CCK node ref field
  $this_node = $vars['node'];
  $author_uid = $this_node->field_drupal_author[0]['uid'];
  $author_nid = $this_node->field_offsite_author[0]['nid'];
 
  // Load the author's biog into the theme variables
  // (Could use Content Profile to help with this)
  if ($author_uid) {
    $biog = node_load(array('uid' =>$author_uid, 'type' => 'biography'));
  }
  else if ($author_nid) {
    $biog = node_load($author_nid);
  }
 
  // Theme preprocess hooks should ALWAYS make the HTML safe
  // Don't rely on .tpl.php files to filter out possible bad markup
  $biog && ($vars['biog'] = check_markup($biog->body, $biog->format));
 
  // &$vars has been passed by reference, so we don't return anything
  // But you can now access the biog (if it exists) in node.tpl.php as "$biog"
}

You can now access the biography text in the theme layer. Note we don't pass down the whole node: we could, but it's safer to pass down filtered HTML, to avoid any possible security holes. In general, it's the job of theme preprocess hooks to handle HTML security, because you never know where else that HTML is going to end up being rendered.

What's important to remember is that this code, and many other snippets like it, need no longer live in your template.php. It's now in a module. It's something you can turn on and off, just like a module. And it's something your themer need never worry about: that logic is now safely hidden behind the scenes, leaving template.php as a theme helper, what it's meant to be. You don't even need any control logic to determine $hook, because module_implements() and the naming conventions do that for you.

Summary

Drupal 5 themeing will never be as versatile as Drupal 6 themeing. But standard code patterns---especially "Drupalish" ones---can go a long way to abstracting out into modules much of the theme preprocessing that Drupal 5 would otherwise force you to do in your theme layer. The more logic you move out of your theme, the more robust it gets, and the easier it is for a non-developer to maintain.

Blog category:

Building pages in Drupal with Panels

Panels and panes are like regions and blocks, done properly if a bit madly

When finished this site will implement several different layouts: blogposts, "static" pages, short "nuggets", blog archives, taxonomy listing and probably a bespoke front page. Although these will all have the same underlying seven-column layout, that can still present some problems that are usually solved in Drupal with many different theme files and a lot of "regions" in which you can put "blocks" of content.

Regions and blocks have serious limitations, though. For example, any one block---say the most recent posts from the blog, or a feed from Twitter---can only be placed in one region, although it can then be made to appear and disappear on other pages based on URL or (dangerously) bespoke PHP embedded in the database. There are modules which replicate blocks, to try to circumvent such problems. Following merlinofchaos' great talk at, once again, DrupalCon Paris 2009, I decided to use Panels and panes instead of the core Drupal region/block system.

It was touch and go initially as to whether I was going to scrap it all and start again with blocks and regions or not. I managed fairly quickly to assemble custom pages for nodes of a few different types, but then had real trouble working out the subtleties of getting custom pages together for existing non-single-node content. Panels and its associated CTools developer framework concentrate far more on front-end functionality than ease of backend user experience. That's a shame, as the most important take-home message of prioritizing user experience is that hidden functionality might as well be no functionality at all. But as with most of these things---api.drupal.org springs to mind here---the first time is the worst, and once you know what you doing, you, well, know what you're doing.

Panels lets you divide up a page into just those panels. A set of standard URL matches come with Panels as "pages" you can enable, but you can also add new pages at new URLs. In terms familiar to Drupal templaters they take over the $content variable in the page templates, leaving your existing block regions available if you still want them. So when you enable panels, you get an extra menu item under Site Building called predictably "Panels". This takes you to a dashboard where you can enable or disable panels support for existing URL schemata (e.g. the node URLs at /node/%) and create variants which take into account e.g. the node type, so your blogposts can look different from your events. 

Slightly more subtly, though, if you want to enable panels on an existing view page... you can't. There's no mechanism for overriding the existing view page at e.g. /blog, like you can with a node page, and if you try to create a new panels page at that same URL then the system complains and won't let you do it. Instead, you have to create a whole new page and eventually discard or at any rate mothball the view's own page. Assuming you have a view at /blog, create a panels page at /blog_new; you can then add the view as a panel pane. You can use any one of the view's configuration variants (default, page, block etc.), not just the standard page variant. When everything looks happy, move your view to /blog_old and your new panels page to /blog.

Drupal also provides taxonomy listings at /taxonomy/term/term-id , which with Pathauto get aliased to /category/vocabulary-name/term-name. If you want to override a taxonomy listing, you can... but again there's a catch. Panels doesn't seem to provide you with any way of replicating the original content as far as I can see, and instead you have to build a view to replace the behaviour of the original taxonomy listing, and then put that into a pane where you'd want the original dumb taxonomy content to go.

When you create the view, you give it a first argument of "term ID". Then, when you add the view to the panel, in the modal lightbox titled "Configure view NAME (Defaults)", under the "Override title" box, you should have a setting where you can choose what to pipe through into your argument. Set that to term ID too. What you end up with is, as seems to always be the case with Panels, more functional and configurable than before, but it's harder to get to. Not just harder than letting core handle it: that's to be expected. But harder than you'd expect a GUI-rich many-developer-hour content-driven application to be.

Here's a summary of my panels the configuration:

Site building > Pages

 

  • System > node_view enabled
  • System > term_view enabled
  • Custom > page_blog created for the blog archives
Node template
  • Node type = blog and Node type = page variants
  • Two-column layout
  • Blog: node content in right column, with custom module providing tags in left column
Taxonomy term template
  • Two-column layout, no variants
  • Term description pane, then  taxonomy-filtering view pane, with view arguments taken directly from /taxonomy/term system URL
Custom view template
  • At URL=blog
  • Paging configured on view
  • View has its own page display variant, at another URL, to provide consistent formatting
CSS
  • Override all core column widths: these are a pain (whoever wants 33:34:33 columns?)
  • Custom CSS classes on some panels and panes, with custom module to also strip down markup

 

Overall Panels has made me feel like I have total control over what I want to appear where on my site. But the learning curve is steep and doubtless puts some people off; some of the greatest advantages come from being happy to get your hands dirty with PHP and the plugin architecture too, which I'll cover at a later date, and that's not possible or advisable for most Drupal end users. If I'd not had the luxury of stepping back for a few days every once in a while I'd probably have done it all in templating with regions and blocks. I'm glad I didn't, though, and I'm looking forward to iterating and perfecting my site's use of Panels.

Website redevelopment hiatus

I was nearly convinced it wasn't even possible for a while there.

The site redevelopment continues, but somewhat slower. Technology has been the main sticking point, and it hasn't been clear until today whether Drupal (plus the otherwise excellent Panels module) could support exactly what it was I wanted to do. It turns out that it is, but it's pretty difficult to work out exactly how to configure and build the necessary components.

Like working with so many other OS projects, implementing something for the first time in Drupal can sometimes be a frustrating experience; the second or maybe fourth time is so straightforward that you can hardly believe you ever had problems figuring out how it was done. Once I've got some of the key components in place, I'll have to write some howto blogposts alongside descriptions of the rationale.

Blog category:

Playing with card sorting

If something's worth doing it's worth doing in excessive and somewhat worrying depth.

If you want your website navigation to reflect the way that users might find your content, you obviously want it to serve their use cases and the terminology they're comfortable with. Ideally you'd do this by asking sample users to build your navigation for you, but in the absence of any willing volunteers one of the best things a site owner can do is card sorting.

It sounds pretty simple. Take the resources you want people to navigate around---so generally the furthermost leaves of your navigation tree: rich content pages, applications and the like rather than section indexes, which might contain navigational preconceptions---and try to assemble them into groups. Pretend they're written on cards---or, in a more agile way, actually write them on cards and shuffle them round a table---and try to assemble piles of similar resources. Closed card sorting involves predefining the groups, and is ideal for arranging new elements in an existing navigation and a good compromise for building a new navigation quickly; open card sorting is the same, but with no predefined groups. The results are better but it takes longer.

Card sorting really helps site maintainers escape preconceptions and build a navigational hierarchy that makes sense. So although it seems like overkill, this is actually what I have just done for this website. As with much that I'm currently doing towards the site rebuild, it's intended as a learning experience; a voyage of discovery, albeit taken on a Tonka truck within the safe confines of the wee sandbox that's my personal site.

My first pass yielded around fifteen resources---rather fuzzily defined, but including varied things like "my blog" and "a link to my Twitter feed"---which I wanted people to be able to navigate around. I arranged these in a single-parent hierarchy beneath six main headings: ongoing, literature, coding, academia and portfolio. However, this felt a bit forced (and some sections, especially "academia", are mostly opportunities for old documents to gather dust. I tried to imagine adding a more freeform vocabulary that cut across a lot of this, something like tagging, but there was something wrong.

Unsatisfied, I completely scrapped the single hierarchy and tried again. This time the list of resources had expanded to more like twenty, and I went for a more radical approach to grouping. Instead of trying to group objects as cards in a pile, so each card could only be in one pile, I tried to imagine from the start what groups plural they might fit into. Although I was still thinking in terms of menus, the parent terms were now more like categories from a taxonomy, with any menu item being available from several categories.

This resulted in seven terms:

tech, content, social, lit(erature), work, love and misc

This blog, for example, could fit under "tech", "content" and maybe "work", and would be accessible from all those places. My attempts at creative writing on Quiet little Lies could go under "content", "literature" and possibly "love".

As long as the number of objects didn't get too long (and objects didn't spread under too many terms) then these seven terms could still make sense to the user as a starting point, even if they found different things in multiple places. In fact, in the brave new world of folksonomies and tags, web users might be getting used to less hierarchical ways of navigating, so this might even pay off.

Drupal's menu system supports multiple or mixed hierarchies out of the box, but I preferred instead to actually use categories, and tie these to a menu with the Taxonomy Menu module. I might not follow that route in future, as it essentially only supports linking to Drupal's out-of-the-box category index pages, with content sorted in reverse date order, whereas I'l almost certainly want to do something nicer. But like card sorting itself it was a good springboard to getting things working and feeling happy with progress.

For now the hierarchy is implemented with dummy content, but I hope to fill it out more---and then expose the navigation---in the next few days. Right now it's just nice to see things starting to come together. Also, having seven top-level terms fits in rather neatly with the design decisions I've already made: more on those later.

Importing from Wordpress to Drupal

The initial import from Wordpress was much easier than then having to run two blogs alongside each other for two weeks.

The first stage of building this site was to import the content from the previous site. Well, the first stage was actually to set the site up: to install Drupal and enable the relevant modules. At Torchbox we've got a custom install profile that does a lot of this for us, installing and configuring relevant modules and creating users and roles. The actual company profile does a lot more work than I needed, in fact, and I've had to pare it back a little so that I've got less to maintain and worry about.

Importing content from Wordpress was largely handled by... the Wordpress Import module. There's a Drupal heuristic that, if it's a problem that a few people have encountered in the past, there's probably a module for it. Wordpress instances provide an XML export file called a WXR file, which you put on the filesystem and the module can convert content, freetext tags, the category hierarchy and users/authors.

The one tweak I had to make to the module was required to import the article summaries or excerpts, the little "humourous" quotes that are intended for blog listings. These were present in the WXR file as the <excerpt:encoded> element, and the Wordpress Import module contains a nice utility function that meant I only had to add this code at around line 621 to bring in the excerpt as a CCK field:

$node["field_summary"][0] = array(
  "value" => wordpress_import_get_tag($post, 'excerpt:encoded'),
  "format" => $params['format'],
);

Overall importing from Wordpress was pretty smooth---thanks to both Wordpress and Drupal, to give both technologies their due---but having content on a beta site is a double-edged sword. It's great to be able to see broadly how the site is going to look when it goes live, with everything in place; on the other hand, it's disappointing to be able to see broadly how the site is going to break when it goes live. Content showed up all sorts of little bugs: missing, slightly quirky CSS formatting you'd forgotten about; oversensitive output filters; slightly wonky imported URL aliases that needed a visit to the database to fix.

As I iterated and tweaked the configuration on the Drupal site---with content already in place---I had effectively frozen the site development, and could no longer roll back and re-import as it would lose my configuration changes. The import itself meant that for a week or so I was running two sites in parallel, writing blogposts on both, and getting a bit flustered about it all.

I think it was the right, pragmatic decision to do that, even though it initially felt like a lot of overhead: writing some sort of module to do the configuration changes was possible, but didn't really suit the way I wanted to fiddle with the site rather than run a set of fixes; importing at the very last minute would have meant I'd not have found most of the little irritations until they were publicly visible; not putting content on the blog for a week wasn't really possible, what with Oxford Geek Night 14 rumbling on, and our most excellent sponsors all clamouring to give us stuff. I just wish, as always, that I'd had twice as much time to do it all in.

Migrating to Drupal

Well, that sort of worked. What next?

I've just migrated my personal website to Drupal. By this I mean: I've just migrated my personal blog to Drupal. The rest of the website will have to wait for 404 reporting to roll in, and for me to build a new site structure around what I want to appear here.

My move to Drupal was the result of a number of motivations. The fact that I'm a senior Drupal developer at Torchbox means that the historical accident of me using Wordpress looked a little odd. Not only should I be "eating my own dogfood"; it also makes sense for me to have a personal site using the technology I implement most often at work, so that I can build on lessons learned in each arena, when I'm programming in the other.

There's also the issue that keeping up to date with two major open-source CMS projects was becoming tiresome. Almost every weekend Wordpress would always need an update, or Drupal would; or both. It makes sense to only have to keep track of one set of security issues, and the fact that I'm already running N Drupal sites off this single instance of the core codebase, that the core is therefore shared across all sites, means that there's little overhead in upgrading N+1 sites instead.

But most importantly I think I have to capitalize on how much I'm starting to like Drupal as a framework---to appreciate the ways in which the deep core works, in cacheing, themeing---and not just as a means to an end at work. Maybe this way I'll be able to play more with Drupal, work out where its hidden strengths and weaknesses are, and just get to play a lot more with a new toy.

Because the site redevelopment is a work in progress, aiming to work out whether or not Drupal works best if you can build a solid backend core first and theme and design it later, I've taken a screenshot of the site, immediately following migration. For posterity's sake. Let's hope I won't recognize it in six months' time.

Blog category:

Get reacquainted with Verity and Jeremy, your UX chums

You might claim that neither of them actually exist, but then they said that about the Druplicon and I totally met him.

As the Drupal 7 code freeze approaches, D7UX is gearing up for final rounds of testing: like much of Drupal's collaborative structure, this will be crowd-sourced. Get involved! You can help Drupal usability!

Anyway, Leisa discusses the next steps to be taken:

a) we need to finalise scripts and make them available to people who wish to conduct testing
b) we need to resolve the issue re: a testing theme, and
c) we need to ensure that drupalusability.org is ready to receive feedback from multiple sources

I'm pretty late to the full-on D7UX party, but tangential to (a) it just occurred to me that we would find it useful anyway to have the Verity and Jeremy user "sketches" in a more persona-like format. That way, it'd be easier to "read" the scripts in the mindset of Verity or Jeremy, and get more of a feel for whether or not their choices and observations are believable within their character.

Below are Verity and Jeremy, in a more structured breakdown similar to the one Torchbox use for in-house user personas. (I've used a bit of artistic licence to pad them out a bit, but they probably still should be considered far more like sketches than personas. As there's only two of them they have to cover quite a lot of experiential "ground" as you run through the test scripts, so they're bound to be a bit vague.)

Content creator

Name
Verity
Age
Late 20s
Job
Part-time administration assistant for a cancer support charity

Experience

  • Not a developer
  • Proficient with the MS Office Suite (Word, Excel etc.)
  • Uses Facebook and email
  • Hasn't really used Macs
  • Doesn't "get" things like Twitter or Spotify

Motivation

  • Verity works part-time while she completes her Social Care Diploma
  • Website is one of many tasks in job
  • Writing content, let alone building a site, isn't high on her career priorities
  • Update "news" every week and small ad-hoc content updates
  • Often interrupted by the phone and other staff while she is updating the website
  • IT consultant that Verity can call: but she likes to avoid doing this

Summary

Verity wants:

  • To be able to complete her website updates quickly
  • Straightforward workflows, without her getting confused
  • confidence that she’s knows where she is and what she’s doing at all times

Non-technical site builder

Name
Jeremy
Age
35?
Job
Social software consultant

Experience

  • Not a developer
  • Researched MySpace, Bebo, Facebook etc. for job
  • Knows of YouTube and alternatives e.g. Vimeo
  • Blogs, uses Twitter, photos on Flickr
  • Has a smartphone?

Motivation

  • Works with medium to large organisations to help them understand how social tools could help
  • Recommends tools that they should use and how they should be implemented
  • Frustrated because it is difficult to customise existing tools to suit his clients
  • Would love to have the ability to ‘build’ a site that would meet his client’s requirements
  • his technical skills are not great – for example, he can edit some PHP code; he understands what CSS is and what it can do, but he’s never written much himself.

Summary

Jeremy wants:

  • to build rich and flexible sites
  • easily discoverable functionality
  • freedom from PHP code or Drupal internals

Slightly less live from DrupalCon Paris

If you'd been on the Rue de Cannettes last night, you'd be less live too.

DrupalCon Paris has begun in earnest, with Dries' state of Drupal talk this morning followed by a lot about Drupal 7. As I've not been closely involved in D7 it's been a real eye-opener. From our clients' perspectives, the most important parts---D7UX and IA changes---are still not settled, but as a developer I'm excited by so much of what's been updated or improved (or, in some cases, removed entirely). Also interesting was Dries' emphasis on "production-ready" being some time after D7's release: it's a very pragmatic viewpoint, to accept that the release of a new full version core is not what makes Drupal truly ready for big websites.

Much of the changes do actually impact on clients: they help to bring in things like content delivery networks (e.g. Amazon S3) more easily, and improve permissions systems to the point where there's less custom work required to get things to do what you want to do. In short, now that webchick's talk has convinced me that D7's going to be pretty exciting, it's time for us at Torchbox to convince our clients. Or at any rate get ourselves more familiar with D7, to try to ensure smoother transitions of our development teams to the new ways of working.

I've been trying to keep up the live blogging of the event, although webchick's lightning-fast delivery nearly killed me. Props to Baris Wanschers for also live-blogging and hopefully filling in the gaps I've left.

Last night we all went to the Rue de Cannettes for various food and drink: crêpes and cider, beer, wine. There's photos on the Flickr DrupalCon pool among other places. Tonight is the Drupal UK meetup at the Le Financier pub (and then moving elsewhere, if I have anything to do with it.)

I'm also hoping to help out with the Saturday code sprint. Tuesday's sprint faltered a bit at the start (although it was fun when we had some raw issue numbers to work on and it all started moving) so I hope to help out in making Saturday's a bit smoother. The starting point could be Dries' "ten carefully crafted exceptions" so as soon as Bryan sticks the photo of that particular slide up then I'll make a start on that.

All in all, I'm having great fun. It only takes a few dozen developers to reach critical mass on enjoying yourself within the context of a project: Drupal has 800+ enthusiastic attendees at this conference, and you can feel the energy in the air. Or maybe that's the smell from the university kitchens.... Anyone want the rest of my boiled courgettes? I was thinking of becoming a freegan anyway.

Blog category:

Pages

Subscribe to RSS - framework