Drupal

DrupalCon London

DrupalCon London is next week and if you’re lucky enough to attend, get ready to have your mind blown by the top minds in the Drupal community. We’re sending two web chefs to escape the Texas heat and bask in the grey skies and rich culture of London*. Here’s what they’ll be presenting:

Mad skillz: Become the best in the world
Diana Dupuis – Wednesday, 15:00

Are you a themer or developer who wants to work on bigger, more complicated projects? Do you want to send your resume to top Drupal shops and get hired? Do you want to assess and improve your skills?

If so, come to this session and create your plan. You will leave with you a take-home list of essential traitz and skillz. You’ll also find out what a few top Drupal shops and in-house Drupal team leaders say are the “Most Important Skillz” their best developers possess.

Don’t design websites. Design web SYSTEMS!
Todd Nienkerk and Adam Snetman (Thinkso Creative) – Wednesday, 13:45

Drupal’s theme layer is very flexible and can accommodate just about any web design. It’s important for designers to remember, however, that they’re not really creating a page — they’re building a complete system to house the all of the site’s content. By creating the sitemaps, wireframes, and mockups, designers are actually outlining a site’s feature set. Designers, not developers, determine a site’s purpose and functionality.

In this session, we will talk about the importance of understanding a CMS during the initial design phase of a project, as well as how to create a Drupal-optimized design. Standard practices, tools, and Drupal-specific shortcuts will be discussed in detail.

UPDATE: The Economist: An informal technical case study
Diana Dupuis and developers from The Economist – Thursday, 14:45

For people interested in big websites and their unique challenges, this panel offers a behind the scenes look at The Economist site. A team of experienced Economist developers will talk about the complicated challenges, the innovative solutions, and the still-to-be-solved issues of this popular website. There will also be a (lively, no doubt) Q&A.

The presentation aspect of this session will focus on workflow challenges, testing, performance issues, necessary custom-coded solutions, and 3rd party integration. Sprinkled in, there will be tales of the complex migration from the legacy site to Drupal. The panel will then answer questions and discuss the issues attendees want to delve more deeply into.


*Fish and chips. Monty Python. Scones. Colour.**
**No, really. We love all these things.

DrupalCamp Austin: Innovative training is on the menu

This year’s DrupalCamp Austin (November 19-20, Saturday-Sunday) has added training sessions to our spicy camp fare! The training track will run concurrently with sessions to create an immersive learning experience. During registration, attendees can add half-day and full-day training courses à la carte to their camp ticket. Training entrees will include site building, PHP, performance, and theming.

Planning to attend DrupalCamp Austin? (Who isn’t?) Let us know if you have a craving for a particular training or have attended a training you’d recommend. Attendees can purchase their entire package online when registration begins.

Interested in offering a training session? We invite experienced Drupal trainers to submit training proposals. Four half-day (3.5 hours) and two full-day (7 hours) trainings will be selected. For proposal and submission guidelines, please send an email to training@drupalcampaustin.org. Deadline for submissions is Monday, September 5, at 11:59pm Central Time (US).

Drupal 7 Release Party Data Stream

Drupal 7 has been released! At the time of this writing there are 308 parties planned in 97 countries including our very own release party here in Austin, TX. That means today a lot of people will be talking about Drupal.

d7rp austin release site

To keep up with the global Drupal discussion, we’ve created http://d7rp.fourkitchens.com/, a live data stream collecting tweets, Facebook status messages and Flickr images from Drupalistas around the world. We will have the site on display at the Austin release party.

So rad this will make your head spin

We’d like you to be able to set up your own data stream, so we’ve released the code on github. Check it out at https://github.com/pifantastic/drupal-7-release-party. The github page includes installation and configuration instructions.

Party on.

Drupal 7 release party in Austin

After two and half years of the blood, sweat, and tears of hundreds of developers – Drupal 7’s release is merely days away. To mark the occasion, user groups from all over the world are celebrating as Drupalistas know best – with a party.

