Sep 04 2008
Sep 04

I have a new client that has hired me to build a small, Drupal-powered web site for his scholarship foundation. Since the site is very straight-forward and not slated to go live for a few weeks, I decided to see if I could build the site using Drupal 6. The big challenge is seeing if I can get all of the image functionality working (and stable) using the bevy of development- and alpha-versions of the necessary modules.

The idea is to be able to add an image field to the standard story and page content types and use ImageCache and Lightbox2 to display the images. As of this writing, the required modules are at various stages of development:

  • CCK: 6.x-2.0-rc6
  • Lightbox2: 6.x-1.8, but only the development version is working with CCK2 at this time.
  • ImageCache: 6.x-1.0-alpha2
  • ImageField: 6.x-3.0-alpha2
  • ImageAPI: 6.x-1.0-alpha2
  • FileField: 6.x-3.0-alpha4

Installation of the modules wasn't as smooth as I hoped, after moving the modules into the sites/all/modules directory, I decided to tempt fate and try to enable all of the relevant modules at once. I immediately got a white screen of death with a error message indicating that the "content_notify" function was not defined. I went back and enabled CCK first, then FileField and ImageAPI, then ImageField, then the rest. It appears that one of the modules I was trying to install tried to call the "content_notify" function from CCK before it was loaded (based on a cursory search of the code, both FileField and ImageField call the "content_notify" function from the install files).

Regardless, once I had all of the modules installed, I set up my configuration as follows:

  1. I created two imagecache presets: "thumbnail" and "large".
  2. I added an imagefield to the "story" content type. For the most part, I used all default values in the imagefield's configuration other than enabling custom title text, allowing for unlimited images per story, and disabling the description field.
  3. I set the teaser and full node display options on "display" tab of the edit "story" content type (admin/content/node-type/story/display) to use Lightbox2. In my case, I used "Lightbox2: thumbnail->500_pixels_tall". This will initially display the thumbnail of the image on the page and when the image is clicked, the Lightbox effect will be used to display the larger image.

Once the configuration was done, I went ahead and added some new "story" nodes with various photos and everything worked great - I haven't seen a single issue yet. Despite the fact that this is simple application of these modules, I'm quite pleased that these 6 modules - with 3 different maintainers (and a whole bunch of contributors) are working so smoothly despite the fact that 4 of the modules are alpha-level code and one is a development version. Thanks and great work!

Sep 04 2008
Sep 04

One of the sessions at DrupalCon I attended was Larry Garfield's talk about "Drupal Databases: The Next Generation", which gave me a good insight into the current state of the Drupal database layer and how they plan to overhaul it for Drupal 7. The key points that I took away:

  • A new API based on PDO
  • Object-oriented, requiring PHP5
  • Support for using prepared statements
  • A unified access API
  • A query builder
  • More support for other database systems (currently Drupal supports MySQL and PostgreSQL only). In particular, they are keen on adding SQLite support, to ease local development.
  • Support for master-slave replication (by randomly distributing reads among the hosts)
  • Support for using different database types in parallel (e.g. using SQLite for read-only tables, MySQL for everything else)

The slides and a video of the presentation are available, if you want to check it out. There is a task list on the web site that keeps track of the ongoing activities.

Sep 04 2008
Sep 04

So Google Chrome is out. Features and developer implications aside, it's another major step for Google in order to push the operating system and its desktop applications into irrelevance, and replace them by web applications. Because the web is where Google has its business. As a nice side effect, we get an open source browser, a fancy new JavaScript engine and a push for wider usage of web standards.

Now I'm a member of that hardliner fraction that emphasizes the "Free" aspect of Free Software (or Open Source, whatever), because it empowers users to choose which tools I can use to operate on any given set of data - as long as that data is available at all and follows open standards. I'm delighted that, nowadays, I can run my system on an open kernel with open drivers, get 3D accelleration from an open X Window System, and have it all fall into place with the wonderful KDE 4.1 desktop (shameless plug). It's all software that I can trust, because the Open Source development model guarantees that the code won't be stripped of crucial features or spiced up with indiscrete phone-home functionality and advertisements. I know that I'll be able to swap applications while still keeping all the important data, and I know that if something goes wrong, everything will still be alright in the end.

Open source web frameworks like Drupal do the same thing for web site creators: they provide a base that you can trust to go into the right direction, because that's the nature of genuine Open Source and in everyone's own interest, too. However, it does not provide the same level of trust to its end users: they only get HTML/JavaScript output without being able to hack the application and control the data that they put on the web page. Users can only delete data if the corresponding permissions are set, they can neither control nor modify the information that is logged about them, and they can only migrate to another system if the web site provides explicit export functionality or a suitable API.

With a tad of worry, I watch the trend of people giving away lots and lots of personal data to the web, in exchange for comfort or reliability. Mails keep being stored by GMail or other mail providers with fancy web interfaces, pulling them away and on one's own system with POP3 is a dying practice. Life is being captured in Blogger, Facebook and Twitter. If I want to browse through my friends' photo albums, I need to register on StudiVZ (German Facebook rip-off) because that's where they store them. Those services are provided by people who I do not trust to do the right thing, because even if the web sites run Free Software, the way it works does not guarantee that my data is safe and my interests are being followed - it might just not match the business model of the web site providers.

If you think that sounds like a lot of paranoia, you're probably right. Still, the point that I'd like to make is that we had all of this before: the user depending on proprietary software that controls what happens to the data, and thus creating vendor lock-in - which is a network effect, and causes more people to use the same software. As the desktop is slowly being freed from lock-in, the exact same thing is now being shifted onto the net. Instead of having to trust Microsoft for their office data, people now have to trust Facebook for their social online life. The only difference is that MS Office costs lots of money while Facebook is free (as in beer), because of their business model.

As of today, the web is not open. The GPL is the new BSD, and the web is the new freeware (not to be confused with Free Software). In order to let users keep the freedom that is now available (and usable) on the desktop, open source web software must work on decentralizing the web. Users should be able to keep their own web presence like they keep their desktop system: personal, trusted and only passing data around when that is desired. It shouldn't be necessary to have a single huge web site where the data of all different users comes together; instead, users would have their own data store that, for example, sends out twitter updates to the data stores of all the intended receivers. Instead of a central site that's in charge of everything, lots of small sites would communicate with each other, and the user would be in control of the data.

If the web replaces the desktop, it should be judged by the same criteria, and that goes not only for bling and usability but also for openness. Personally, I think that centralized, data-centric web applications are the biggest threat for openness and self-determined choice of client software since MS Office came around, and Google is doing well covering that issue by supporting Open Source where it doesn't hurt their main strategy. But at least they're being honest about it and try to do it nicely: I'm still a big fan of the Summer of Code and GHOP programs :P

In other news, both my Japan/India trip and Drupalcon were a blast, and I'm finally going into stealth mode now. See you later!

Sep 03 2008
Sep 03

In Build An Aggregation Site With Drupal (Part 1) and Build An Aggregation Site With Drupal (Part 2) I covered setting up the foundation of your aggregation site using Drupal and SimpleFeed and then using cron to auto-update content and views to create the site sections and RSS feeds for our content.

In this third part of the series I'll look at theming the news items, and finally in part 4 some extra touches including filtering options for our users.

Step 1: Set up the new theme

So far during this tutorial series I've been using a clean install of Drupal with the default Garland theme enabled.

Now that we'll be making various changes to the site's theme it's best to set up a new version of Garland in your site's sites/all/themes folder which you can then enable and edit instead of the default Garland theme (which is located at themes/garland) thus keeping the original Garland theme intact.

To do this:

  • Create a new folder called 'themes' inside of your site's 'sites/all' folder, so that you end up with a folder structure like so 'sites/all/themes'
  • Copy the entire original Garland theme folder (called 'garland') which is located in your site's 'themes' folder and paste it into the newly created 'sites/all/themes' folder
  • Rename the copied folder to 'aggregation'
  • Log in to your site and navigate to the main 'Themes' section (admin/build/themes)
  • Enable the 'aggregation' theme, set it as the default and save

Drupal - aggregation site folder structure
Drupal - aggregation theme enabled and default

Step 2: Gather the news source icons

As part of the styling in Step 4 (below) we'll use the favicons from the news sources whose feeds we aggregate within the feed item nodes to add some more visual interest.
So, we need to gather these from the various feed sources. In this case, we have three main sources and, therefore, three favicons:

  • BBC
    BBC favicon
    file name - bbcicon.png
  • ESPN
    ESPN favicon
    file name - espnicon.png
  • favicon
    file name - mlbcomicon.png

Once you have collected the favicons (which should be 16px x 16px in size) place them in your theme's images folder - 'sites/all/themes/aggregation/images' - ready for Step 4.

Step 3: Override the news item layout with node-feed_item.tpl.php

In order to make our aggregated news items more appealing we're going to override their layout using a template override. In this case, this is basically just a file which we will place in our theme folder that targets certain types of nodes. When it finds the type of node it's looking for Drupal overrides the node's output (which by default is controlled by the code found in node.tpl.php) with the new output (in this case, the code found in our node-feed_item.tpl.php file).

So to do this:
First create a new PHP file in your 'aggregation' theme folder and name it 'node-feed_item.tpl.php', so that you have a folder structure like so: 'sites/all/themes/aggregation/node-feed_item.tpl.php'.

Now copy the following code and paste it into the 'node-feed_item.tpl.php' file:

<div class="node<?php if ($sticky) { print " sticky"; } ?><?php if (!$status) { print " node-unpublished"; } ?> <?php print $node->type; ?>" id="node-<?php print $node->nid; ?>">
  <?php if ($page == 0): ?>
    <h2 class="title">
      <a href=""color: #000000"><?php print $node_url ?>"><?php print $title ?></a>
  <?php endif; ?>
  <div id="news_info">
  <span class="taxonomy"><?php print $terms ?></span>
    <p class="date"><?php print format_date($node->created, 'custom', "l jS F, Y @ g:ia"); ?></p>
  <div class="content">
