“A wakeup call for the Drupal community”

Freeman recently wrote A wakeup call for the Drupal community and I wish I could have put the failings of the Drupal CMS as well as he has:

This is a common theme in the community. You can kludge your way to victory with just about any feature set you can think of if (and only if) you write enough hook_$n_alter() code, can find some contrib modules to pick up the slack, and have a designer who can code php tucked in your back pocket

Freeman’s states that the reason Drupal failed to win CMS of the year over WordPress is because WordPress is simply easier to use.


Drupal Internet Explorer 6 has a hard limit of 31 CSS files

I don’t know what’s worse, that Drupal Internet Explorer has an arbitrary limit on how many CSS files it can include, or that we’re developing a website with 32 separate CSS files.


Customizing an RSS feed using Drupal and Views

Note: This has only been tested with Drupal 6.x.

For some boneheaded reason, the latest version of Views for Drupal doesn’t let you customize the fields output in an RSS feed. If you create a new feed view, under the Fields block, you’ll get a message saying “The style selected does not utilize fields.” Well la de da. This means you’re stuck displaying the default content, despite which fields CCK says it is displaying or hiding.

Of course. Why would you want to customize your fields, anyway?

So here’s how I was able to customize the RSS fields output by including the entire node in the RSS feed results. If you want a tutorial on how to first setup an RSS feed, there’s a tutorial on creating a custom rss feed in Drupal.

Now that you have your feed setup, you’ll see there’s nothing you can do with it. But there is a Views function you can overwrite in template.php to add more data to the output rows.

 * Default theme function for all RSS rows.
function phptemplate_preprocess_views_view_row_rss(&$vars) {
  $view     = &$vars['view'];
  $options  = &$vars['options'];
  $item     = &$vars['row'];
  // Use the [id] of the returned results to determine the nid in [results]
  $result	= &$vars['view']->result;
  $id		= &$vars['id'];
  $node		= node_load( $result[$id-1]->nid );
  $vars['title'] = check_plain($item->title);
  $vars['link'] = check_url($item->link);
  $vars['description'] = check_plain($item->description);
  //$vars['description'] = check_plain($node->teaser);
  $vars['node'] = $node;
  $vars['item_elements'] = empty($item->elements) ? '' : format_xml_elements($item->elements);

I need to get a real code parser. This is just embarrassing.

What I’ve done above is use the 'result' array and 'id' value returned in the &$vars variable to determine the node ID of the returned results. The ID is just the position the node appears in the list of results (1,2,3,etc.). It’s one higher than the keys to the objects in the ‘results’ array (0,1,2,etc.) so just tell the function to get the nid in the object at position ID minus 1, and now you have the nid of the result. I load the nid into the &$vars array to be sent to the Views template, which I’ll get to now.

Views already has support for templates, but my complaint with its templates — like my complaint with much of Drupal — is that it gives you a half-finished template. It doesn’t give you the perfectly-rendered, nicely polished HTML to want, and it doesn’t give you an array to customize how you see fit: it gives you something in the middle, usually consisting of an array of preformatted elements. So thanks for that. I hope you like all your content wrapped in <p> tags! Well, most of the time, anyway!

Ahem, where was I? Ah, the template. Views recommends using a template called views-view-row-rss.tpl.php (you’ll notice it corresponds to the function name above). This is the most generic RSS template, but you can use a more specific one if you don’t want to use the same formatting on all your RSS feeds. Now that you have the $node variable at your fingertips, you can put any of the node content in the feed. Here’s what I did with it.

< ?php
// $Id: views-view-row-rss.tpl.php 3296 2009-05-27 23:08:21Z timtoon $
 * @file views-view-row-rss.tpl.php
 * Default view template to display a item in an RSS feed.
 * @ingroup views_templates
	<title>< ?php print $title; ?></title>
	<link />< ?php print $link; ?>
	<description>![CDATA[< ?php 
		$desc = $node->field_teaser[0]['value'] ? $node->field_teaser[0]['value'] : $node->body;
		print nl2br(check_plain(trim($desc)));
	< ?php print $item_elements; ?>

Christ how can anyone read that. Fixed! Anyway, nothing too fancy here. I don’t like Drupal’s auto-truncating teaser field, so I’m using my own in a custom field called field_teaser. But if there is no field_teaser value, use the whole node body. I hope this isn’t too many unrelated things to make a clear example.

Now that I have my node’s teaser/body, I trim the content, use Drupal’s check_plain function to do the same thing as PHP’s strip_tags method, and convert the new lines to line breaks using nl2br.

So your RSS reader won’t try to parse those <br /> tags as XML, I enclosed the content in <![CDATA[ ... ]]>, so now you won’t lose any formatting that wasn’t just stripped out by check_plain.

At last, I have a custom-formatted RSS feed showing only the field I want. I can use this to put whatever node content I want into my RSS feed, and if you have been able to follow my rambling example, so can you!

There is another method here: Control Title link and “read more” in RSS Feed of views


Fix to Drupal to allow NOW() and CURRENT_TIMESTAMP in new tables

This is why I hate CMS software — their incessant, misguided need to over-abstract every little detail. Take for example Drupal’s system for including additional tables into your existing MySQL database. Drupal would have you create a needlessly complex multidimensional array of all the elements in your new data table schema, created with a separate function and called by another custom Drupal function. Because I guess including the actual SQL to create a table was just too fucking simple.

So here’s Drupal’s way of doing it. I hope you like nested parens!