But we’re not the only ones – there are now more than 238 300 parties, in over 80 90 countries. This should be proof enough that Drupal enthusiasts all over the world are more than a litttle excited about January 7, 2011.

If you love Drupal and live in the Austin area, come join us the Boom Boom Room at Union Park from 6:30–9:30 PM. We’ll be talking about what’s new in D7, monitoring chatter and photos from other parties, Skyping with the NYC party, and toasting to the best version of Drupal yet.

Cost: Free!

RSVP: austindrupal7releaseparty.eventbrite.com OR groups.drupal.org

When: Friday, 1/7/2011, 6:30-9:30 PM

Where:
Union Park - Boom Boom Room (map)
612 West 6th Street
Austin, TX 78701

What’s new in Drupal 7?

Partial list taken from drupal.org/about/new-in-drupal-7

Security

  • More secure implementation for scheduled tasks (cron.php).
  • More secure password system.
  • More secure log-in system.
  • Modules can be updated via the web.

Usability

  • Administrative links to edit existing page elements are now available on each web page, without having to go to an administration page first.
  • Improved support for integration of WYSIWYG editors.
  • Added more drag-and-drop for administrative tasks.
  • Permissions now have the ability to handle more meta-data (permissions now have a description).

Theme system

  • Removed the Bluemarine, Chameleon and Pushbutton themes. These themes live on as contributed themes
  • Added “Bartik” theme as the default user interface theme.
  • Added “Seven” theme as the default administration interface theme.
  • Added “Stark” theme to make analyzing Drupal’s default HTML and CSS easier.

Database

  • Added query builders for INSERT, UPDATE, DELETE, MERGE, and SELECT queries.
  • Support for master/slave replication, transactions, multi-insert queries,delayed inserts, and other features.
  • Added support for the SQLite database engine.
  • Default to InnoDB engine, rather than MyISAM, on MySQL when available for greater scalability and data integrity.
  • Several Performance Improvements Implemented

File handling

  • Files are now first class Drupal objects with file_load(), file_save(), and file_validate() functions and corresponding hooks.
  • Files use PHP stream wrappers to enable support for both public and private files and to support pluggable storage mechanisms and access to remote resources (e.g. S3 storage or Flickr photos).

Image handling

  • Improved image handling, including better support for add-on image libraries.
  • Added a field specifically for uploading images, previously provided by the contributed module ImageField.

Added ability to add custom fields

  • Provides most of the features of the former Content Construction Kit (CCK) module.
  • Custom data fields may be attached to nodes, users, comments and taxonomy terms.
  • Node bodies and teasers are now fields instead of being a hard-coded property of node objects.
  • Fields are translatable.

…and much more!

Vote for web chef offerings at DrupalCon Chicago!

Voting on session proposals for DrupalCon Chicago ends tomorrow, December 23rd. The Four Kitchens’ web chefs have added delectable entrées to the impressive buffet of offerings. From theming to performance, jQuery to hiring developers, we’re serving a little something for everyone. You must be registered to vote, so register today and cast your vote for the sessions you’d like to attend.

Our Chi-Town à la carte menu:

Theming From Scratch

Prepared by: Zach Meyer
This session is designed to explain some basic to intermediate concepts about theming to non-developer types. Much of the information revolves around demoing these concepts using a short tutorial and building a basic theme from scratch.

The state of web typography

Prepared by: Aaron Stanush
See how far fonts for the web have come, understand the current battle over licensing, and finally learn how to implement the sexy @font-face method to make your web typefaces sing.

Don’t design websites. Design web SYSTEMS!

Prepared by: Todd Ross Nienkerk and Aaron Stanush and Adam Snetman
In this session, we will talk about concepting and creating a Drupal-optimized design and the importance of understanding a CMS during the initial design phase of a project. Standard practices and tools will be discussed in detail.

Panel: Mad Skillz. What’s on your resume?

