Open source <acronym title="content management system">CMS</acronym> powered by PHP and MySQL.

Drupal 9 Is Here, and the Pirate Module is Ready. Yarr!

In anticipation of the June 3rd launch of Drupal 9, I spent the weekend a week previous to the launch dusting off the Drupal module I'm most famous for: the Pirate module! What does it do, exactly? Like the WP extension, the Pirate module changes your site's content to pirate-speak on September 19th, International Talk Like a Pirate Day. I took the tagline ("Ah, Squiddy! I got nothing against ye. I just heard there was gold in yer belly. Ha ha har, ha ha ha har!"), which I buried in the configuration, from a non-pirate, sea captain Horatio McCallister. (Spoiler alert: He's not even a real sea captain.) It adds a text filter (previously known as an input format) to whatever field you specify, and on September 19th, that field's content is changed into various pirate-like sayings, interspersed with yarr! and avast! During Drupal's semantic versioning transition, versions 8.x-1.1 forward are intended to be fully compatible with Drupal 9.

The module started out as an internal ticket at Bryght in 2005. Boris Mann came across the Talk Like a Pirate plugin for WordPress, and since both Drupal and WordPress are written in PHP, he wanted it ported over. I took the ticket, 45 minutes before a colleague saw it and, almost 15 years later, it serves as the project I use to keep up with Drupal internals. Thanks to a patch from Snehal Brahmbhatt, later confirmed by a robot, I am able to legitimately claim that the module has full Drupal 9 compatibility. (Unlike the move from Drupal 7 to 8, Drupal 9 is an update, not a rebuild.) It has had an official release for all versions of Drupal since 4.6.

Over the weekend of updating the module for D9, I caught wind of DrupalSpoons, and without fulling realizing the implications, I applied to have the Pirate module mirrored there. (Moshe was excited!) After reading the DrupalSpoons announcement, I understood it to be an experiment in using GitLab as the issue queue and repository platform more directly than the Drupal core and contributed modules projects, which uses GitLab as an underlying provider for their official repositories. As long as code and issues are synced between the two, I don't have a problem pushing and responding in both spaces.

I'm looking forward to September 19th this year and years to come. Yarr!

Just a Gwai Lo Supports Dark Mode

I have to say, I was skeptical about dark mode in our current operating systems, but since wiring it up to switch to it automatically after sunset, I’m a believer. I know some people always operate their in dark mode, and that's not for me. I prefer the light on my screen to match the light of the day. It's especially nice to have my iPhone in dark mode at concerts, so I can avoid being "that guy" who blinds the person behind me,

Websites now respect the system setting of dark mode, and ever since Jeff Geerling updated his site's theme to support dark mode, I had on my list to do the same.

It turns out that the Responsive Blog Drupal theme, a very nice theme that does what it says on the tin, has a switch for turning on the dark mode version of it. I'm glad I realized that most of the work had been done for me, and I've submitted a patch to the project for review.

The last frontier of dark mode based on system setting is third-party JavaScript widgets. None of the 3 widgets on my blog, to my knowledge, have the ability to switch automatically.

Upgrading Drupal Sites: Two Case Studies and a Spreadsheet

Upgrading Drupal sites between major versions can be tricky. The community of developers that numbers in the thousands has taken great care to maintain upgrade path between adjacent versions of the content management system. This is especially true of Drupal's core, though one must go through each version to get to the destination. (An example: going from Drupal 5 to Drupal 7 requires passing through Drupal 6.) Contributed module upgrades take place with a very slight degree of peril, though typically a developer will include upgrade paths between major versions. Though incredibly rare, some modules will not upgrade their database to the new version of the module, and even then someone will flag it as an issue and it will get resolved.

Official Documentation

If you came here looking for guidance on upgrading your Drupal site, please consider visiting the official documentation at Drupal.org. The following only deals with two specific cases that may not apply to your site.

Upgrading Roland's Site

Some upgrades are very easy, however. Upgrading Roland's website was a breeze. My method:

  1. install a fresh copy of Drupal 7 on my local environment
  2. copy his site's database to my computer, and import into a fresh database
  3. run the update.php script, taking notes if any errors pop up. If they do, either fix them or make a note of what to do when it comes to do it for real
  4. do another test upgrade locally, just to make sure
  5. clear out temporary data like sessions and cache on the local install
  6. export the database and upload it to Roland's server
  7. install Drupal 7 fresh with a very few modules (WYSIWYG, which he uses, and Views, which he doesn't)
  8. import the database, and run update.php, perform the fixes from the earlier notes
  9. show Roland what it looks like, then make the necessary switches behind the scenes to make it live on the rolandtanglao.com domain

(To keep it brief, I've excluded the steps about virtual host files on his server and faking a subdomain with my /etc/hosts file on my own computer.)

One funny bug that I couldn't put my finger on, which came up with another client's upgrade, was the need to save a node in order for URL aliases to kick in. If it comes up again, I'll dig further into Drupal.org's issue queue. One thing you learn quickly about the issue queue is that URL aliases are a common problem.

Upgrading Just a Gwai Lo (Eventually)

Other upgrades are not so easy. For the better part of a year, I've been working on porting over Just a Gwai Lo to Drupal 7. Working against me are the following:

  • my SkyTrain Explorer page, which contains custom PHP to display the hierarchical book view plus the use of Viewfield to show station pages (example). I cherish that section of my website, and would like to see it come over in an upgrade.
  • a few custom content types need their modules to either be upgraded or provide an upgrade path. I use Embedded Media Field in conjunction with Feeds to display my own photos posted to Flickr. I will need to move to the Media module along with Media: Flickr to do the same thing. There is an issue asking for an upgrade path, which I continue to monitor.
  • I have a spreadsheet for other modules, which, for a laugh, I've made public. An explanation of my methodology follows.

The Spreadsheet

Every major upgrade to a site I work on gets a spreadsheet. Though some upgrades will need to require certain added and maintained functionality, those same upgrades can drop functionality too. It's usually best to conceive of features first, then map modules to them. Since I already know what I want (essentially status quo), the module-based approach stays for this spreadsheet.

Using my personal site as the example, I'll go through my research process.

  1. Make a raw list of the modules used. I'm OK with doing this manually, since it gives me a chance to think through whether installing it in the first place was a good idea.
  2. Highlight in blue the modules that are either custom modules (there's always at least one in all of my projects, personal and otherwise) or ones I can drop. In my case, I have the Fenchurch module (named after my first VPS, which was in turn named after Fenchurch in Hitchhiker's Guide to the Galaxy), which adds some small things to forms and whatnot, to upgrade. I'll also likely drop Better Formats since Drupal 7 adds most of what I need.
  3. Highlight in red the modules that are not ready and that I need (called blockers).
  4. Highlight in yellow the modules that I'm not sure are ready or that I don't know whether I'll need.
  5. Highlight in green the modules that are ready for Drupal 7. Developmental and bet versions of modules are OK to use as long as they work. I always evaluate modules on their merits, not what their version number says. Green means go!
  6. A row for notes, such as links to issue queues or which modules to use instead, or what I can do to make them ready.

As soon as it's all green, then it's time to do the work of upgrading. I then follow the same general process as outlined for Roland's site, though usually quite a few more times, since more things tend to go wrong

The spreadsheet definitely has flaws. Breaking it into a sheet per sections (such as one for content, another for each custom module) might make sense if only the format allowed for freer form of information. I remain a fan of Google Docs and its sister service Sites, so one can combine the two and embed a spreadsheet into a more freeform Site, for example. The online spreadsheet allows for live collaboration, though I have no experience with it in the context of upgrading a Drupal site.

Spreadsheets are most useful when a project requires a arithmetic calculation. I use them a lot for trip budgets, though only to get a rough sense of how much it might cost in total. This form of spreadsheet works as a status dashboard.


The roadblocks and the work to overcome them tempted me to archive the site and start all over. A complete restart would have, in theory, allowed me to concentrate on writing instead of futzing with the site's details. On the other hand, most of what I learn about Drupal's capabilities comes through experimentation and breaking, then fixing, things. While I've archived Drupal sites in the past (such as PDXphiles and improvident lackwit), and a method exists for doing so (and possibly another using a module intended for caching), I can't be sure that my thousands of posts and thousands of tags will come in properly, not to mention that changing one little thing could mean having to do the archiving process all over again. And I don't even want to think about redirecting to a subdomain like archive.justagwailo.com but also ensuring that any new justagwailo.com URLs work.

Looking Forward to Drupal 7

Assuming all goes well, I look forward to using some of the RDF features baked into Drupal 7. I experiment with semantic markup in my reviews section, with most using microformats, at least one what I believe to be RDFa (I'm never really sure, but that's why I experiment!), and I hope in the future using some of HTML5's features such as micro data. Ideally the next incarnation of this site will feature stripped-down theme. Still pink, of course.

Introducing the Readability Button Module for Drupal

Spend any significant amount of time reading long articles on the web and you get distracted. Distracted by sidebars and insets full of links and animated graphics, many of which are advertisements. Distracted by badly set typography. Distracted by "next page" links at the bottom, forcing you to wait for the next part of the article to load as the publisher gets another increased statistic to sell. 

Enter Readability. Developed by Arc90 as an experiment, Readability started life as a bookmarklet and browser extension designed to improve the reading experience. In addition to decluttering distracting constituents of a web page, the bookmarklet offered a consistent look that stripped an article to its essential element, the text. After Arc90 released the bookmarklet as open source software, Apple's integrated the code into the Safari web browser. Subsequent to that the company changed direction with Readability in January of this year and started a web service for both website publishers and readers. While keeping the core service of simplifying articles for easier reading, with the new Readability, publishers of any type on the web — from magazines with multiple contributors to single editor blogs — can integrate Readbility into their website and optionally receive payments for their work from readers who sign up to contribute.

How Readability Payment Works

Publishers first must claim their website by adding a special code to the HTML header, which they can remove after verification. Using their own Readability accounts, readers can contribute a monthly fee that they, the readers, individually specify. (Publishers have no say what readers have to contribute, though Readability sets the monthly minimum at $5.) Readers' money first goes to Readability, who take a 30% cut. Readability then divides the remaining 70% amongst the publishers that readers, while logged into Readability, read through the service. As a simple example, let's say a reader only reads two online publications, The New Yorker and The Bygone Bureau. If a reader contributes $10 per month, and in the span of a month, uses Readability to read 6 articles from The New Yorker and 5 articles from The Bygone Bureau, Readability takes its $3 cut and The New Yorker gets $3.82 ($7 divided by 11 total articles, multiplied by 6 New Yorker articles) and The Bygone Bureau gets $3.18 ($7/11*5).

Readability buttons, as they appear on websites, typically offer the reader has the option to send the article to Readability and come back to it later ("Read Later") or immediately convert the article to Readability's simplified version ("Read Now"). Some tools that do 'read later' functionality, like Instapaper, can, after reading through the app, send the link to Readability so that it is counted towards the reader's monetary contribution.

Publishers do not need to claim their website or receive any payment in order for readers to use the part of Readability that converts article to pleasant-looking text, nor do readers need to pay Readability to convert distracting pages. The publisher-contributor model constitutes a new way for publishers and writers to make a few bucks on their creation and for readers to keep good writing coming without have to put up with (as many) advertisements. One publisher confided in me that "nobody's getting rich off it," referring specifically to Readability, but Readability at leasts represents an opportunity for innovation in the ways publishers, writers and readers interact and support each other.

Readabilty Button for Drupal

Screenshot of a Readability 'Read Now | Later' button on an example node in Drupal

Since I work primarily with the content management system Drupal, and wanted the functionality not only for my site but for other Drupal sites, I've developed a module called Readability Button. "Without this module, site maintainers would have to edit their theme directly, introducing code that they need to maintain. Instead, they can turn on the module and change settings, and if they want to discontinue Readability integration, can simply disable the module. Readability Button features the following:

  • Enable the button on a per-content type basis. Also a permission to show the button on nodes to certain roles.
  • In the module configuration, temporarily add the verification string (the full element provided by the Readability web service) without editing your theme. You can disable this after you've verified your domain.
  • Configure whether to show only on the individual node view or also on lists (such as the blog page or taxonomy views).
  • Optional Print, Email, "Send to Kindle" buttons.
  • Modify the colours of the foreground and background using hexadecimal colour codes. Optional integration with jQuery Colorpicker.
  • Change the orientation of the button from horizontal to vertical.
  • If a reader is logged into their Readability reader account, and the reader is a contributor, clicking the button sends a portion of their contribution to the site's publisher.

If you add the module to your Drupal site, I encourage you to make a feature request and submit bug reports in the issue queue.

Imagining a 2.0 branch

The module as described as above has some limitations:

  • Once you add it to a content type, all nodes of that content type receive buttons, no matter how short
  • If you allow the button on lists, it appears on all lists. that includes views, taxonomy term pages, blogs, etc.
  • The weighting of the button is somewhat of a kludge

A 2.x branch of the module, which only exists in my head, comprises of the following features:

  • Make the Readability button a field in the Drupal 7 sense. This would enable many things for "free":

    • flexible placement of the field in content types, using the per-content type field settings
    • Views integration, meaning with any list you can override settings to show or hide the Readability button
  • Readability API integration, meaning authentication and management of your Readability publisher account for websites and reader accounts for site members
  • If the website uses the Domain Access module, then each site could conceivably have its own 'domain' in Readability as well. Imagine individual bloggers on a Drupal site as a publisher who gets the 70% cut from Readability

Beyond the Module

Just a Gwai Lo currently uses the Deco theme, and, in order for Readability to reliably convert my own website to the clutter-free text, I made some slight changes. In particular, I needed to ensure Readability correctly picks up on article titles and dates. Per Readability's recommendations to mark up articles in the hNews microformat, I've added an entry-title class to my h2 tags, necessitating modifications to the theme's template.php and node.tpl.php files. I also added a element wrapped around the date for blog posts. The right way to do all of this would be to find a way to modify the theme elements in a module, though I think the only option available to me is to maintain a sub-theme.

Some Wins

Early last year, around the time of DrupalCon San Francisco, Packt Publishing approached me to serve as technical reviewer for a book. Several Microsoft Word documents and 7 months later, the dead trees edition of Drupal Theming Cookbook by Karthik Kumar, arrived at my doorstep, complete with an acknowledgement of my work inside the front cover. In the hopes of branching out a little, I also received a complimentary copy of Django 1.0 Website Development by Ayman Hourieh. Over the course of a month in December 2010 it served as an excellent guide to completing one's first app, with little or no Python knowledge required, but taking the 'dive right in' approach. (Anything that didn't work with Django 1.2 was a quick Google search away. I have sticky notes at every point at which it differs from the current version as of this writing.) I hope to ship an app based on the example sometime this year.

At the end of last November, I helped instruct at a community-based clinic teaching a basic-level introduction to the Drupal CMS. Based on notes from the Seattle Drupal Clinic held in 2009, several members of the Drupal community and people new to Drupal converged at the FCV office in downtown Vancouver. We covered modules, content types, image manipulation, and for my session at the end, the Views and Block modules. We the trainers learned a lot from that first session, and it seems like the same can be said about the participants. My thanks go to everybody involved. It's an initiative I'd like to participate in again.

A third win involves getting back into the Drupal support game. You can find me on the #drupal-support IRC channel when things slow down at work, and recently on Stack Overflow's Drupal-related questions. While having reservations about not tracking the Drupal.org forums for support, I will go where the people are.

Since some people have asked, since June of last year, I've been working for OpenRoad Communications, a web services company based in Gastown. They're technology-agnostic, and when they had a couple of Drupal projects come their way, it made sense to have me on full-time. Separately from web services, they created a product called ThoughtFarmer, which they bill as a social intranet. (It might be tempting to make a connection between Drupal and ThoughtFarmer, but other than my sitting next to the development team, rest assured the two are not related.) Since months can go by between my mentioning my employer, it's probably best to refer to LinkedIn or my resume for my latest professional status.

Attending DrupalCon San Francisco April 19th to 21st

Starting with the community site Urban Vancouver, then as the support cowboy for Bryght and Raincity Studios and now with an independent practice, I've enjoyed all of my almost 6 years with the Drupal community. In a couple of weeks, I'll fly to San Francisco to attend my first DrupalCon. With my flight and hotel booked, conference ticket registered, and a ticket to a Major League Baseball ballgame ticket received in the mail, I look forward to the 3 full days of sightseeing in the Bay Area, including the plans to take a tour of North Beach and ride San Francisco's historic streetcars.

The conference itself will present me the opportunity to meet many of the people working on the open source CMS that I admire. I'm looking forward to attending sessions and hanging out in the lobby, and in the evenings, drinking some sweet delicious beer with colleagues. Tuesday night sees me riding BART out to Oakland-Alameda County Coliseum for the first time in some twenty years where I saw my favourite Blue Jay of all time, Jesse Barfield, sock a dinger. This time, without a team to cheer for, I hope to soak it all in, arriving as early as possible to catch hitting and fielding practice, then taunt and boo the Yankees until my throat is sore. Leaving the conference early means missing some fantastic-looking DrupalCon sessions from Narayan Newton and Greg Knaddison. If the baseball gods get angry and rainout the A's game, you'll see me at one of those two sessions.

Show Google AdSense to Visitors from Search Engines Only Using Drupal

Unbeknownst to people who visit my website directly, Just a Gwai Lo has served Google AdSense ads for some time now. Very early on I came to the conclusion that showing automatically-generated content-aware ads on personal sites was tacky, since those visiting directly were likely those who wanted to develop a personal relationship, no matter how loosely defined, with the author. That applies to the relationship I want to build with my readership as well: if they visit the site directly in a browser of subscribe to a feed, they shouldn't have something hawked at them.

People visiting through search engines, however, get no such treatment. They're likely people I don't know and, based on what people search for—and don't find on the site—don't want to have a relationship with. So anybody visiting in from one of the major search engines would see a Google AdSense ad, and over the years I've made enough to help fund some small vacations to the United States. (Since Google pays me in American dollars, it goes in my USD account, which I then withdraw for trips south of the border.) Nothing spectacular, and definitely not worth the amount of investment I put into the custom PHP script which looped through a list of domains returning TRUE if one of those domains were Google, Windows Live Search (as it was known then), Yahoo! and some others. Now I use Drupal, the following contributed modules and a one-line conditional in the block display filter to show ads to people finding my site that way.

  • AdSense, with the component modules "AdSense core" and "Managed ads" enabled.
  • Search Engine Referer API, which returns FALSE if the referrer is not a search engine and an object (essentially TRUE) if it is.
  • The following line of PHP in the "Page specific visibility settings" for the ad's block: I could have written a ternary operator, but I sought clarity in this case.

After my next payment, I'll disable this feature as part of an effort to simplify my Drupal install. This will cut down on the number of updates needed and ever so slightly decrease the load on the server. It's never been worth displaying them based on the time invested in this, though I can say the money plus experience with the advertising system in general did offset it a bit.

Developmental release of Pirate module for Drupal 7 available

Three weeks until Talk Like a Pirate Day, and next week the Drupal project freezes its code in anticipation of the version 7 release of the CMS. In anticipation of that, I've updated the Pirate module, which turns all contributed content on a Drupal-powered website into pirate-speak for just the day of September 19th, to include a developmental release for the Drupal 7 platform. I'd like for people to test it out, and in order to do so on a day other than September 19th is to either modify the date in the following code of the module or remove it altogether.

  if (date('md') != '0919') {
    return $text;

I see that similar code to my module has been included in the Dialectic module, which supports other novelty input formats. I may be convinced to officially merge my work into that project in the future, though my module differs in that it activates on only one day a year.

Any issues specific to the Drupal 7 conversion can added be to the issue for that. One sticky, longstanding issue that I could use some help with and affects all versions is a bug involving URLs that contain 'ing'.

I pledge that Pirate will have a full Drupal 7 release on the day that Drupal 7 is released. #D7CX:

Addison Berry on Herding Cats in the Drupal Documentation Community

Addison Berry, aka @add1sun, presented about her experience as documentation lead for the Drupal content management system project the other day at the Writing Open Source conference in Owen Sound. In her role as chief cat-herder, she found that the most difficult people aren't poisonous. Instead they just don't know how to communicate with the community, and they need to translate where they're coming from to the way the community operates. It's hard work, she reports, to turn them into a contributor. She referred the audience to the "Poisonous People" presentation by the Subversion people, as yet unwatched by yours truly.

Addison talked about religious wars that occasionally break out. That is, the crux of the issue is more important than the resolution, and often leads to inaction. She also discussed the differences between recruiting in the corporate world and recruiting in the open source world. For private companies, they hire a skillset that they can filter for by listing the job requirements, either explicitly or implied. In open source, she says, you have the skillset first and you work with it. Many cats scratching their own itch, hence the herding to get them to scratch the community's itches too. The people you get working on a project have a rich background, both in terms of skills and life history. Skillsets include a lot of non-technical backgrounds in open source (Addison has an anthropology degree, for example, and my education is in political science).

Drupal has a large mass of documentation, and Addison is trying to whoop up energy in managing the base of existing documentation for Drupal 5 and 6 while gearing up for writing the documentation for the upcoming Drupal 7.

Open source has a natural passion that brings people together. Showing the example of a rowing team on her slide illustrated the need to hire a coach to tell them when to row. Herding involves keeping lines of communication open and opening up new ones as well as banging on pots about documentation. Instead of telling people what they can do, empower them by including them in the conversation. Addison, as leader, knows what she won't do and has so far been able to find people who will. Tracking metrics around the documentation—answering a question I had before I had the chance to ask it—Addison is not interested in, but she found someone who is. Many "soft-skills", such as facilitation, have come in handy even if the person with the skill does not claim membership in the software community. Also universities and their students have found time and energy to contribute usability testing as part of course credit or as part of their graduate studies.

Letting go and getting out of the way: Addison wanted the vision to be perfect, but quickly understood that she can't lead the charge or drag it out all the time: instead she recognized the need to let people run with things and support them. Getting people to trust you that that's the right direction.