Some tweaks for a Drupal WoW guild site

26th May
2007

tempestraidspost.pngThe Tempest is was a World of Warcraft guild site built initially on Drupal 4.7 and recently upgraded to Drupal 5. It provides guild membership management via user accounts and roles, forums with public and private access, raid listings with sign-ups and other groovy stuff like private messaging, image galleries and a links/resources directory.

For managing raids and sign-ups we use a CCK type called 'raid' which includes fields for:

  • Date using the Date API;
  • Instance as a drop-down list (see the attached instance_list.txt for the values we use);
  • Notes for anything else, eg what the goals of the run are.

A slighty tweaked Sign Up module allows guild members to sign-up for raid nodes. We also use the Calendar module along with trusty Views to provide both an Upcoming Raids List and a Raids Calendar.

Theming usernames by WoW class

We have WoW class set up as a profile field for all our site members (profile_wow_class). A nice touch for the site was to re-theme all our username links to show the class colours as used in mods such as the awesome Ace-based mods.

So, we simply re-theme the theme_username function. Luckily we have all the profile data we need within the $object parameter passed to it, so the only thing we add is the following:

  1. if ($wow_class = drupal_strtolower($object->profile_wow_class)) {
  2. $output = '<span class="'. $wow_class .'">'. $output . '</span>';
  3. }

just before the $output is returned. We now have a span tag with a CSS class we can colour up in our style.css file, for example:

  1. .warrior, .warrior a { color: #c69b6d; }
  2. .hunter, .hunter a { color: #aad372; }
  3. .mage, .mage a { color: #68ccef; }

See the attached list for all the colours we use in our theme. Priests, unfortunately, are grey as the site has a white background.

Tweaking Sign Up module

We made these changes against the 5.x-1.0 release. My apologies if some of these issues are addressed or more easily solved in the later development versions, I haven't got round to looking at the newer version of the module yet.

Open/Closed tweak

The list of sign-ups returned by signup_list_user_signups() didn't seem to take into account a raid's Open or Closed status, but instead relies on event module start dates to filter its results. As we have a 'my sign-ups' block showing for our raiders, we didn't want this cluttered with raids that were closed.

In signup.module, function signup_list_user_signups(), we replaced the query:

  1. SELECT n.nid, n.title
  2. FROM {node} n
  3. INNER JOIN {signup_log} s_l ON n.nid = s_l.nid $event_join
  4. WHERE s_l.uid = '%s' $event_where
  5. ORDER BY $order_by

with a query that contains an additional join to filter on our sign-up status:

  1. SELECT n.nid, n.title
  2. FROM {node} n
  3. INNER JOIN {signup_log} s_l ON n.nid = s_l.nid
  4. INNER JOIN {signup} s ON s.nid = s_l.nid $event_join
  5. WHERE s_l.uid = '%s'
  6. AND s.completed = 0 $event_where
  7. ORDER BY $order_by

Ideally this should work with the Date API's CCK field in a similar way to how the start/end dates provided by the Event module are handled, ie filter the results to include raids where the date is in the future. There's a patch for Sign Up/Date API support which might be worth a look at.

Sorting sign-ups by by WoW class

To aid the raid officers, the list of sign-ups for each raid ideally needed to both include and be sorted by the raider's class. We call on our profile field for class again, so all we need to do now is some sorting on the results in the $registered_signups variable near line 620 in signup.module. We replace:

  1. while ($signed_up_user = db_fetch_object($registered_signups)) {
  2. $rows[] = array(
  3. theme('username', $signed_up_user)
  4. );
  5. }

with:

  1. while ($signed_up_user = db_fetch_object($registered_signups)) {
  2. $these_users[] = user_load(array('uid' => $signed_up_user->uid));
  3. }
  4.  
  5. if ($these_users) {
  6. csort($these_users, 'profile_wow_class', 1);
  7. foreach ($these_users as $this_user) {
  8. //build the row for this user
  9. $rows[] = array(
  10. theme('username', $this_user),
  11. $this_user->profile_wow_class,
  12. );
  13. }
  14. }

We call a function here, csort which is "a quick, fairly uncluttered way of sorting an array of objects by a certain object attribute". This code is taken from a comment on PHP's usort function. I've not included the code here, but suffice to say it needs to be available to our modules. We have a module called tttoolbox which houses snippets like this that are specific to The Tempest site.

Altering the sign-up fields

In signup.theme we simply alter the user signup form to suit, as described in the comments for the function (theme_signup_user_form()) to simply include a comment field, in which raiders can include information such as their current spec. Obviously this function can be tailored further to include more complex fields that aren't included in a custom user profile.

  1. function theme_signup_user_form() {
  2. $form['signup_form_data']['#tree'] = TRUE;
  3. $form['signup_form_data']['Comment'] = array(
  4. '#type' => 'textfield',
  5. '#title' => t('Comment'),
  6. '#size' => 40,
  7. '#maxlength' => 64,
  8. );
  9.  
  10. return $form;
  11. }

This function can also be over-ridden in a theme's template.php:

  1. function phptemplate_signup_user_form() {
  2. ...
  3.  
  4. return $form;
  5. }
AttachmentSize
instance_list.txt389 bytes
wow_class_colours.txt372 bytes

Comments

Your raid calendar was built using Drupal?

I thought Drupal was just a blogging package. Even if it's a CMS, I'm impressed if you actually modified it for raid signups!

Cool

I signed up to drupal groups today and there is a discussion there about drupal is great for wow guilds. While reading this I can only agree more.

While reading your blogpost it comes to me that you really have a lot of possibilities with drupal.. Take the raid signup form for example. That's very cool.. Thou it looks a bit hard to code =).

I wish our old guild (game over) would have found that platform before we collapsed =(..

I will give a tip to my new guild master about drupal.

Errors

I'm trying to implement your username theming on my guild's new website but I'm getting the following 2 errors:

Warning: array_key_exists() [function.array-key-exists]: The second argument should be either an array or an object in /home/.../iiv/includes/module.inc on line 217 warning: Cannot modify header information - headers already sent by (output started at /home/.../iiv/includes/theme.inc:1) in /home/.../iiv/includes/common.inc on line 141.

(this was after I fixed the coding problem of it needing to be $object->profile_wow_class)

I'm also confused on another thing.

$output = ''. $output . '';

Unless I'm mistaken, that doesn't change $output at all. In essence this function does absolutely nothing. Are those really ' or are they supposed to be "?

Is the post incomplete or am I missing something?

Broken filtering

Sorry, something went awry with the filtering of the code on this page. Please check the code above again, it should be:

$output = '<span class="'. $wow_class .'">'. $output . '</span>';