Prepared by: Diana Montalion Dupuis and Todd Ross Nienkerk (more panel members TBA)
Even in this tough economy, there are more jobs for expert Drupal developers than there are developers. Want to be a rising Drupal star? Which mad skillz get you sought after, fought over, and hired by Drupal shops? What’s important to get onto your resume and what’s not? What kind of experience should you seek? The answers may surprise you!

PHP for NonProgrammers

Prepared by: Diana Montalion Dupuis
This is a friendly programming introduction for people new to coding. We’ll take a “Physics for Poets” approach to basic PHP concepts like variables, if/else statements, and functions. You’ll write some code, speak some geek, and start down the addictive path of programming logic. There’s also a geek quiz - in case you don’t know your Picards from your Kirks.

Drupal Sex Appeal: Attracting More Female Developers

Prepared by: Diana Montalion Dupuis
We will take a clear and organized approach to meeting the goal: increase the percentage of female Drupal developers.

Introduction to jQuery

Prepared by: Aaron Forsander
An introduction into the powerful javascript library that powers Drupal and countless other web things. This session is for people just starting out with jQuery and for people looking to learn more advanced uses and best practices.

Writing High Performance Drupal Modules

Prepared by: Aaron Forsander and Rob Ristroph
This talk is aimed at developers writing modules that have to perform well under heavy load and lots of traffic. We will present an overview of a number of techniques that we have used with success on high traffic Drupal sites.

Debugging Techniques for Drupal

Prepared by: Rob Ristroph
A general approach to debugging Drupal problems will be presented, followed by an overview of a variety of tools such as the Devel suite, krumo, xdebug, and client side debugging such as Firebug and LiveHTTPHeaders. In addition to debugging functionality, approaches to performance related problems will also be covered.

Introduction to GIT Version Control

Prepared by: Rob Ristroph
A goal of this talk is to convince developers and site builders that are not using version control that starting does not have a steep learning curve and using it does not come with a lot of overhead. People should be able to come away from this session able to start using Git with immediate payoff, and be able to interact with hosting systems that use version control for code promotion and continuous integration.

User-Centered Development

Prepared by: Shannon “Heathen” Lucas
This high-level session will teach developers how to include user experience in their process. We’ll talk about developing usable software for end users as well as developing usable code for other developers.

Panel: Recruiting, growing, and keeping Drupal developers

Prepared by: Shannon “Heathen” Lucas
The demand for Drupal knowledge is higher than it has ever been, and there’s a shortage of Drupal talent. While this seems like an ideal situation for current Drupal developers, it presents a challenge for businesses that are wanting to either implement a new Drupal solution or maintain an existing one. This panel will share the experiences of both Drupal developers and the business leads of Drupal shops.

Design and UX sessions needed for DrupalCon Chicago

Attention designers, user experience specialist, and interaction designers: DrupalCon Chicago needs you!

The Design/UX track has been very successful at inviting speakers from outside the Drupal community. Now we need those from inside the community to step up! We currently have four confirmed and 19 proposed sessions. This is good, but we can do better.

We’re looking for sessions that address the following topics (and not necessarily in Drupal-specific ways):

  • Principles of design (aesthetics, etc.)
  • Principles UX and interaction design (usability, UI, etc.)
  • Information architecture and knowledge management
  • Typography

The Design/UX track is for artists, usability experts, and site architects — all the people who decide what a site should look like and why. While the Theming track focuses on execution, the Design/UX track is about what happens before anyone touches markup and CSS. This track is about more than Drupal — it’s about building a more attractive, usable, and purpose-driven Web.

If you’re interested, please hurry: Session proposals are due by Friday, 12pm ET. You can submit your session proposal here.

Promiscuous stylesheets in Drupal 7

One common practice when using CSS frameworks such as 960 Grid System, Blueprint, or Baseline is to use a CSS reset. Each web browser applies a set of default styles to HTML elements, and these styles vary among browser vendors. A CSS reset is a stylesheet that clears these default styles so that you know what you’re working with as you implement your theme’s CSS.