= explode(" ", $content);
$finalstring = "";
$mywords as $word) {
strlen($finalstring) <= 197) {
$finalstring = $finalstring . " " . $word;   
    } else {
$finalstring = $finalstring . " <strong>[...]</strong>";   


  <?php if ($links) { ?>
    <div class="links">
      <?php print $links ?>
  <?php } ?>

You should now see a few changes to the aggregated feed items' layout. Basically, we did four main things within this override file:

  • Moved the taxonomy term from the bottom right corner to just below the title. We will theme this further in step 4 (below).
  • Changed the date format from something like "Tue, 08/19/2008 - 18:57 - admin" to "Tuesday 19th August, 2008 @ 6:57pm". This makes it more readable and also removes the information about who published the node (admin) which is not really necessary for an aggregation site.
  • Made sure that our node's content will auto-truncate (stop) after roughly 200 characters. This keeps our nodes compact and helps to ensure that we do not get in to hot water with regards copyright infringing those people whose feeds we aggregate. This is particularly the case where people publish full posts in their RSS feeds ;) For those that are interested you can check out a discussion on other truncation methods in a previous post - auto-truncating content at the end of a word.
  • Added a class of 'feed_item' to all feed item nodes. This will be useful for targeting our CSS in step 4 (below).

Step 4: Add styling in style.css

OK, now that we've got everything in place let's add some styling. To do so, open your theme's 'style.css' file (sites/all/themes/aggregation/style.css) and scroll down until you find the section marked:

* Color Module: Don't touch

Directly above that commenting add the following:

* Build An Aggregation Site With Drupal (Part 3)

.feed_item .taxonomy ul.links li {
margin: 0;
padding: 0 0 5px 25px;
.feed_item .taxonomy ul.links li a {
font-weight: bold;
.taxonomy li.taxonomy_term_1, .taxonomy li.taxonomy_term_2 {
background: url(images/bbcicon.png) no-repeat 0 0;
.taxonomy li.taxonomy_term_3, .taxonomy li.taxonomy_term_4 {
background: url(images/espnicon.png) no-repeat 0 0;
.taxonomy li.taxonomy_term_5 {
background: url(images/mlbcomicon.png) no-repeat 0 0;
.feed_item h2 {
margin: 0 0 5px 0;
.feed_item .taxonomy {
float: left;
padding: 0 10px 0 0;
.feed_item .content {
margin: 0;
padding: 10px 0 0 0;
#news_info {
color: #6d6d6d;
#news_info p {
margin: 0;
.feed_item div.links ul.links li {
padding: 0;
.feed_item li a.simplefeed_item_parent {
display: none;
.feed_item li a.simplefeed_item_url {
border-bottom: 1px dotted #333;
.feed_item li a.simplefeed_item_url:hover {
border-bottom: 1px dotted #fff;
.feed_item li a.node_read_more {
display: none;

Everything should now be nicely styled in your feed items.

Finished (Part 3)

We now have a fully functioning, neatly styled aggregation site running on Drupal. In the final part of the series (part 4) I'll look at a couple of extra bits you can do with the site including adding some filtering functionality for your users.

Also in this series

Sep 03 2008
Sep 03

I had a nice chat with Kieran from Acquia at DrupalCon last week - we discussed how people running local Drupal user groups could expand their outreach into other communities, in particular into the MySQL User Groups. Scott Mattoon captured our conversation on video, which is now available on

The gist of what we talked about: if you are organizing a local Drupal User Group Meetup, check out to find out if there is a local MySQL user group nearby. Chances are high that there is! And if not, you may find at least people in the area that would be interested in meeting about this subject. We also maintain list of user groups on the MySQL Forge Wiki. Consider extending your invitation for your next meetup to these folks as well! It's very likely that someone would be interested to learn more about Drupal. The same applies to other user groups, e.g. from the PHP community.

I personally run a MySQL User Group here in Hamburg, and I usually extend my invitations to a number of channels and mailinglists, including the local PHP, Perl and Linux User Groups. Every once in a while, a new member from these communities shows up.

So this thing works the other way around, too: if you are the organizer of a MySQL Meetup, have you thought about looking at yet? Maybe you will find a Drupal User Group in your very own town that you could invite to learn more about MySQL and exchange contacts? If you are looking for more tips on how to run and expand your User Group, I've created a page with useful hints about this topic on the MySQL Forge Wiki. Your feedback and additions are very welcome!

Sep 02 2008
Sep 02

I promised to post the SunSpider benchmarks for Google Chrome, and boy, V8 surely blew away other browsers in many aspects! For the visual learners, here's a pretty chart to show just how monstrous Chrome is when it comes to JS perfs (as Intchanter noted, smaller is better):

Here are some nicely formatted raw numbers:

  Chrome Firefox 3.0.1 Safari 3.1 WebKit nightly Opera 9.52 IE 7 3d 110.2 357.2 412.8 371.8 418.6 1287.6 access 83.8 494.8 531.4 346.8 612.2 1887.4 bitops 61.2 336.8 421.8 187.6 550.2 1718.4 controlflow 3.6 40 93.8 18.8 53.4 484.6 crypto 54.2 200.4 250.2 128.2 227.8 1022 date 265.2 254.2 343.8 197 631.4 874.6 math 110.2 357 450.2 331.6 337 1177.8 regexp 370.2 225.6 303.2 265.6 465.4 375 string 511.2 719 721.6 487.8 985.2 18296.8
If you'd like to hack on the V8 JavaScript engine or play around with the V8 shell and you're on a Mac, I encourage you to take a look at this post.
Sep 02 2008
Sep 02

So did my trusty MacBookPro. In evening rush hour in Budapest airport somehow my laptop was pushed off the conveyor belt of the security screener – and the poor thing landed right down to the marble floor. The LCD is clearly broken, there is some hope that hard disk survived, let see what Apple service has to say.

The most bummer part is that I can not afford to repair the thing or get a replacement to it, so my online presence and Drupal contribution level is pushed back to minimum what is truly a shame – at least for a while.

There is some irony in it: we talked in Szeged UX sprint quite a lot about low-tech usability and paper prototyping. I was not expecting that day will come so soon. I am off to stationary store to grab a "PaperBookPro" now. ;)

Sep 02 2008
Sep 02

With the release of Google Chrome just coming up tomorrow, by now the blogosphere should be on fire with all the screenshots and juicy details. Even though I see Google Chrome as something that means more to the user than to the developer, there are certain goodies in Google Chrome that aim to provide a better platform for developers. What's the implication for web developers here?

  • A stronger push for WebKit. This addresses some moans I saw on Digg (or is it Slashdot?) that could basically be summarized as "oh, great, now we have another fugging browser to debug." Google chose WebKit as the rendering engine for Chrome, so as a web developer, if your current pages and apps work on Safari, it's probably going to work fine on Chrome.
  • The V8 JavaScript virtual machine. Google apparently developed their own JavaScript engine and sources show that V8 can at times be up to 10x faster than Tracemonkey, Mozilla's recent effort to integrate Tamarin tracing into the existing SpiderMonkey JavaScript engine. With IE 8 Beta 2 also having an about 400% percent perf increase in their JScript engine, web developers can start worrying less about the performance constraints of JavaScript and start writing better web apps. I'm probably going to have some SunSpider benchmarks to do when Chrome is released tomorrow.
  • Gears included. Just having a better JS engine doesn't seem enough for Google, so they also included Gears, which provides developers a client-side database storage to enable offline usage for web apps.

JavaScript is gaining more and more momentum as the Web moves forward as a platform and developers will no doubt find themselves held back when writing JavaScript. Drupal is already at least 8% JavaScript and I'd like to see more. JavaScript was, is, and will be the lingua franca of the Web!

Sep 01 2008
Sep 01

I eagerly awaited the videos for the Boston Drupalcon. They never seemed to appear. 

However, the videos for Szeged are already available here ! The quality is very good. Audio is good and the presentation screens are fuzzy but you can get the general idea. 

Very impressive. There are many hours of must watch video here if you were unable to attend the conference live.

Sep 01 2008
Sep 01

I'm back home from DrupalCon 2008 now - it has been a great event! I met a lot of nice people from the Drupal Community and learned a lot about this CMS. I've been very busy in uploading the remaining pictures from the event to my gallery - so here's for your viewing pleasure:

I also gave two talks and held a BoF there - the slides have now been attached to the session nodes, one of them (the HA session) even includes a video recording:

I've also uploaded some pictures from FrOSCon to my Gallery now, hope you enjoy them! The slides of my FrOSCon talks are now uploaded to the conference system as well:

Aug 29 2008
Aug 29

Day three already… time flies. Today starts off with a theming talk by my roomie MortenDK – who has apparently recently promoted himself to “King of everything”, which is very humble of him, I’m sure. The Dane managed to cuss his way through ninety minutes of ‘Sex, Drupal & Rock n Roll’ with ease, despite the horrific amounts of heckling from yours truly and Si (LyricNZ).

Next up, I watched William Lawrence with his overview of accessibility in Drupal theming. Some good points here, and answers to questions about screen readers, browser extensions and such. All good!

With it being Friday, we took this opportunity to have a long lunch and went out for Goulash soup, which was grand.

Post luncheon, I attended the Acquia beta test kitchen, where I proceeded to break pretty much everything. I am assured that this is providing them with “useful information”, but I worry that there may have been some fairly colourful language used in reference to certain parts of that session…!

Then followed a quick BoF in the form of a chat about taxonomy and menus, hosted by pwolanin and catch, which proved to be quite useful – lots of stuff about the new hierarchical select module by WimLeers and other titbits like taxonomy_context.module and some potential uses.

The evening takes us to the Taj Mahal indian restaurant, where the service was appalling, but the belly dances were frequent. I hear some people enjoyed that rather more than the meal…

Aug 29 2008
Aug 29

Thursday, Day two. I didn’t do much today in terms of sessions, but I’d spoken to Kieran Lal of Acquia the day before regarding a voluntary interview… more on that in a tick.

I hear that the testing party went well in the morning, the pancakes weren’t fictitious and lots of people turned up!

Just after lunch, we had the redesign session. Mark Boulton [Design] acknowledges that this particular redesign is potentially the hardest thing he’s ever done, with over 200,000 clients involved in the project – I hope he realises how damn picky we all are!! MortenDK, myself and no doubt several others have put our names down to help out with whatever aspects of the theming that we can.

Next, for me, followed an interview with Leisa, who is the usability expert assigned to interview lots of users prior to the redesign process. I surprised myself with how little I could remember about the various aspects of the front page and most other sections of the site. I genuinely hope that these interviews are going to be useful – I strongly suspect that they will be, as I hear that lots of things were being mentioned repeatedly.

Later that night, we had the welcoming party. You can keep the wine spritzers, thanks – I’ll have a beer. A good time was had by all, after we worked out how to actually get beer. Some pretty good photos from the party can be seen on my Flickr account, in the set tagged DrupalConSzeged2008, with the title DrupalCon Szeged Welcome Party

Aug 28 2008
Aug 28

Hello and greetings from DrupalCon 2008 in Szeged, Hungary!

We (Thierry Manfé, Scott Mattoon and myself) are having a great time manning our booth and talking about Drupal, MySQL and Open [email protected] with the nice crowd of Drupal Users and Developers here. Sun is a gold sponsor of the event and we're giving a number of sessions as well.

Today I gave my first presentation about MySQL Backup and Security - Best practices - unfortunately I ran a tad bit out of time at the end... The slides have already been attached to the session page, so you can read up on the last few things I was going to talk about. Feel free to contact me, if you have further questions!

Tomorrow I'll be talking about High availability solutions for MySQL: An Overview and practical demo, which will also include a practical demonstration of a two-Node Linux Cluster, performed by Jakub Suchy. In the afternoon, I will also hold a BoF about bzr - The Bazaar source revision control system

I've also uploaded some pictures from the event (and some impressions from the city) on my gallery (more will follow later). Enjoy!

Aug 28 2008
Aug 28

Back at the start of the year when I was building a website for some self-catering cottages on the Isle of Man, I needed to replace some availability calendar functionality that I'd originally coded for the site back in 2000 or so.

As I was moving the site to Drupal, the availability calendar solution really needed to be something that was fully integrated as a Drupal module. I had checked out a couple of modules and the two that I found (Availability and OpenResort) didn't really do what I was looking for, so I went about customising the Availability module to do what I wanted.

Preview of Availability Calendars module for Drupal

Soon enough, the module had changed shape quite considerably, so it didn't feel like it would fit back into the original module. After about six months of running the module, the new Availability Calendars module got released back to the community last night.

If you run a small accommodation provider business (like a self-catering cottage, a bed and breakfast, a guesthouse, etc.) and are using Drupal to power your site, you might find this module quite useful. It will allow you to show an availability calendar for each node of a certain type (e.g. cottages, rooms, etc.), change the availability for each day, and also leave a note (such as a rental price) next to each week.

If you have any issues with the module or would like to request new features, please add a comment to the issue queue.

Aug 28 2008
Aug 28

I had four reactions to this, that went in this order:

  2. Does she have time for this with the book and everything?
  3. Oh wait. She said the book would be DONE by Drupalcon.

I expect to see patches flying in (almost literally, except for the fact that it would take a while to fly from Montreal, her home base, to OSUOSL in Oregon, where the Drupal repositories are), especially testing patches.

I’m surprised there hasn’t been more noise about this on the planet, but CONGRATS!

Aug 27 2008
Aug 27

Day one of the Drupal Con in Szeged, Hungary. Morten and I made the initial keynote speech by Dries & Co. Well, almost. We were in the door about 4 seconds, there was some clapping, and we left. Couldn’t tell you why we were so late… ;)

Sam Boyer then presented a very decent overview of the Panels module, with some information about the direction of Panels 2 and what’s upcoming in version 3. The key fact that people are most likely hanging on for is the release date for Panels 2 under Drupal 6. Sam seems confident that the answer is something akin to “soon, I promise!” This is a Good Thing. Currently we’re developing a magazine website and using version 6, and really Panels 2 is the last great module that’s not working under that version.

One thing I picked up on was the proposed abstraction of the override functionality (node, taxonomy, etc) into a separate module. This is pretty smart thinking – when I give people a tour of the panels administration interface that powers the Curt Smith website, the override stuff is probably about 40% of the show.

As I write this paragraph, Rasmus Lerdorf is talking about some insane low level PHP optimisation stuff. Some of it I get, some of it is working at a level that is so low that I just can’t afford the brain cells to care about it. He makes a pretty convincing argument for this optimisation though, and points out that you’re basically an idiot if you don’t use opcode caching on your server. Ahem, no comment.

Rasmus also mentions how optimisation can have a positive effect on managing environmental damage – specifically he mentioned the ubiquitous kitten and its untimely demise due to environmental damage. I have taken this concept and run, coming up with the concept of a new unit of measurement for computing – “cycles per kitten”.

Next on the agenda (of most interest to me) is Emma Jane Hogbin’s small business overview, or Wolfgang’s rules module talk. Not sure which yet. More later.

Later: went to Emma Jane’s talk, which was very frank and it was most refreshing to see someone with such vigour and passion talk about her business and practises. Currently listening to ChX talking about menus. I have not a lot to say about that, as I understand very little…

Day one is a great start to an already cool ‘Con, so here’s looking forward to more of the same!

Aug 27 2008
Aug 27

Posts · 27th August 2008 · 5 comments

So I came across this today whilst wasting time doing something useful:

Drupal - Live Search Health results

According to the F.A.Q. Live Search Health "is a new search engine for the web that helps you to discover, learn, and act on answers to your health questions" - err...what?

Aug 27 2008
Aug 27

Over the last 6 months I have been working for a company on a selection of in-house developments. Yesterday in a meeting I found myself saying "Is Drupal too general?" and that got me thinking, "is it?".

Read the full post on Millwood Online

Aug 26 2008
Aug 26

a while ago i posted some performance benchmarks for drupal running on a variety of servers in amazon's elastic compute cloud.

amazon have just released ebs, the final piece of technology that makes their ec2 platform really viable for running lamp stacks stuck as drupal.

ebs, the "elastic block store", provides sophisticated storage for your database instance, with features including:

  • high io throughput
  • data replication
  • large storage capacity
  • hot backups using snapshots
  • instance type portability e.g. quickly swapping your database hardware for a bigger machine.

amazon also have a great mysql on ebs tutorial on their developer connection.

let me know if you've given this a go. it looks like a great platform.

Aug 26 2008
Aug 26

Recently I have upgraded a customer site from Drupal 5 to Drupal 6. The site contains a number of custom modules that required considerable work because of some changes in the Drupal API. One of the API changes is the removal of hook_info and hook_auth.

The new authentication mechanism has two advantages:

First of all, two authentication-specific hooks have been eliminated. There is no replacement hook, instead you must use hook_form_alter to replace the built-in validation functions of the user login form. This is a more general and more flexible approach and it shows the power of the current form API. You can check user_login_block and user_login_default_validators for examples.

Secondly, there is a lot more flexibility to do error reporting when authentication fails. In Drupal 5 when hook_auth returned false, Drupal would always display the error message "Sorry, unrecognized username or password. Have you forgotten your password?" even though the real problem might be something else, for example a remote server responsible for doing the actual verification of the password is not available. In Drupal 6 you can fully control which messages get displayed during an authentication failure.

Even though there is some work involved to migrate custom authentication functionality to Drupal 6, the end result is code that is much cleaner and more powerful.

Aug 25 2008
Aug 25

Szeged here we are: me and Fabiano arrived half an hour ago.

More news soon.

Aug 25 2008
Aug 25

In Build An Aggregation Site With Drupal (Part 1) I covered setting up the foundation of your aggregation site using Drupal and SimpleFeed. In this second part I'll cover using cron to auto-update content, and then look at using views to create site sections and RSS feeds for our content.

Step 0: Before we start
There is currently one flaw in the SimpleFeed module which we need to correct before continuing. Sometimes taxonomy terms are not assigned automatically to aggregated items, which will stop our site from functioning properly. You can find a more detailed discussion about this issue here.

The good news is that it has been fixed in both the 5.x and 6.x branches and is easy for us to correct :)

Just download the new Drupal 5 version of the updated simplefeed_item.module file from CVS and save it over your current simplefeed_item.module file which you will find in your SimpleFeed module folder (sites/all/modules/simplefeed/simplefeed_item.module).

Step 1: Cron
Adding cron functionality to an aggregation site is pretty crucial because without it our content will not auto-update. We could technically update our feeds manually but that would be a very tedious process, so cron is definitely the way to go!

Cron works like so:

  • we set up a cron job to access the file cron.php, which is located in the root folder of our Drupal install (e.g. at
  • accessing cron.php then triggers a cron run where our modules, and hence SimpleFeed, are queried to check if they have declared that they need updating
  • modules which need updating are then updated. In our case, this means that SimpleFeed will then check our feeds to see if there are new items and if there are it will import those new feed items into our site

When it comes to cron on a Drupal site there are two obvious choices:

In this case, the demo aggregation site is set up on a VPS running Plesk which allows cron jobs to be created so we will use this option. However, not all web hosts allow the creation of cron jobs. If this is the case you can instead use the poormanscron module to schedule a cron job from within your site's admin panel (see the module's README file for an explanation).

Cron set up on Plesk
We will set a cron job up through Plesk to run once every hour on the fifth minute of the hour (remember to replace the '' part of the command URL with your site's URL), like so:

Drupal cron job on Plesk

And that's it - cron should now regularly auto-update our content, so let's get to organising the content a little better with some site sections, and also adding our own RSS feeds, using the views module.

Step 2: Views
For our sports news site we'll create three views:

  • sports
    - the front page view with all of the sports news items
  • baseball
    - a view with all of the baseball news items
  • football
    - a view with all of the football news items

We'll also output an RSS feed for each view so that users can subscribe.

Adding a view
To set up a view first navigate to the main 'Administer views' page (admin/build/views).

You can add a view by either:

  • 1. clicking on the 'Add' tab, which will take you to the 'Add a View' page (admin/build/views/add), and filling out the form
  • 2. clicking on the 'Import' tab, which will take you to the 'Import a View' page (admin/build/views/import), and submitting the import view code

Drupal views module tabs

The SimpleFeed module does actually come packaged with a few default views (feeds, feeds_latest, and feeds_latest_block) which we could edit to get what we want, but I find it simpler to create the views I want from scratch.

For each of the views I'll provide both the import view code and a screenshot of the view's finished form options. I would suggest using the import view code first to actually create the view and then double checking that all of the view options look correct on the form in comparison to the screenshots below.

'Sports' view
To set up the front page 'sports' view:

  • copy the sports import view code (I've placed it in a separate text file because it's quite long)
  • navigate to the 'Import a View' page (admin/build/views/import)
  • paste the sports import view code into the text area labeled 'Import View Code:'
    Drupal - import view code
  • Click 'Submit'

If the import is successful you will be re-directed to the 'Add a View' page and should find that all of the 'sports' view options are already filled in, like so:

Drupal - add a view page

Scroll down to the bottom of the page and click 'Save'. Drupal will save the view and present you with a 'View successfully added' message. You will also see the new 'sports' view listed in the 'Existing Views' section:

Drupal - view added

Now do the same for the 'baseball' and 'football' views.

'Baseball' view
Import the baseball import view code the same way as we did with the sports import view code.

The 'baseball' view options should be as follows:

Drupal - add a view baseball page

'Football' view
Again, import the football import view code the same way as we did with the sports import view code.

The 'football' view options should be as follows:

Drupal - add a view football page

In each view we are using the taxonomy terms which we set up in part 1 to filter the news items in a section. We are also limiting the nodes in each section to just feed items, and we are sorting news items by showing the newest item first.

You should now see all three views listed in the 'Existing Views' section:

Drupal - existing views

One quick thing to note - the title for the RSS feeds is taken from the view's page title and the description is taken from the view's description field on the 'Add a View' page.

Step 3: Menu items
Lastly, we need to create some menu items for our new views site sections. To do so, navigate to main 'Menus' page (admin/build/menu) and click 'Add item' for the 'Primary Links' menu. This will take you to the 'Add menu item' subsection page (admin/build/menu/item/add/2).

We'll create the 'sports' home page link first using the following settings:

Drupal - add sports menu item

Now just do the same for the baseball and football menu items using the following settings:

Title - Baseball
Description - Baseball news
Path - baseball
Expanded - unchecked
Parent item - Primary links
Weight - 1

Title - Football
Description - Football news
Path - football
Expanded - unchecked
Parent item - Primary links
Weight - 1

This will give us three primary links, like so:

Drupal - primary links menu items

Step 4: Home page setting
Finally, we need to tell Drupal that we want to use the 'sports' view as our home page. So, to do this navigate to the 'Site information' page (admin/settings/site-information), scroll down to the bottom and change the 'Default front page' setting to sports, like so:

Drupal - default front page

Finished (Part 2)
You should now see that the front page of your site contains our 'sports' view, and that the Baseball and Football sections contain our 'baseball' and 'football' views, respectively.
Furthermore, all three sections have their own RSS feed available for subscribers.

Also in this series
Build An Aggregation Site With Drupal (Part 1), where we set up the foundation of our aggregation site.

Coming soon...
Build An Aggregation Site With Drupal (Part 3), where we'll look at theming everything.

Aug 24 2008
Aug 24

I will be writing a few posts on connecting silverlight and drupal in which I will replicate my main site. I will be doing this piece by piece as I investigate each drupal module that I am using and how I can request the appropriate data to populate my silverlight controls. I have outlined the basics needed to accomplish this in my previous post and will be focusing on the new information that is needed to complete each new piece.

Drupal's aggregator module is a core module that is used for fetching syndicated content from other sites. However, it has the ability to provide an xml syndication button for your drupal site if you decide to show the syndication block. There is much more functionality that this module can provide, but all I needed was a simple link to my sites syndication. After doing some initial research I did not find a way to call some method that returned my sites syndication. So I decided to 'cheat' a little bit and produce my sites syndication link manually (at least I did not hard code this!). Here is the php below:

$mainSiteRSS = variable_get('site_name', 'Drupal');
$mainSiteRSS .= url('rss.xml');
return array('rssLoaded', $mainSiteRSS);

I simply grab the sites name, append 'rss.xml' and return a correctly formatted url string to my silverlight application. I then tie that url to my rss button:

private void rssLoaded(object feedSite)
    string rssLocation = ((MethodToCall)feedSite).MethodName;
    Uri rssLink = new Uri("http://" + rssLocation, UriKind.RelativeOrAbsolute);

Remember, I have a generic method that gets called when drupal returns its data that casts the data to a MethodToCall object as outlined in my previous post.

And that's it! This was one of the simpler controls and that is one reason that I decided to start with this one. The silverlight code was very simple as well; just a button that looks like the standard rss icon that was made using Expression Blend that has a click event that sends a request to drupal to return my sites syndication link, as outlined above in the php code. Here is the XAML for the rss icon:

<Button Click="rss_Click">
        <ControlTemplate TargetType="Button">
                <Rectangle Width="50" Height="50" Fill="Orange" RadiusX="5" RadiusY="5" />
                    <Ellipse Width="10" Height="10" Fill="White" Canvas.Left="10" Canvas.Top="30" />
                    <Path Stroke="White" StrokeThickness="5" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Data="M 15,20 a 15,15 90 0 1 15,15" />
                    <Path Stroke="White" StrokeThickness="5" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Data="M 15,10 a 25,25 90 0 1 25,25" />

I will post my full source code when I complete this entire replication of my site to silverlight. Until then, I will post the source for each control in a separate solution. If there is a specific drupal module that you would like converted to a silverlight control let me know and I will try to help you out!

AttachmentSize 141.97 KB 939 bytes 652 bytes
Aug 22 2008
Aug 22

There is an interesting presentation by psychologist Barry Schwartz at TED called "The paradox of choice". He explains why people are not better off when there is too much choice.

He claims:

Some choice is better than none. But it doesn't follow from that, that more choice is better than some.

His explanation makes sense:

The more options there are, the easier it is to regret anything at all that is disappointing about the option that you chose.

I think he has a valid point. A point which is also true in software:

I'm not saying that there should be no choice at all but very often there is simply too much choice and investigating all possible options takes too much time. Luckily Barry Schwartz reveals how to be happy with the choices you make:

The secret to happiness is "low expectations".

You can watch the presentation below or over at TED:

Aug 21 2008
Aug 21

UPDATE: Earl comments below how this is already built in. Two different ways to achieve a similar result, each with their own pros/cons.

Hats off to Earl Miles and the rest the views developers they have done a tremendous job with Views 2. While the interface is entirely different from that of Views 1, it is so much more intuitive that within a few minutes I had quickly forgotten my bewildered "oh no, I know nothing" look :)

From reading all of the docs and quietly watching development commits, I knew Views 2 was going to eliminate a lot of the Views 1 helper modules and open up a whole new world of awesomeness. While I haven't seen many blog posts detailing just which functionality/modules have been replaced with Views 2, I wanted to kickstart things with my own discovery as I played around with Views 2 quite thoroughly this afternoon.

With Views 1, to build an alpha pager you would use the views alpha pager module in conjunction with your view. But what about Views 2?

Well it's not so straightforward. I read somewhere about some sort of "glossary" view, but how could that be used to create an alpha pager? Well turns out, quite easy. Here's how:

  1. First, create a new page view and set your path to "directory"
  2. Assuming you want your pager to be based on the nodes title, add in an argument: "Node: Title"
  3. Set title equal to: "Directory: %1"
  4. Action to take if argument is not present: "Display all values"
  5. Check "Glossary Mode"
  6. Set character limit to "1"
  7. Case: "upper case"
  8. Case in path: "lower case"
  9. Save and update
  10. Add in a header under basic settings
  11. Set up your alpha pager: Note: if you have PHP filter enabled, you can set up proper links using l(), otherwise use basic HTML

And voila! You can now browse by starting letter of each node. Add in a few more exposed filters like taxonomy terms or search and you have a powerful directory!

That was definitely easy and Views 2 replaces its first helper module. What's next? :)

Written by on August 21, 2008

blog comments powered by
Aug 21 2008
Aug 21

Everyone rejoice, as Dries has just committed the long standing Drupal Database Layer: The Next Generation patch. This was one of the items on my original Drupal 7 wishlist, and is one of the major steps that will make Drupal 7 a killer release. This patch does a number of awesome things, as outlined by Crell:

  • Allows fancy PDO database queries (foreach through a result-set, select columns of result-sets, etc)
  • Connect to multiple databases simultaneously
  • Database replication
  • Type-agnostic prepared statements, so we don't need to bother with %s or %d
  • Proper support for NULL values
  • Adds support for transactions, while allowing them to not die on non-transactional databases
  • Support for "INSERT ... ON DUPLICATE KEY UPDATE ..." on MySQL or whatever the database-specific equivalent on other databases
  • Support for multi-insert statements, on all databases, using the appropriate database-specific mechanism
  • "INSERT DELAYED" support on databases that support it or some equivalent, which should help performance on logging and similar "don't need it back immediately" queries
  • Fully-structured INSERT, UPDATE, and DELETE queries with a simple fluent API (chainable, like jQuery) syntax
  • A Fluent API query builder for SELECT statements that weighs in at only a few hundred lines (not counting comments)
  • .... And that's just naming a few of the benefits

Congratulations everyone! Crell, chx, bjaspan, catch, swentel, recidive, you guys rock!

Aug 21 2008
Aug 21

Note: A better version of this patch is going into Drupal 7. View the issue/patch here.

Getting Drupal to play nice with your CDN can be a bit of a hassle. You have to make sure your assets (like JS, CSS, and image files) work not only on your webserver but when copied to the CDN, are served from there instead of your webserver. There is one Drupal module, the CDN module that attempts to make this a bit easier but right now, it's not in production, and in my opinion, is a bit too complicated. There is a slightly easier way :)

Depending on which CDN you decide to go with you'll want to make sure it offers HTTP synchronization. What this means is you don't have to manually upload files to your CDN--if they don't exist on the CDN, it will check your website for the file and download it through HTTP, putting it on the CDN. This works using some DNS magic.

For the ParentsClick Network we chose to go with Limelight Networks as our CDN provider. We configured out DNS so that we would have 2 static domains for performance (Yahoo discusses the benefits of 2 CDN domains): and To roughly split which assets are served from which domain, we set anything that is CSS defined (whether the file itself, or any image defined as a url() within the file) as static1 and then any JavaScript or image as static2. We also chose a different domain for our CDN so that we could send assets without the cookie overhead.

When you request a file that isn't on the CDN, it checks the fallback domain, which in our case, is, and grabs the file from there, putting it on the CDN for you in realtime (in my tests, I didn't even notice a delay, even using a 1MB zip file). This is all setup within our Limelight account.

So now that we're sycning properly with the CDN, the next step is fix the URLs in Drupal. Of course, you don't always want to use your CDN -- especially during development, so you need a way to quickly turn this on and off.

First up, you need to patch Drupal, see the attached patch that fixes hardcoded paths for CSS, JS, and images. You'll see that I'm using two defines: static1 and static2. In our settings.php, we added:

global $enablecdn; if ($enablecdn) { define('static1', ''); define('static2', ''); } else { define('static1', ''); define('static2', '');

We chose to use a global variable here. Your setup may be better off with a variable, a define, or something else. Then all you need to do is set $enable_cdn = TRUE to turn it on or FALSE to turn it off.

In my opinion, this functionality should really be baked into Drupal 7 and a patch woudn't be too hard. Having a way to configure this under the performance section and being able to specify up to 2 domains to use would be great. If I have some time later I'll work on a patch but if someone beats me to it, please let me know!

Written by on August 21, 2008

blog comments powered by
Aug 21 2008
Aug 21

As copies of Pro Drupal Development, Second Edition hit the streets, I'd like to take a moment to clarify what the book is and what it is not.

What it is not

  • A complete and comprehensive guide to using MySQL with Drupal
  • A detailed howto on integrating Drupal with Sphinx
  • The ultimate reference on using jQuery/AJAX/JavaScript with Drupal
  • A step-by-step tutorial on building an ecommerce site with Drupal
  • ...

What it is

The target audience of Pro Drupal Development is smart people who know PHP (or other languages; PHP can be picked up pretty easily) and are looking for an overview of how Drupal core works. It achieves this by walking through Drupal's major systems: users, nodes, filters, triggers, themes, etc. One of the challenges in writing the book was knowing when to stop. Take theming, for example. To do justice to Drupal's theming system would take a 400-page book in itself. The same goes for working with multimedia files, or optimization, or jQuery. The idea of Pro Drupal Development is to lay down the basics in each of these areas so that the reader is oriented and can then go on to use other resources, or to just better understand the code itself. Other books are being written that will provide great detail in specific areas, and I'm glad to see that -- it's a sign that Drupal is maturing and becoming well-known enough that there is a demand.

Pro Drupal Development was written to provide an on-ramp for intelligent people starting with Drupal so they can avoid months of feeling dumb in irc or having to piece together the big picture from a blog post here, a doc page there, a README here (that's the way I learned Drupal, and it's a frustrating way to learn). If the book fulfills this goal (and from my conversations with new developers it has) then I am satisfied.

When you find errors in the book, please post them as errata so that others can benefit. I'd recommend that when you get the book, go through the errata and make notes in the margins so that when you use the book for reference, you'll see the corrections. With the first edition, we were able to correct a lot of the errors in the second and third printings.

Aug 21 2008
Aug 21

I received in the mail my pre-ordered copy of Pro Drupal Development Second Edition yesterday.

The book is a brick. 667 pages with the index.

I am a little disappointed already... To be fair, I had high expectations. The treatment JavaScript and Ajax would receive was the first thing I'd look into.

AHAH is covered but the example provided is lame. It does not cover modifications to a form... Well it does, but you only inject some text in a field of type markup, so you do not need to fiddle with the cached form, or even read anything from it in the callback function. (The callback function is the PHP function that 'writes' the JSON that's returned to the browser...).

The chapter on jQuery provides one additional example module, besides PlusOne. That other module only attaches an additional JavaScript file to the page, using HOOK_init() and a registered theme function. No Ajax.

PlusOne still doesn't does degrade in this Drupal 6 version (see comments below). The book Learning Drupal 6 Module Development provides an example that does degrade. Meaning: without JavaScript, things won't look broken, as they do with the PlusOne module.

The chapter on jQuery explains how to add a function to Drupal.behaviors, but it does not explain how to pass a variable from Drupal PHP to the client-side Drupal.settings namespace. Learning Drupal 6 Module Development does explain this. It becomes important to use drupal_add_js to pass PHP variables over to our JavaScript to always avoid hard-coding certain values in our scripts.

We learned that in Drupal 6 our JavaScript is themable. Example, please? The book provides none.
(Any module's JavaScript file that produces HTML content must now provide default theme functions in the Drupal.theme.prototype namespace.)

The book does not even show one case where Drupal.t() is used. That function should have been mentioned at least.

Coverage of JavaScript best coding practices (such as... use camelCase for 'variable' and function names, etc.) should have found its place somewhere in that second edition, because the Drupal community and this very book are pushing hard for coding standards.

The book Learning Drupal 6 Module Development has its own shortcomings in its treatment of JavaScript due to the timing of its publication probably. By the way, the author of Learning Drupal 6 Module Development, Matt Butcher, has encouraged to update its handbook JavaScript coding standards page, to extend it based on a more thorough definition. Kuddos to him. JavaScript and Ajax are that important. Contributed modules developer (I am part of them) need to follow some conventions.

Last edited by Caroline Schnapp about 5 years ago.

Aug 21 2008
Aug 21

Sometimes, you need to change the HTML markup output by some module, and you want your changes to keep whichever theme you will use. The need came up for me recently when I had to provide special markup for pages that display a webform. I had to quickly put together a module for a client, a module that would provide a template file, which I decided to name (arbitrarily) page-webform.tpl.php.

The situation may arise for you as well, so I will share my technique with you. Say you want to provide a template file for all pages that display one node of a content type with machine-readable name CONTENT_TYPE_NAME. And say you want to use a module to provide such template. Say you decide to name your module special_page.

You start with creating a DOT info file for your module. The name of which would be in our case

name = Special Page
description = Provides a template file for my content type CONTENT_TYPE_NAME.
core = 6.x

Then you go about creating your DOT module file, ie: special_page.module.

// $Id$
 * @file
 * Module that provides a special template for pages that show 
 * ONE node of content type CONTENT_TYPE_NAME.

You probably should implement HOOK_help() in your module, but I will skip that, and cut the chase to what we really need.

At this point, you need to tell the theme system to use your template, and to use it only in certain situations. Your 'situations' will differ from mine. In my case, I wanted the theme system to use my template on a node page, hence any page with path node/nid, yet only on pages that show the node in view 'mode', so I did not want the template to be used when the path is node/nid/edit for example. There are many ways to skin the cat here. I decided to use the fact that a $node object is passed to the page.tpl.php template only when the page is a node page, as you will see in the following code snippet. Here, I will make use of a preprocess function to pass on to the theme system a suggestion about a new module-supplied template.

function special_page_preprocess_page(&$variables) {
  // If this is a node page (not a list of nodes page) and
  // the node is shown in 'view' mode rather than 'edit' or whatever.
  if (isset($variables['node']) && (arg(2) === NULL)) {
    // If the content type of that one node is 'CONTENT_TYPE_NAME'.
    if ($variables['node']->type == 'CONTENT_TYPE_NAME') {
      $variables['template_file'] = 'page-CONTENT_TYPE_NAME';

Then feel free to create such template file. As a reminder, no need to add the tpl.php extension to the value you assign to $variables['template_file']. Also, that name can be anything, I am just following conventions here by prefixing with page, as in page-SOMETHING.tpl.php. Make sure that the name you provide here matches the name of your template file.

Then, you are faced with a small problem: the template file will need to be placed in the theme folder in order to be picked up by Drupal's theme system. But you don't want that. So what to do? Here comes a situation where we can use the module hook HOOK_theme_registry_alter(). For the theme hook you want to provide special theming for (hook in theme parlance here), you will have to tell Drupal Hey, Drupal, please look in my module folder over here, you may find a template file you will need.

EDIT: As of Drupal 6.7, this last step should no longer be necessary. See this page in the Theming Guide on for details. I haven't had the chance to re-test my module without the following snippet.

function special_page_theme_registry_alter(&$theme_registry) {
  $theme_hook = 'page'; // my hook name
  // Get the path to this module
  $modulepath = drupal_get_path('module', 'special_page');
  // Add the module path on top in the array of paths
  array_unshift($theme_registry[$theme_hook]['theme paths'], $modulepath);
  // dsm($theme_registry[$theme_hook]['theme paths']);

And you are done.

What's more...

The hook function HOOK_theme_registry_alter() is called only when the theme registry is rebuilt, that is, when you clear your Drupal cache. (It is called for all modules that implement it of course.)

The hook is NOT called at every page refresh :-)

What a relief.

To test this, uncomment the dsm() call.

Last edited by Caroline Schnapp about 4 years ago.

Aug 20 2008
Aug 20

So I just made a new beta release of Language Icons. (If you don't know the module - it's the one adding the flag icons to the language selection block to the left, as well as on translated nodes.)

The most important thing in this module is probably that it now contains an upgrade path from when it was a part of the Internationalization module suite, namely converting the i18n_icons_* site variables to languageicons_*. I think I tested it rather thoroughly and made sure I'd covered most (if not all) cases of the variable not existing or having been set, but to the old default path, etc., etc. - but there is always the off chance that something was somehow missed. So please give the beta2 a spin, and if you can do it with an update, it'd be great. And don't forget to report bugs! ;)

(Also, once this has gotten some testing, I think we're close to a final release as well. I don't know how much Jose wants done on the module before releasing 6.x-1.0 final, but there isn't really a whole lot more to do to it now, other than adding flags, of course. :))

Aug 19 2008
Aug 19

This tutorial will be split into three parts - part 1 (this part) will explain how to set up the aggregation and import feeds, part 2 (to be published next post) will explain setting up cron to handle auto updating the feeds and will also cover using views to create some different site sections, and part 3 (to be published the post after that) will explain how to theme everything. In the tutorial I will be building a Drupal based sports news aggregation site, but you can obviously tailor this to whatever type of news items you'd like.

The goals:

  • Create an aggregation site which aggregates RSS feeds and outputs them in river of news style pages with the most recent news items first.
  • Create some different site sections (football and baseball) which only show news items related to that topic.
  • Allow users to filter news items by source (e.g. ESPN, BBC etc.).
  • Create RSS feeds of our aggregated pages which are available for our users.

The set up:
For this tutorial I'll be using the following:

  • A clean install of Drupal 5.10 (using Garland)
  • SimpleFeed 5.x-2.2
  • Views 5.x-1.6

A quick word on SimpleFeed vs other aggregation modules:
There are a number of other aggregation modules available for Drupal. From my own experience the two best are SimpleFeed and FeedAPI. FeedAPI has excellent functionality and can do some very cool stuff (for example, check out this video on which shows how to use FeedAPI and feed element mapping). However, in this case I've chosen to use SimpleFeed because I don't require any of this extra functionality and SimpleFeed is, well, the simplest to use.

Step 1: Set up the site and modules
Set up your Drupal site and then download and install the SimpleFeed module and the Views module. Select the following options for each module:

Drupal SimpleFeed and Views module options

Step 2: Install the missing file
In order for SimpleFeed to work correctly it requires that we place the file from the SimplePie library into our SimpleFeed module directory. If you currently go to your status report (admin/logs/status) you'll see the following error alerting you to this fact:

Drupal SimpleFeed SimplePie missing error message

So, to sort this out do the following:

  • Go to and download the latest version of SimplePie by clicking on the big 'Download' button (at the time of writing this is SimplePie version 1.1.1).
  • Extract the contents of the download, which will create a folder named 'SimplePie 1.1.1'.
  • Open this folder, locate the file, and copy it into your SimpleFeed module folder. So you should have 'sites/all/modules/simplefeed/'.

Now when you check your status report page you should not see any errors.

Step 3: Set up a vocabulary
In order to theme our news items more effectively, and to help us with filtering and sorting news items, we're going to assign taxonomy terms to them. SimpleFeed includes auto-assign functionality for taxonomy terms which will be very helpful here.

First, go to the 'Add vocabulary' subsection of the 'Categories' admin section (admin/content/taxonomy/add/vocabulary). Then create a vocabulary with the following settings:

  • Vocabulary name: Source
  • Types: check 'Feed' and 'Feed Item'
  • Check 'Free tagging'

Drupal vocabulary settings

Step 4: Configure your SimpleFeed settings
There are a few places where we can configure settings for SimpleFeed:

  • SimpleFeed settings page (admin/settings/simplefeed)
  • Access control 'simplefeed module' settings (admin/user/access)
  • 'Feed' content type settings page (admin/content/types/feed)
  • 'Feed Item' content type settings page (admin/content/types/feed-item)

SimpleFeed settings page
The SimpleFeed settings (admin/settings/simplefeed) are fairly self explanatory. In this
case we will use the following settings:

Drupal SimpleFeed settings

'Discard feed items older than:'
we always want our feed items to be available to users so we set this to 'Never'.

'Check feeds every:'
1 hour is good here as sports news is quite frequent, so we want to check for updates

'Default input format:'
we'll start be leaving this as the default 'Filtered HTML' option which will filter out
any HTML tags that are not specified in the input format settings (admin/settings/filters).
However, with RSS feeds you can find that unclosed tags in a feed item will have an
adverse effect on the rest of your page so you may need to remove further tags options
after some testing.

set this to 'Source' which was the vocabulary we set up in the previous step. This will
allow feed items to automatically inherit their parent's taxonomy terms.

'Automatically add categories set by external feeds to the vocabulary above'
we will leave this unchecked as we want to tightly control the taxonomy.

'Cron throttle'
the default 50 will be plenty for now!

Access control 'simplefeed module' settings
For this tutorial we're not going to change anything here, but you may want to depending upon the site usage.

'Feed' content type settings page
By default both the 'Feed' content type and the 'Feed Item' content type have their 'Default comment setting:' option set to 'Read/Write'. In this case we don't want users commenting on either so we'll change them to 'Disabled'.

To do so, first go to the 'Feed' content type settings page (admin/content/types/feed) and
scroll down to the 'Workflow' section. Then just change the 'Default comment setting:'
option to 'Disabled'.

Drupal SimpleFeed settings

'Feed Item' content type settings page
Do the same as for the 'Feed' content type and set the 'Default comment setting:' option to

Step 5: Find some RSS feeds
As this is going to be a sports news aggregation site I've gathered together the following RSS feed URLs and chosen a taxonomy term for each:

Just remember to check the terms of use sections on each of the websites regarding the republishing of feed content.

Step 6: Add your RSS feeds
Now everything is set up, let's add some feeds!
Go to 'Create content > Feed'. We'll start by adding the BBC sport front page feed with the following settings (the feed URL and taxonomy term are taken from Step 5 above):

Drupal - add a SimpleFeed feed

We've already taken care of all of the other settings (like input format, comment settings), so hit 'Submit'. The feed will be created and you should get the following confirmation screen:

Drupal - SimpleFeed feed created

Now we need to actually import the feed items.

We could wait for our cron job (which we'll set up in part 2 of the tutorial) to fire and trigger the auto update of the feed for us, but for now we'll do it manually.

So, click on the 'Refresh this feed' link and SimpleFeed will look for, and import, the new feed items. SimpleFeed imports each feed item as a node. After a second or two it should have found the new items, created the nodes, and output the following success message:

Drupal - SimpleFeed feed items created

One quick thing to note here is the first line 'The directory files/cache_simplefeed has been created'. If file permissions for this folder are not set correctly on your server it can cause cron errors, but we'll deal with this later on if it's a problem.

Finished! (Part 1)
If you now check the front page of your site you should see all of the feed items from the BBC front page RSS feed. Go ahead and add the other feeds the same way as the BCC feed (using the feed URLs and taxonomy terms from Step 5 above). The site won't do a lot yet, though, so we'll sort that out in part 2.

Also in this series
Build An Aggregation Site With Drupal (Part 2), where we set up cron to handle auto updating the feeds and also use views to create some different sports sections (football and baseball) and RSS feeds.

Coming soon...
In part 3 we'll get to theming everything.

Aug 19 2008
Aug 19

19th Aug

Simple bit of Drupal module code from yesterday: permissions are provided for each node type which can have attachments, providing a more granular permission set based on node type. Then, we alter any node add/edit forms and set the #access property for the attachments part of the form based on these new permissions.

Check the code out after the break, hope its of some use somewhere. Does anyone have any thoughts on unsetting form elements like this? Is it a wise thing to do, or is there a better way? Cheers to those who commented, I've modified the snippet accordingly.

  1. /* @file attachments_by_nodetype.module

  2.  *

  3.  * Simple granular permissions for uploading files per node type.

  4.  */

  5. /* Implementation of hook_perm(). */

  6. function attachments_by_nodetype_perm() {

  7. $permissions[] = "upload files to $type nodes";

  8. }

  9. }

  10. return $permissions;

  11. }

  12. /* Implementation of hook_form_alter(). */

  13. function attachments_by_nodetype_form_alter($form_id, &$form) {

  14. if ($form['type']['#value'] .'_node_form' == $form_id) {

  15. $form['attachments']['#access'] = user_access("upload files to {$form['type']['#value']} nodes");
  16. }

  17. }

Aug 18 2008
Aug 18

Here's a small snippet to allow the output of blocks in your user profiles. This is assuming that you are currently over-riding the user page with the following code.
Update!I've added code for both Drupal 5 and 6, take a look.

Drupal 5

* Catch the theme_user_profile function, and redirect through the template api
function phptemplate_user_profile($user, $fields = array()) {
// Pass to phptemplate, including translating the parameters to an associative array. The element names are the names that the variables
// will be assigned within your template.
/* potential need for other code to extract field info */
return _phptemplate_callback('user_profile', array('user' => $user, 'fields' => $fields));

(Code from: )

and have your user_profile.tpl.php named as so.

Settings up your block regions:

First we'll slip into our theme's template.php file and make sure we create a new region.

function basic_regions() {
return array(
'sidebar_left' => t('left sidebar'),
'sidebar_right' => t('right sidebar'),
'content_top' => t('content top'),
'content_bottom' => t('content bottom'),
'header' => t('header'),
'footer_block' => t('footer'),
'profile_block' => t('profile blocks'),

This allows us to create a new region called profile block which will hold all our blocks that we decide to put there. Now we want to be able to pass the $profile_block variable onto our user_profile.tpl.php to be outputted.

Adding the Block variables:

function _phptemplate_variables($hook, $vars = array()) {
switch ($hook) {
case 'user_profile':
$vars['profile_block'] = theme('blocks', 'profile_block');
return $vars;

Now we can go into our user_profile.tpl.php and add the following code anywhere in the file. This is where our newly created block region will be outputted.

echo $profile_block;

Drupal 6

In your file (themename being replaced by your actual theme name) add your block region.

(In our

regions[profile_block] = Profile Block

We now create our user-profile.tpl.php file where we will output the block region and any other profile information that we need. To expose the $profile_block variable to our user-profile.tpl.php, we add the following code to our template.php file:

(In our template.php)

function phptemplate_preprocess_user_profile(&$variables) {
$variables['profile'] = array();
// Sort sections by weight
uasort($variables['account']->content, 'element_sort');
// Provide keyed variables so themers can print each section independantly.
foreach (element_children($variables['account']->content) as $key) {
$variables['profile'][$key] = drupal_render($variables['account']->content[$key]);
// Collect all profiles to make it easier to print all items at once.
$variables['user_profile'] = implode($variables['profile']);
$variables['profile_block'] = theme('blocks', 'profile_block');

Note the added $variables['profile_block'] = theme('blocks', 'profile_block'); at the end. This allows us to access the block region, profile_block, by echoing out $profile_block in our user-profile.tpl.php file like so:

(In our user-profile.tpl.php)

echo $profile_block;

Voila! Block regions in our user profile template file!

Aug 18 2008
Aug 18

The author's copies of Pro Drupal Development, Second Edition arrived today. At 667 pages, the book is significantly thicker than the first edition!

I worked on this edition from November of 2007 to July 2008 pretty much without stopping. One morning my daughter found me in the living room writing a chapter at 3 am. It is difficult to express how much work this book has been, and how happy I am to hold the printed copy in my hands. Those who have written books will understand. :) I am glad to finally have it get into the hands of Drupal developers everywhere, and I hope that this contribution helps to complete the transition from Drupal 5 to Drupal 6. Thanks so much to all who have helped with this project!

Profits from the book go to this little guy's college fund. (And if you buy it through, the Drupal Association gets a percentage of each sale.)

Aug 16 2008
Aug 16

The above silverlight application will allow you to do the following actions:

  • Login
  • Anonymous login
  • Create a new user
  • Logout

You can do multiple actions above during a silverlight session; there is no need to refresh the page for the actions to take effect within the silverlight application. But refresh the page once your account is created or when you are logged in to allow drupal to recognize the changes.

drupalLogoDrupal is an open source content management system (CMS) that allows users to add modules to their sites for great flexibility. These modules are typically written in PHP and use drupal's API to connect themselves with the framework. Silverlight (version 2.0 and greater) is a cross-platform browser plugin that allows users to write managed .NET code for the back end and use XAML as the front end. Since silverlight is a browser application and drupal is a framework for hosting data in browsers there can be data that is shared between the two using HTTP as the transport. In this example, I have chosen to use XML-RPC as drupal uses xml-rpc natively and silverlight can easily take advantage of this.xmlrpc

One thing to note, drupal has a module called services that is currently under development that will allow external applications (such as silverlight) to easily communicate through various interfaces, such as: XML-RPC, SOAP, REST and AMF. I am NOT using this module in my example.

Custom Module for Drupal:

As far as the drupal side of things go, I have a basic install of drupal 6.2 with a custom module that I have written to communicate with my silverlight application. I wrote the module based off of tips from Pro Drupal Development using chapters 2 and 19. There are two files that are needed to construct a drupal module: a .info file that contains information about the module and a .module file that is the actual custom module. My custom module is extremely simple in which it implements hook_xmlrpc to map xml-rpc methods to php callback functions. The xml-rpc methods are received from silverlight and then call the appropriate php function with the appropriate arguments. My php functions do various tasks, such as: checking the drupal database to see if a user exists so that user can login if the correct credentials are supplied,logging in an anonymous user, logging a user out and creating a fully authenticated user. Once the module is uploaded to the server, enable the module and your done! Well, done with the drupal side.

Silverlight application:


There are currently two methods in silverlight to communicate via a web service (in this case xml-rpc): WebClient and HttpWebRequest. HttpWebRequest contains all of the properties and methods that WebClient has and then some. But of course the extra goodies that HttpWebRequest provides come at a price; added complexity. WebClient is extremely easy to use and only requires one event and one property to be used, all though there are additional events and properties that can make life easier. Here are the events and properties that I have used in my application:

drupalDB = new WebClient();
drupalDB.UploadStringCompleted += new UploadStringCompletedEventHandler(drupalDB_UploadStringCompleted);
drupalDB.UploadProgressChanged += new UploadProgressChangedEventHandler(drupalDB_UploadProgressChanged);
drupalDB.UploadStringAsync(location, xmlData);

drupalDB is my WebClient and there are two events defined that will notify me when upload progress has changed (perfect for a progress bar) and completed. The property, UploadStringAsync takes in a Uri and a string as the data to upload to the web service. One thing to note here is that I am using UploadStringCompleted and not DownloadStringCompleted as WebClient does a GET for downloads and a POST for uploads and xml-rpc only accepts POSTs.

The data that I am uploading to the xml-rpc service is a string that is xml formatted that uses the standard xml-rpc definition:

string xmlData = "<?xml version=\"1.0\"?>"
              + "<methodCall>"
              + "<methodName>userlogin.logAnonIn</methodName>"
              + "<params>"
              + "<param>"
              + "<value>"
              + "</value>"
              + "</param>"
              + "</params>"
              + "</methodCall>";

There are two important things to note here. The tag <methodName> contains the xml-rpc method that the hook_xmlrpc function will map to a php function. The first part of that argument, userlogin is the name of my module and a standard format that drupal follows. The <param> tag contains a <value> tag where an argument can be passed to the hook_xmlrpc function. If multiple arguments are required then one needs to add additional <param><value>my data here</value></param> tags in between the <params> tag. Once the data is sent from silverlight to drupal and the appropriate mapping php function is processed, a return value is sent back to silverlight:





        <string>return value</string>





The UploadStringCompleted event will fire once all of the above data is received. A popular way to parse the returned data is to use LINQ. LINQ is very powerful and very easy to use once you learn a little about it. I can parse the above data with the following LINQ statement:

XDocument document = XDocument.Parse(e.Result);
List<MethodToCall> methodsToCall = (from user in document.Descendants("value").Elements("string")
                                    select new MethodToCall
                                        MethodName = user.Value

I place the result in an XDocument and use LINQ to parse the document for any node 'value' that has a child node 'string'. This is the standard format that xml-rpc sends. If there are multiple arguments then there will be multiple 'value' nodes. I call ToList() on the LINQ statement to create a generic list for multiple arguments that may be passed back.

With my particular application, since I can control what I send to and from the xml-rpc service, I decided to use reflection and pass back a string from drupal that I have defined as a method in my silverlight application. One thing to note here is that arguments are passed back as objects. If multiple arguments are passed back they are each an object, not an object[] so your method must take multiple arguments that are each objects instead of one argument of type object[].

After my method is called via reflection I simply update my user object as appropriate. And that's it! That is the basics of how to get drupal to talk to silverlight and vice versa. Of course, one needs to add some more logic and flare to a silverlight application to take advantage of the data it receives from drupal. I have added a few items that hopefully make the user experience that much better (and easier) in my user login application.

As a side note, once silverlight is configured on your web server all you need to display the silverlight application is the following html code placed wherever you would like:

<div style="width: 325px; height: 350px;">
    <object data="data:application/x-silverlight," type="application/x-silverlight-2-b2" width="100%" height="100%">
        <param name="source" value="/silverlight/SLApps/DrupalGameDemo.xap" />
        <!-- Only need the below to show a link to get silverlight if it is not installed -->
        <a href="" style="text-decoration: none;">
            <img src="" alt="Get Microsoft Silverlight" style="border-style: none" />

The <object> tag contains a <param> tag that has the 'value' attribute of the location of your .xap file. The link in the above html code (<a> tag) is the link that will be displayed if a user does not have silverlight installed.

Feel free to try out the attached silverlight source (application is also displayed at the top of this page) and change things to your liking. Enjoy!

I have uploaded the custom module file as 'userlogin.txt'. (Rename it to .module) Remember to include a '' file as well to complete your custom module. You can view the module file with notepad.

The LayoutTransformControl that I am using has been updated to the RTW bits. The latest code required additional code to update the transform at any time an animation was fired that would normally update the transform. Dave talks about why that is and one of the comments in his post points out a simple way to achieve this. Go grab this control as it's a great control to keep in your toolbox!

AttachmentSize 448.1 KB 3.6 KB
Aug 16 2008
Aug 16

Yep, I am coming to Drupalcon: its great to have a convention so close to home (at least it's the same East Europe). But before I'd like to have a little pre-conf rant, sort of an introduction of my thinking. I'd like to collect together some fundamental problems in Drupal user interface. Being out of active contribution phase but closely following the development from the shadows here are my observations.

But before getting to issues, first some meta-level talk.

We all know Drupal has changed from humble “nicely designed CMS” to hyper-powerful CMF and pains and complexities of UI decisions have grown exponentially. Being so open-ended, so plug-and-play, so drupal-is-whatever-you-want-it-to-be is in direct contrast of process of creating simple, user-friendly UI what removes say unnecessary config screens and makes some decisions for the user. Thing is: The key for Drupal end-user experience is often not what we do in core UI but the administrator what uses his super-Drupal-toolbox to shape the UX. He can either make it really nice, removing UI baggage, picking best possible UI components and themes (just look what Michael Angeles is doing over or completely overload the site with ridiculous add-ons and non-functioning themes.

So what we should do?

As we giving the site builders the best possible code components and APIs we also need to give them the best possible UI components and enforce and share the best practices. We need “Drupal UI Police” what provides law and order in this rebel countryside. We need a good Drupal Human Interface Guide so developers and site admins can follow this and Drupal shops can base their own HIGs on Drupal HIG.

Now, on to the problems.

UI design process

The nature of Drupal development is shaped by several factors, such as being a OSS project and being heavily driven by talented coders. This is reflected both in human relations (decision processes) and available project managing tools. User experience-centered design has yet to find its place to this process. We do not have many things:

  • No lead UI designer or “core design team”
  • No “UI core committer”
  • No roadmap or vision for UI
  • No “visual sandbox” where UI designers can play around with UI prototypes (either views + panels – based, html mocks or static images) what we could crowd-source the usability testing
  • No proper UI / usability metadata for issue filtering. See
  • No proper usability testing process (different big academic initiatives on this have been great but what we often need are lot of quick crowd-sourced cheap tests in small scale).
  • How we could get some eye tracking coolness in? :)


We have lost (or semi-lost) several very talented Drupal UI contributors / consultants: Chris Messina, Michael Angeles, Steven Wittens, Peter Van Dijck (am I correct?). How to engage them, how to bribe them to come back?

UI challenges

Ok, now the UI challenges in no particular order nor grouped around common topics. I just had to let it all out, quick. I do not touch the issues what are listed on – these gonna be interesting sessions and hopefully filled with great solutions.

Lists UI

We need proper:

  • Selecting: standardized UI for selecting “all in page”, “all in page + subpages”, “none”, "
    " (think Gmail)
  • Actions on selected list elements: the current dropdown in inefficient: it does not give enough hints what are the outcomes of certain action, is there a confirm screen before real action, is the action reversible / undoable. Also, several actions need additional settings / tinkering / confirming what ideally would happen next to the action dropdown (example: associate with term → add new term).

  • Filter: current filter is hard to understand mess: replace with standard “smart folder / e-mail rules”-style filter

There already some word done with views plugin though.

Inconsistent “add new item” entrypoints and forms

In core we use a link on top of listings (“add new blog entry”, …), “add” tab, embedded add form in top of the listing or below the listing and in some contrib modules even popups.

This needs standardization and consistency.

Admin Space vs User Space

Ah, the lovely discussion, going back how-many-years. So far the alternative models for user/admin space have been “Joomla/Wordpress/MT” style clearly separated admin pages vs Drupal all-meshed-together approach.

Perhaps we should look it with a fresher perspective, there are already several developments what use smarter UI to both distinctively separate user / admin space _but_ still provide preview of live site for instant feedback of changes:

Edicy (screenshots and the blog post where from it all started)

Similar ideas can be also seen in Drupal client localization UI and theme helper palette.


There are clear steer in community to get it right, Gabor battle plan and some healthy discussion going on. My ideas on this are:

  • think in larger context: palettes, inline elements draggable inside content – this all needs not just pluggable wysiwyg API but more flexible / interwingled APIs (in the lines of sun's inline api)
  • provide best possible user experience for all “classic” editor options:

-- plaintext editor in core – markup editor in core or in contrib – wysiwym editor in core if drupal-specific and superlight: (think bloated SimpleTest → lean DrupalTest). Hide all unnecessary tools (or even better: work inside-out, start adding tools conservatively)

Using horizontal space

Drupal is very vertical e.g. we are not using much horizontal space what widescreen monitors and improved resolutions give us (compare the situation of early days Drupal).

There has been some UIs though what have been exploring using vertical space more effectively:

  • views 2.0 UI
  • panels 2.0 UI
  • fieldsets in node edit forms (dropped because on theming complexity and introduction collapsible fieldsets)….preview.png
  • 2-column layout of /admin

Views + Panels + CCK UI

These “developer eliminator” modules really provide a huge advantage for Drupal to break to the mainstream and differentiate from any other cms/cmf because the flexibility of these tools is just unmatched. And all can be done without coding!

In the same time the intuitiveness of UI of these modules really crumbles under the weight of flexibility (read: complexity). Views 2.0 has made some good progress, providing a glimpse of nextgen interfaces but there is still a long way to go. CCK builds on core content type UI and does not contain _that_ much of complex interactions but there are still loads of UI problems (some of them are noted below). Panels seems to be in worst shape: many elements and configurations screen are just way too cryptic and require a lot of background knowledge and endless screencast-watching.

Also note that these mission-critical modules are using non-core UI widgets and concept, everybody having their own visual language. It is good in terms of development and exploration (somebody had to do the advanced help, vertical tabs, live previews, drag-and-drop blocks etc) but in a final product this diversity kills consistency, lessons learned in one module do not help in other and user experience is hurt.

Cascading settings UI

We have a problem handling UI cascading, global-vs-local settings. It's a super-powerful concept in theory It's hard to understand for the user how toggling the setting in global space affects the local setting etc. Also, every such a case handles the UI a little bit different:

  • Views: global vs local overrides between subviews
  • CCK (global and field instance settings)
  • Theme settings: global vs theme-specific


Notifications API and UI are very inflexible and are riddled with problems

  • no icons (see the “No icon API”)
  • no notification aggregation, grouping
  • not scalable for big number of notifications or notifications with long content
  • placement is static: no way to do “Yellow Fade Technique”-type inline indications or inline, spacial context related notifications
  • perhaps not always optimal placement (see Googles “yellow bar”, it “jumps” dependent on the context)
  • permanent messages (“you are in offline mode”, admin/reports/status") vs temporary messages

Aging look of UI widgets and no icon API

Time flies fast and once-cool progress bar and ok/notification/error look aged and buggy There are some cool work done such as icon API and icon API guidelines – have not looked into it with that much detail but gut reactions say theme(‘icon’,‘error’); and icon filename standardization (and possibly name cascading in spirit of tpl.php cascading) is good and necessary – but the term “icon packs” give me shivers. Possibly there has been just too many horrible icons packs out there? Anyhow, some icons work well with some themes and some not and sometimes it is not really up for admin skills to specify it. Perhaps we need a ‘icon pack compatibility’ field on theme .info file? ;)

Broken Flows

Installer: not really broken but can really smoothened out: kill unnecessary steps (merge 1st and second screen of installer, merge 1st and 2nd screen of update, merge last screen of the installer and first welcome screen); simplify site settings form; clean up password strength UI etc

Adding new module: discussed to death but not much done in terms of indicating next steps after enabling the module. Literally we need to convert INSTALL.txt to the task-centric UI. Possibly has a strong dependency on nextgen notifications UI.

There are other critical flows and some of them – Where did my content go and 1st screen – will be discussed in Szeged BoF, that's cool.

No standardized UI and behavior for js popups

We use browser-frame popups, inline elements (password strength), expanding panels (form field groups) or we just taking user to another page, ruthlessly breaking the flow (extended filter hints)

We need standard UI pattern for these elements. This can be used for nextgen help, filter tips, inline term adding, all kind of palettes (panels).

No nextgen help

Discussed and projects underway, GHOP and Views 2.0-wise. My quick thoughts: help should allow inline, spatially contextual hints (see notifications UI and popups above), standardized “read more” behavior and look; clear distinction between local and help pages.


Ah, poor tabs.

AFAIR tabs were introduced when more rigid page structure $title . $tabs . $content was needed and we did not wanted to mash everything to the $content blob.

Originally tabs were meant for “local tasks”: actions you do in local page context, under the same header. This is echoed in Menu API (MENU_LOCAL_TASK) and in many core pages where original guideline "tab titles have to be active verbs such as "view, edit, configure"" still exists. During tab introduction there was lot of talk that we need introduce tab UI guidelines and tout them to module developers as best practice. But pretty soon such a constraint proves inflexible and module devs AND core devs started to mangle and misuse tabs / local tasks in every possible way.

Tab's Problems:

  • people do not see tabs
  • some tasks are are more important than others: it's ok to hide complex, never-touched configuration form under a tab but poor “add” needs way more spotlight.
  • very OO-mapped, “object_id/action” (echoed in URL) based on system architecture (system mental model), not user mental model. Especially bad is search results approach to tabs: instead showing all results (grouped by type) in one screen as user expects coming from any web search around, search module “sticks to Drupal standards” and pushing the results to different tabs, completely ignoring the original tabs-as-verbs concept.
  • hard to use outside the originally designed context, such as $tabs . $title . $content
  • no support for js-enabled tabs such as jQuery tabs.
  • horizontal tabs have known scalability problems
  • LOCAL_TASK and it's rendering are too tightly coupled. We need to decouple them. Tabs rendering component should allow re-usage for different contexts (primary / secondary links, other global tabs, tabs in blocks – there are some initiatives around Views plugins on this)
  • LOCAL_TASKs could be rendered in a different way when needed, such as Basecamp or UI where tasks are on right column? Or should some tasks brought over to initial screen as inline/expandable element instead invisible tabs?

Pushing the limits of HTML form elements

Known issue, discussion is bubbling and hierarchical select module has been around for some time We need action!

Some broken, never-usability-tested UI widgets made it to interface

  • “Split summary at cursor”. No comments.
  • Password strength meter. Not totally broken, after redesign can even prove to be usable


It's great addition to Drupal UI but has several problems still:

  • Saving: the asterisk * next to a moved item and invisible footer message (again a non-standard one) just do not communicate the need to save page in order to store changes.
  • It works well only when dragging list items vertical dimension: in block configuration page users just do not get the limitation why they cannot move items around to to real block containers, especially when dragging affordance (4-way arrow) tells them so.

Now what?

While this all seems all-talk-and-no-constructive action, I am really trying to get time to get back to Drupal this autumn and help out in every way I can. See you in Drupalcon!

Aug 15 2008
Aug 15

SXSW InteractiveI'm certainly not the first to post about this, but it looks like Drupal will have a strong showing at SXSW Interactive 2009. There's even a front page post on to bring awareness. A group of us from Lullabot went last year and we had an absolute blast. If you haven't been, sign up now!

The panel picker is live and I suggest you *all* vote for Drupal with Its Pants Off (you know you wanna). What's really exciting, though, is the long list of other Drupal panels on the list.

Looks like there'll be lots of Drupal in Austin next March... even is Drupal powered!

My hotel is booked. See you there!

Aug 15 2008
Aug 15

SXSW InteractiveI'm certainly not the first to post about this, but it looks like Drupal will have a strong showing at SXSW Interactive 2009. There's even a front page post on to bring awareness. A group of us from Lullabot went last year and we had an absolute blast. If you haven't been, sign up now!

The panel picker is live and I suggest you *all* vote for Drupal with Its Pants Off (you know you wanna). What's really exciting, though, is the long list of other Drupal panels on the list.

Looks like there'll be lots of Drupal in Austin next March... even is Drupal powered!

My hotel is booked. See you there!


About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web