Drupal

OpenSourcery officially a Drupal Association member

September 4, 2008

OpenSourcery - believer in, contributor to, supporter of, and advocate for Drupal in more ways than we can recount here - is officially an Organizational Member of the Drupal Association. We're still having difficulty transferring "ownership" from the individual who opened the account (yours truly, Thomas King) to the organization, so I'll just post a little screen shot here for good measure. We applaud Drupal.org for being such an incredible resource for everyone from independent developers to interested site owners to professional development shops.

Creating theme-independant, custom markup for your Views

August 29, 2008

The Drupal Views module has powerful theming abilities. CSS classes abound, allowing you to accomplish a great deal with stylesheets alone. If that's not enough for you, custom phptemplate files can be added to your theme. The new Views 2 will even helpfully suggest a list of possible template files (under Basic Settings -> Theme: Information).

Wouldn't it be nice, though, if you could have custom markup independent of the theme? Or perhaps you'd like to apply your custom styles more selectively to just certain views or view displays?
With hook_views_plugins(), you can.

Drupalcon: Rasmus Lerdorf, PHP performance, and a Drupal performance correction

August 27, 2008

Today, on the first day of Drupalcon, Rasmus Lerdorf gave a fantastic presentation about PHP, performance, scalability and security. In this talk (the slides are available here), he discussed the writing of frameworks, and how they tend to trade off performance for what might be deemed as cleaner code. After walking through some very cool benchmarking methods (see slides 8, 14 and 16), he proceeded to benchmark some of the more popular PHP frameworks out there (slides 24 through 32). Unfortunately, when it came to Drupal, it was benchmarked without caching enabled. I have duplicated his Hello World module, and enabled it on a clean Drupal 6 install. While the absolute numbers are incomparible due to my local environment being different from his, I have run it without caching

Response time:                  0.38 secs
Transaction rate:              13.10 trans/sec

and then with aggressive caching enabled:

Response time:                  0.04 secs
Transaction rate:             119.42 trans/sec

The performance increases by roughly 9. By applying this ratio to his results for Drupal:

Response time:              0.10 secs
Transaction rate:          51.37 trans/sec

the numbers would be something like:

Response time:             0.0105 secs
Transaction rate:           468.5 trans/sec

With the pure html page coming in at about 610 transactions per second, Drupal 6.4 with aggressive caching enabled (as well as css and javascript optimization enabled) is much closer to that than any of the other applications/frameworks tested for the presentation. Of course, not having the exact same environment as Rasmus, I'm not sure if these results scale linearly, so this is mostly speculative. Even so, it takes Drupal a lot closer to that goal of not killing kittens, and a greener computing world.

 

Edit:

The above numbers were without APC enabled. With APC, the ratio is more like 5-6, so in that case, Rasmus' numbers would look like this:

Response time:              0.017 secs
Transaction rate:          256.85 trans/sec

While not as good as those above, still these numbers come in very close to the best of the applications benchmarked by Rasmus.

Leaving for Drupalcon

August 22, 2008

Drupalcon SzegedTomorrow I fly to Budapest by way of Frankfurt as I start making my way towards Drupalcon in Szeged. Brian will be joining me in Szeged closer to the start of the conference. I'll have several days to take in the sites of Budapest (the funicular railway to Buda Castle looks awesome), then catch a train south to Szeged. I'm looking forward to meeting so many Drupal people all in one place, and the sessions are looking fantastic.

I'm particularly excited about the Awesome Testing Party, not only due to the free pancakes, but also, writing tests is a whole lot of fun, and they're critical for a solid Drupal core, and a more feature-rich development cycle.  It also looks like there should be several excellent sessions on the state of GIS, mapping and Drupal (A Roadmap for Mapping: GIS on Drupal in 2008 and Beyond, Simple Mapping Mashups with Drupal, and Mapping with Drupal and Mapnik just to name a few). And of course, no Drupal gathering would be complete without a session about Awesomeness and Drupal.

I'll be posting updates frequently from Drupalcon. Also, if you'll be in Budapest prior to Drupalcon and are interested in any pre-Drupalcon activities, drop me a comment here, or contact me directly.

OpenSourcerers at Drupalcon

August 22, 2008

While the rest of us stand enviously put, CEO Brian Jamison and lead Drupal developer Jonathan Hedstrom pack their respective bags and transform into international men of open sourceOpen source software is computer software for which the human-readable source code is made available under a copyright license (or arrangement such as the public domain) that meets the Open Source Definition. mystery and mastery. Both will parlay their "business" trips into personal adventures, but we expect them to enjoy the stay, hobnob with the likes of Dries Buytaert and Kieran Lal, and return with plenty of new ideas.