The caveat with a CSS reset is that it needs to come before all of your other stylesheets. This presents a problem if you want to use a reset in your Drupal theme: all of the theme’s CSS will be added after Drupal’s system CSS and after any modules’ CSS. If your reset is loaded after these, the system and modules’ styles will all be undone, which probably isn’t what you want. Drupal loads theme styles last because, usually, you’re just adding to or overriding the existing styles, not wiping them all clean. It is possible, however, to have Drupal output a stylesheet from your theme before the system and module stylesheets.

In Drupal 6, the easiest approach is to hard code the link to the reset stylesheet in your page.tpl.php template. Unfortunately, this approach doesn’t take advantage of the built-in CSS aggregation and caching capabilities that Drupal offers, and it might get lost by a sub-theme that provided its own page.tpl.php template. Doing it programmatically in your theme isn’t easy, but a good example can be found in the ninesixty_css_reorder function in Joon Park’s NineSixty theme.

Drupal 7 makes life easier with an enhanced drupal_add_css function. CSS files can now be added to groups and then weighted within those groups to control the order of their presentation. Three numeric constants for groups are provided:

  • CSS_SYSTEM: Any system-layer CSS.
  • CSS_DEFAULT: Any module-layer CSS.
  • CSS_THEME: Any theme-layer CSS.

This is the actual ordering of the groups; stylesheets in the CSS_SYSTEM will be added first, followed by those in the CSS_DEFAULT group, and finally by your theme’s CSS files which are automatically added to the CSS_THEME group. At first glance, this may not appear to help much, but your theme can put its stylesheets in groups other than CSS_THEME. Consider this code snipet from a template.php file:

/**
 * Preprocesses the wrapping HTML.
 *
 * @param array &$variables
 *   Template variables.
 */
function yourtheme_preprocess_html(&$variables) {
  $reset = drupal_get_path("theme", "yourtheme") . "/reset.css";
 
  $options = array(
    'group'  => CSS_SYSTEM,
    'weight' => -10,
  );
 
  drupal_add_css($reset, $options);
}

Assuming that your reset.css is listed in yourtheme.info file (required in Drupal 7), your reset is moved to the same group as Drupal’s system CSS files. So what weight should you use to make sure your CSS gets loaded first? Well, really, you don’t know unless you dig through Drupal’s source to figure out how the system stylesheets are weighted.

Or you can get a bit promiscuous.

Remember that those stylesheet groups are actually numeric? CSS_SYSTEM, CSS_DEFAULT, and CSS_THEME are (currently) the numbers -100, 0, and 100, respectively. The groups are output by their natural numeric ordering, so let’s change one line in the example above:

/**
 * Preprocesses the wrapping HTML.
 *
 * @param array &$variables
 *   Template variables.
 */
function yourtheme_preprocess_html(&$variables) {
  $reset = drupal_get_path("theme", "yourtheme") . "/reset.css";
 
  $options = array(
    'group'  => CSS_SYSTEM - 1,
    'weight' => -10,
  );
 
  drupal_add_css($reset, $options);
}

We’ve changed the group from CSS_SYSTEM to CSS_SYSTEM - 1 , giving it a value of -101. This creates a new grouping that is numerically less than CSS_SYSTEM causing our reset to be output before the system stylesheets.

So why is this promiscuous? This tecnique relies on an implementation detail of Drupal’s internals that could potentially change. Techncially, you’re abusing the system, and you should only use it when you have a good reason. Of course, you can also just hard code the reset in your html.tpl.php template, but this carries the same disadvantags as it did in Drupal 6.

Option groups in Drupal forms

One really useful HTML element that doesn’t seem to get much love is optgroup. It allows you to group the items of a select list in a way that may be more meaningful (and more readable) to your users than a long, uninterrupted list. The option group labels themselves can’t be selected, so there’s no need for back end logic to filter them out of your form data.

Drupal’s Form API provides option groups, but it isn’t immediately obvious how to use them. A quick check of the select type and #options attribute in the Form API reference doesn’t provide any clues about option groups, so it’s necessary to dive into Drupal’s source code.

