Restarting the BlogAPI Alternative project


In Drupal 5 and 6 there was a module shipped with core called "BlogAPI" which provided the necessary plumbing to let you post content using desktop clients that supported a variety of APIs. Unfortunately the module languished and, while APIs improved, the module's support for them did not keep up. During 2009 my employer at the time, Bonnier Corporation, wanted a way for their editorial staff to post content while working remotely, so I created the BlogAPI Improved project to add improvements to the module. As often happens, Bonnier decided to postpone their mobile efforts and focused on their core (desktop) web experience instead; when this happened I let the module languish as I just didn't have time to commit to it.

In Drupal 7 the BlogAPI module was removed entirely from core and moved into a separate project which someone volunteered to maintain. After several years, after a ChipIn fundraiser met its goals and with dev versions available for two different branches, there's still nothing available for Drupal 7 that works.

While the whole BlogAPI platform was languishing, along came dedicated projects like Drupad, which used a combination of a contrib module and a customized application to post content, the hope being that by controlling both ends of the equation it should be more reliable & powerful than 10-year-old APIs. At the same time many of the iOS and OSX blogging tools disappeared, e.g. both Ecto and iBlogger were bought out and are currently unavailable, so the market for client software is questionable.

When I decided to upgrade my personal site to Drupal 7 one of my goals was to be able to post content using one of the various iOS clients available. Unfortunately my attempts at posting with Drupad failed, so I'm back to needing BlogAPI again.

Which brings me to the point of this post.

I've started development of the BlogAPI Improved module again, which I've renamed to the more appropriate BlogAPI Alternative as it more clearly speaks to my goals for it, and the first beta for Drupal 7 has been released. My sole aim for this project is to provide a temporary solution while the official project is finished; once there's a working version of the main BlogAPI project, with a working upgrade path, I'll be more than happy to retire BogAPI Alternative.

"Why didn't you just join the official BlogAPI project?" you may ask. Simply put, I don't have a lot of time to put into maintaining it, so slapping putty & duck-tape onto an existing module will take less of my time than learning the Services API and trawling my way through a new codebase; further, it means it'll take less time for me and other people to be able to start writing blog posts offline. Also, it provides some temporary relief from the official module's maintainer(s) so their issue queue isn't filled with people bitching that nothing has been released yet. Finally, it keeps a distinction between a project that has already been sponsored by several companies, versus my project which has not.

I'll see you in the issue queue!

Site upgraded to Drupal 7

Over the past few days I did a very simple upgrade of my site from Drupal 6 to 7. I'm also working on a theme update and, you know, writing more, so stay tuned.

Lullaby Renditions of Coldplay


My Rating: 

Average: 5 (1 vote)

Originally posted on Rockabye Baby!'s website as a review.

While the Rockabye collection is very good, not many artists produce music that is as well suited to lullaby renditions as Coldplay, particularly the "Parachutes" and "A Rush of Blood to the Head" albums which this is based around. As a Coldplay fan I can sit and listen to this album alongside any of the band's regular albums, it fits marvelously.

That said, the proof has been in how much our youngest has simply adored this particular album - we've used it for *several* *years* as nighttime music for him, ever since he was a very young infant, and he has been completely transfixed by it and he quietly, peacefully and happily drifts off to sleep quite quickly. I can't count the number of car rides our sanity has been saved as the over-tired, unhappy and doesntwanttobeinhiscarseatanymoreNOWMOMMY toddler relaxed almost instantly upon hearing "In My Place" starting.

This album has a special place in our hearts for both its brilliance and how well it has helped our lives, we'll always be grateful to you for producing it. Thank you.



Customize the Subscriptions terms list


A client recently requested instructions on how to customize the Subscriptions module's user subscriptions page to show more details instead of just the term title, e.g. show a description, image, etc. Thankfully this turns out to be pretty easy and just involves using hook_form_alter to customize the labels.

To use the following code just add it to a custom module and replace the "mymodule" bit with your module's name.

FYI this depends upon the patch from and is for Drupal 7.

 * Implements hook_form_FORM_ID_alter().
 * Replace the term labels on the User Subscriptions page. This works by
 * building a full display of the term, thus the term's display should be
 * configured & themed as necessary.