They leave Portland with happy news on the home front. OpenSourcery's newest Drupal developer, Dylan Wilder-Tack, is making the most of his new position. His transition has been seamless and his work spotless. We only wish he could crawl into Jonathan's suitcase (we're talking Dr. Who level of comfort, TARDIS-like in its ability to expand for our intrepid Dylan) and travel to Szeged.

And look for some very exciting Drupal partnerships in the near future, bringing OpenSourcery together with some of our favorite nonprofit and developer groups both in Portland and nationally.

Bon voyage, gentlemen. And pirítós!

OpenSourcery to host Drupal Meetup Wednesday, August 13

August 11, 2008
Event Date: 
13 August 2008 6:00pm - 8:00pm

OpenSourcery is hosting its third monthly Drupal meetup this Wednesday, August 13; as always, it's free, open to the public and wildly stimulating.

This week Alex Bronstein of CraftySpace will do a presentation of his oop module. In addition to the scheduled presentation, the meetups always encourage free question-and-answer sessions, problem-shooting riffs and comiseration. It's a wonderful place for Drupal experts and beginners alike, or those who are curious about what Drupal has to offer.

The meetup begins at 6pm at the offices of OpenSourcery: 711 SE Ankeny St. Call 503.777.7033 or email thomas@opensourcery.com for further details.

Merging two Drupal instances into a single database

August 8, 2008

I recently had to transfer some tables from a Drupal site that had been developed in it's own database, into an existing Drupal database. In order to do this, the MySQL dump needed to be edited to add table prefixes, lest the existing Drupal install be wiped out.

Editing this by hand was out of the question, but thanks to the emacs replace-regexp command, I was able to change the entire dump file in a matter of minutes.

To initiate the command, one hits ALT-x and types in replace-regexp. First, enter the pattern to find. To add a prefix to all the DROP TABLE commands:

DROP TABLE IF EXISTS `\(.*\)`

The \(.*\) is the regular expression that tells emacs to match everything inside those parenthesis.

After entering the search, one is prompted to enter the replacement pattern. To add a prefix, for example myprefix to the DROP TABLE commands I used this pattern:

DROP TABLE IF EXISTS `myprefix_\1`

The \1 pulls in whatever was matched in the first set of parenthesis in our search pattern.

I repeated a similar search and replace for the other commands that reference a table in a typical Drupal database:

 CREATE TABLE `\(.*\)`
 CREATE TABLE `myprefix_\1`
 
 LOCK TABLES `\(.*\)`
 LOCK TABLES `myprefix_\1`
 
 ALTER TABLE `\(.*\)`
 ALTER TABLE `myprefix_\1`
 
 INSERT INTO `\(.*\)`
 INSERT INTO `myprefix_\1`

After that I was able to import this dump file into the existing Drupal database (without wiping out the other installation) and continue development as a multi-site sharing a single database.

Jonathan Hedstrom's Drupal module a "Success Story"

August 6, 2008

We already knew Jonathan's work on 247 Townhall would turn heads, but we're still excited to announce that the project has appeared on Drupal's "Success Stories" page with a full-page description. Among the featured successes of 247 Townhall's launch is Jonathan's video upload module, which you can read about here.

We urge you to visit 247 Townhall and the Drupal node yourself, but we've gathered a few highlights anyway:

  • Site visitors can maintain custom lists of their favorite content.
  • Avatar images are automatically resized and given rounded corners and orange borders.
  • Site contributers can submit custom background images for article postings.
  • Site contributers can submit videos on node/add and node/edit forms that are automatically, and silently, uploaded directly to youTube for processing and display.
  • Site administrators can aggregate interesting user-generated content into a "series" or online publication.

Thank you for reading.

Writing SimpleTests for hook_file as part of the Media Code Sprint

July 30, 2008

Last Friday I met Aaron and drewish at the Ace hotel for a day of SimpleTest writing for the long-awaited hook_file() patch. This was part of the Portland Media/Files Code Sprint, organized by drewish to solidify the patch during the week of OSCON.

The day was very productive, as file.inc went from having virtually no tests, to near complete test coverage. As is often the case when writing comprehensive unit tests, several inconsistencies with expected behavior/documentation were found and fixed.

Aaron has provided an overview of the goals of the code sprint, and the remaining work to be done (both on the immediate patch, and beyond). But to summarize, the goal is better file (thus, media) handling in core.

If you maintain or develop modules (or themes) in Drupal that need to deal with any sort of files, go give this patch a try (it's currently the spotlight patch).

I've had a tremendous amount of fun writing tests for file.inc (hopefully I'll get to do a few more before the patch goes in), so I may very soon jump on some of the other needed tests for Drupal core.

Improving the security of Drupal's securepages module

July 24, 2008

A common scenario we encounter is where the bulk of a site's traffic is anonymous users, for whom it would be an unnecessary burden on the server to transfer pages with SSL. However, it is still desirable to serve some parts of the site with SSL (typically the admin pages, or perhaps some commerce-related pages). Luckily, the securepages module accomplishes this nicely.

This approach has a drawback, however. The same session cookie is used to access both SSL and non-SSL pages. Since this cookie is passed around in plaintext, it's easily hijacked by an attacker, who can then access your SSL-protected pages with the hijacked session.

CiviCRM deployment from host to host

July 23, 2008

While working on a CiviCRMCiviCRM is an open source and freely downloadable constituent relationship management solution. CiviCRM is web-based, open source, internationalized, and designed specifically to meet the needs of advocacy, non-profit and non-governmental groups. site, I ran into a problem of migrating the installation from the development host to the QA, and from there to production. Since CiviCRM stores so much host-specific information in the database, every transfer needed to re-configure the host information. After much research and a little bit of pain, we discovered that the proper way to do this is to simply empty the config_backend field in the civicrm_domain table.

So with this little bit of code tacked onto our deployment scripts:

#Reconfigure the CiviCRM backend
echo 'UPDATE civicrm_domain SET config_backend = NULL WHERE id = 1;' \
| ssh $USER@$HOST "mysql -h $DB_HOST -u $DB_USER -p$DB_PASSWORD $DB_NAME2"

deployments are once again flowing smoothly.

Programmatic node creation, Drupal 6 and the drupal_get_schema() function

June 16, 2008

While working on importing a bunch of content from an old Drupal site to a new one, I discovered a little gotcha with the D6 database schema functionality. The method I was using involved loading a bunch of nodes from the old database via a call to db_set_active(), followed by a series of calls to node_load(). Once I had the nodes in an array, I switch to the new db via another call to db_set_active and store the nodes via node_save().

The problem arose due to the fact that Drupal is caching database schema information. Thus, during the node load phase, CCK attempts to load up information on a table that doesn't exist, and the result is cached. When back in the new database, where the table really does exist, the cached schema thinks it doesn't.

The solution was to clear the database schema cache every time I switched back to a different database:

function import_old_set_db($db = 'default') {
  db_set_active($db);
 
  // clear schema
  drupal_get_schema(NULL, TRUE);
}

The key in the above function, which I used as a wrapper to db_set_active() in my import script, is the call to the drupal_get_schema() function, which clears the cached database schema information.

This was a viable solution because this is a one-time import script where performance really isn't an issue. It would not be recommended for production sites when regularly switching between databases during normal page loads.

Drupal 6 and Primary/Secondary menu translation

June 13, 2008

I ran into the following issue while developing a bilingual (English and Spanish) site recently:

I wanted the site, for ease of use, to have a single menu structure so translators didn't have to worry about mimicking the primary navigation every time they translated a page or added a new one.

The problems, when the site was in Spanish, were three-fold:

  1. Primary links were linking to es/english-path even though es/spanish-path existed.
  2. For every sub item that was in English, when on the translated page, the secondary menu didn't display, since the menu system didn't see the translated page as a child of the parent.
  3. Both primary and secondary link text was still in English.

The 3 issues were solved as follows.

in theme_preprocess_page:

  $vars['primary_links']   = _opensourcery_primary_links($vars['primary_links']);
  $vars['secondary_links'] = _opensourcery_secondary_links($vars['secondary_links']);

and these 2 functions look like this:

function _opensourcery_primary_links($primary) {
  global $language;
 
  foreach ($primary as $lid => $link) {
    $link = opensourcery_translate_translate_path($link);
    $primary[$lid] = $link;
  }
  return $primary;
}
 
function _opensourcery_secondary_links($secondary) {
  global $language;
 
  // This function call will rebuild the secondary menu as if the page were in
  // English, thus solving the second issue.
  if ($language->language == 'es') {
    $secondary = _opensourcery_rebuild_secondary_links();
  }
 
  foreach ($secondary as $lid => $link) {
    $link = opensourcery_translate_translate_path($link);
    $primary[$lid] = $link;
  }
  return $secondary;
}

As you can see, the key to each of these functions is the opensourcery_translate_translate_path($link) function, which looks like this:

Session Favorites module released

June 4, 2008

The Session Favorites module provides a "Favorites" or bookmark system based solely on a browser cookie. This allows site visitors to aggregate lists of content without becoming full-fledged users.

The module can be configured on a per-node-type basis, and optionally provides AJAX add/remove links.

This module will soon work alongside the Favorite Nodes module, or possibly Views Bookmark (or both, depending on demand), such that once a visitor registers or logs in, their collected session favorites are transferred to the more permanent Favorite Nodes or Views Bookmark storage.

The seldom used hook_requirements()

April 28, 2008

Whilst writing the Video Upload module, I came across Drupal's hook_requirements() function. As it turns out, this is the perfect place to check for all the little stuff your module requires in order to function properly.

For example, the video upload module won't work at all unless it has a YouTube developer key, a username and a password configured.

Introducing the Video Upload module for Drupal

April 23, 2008

The Video Upload module, while in alpha state, provides a CCK field type that allows for the end user to upload video directly to YouTube, using a single account for the site.

The video never hits the Drupal host, saving on storage and bandwidth bottlenecks, and the end-user doesn't need a YouTube account, since all video is stored under the site's account. Video can be organized on YouTube with customized developer tags, currently with limited token support.

The module uses the Zend GData client library for communication with YouTube. This can be downloaded here. See Video Upload's INSTALL.txt for details on installing this library.

The module in extreme alpha state, with nightly builds available here.