The content management category filter is generated in node_filters(), and if you follow the rabbit hole, you’ll find that the options are generated by taxonomy_form_all(). What this function returns is a nested array that maps vocabulary names to an array of term IDs and term names.

So how do we make use of this? The select element in the figure above could be expressed like this in HTML:

<select name="category" id="edit-category">
  <optgroup label="Image Galleries">
    <option value="1">Book Covers</option>
    <option value="2">Movie Posters</option>
    <option value="3">Illustrations</option>
  </optgroup>
  <optgroup label="Authors">
    <option value="4">Arthur C. Clark</option>
    <option value="5">Frank Herbert</option>
    <!-- ... -->
    <option value="9">Robert Heinlein</option>
  </optgroup>
  <optgroup label="Genres">
    <option value="10">Alien Invasion</option>
    <!-- ... -->
    <option value="14">Space Wars</option>
  </optgroup>
</select>

Typically for a select item, we set the #options attribute to an array of scalar types (numbers, strings, and booleans). Each element of the array corresponds to an HTML option whose value attribute is the element’s index (or key) and whose value becomes the text inside the option element.

To create option groups, the #options attribute is given an array of arrays. The keys of the outer array become the label attributes for optgroup elements. Each element of the inner array is then used to create an option element contained within that optgroup.

To get that result using the Form API, we would create an array for the #options attribute like this:

$options = array(
  // -- First option group
  'Image Galleries' => array(
    1 => 'Book Covers',
    2 => 'Movie Posters',
    3 => 'Illustrations',
  ),
  // -- Second option group
  'Authors' => array(
    4 => 'Arthur C. Clark',
    5 => 'Frank Herbert',
    // ...
    9 => 'Robert Heinlein',
  ),
  // -- Third option group
  'Genres' => array(
    10 => 'Alien Invasion',
    // ...
    15 => 'Space Wars',
  ),
);
 
$form['category'] = array(
  '#title'   => t('Category'),
  '#type'    => 'select',
  '#options' => $options,
);

One of the benefits of the option group is that the labels can’t be selected. This means you don’t have to insert dummy grouping values in the select list that you then have to filter out in your form submit handler. And since the values for the options in a select element don’t have to be unique, you can place the same option in multiple groups if you need to.

Now go forth and be groupies! :-p

Drop that cron; use Hudson instead

For years, I used cron (sometimes anacron) without asking questions. The method was simple enough, and every project requiring cron-related capabilities documented the setup.

There is a much better way, and it involves Hudson Jenkins. I introduced “Hudson for cron” as a sidebar at the Drupal Scalability and Performance Workshop a few weeks ago. To my surprise, several of the attendees remarked on their feedback questionnaires that it was one of the most valuable things they picked up that day. So, I’ve decided to write this up for everyone.

Why not cron?

First, I have the burden of explaining why you should drop most use of the tried-and-true cron. To be honest, I don’t think cron is even a “good enough” solution for most of today’s systems:

  • You either get email from every run’s output, a dumb log to disk, or no reporting at all. When you do log to disk, you have to worry about segmenting and rotating logs.
  • Jobs have to be manually staggered to avoid massive slowdowns every hour (or midnight or ten minutes or other interval)
  • Even if the previous job hasn’t finished, cron happily starts up a new one on top of it
  • It doesn’t integrate with any other job kickoff or monitoring system
  • There’s no built-in ability to run remote jobs, let alone move a remote job from one machine to another
  • Most of the web-based tools for configuring cron aren’t very nice
  • There’s no built-in logging of job execution time, even though a cron job taking excessive time is one of the most common failure cases.

Why Hudson is better