function mymodule_form_subscriptions_page_user_overview_alter(&$form, &$form_state, $form_id) {
  // Only proceed if the 'taxa' field is present, thus the Taxonomy
  // Subscriptions module is enabled.
  if (isset($form['taxa'])) {
    // Process each vocabulary.
    foreach ($form['taxa'] as $key => $data) {
      // Vocabularies will have a numeric $key and the $data will be an array.
      if (is_numeric($key) && is_array($data)) {
        // Change the label to a copy of the term rendered out fully.
        foreach ($data[0]['labels'] as $tid => $label) {
          // Load the term.
          $term = taxonomy_term_load($tid);

          // Build the display array for the term. This can be changed by adding
          // another attribute to the function to specify the view mode - see
          // for full details.
          $term_array = taxonomy_term_view($term);

          // Render the final output & replace the label.
          $form['taxa'][$key][0]['labels'][$tid][-1]['#markup'] = render($term_array);

This results in the page listing taxonomy terms as follows:
The subscriptions list now shows the full taxonomy term display, not just the title.

Simple HTTP authentication for Drupal sites [updated]


There are lots of times when you need some simple password protection, typically via HTTP Authentication, on your Drupal site; my most common use being for publicly accessible development sites that I don't want accidentally indexed by search engines. Thanks to some simple code, based on something originally written by someone at Acquia (thank you, phantom coder!), it's pretty easy to add HTTP authentication to your site and then enable it per site instance; this will keep your codebase and your modules list pretty clean. FYI this works equally well on both Drupal 6 and 7.

There are three parts to this solution:

  1. Modifying the .htaccess file to allow the authentication.
  2. A function that can be added to settings.php or elsewhere in the execution process.
  3. A function call that is used as the on/off switch.

Step 1: Customize the .htaccess file

The first piece is a new line that needs to be added to the .htaccess file:

  # Password protection.
  RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

This should be added at the end of the file, just before the final , so that it looks like so:

  # Password protection.
  RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

Step 2: Add the Special Function

All of the logic is housed in a PHP function that needs to be added to your site, probably the best location being your settings.php file.

 * Password protect the site with a single function.
function secure_the_site_please($username = 'monkey', $password = 'monkey', $message = 'This site is protected') {
  // Password protect this site but ignore drush and other command-line
  // environments.
  if (php_sapi_name() != 'cli') {
    // PHP-cgi fix.
    $a = base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"], 6));
    if ((strlen($a) == 0) || (strcasecmp($a, ":") == 0)) {
      header('WWW-Authenticate: Basic realm="Private"');
      header('HTTP/1.0 401 Unauthorized');
    else {
      list($entered_username, $entered_password) = explode(':', $a);
      $_SERVER['PHP_AUTH_USER'] = $entered_username;
      $_SERVER['PHP_AUTH_PW'] = $entered_password;
    if (!(isset($_SERVER['PHP_AUTH_USER']) && ($_SERVER['PHP_AUTH_USER'] == $username && $_SERVER['PHP_AUTH_PW'] == $password))) {
      header('WWW-Authenticate: Basic realm="' . $message . '"');
      header('HTTP/1.0 401 Unauthorized');
      // Fallback message when the user presses cancel / escape.
      echo 'Access denied';

Step 3: The on/off switch

The final step is to add the following line to the end of the settings.php file somewhere after the function above:

// Password protect the site.

This is the master on/off switch that lets you control the authentication functionality. You can easily disable it as needed just by commenting out the line, then the site will continue to work as-is without any problems.

You may have noticed that the function had some arguments? You can use these arguments to change the default username & password from "monkey" to something more relevant, or easily remembered, e.g.:

// Use a custom username & password.
secure_the_site_please('albatross', 'mint');

The function accepts a third argument which controls the message displayed so it can be changed from the default "This site is protected" to something more suitable, e.g.:

// Use a custom username & password.
secure_the_site_please('albatross', 'mint', 'What flavor is it?');

Or even:

// Use a custom username, password & message.
secure_the_site_please('albatross', 'mint', 'The username is "albatross" and the password is "mint"');

Final notes & thoughts

The main reason I like this solution vs e.g. SecureSite is that it doesn't require a different set of modules for one site vs another, all that's needed is one change to the settings.php file and it's easily turned on or off.

I include a settings_shared.php at the top of each settings.php file to store shared settings between all of the per-hostname site instances, and this is where I added the function. On one site I had 44 different per-hostname settings files for four different instances of eleven sites, half of which needed to be protected, so it was very easy to have the function in the settings_shared.php file and then just add the function call to the individual settings.php files.

The HTTP authentication variable, "HTTP_AUTHORIZATION", was so-named so it could be compatible with Drupad, which also uses HTTP authentication; please note that you currently must have this authentication disabled in order for Drupad to work.

So, what do you use to product your in-development sites from prying eyes or being accidentally scraped by search engines?

Updated April 9th:
Thanks for all the feedback. It turns out that the Shield module can basically do this too, using variables (that can be added to settings.php) to control everything; also the SecureSite module has an on/off switch variable so in effect it could be used too. FYI the reason I didn't use any Drupal 7 functions was so that the same code snippet would work with D6 too.

Updated April 12th:
Fixed a small =) bug that inadvertently allowed any password to be passed through, once the username matched.


Subscribe to Front page feed