Here’s how using Hudson with periodic “builds” beats cron:

  • Among the myriad ways Hudson can measure success of a “build,” it can verify a zero return status from each “execute shell” build step. If a job simply returns anything but zero, Hudson considers the build a failure and can notify you however you like. It can email you (on first failure only or every time), you can subscribe to build feeds via RSS, or you can simply use the Hudson interface as a dashboard that shows failures in a convenient, summarized way.
  • Hudson logs the output of “execute shell” build steps. Success or failure, Hudson archives the build output without filling your inbox or local disk. If the console output isn’t enough, Hudson can archive per-run “build artifacts,” which are files on disk matching a defined pattern. There’s also no-hassle “log rotation” by specifying a cap on the number of builds or a set number of days to keep results; this is configurable per-job. If a particular run had output (say, for troubleshooting) you want to keep around, you can tell Hudson to “keep this build” indefinitely.
  • Hudson runs each build on “build executors,” which are effectively process slots. Any system can have any number, but it puts a cap on how much Hudson tries to do, systemwide. This mean 50 jobs can get scheduled to run every hour with four “build executors,” and Hudson will queue them all every hour and run four at once until they’ve all finished.
  • If a job is still running when the “periodic build” time comes around, Hudson can either run the job immediately (like cron) or queue the job to run when the one in progress finishes.
  • Hudson isn’t limited to time-based scheduling. Sometimes, it’s useful to take a job that used to run periodically (say, a database refresh) and make it only available for manual kickoff. Of course, as a CI tool, Hudson can kick off jobs based on polling a version-control system.
  • For remote jobs, Hudson can sign onto systems with SSH, copy over its own runtime, and run whatever you’d like on the remote system. This means that, no matter how many servers in a cluster need scheduled jobs, Hudson can schedule, run, and log them from one server. Hudson can distribute the jobs dynamically based on which machines are already busy, or it can bind jobs to specific boxes.
  • Hudson has a solid web interface that can integrate with your Unix shadow file, LDAP, or other authentication methods. For people who prefer operating from the command line, Hudson has a CLI.
  • Every job’s running time is logged. Hudson even provides estimates for how long it will take the system to get to any particular job when there’s a queue.

Hudson isn’t perfect

To be fair, there are still a couple reasons continue using cron:

  • As a Java-based web application, Hudson is heavyweight. A low-memory or embedded system is better-off with cron. Even Hudson’s remote job invocation installs and starts a Java-based runtime. You can, however, use the SSH plugin if even one box can run the main Hudson instance.
  • Cron’s scheduling is more precise if things have to happen exactly at certain time intervals. Hudson’s assumption is that your periodic builds aren’t dependent on when they start within a minute or two.

Adding a cron-style job to Hudson

Moving jobs from cron to Hudson is easy:

  1. Install Hudson. From the front page of Hudson’s site, there are repositories for Red Hat Enterprise Linux, CentOS, Ubuntu, Debian, and a few others.
  2. Open Hudson in a browser (on port 8080 by default).
  3. Add a new “New Job” of type “Build a free-style software project.”
  4. Check “Build periodically” and put in a cron-like schedule.
  5. Click “Add build step” and “Execute shell.” The Hudson wiki has a page explaining this.
  6. Configure access control from within Hudson.

Drupal and Pressflow best practices

It’s easy to drop in the standard call to wget or cURL to run your Drupal/Pressflow cron from Hudson, but the best way is with Drush.

Why Hudson with Drush?

  • You can configure PHP’s CLI mode to be liberal in error reporting, giving you far more data on failure than a WSOD from wget or cURL. Hudson will also fail the “build” if PHP runs into a fatal error.
  • You can block access to cron.php entirely. (This advantage isn’t unique to Hudson integration.)

Because Drush requires local shell execution, there’s a bit more overhead to having one Hudson box run Drupal’s cron on remote servers in a cluster. It’s not that hard, though. Just configure a Hudson “slave” on each box that needs to run Drush and configure each job to run on the “build executor” that hosts the site. If using a Hudson slave is overkill, use the SSH plugin.

There are even better reasons to use Drush with Hudson for things like database schema updates, but that’s outside the scope of this blog entry.

In the wild

Four Kitchens is widely using Hudson for cron automation on client sites. We’ve also deployed Hudson to Drupal.org infrastructure for multiple non-testing purposes, including deploying updates to Drupal.org (to be discussed in a future blog post).

Pages