Chapter Three LLC

The Day You Dress Yourself: The New Chapter Three Website

Matt Cheney

There comes a time in the life of every young child when begin to dress yourself. No longer are you content with the dorky collared shirt your mother laid out for you each morning or the matching shoes you and your siblings wore because it was just easier that way. Instead, you yearn for a little class, a little flash, and for the older kids some san francisco style.

In this spirit, for our first year and a half of doing business, Chapter Three has rolled with a functional and utilitarian website design created by, well, Josh’s mother. A great graphic designer in her own right, Josh’s mother helped us with an initial design and it helped kick off our successful business.

However, with no disrespect to Jeremy Bentham or Josh’s mother, we recently put our collective heads together with the inspired graphic artist Monica Katzenell and are launching a new website. The new design is a little sleeker and gives a lot more information throughout the site about who we are as a company, the projects we have done, and the way we have participated in the Drupal community.


To make it all happen, on a technical level we make moderately liberal use of the Drupal block system and created several of our pages with the soon to be dominate Drupal content layout system called Panels module. Much of the image resizing is done through Imagecache and there is some neat integration with the Bio Module to generate our About Page listing and store biographical about everyone who works for the company.

Now that we are all dressed up, anyone want to dance?

HOWTO: Quick jQuery Usability Tip: Automatically Clear/Restore Useful Default Values

Josh Koenig

Just wanted to post this quick trick I’ve been using lately to automagically hide/show useful default text field values (e.g. “Search” in the search box) using jQuery and the ultra-handy Drupal.settings() object.

Here’s the short and sweet copy/pastable jQuery code:

$(document).ready(function(){
  Drupal.settings.inputDefaults = {}
  $("input:text").focus(function() {
    var element = $(this);
    Drupal.settings.inputDefaults[element.attr("id")] = element.val();
    element.val('');
  });
  $("input:text").blur(function() {
    var element = $(this);
    if (element.val() == '') {
      element.val(Drupal.settings.inputDefaults[element.attr("id")]);
    }
  });
});

Basically this quick snippit will add a blank array object (ahh, the joys of moving between js and PHP) to the Drupal.settings object — which is useful for all sorts of great javascript functionality, and is integral to Drupal 6.0’s extended AHAH features; if you don’t already know it, do your self a favor and study up — and automatically fill it with any textarea’s default values when a user clicks/tabs it into focus. This lets us clear the default value, but replace it quickly if the user moves on to another element.

As listed, you probably don’t want this on your site, as it will affect things like editing nodes (e.g. title inputs will go blank when you click on them… not what you necessarily want), but it’s easy to tune this to only hit elments within certain forms since every form in Drupal has a unique #id.

Thinking about this, I decided to tune it up and actually make an extended jQuery function for this so it could be more easily applied to speecific elements like so:

$(document).ready(function(){
  // handle hide/show for text field default values in only one form
  Drupal.settings.input_defaults = {};
  $("#specific-form input:text").clearDefaultText();
});

jQuery.fn.clearDefaultText = function() {
  return this.each(function(){
    var element = $(this);
    Drupal.settings.inputDefaults[element.attr("id")] = element.val();
    element.focus(function() {
      if (element.val() == Drupal.settings.input_defaults[element.attr("id")]) {
        element.val('');
      }
    });
    element.blur(function() {
      if (element.val() == '') {
        element.val(Drupal.settings.inputDefaults[element.attr("id")]);
      }
    });
  });
}

This is a pretty nice little plugin, I think, and it shows just how easy it can be to add nice/reusable UI functionality. Happy Drupaling, and go get ‘em jQuery!

(updated w/slight improvement to jQuery fn)
(updated again w/object style improvements from comments)

The Power of Organizing Without Organizations

Josh Koenig

I simply cannot recommend highly enough Clay Shirky’s new book, Here Comes Everybody: The Power of Organizing Without Organizations. He’s been the “smartest guy in the room” when it comes to the internets for a while now, resisting the lure of hype while still appreciated the revolutionary changes we’re all living through.

This particular passage struck me as an excellent summation of what Chapter Three is all about:

We are plainly witnessing a restructuring of the media businesses, but their suffering is not unique, it’s prophetic. All businesses are media businesses, because whatever else they do, all businesses rely on the managing of information for two audiences — employees and the world. The increase in the power of both individuals and groups, outside traditional organizational structures, is unprecedented. Many institutions we rely on today will not survive this change without significant alteration, and the more an institution or industry relies on information as its core product, the greater and more complete the change will be.

One of Shirky’s overarching points is that any specific technology is only a small part of the equation. What’s critical is that the technology is ubiquitous to the point of invisibility (as the web is rapidly becoming), and that new and helpful social practices emerge which make advantageous use of the new capabilities the technology offers.

Being a part of the Drupal community is fascinating in this respect because we are at once participating in an astounding phenomena (the peer-based production of an amazingly useful piece of software) and helping others use that tool, and the methods used to make the tool itself to pursue their objectives.

It’s a jungle out here, but I wouldn’t have it any other way.

Doubling Drupal

Zack Rosen

“They’re going to double in a year. That’s insane, in my opinion” Steve Ballmer (Microsoft, CEO), speaking of Google’s rate of growth as an organization

It’s one thing to see the Drupal community’s exponential growth curve plainly plainly graphed. It’s was quite another to walk into a massive conference hall packed with over 800 Drupal developers last week in Boston. It was honestly all a bit overwhelming.

Since I have been a member of the Drupal project, the incredible rate of growth for the community has been a given. When a relatively small piece of the ‘market’ knew what Drupal was, it’s rate of growth seemed more an interesting aspect of the project than a defining characteristic. But as more and more individuals, organizations, and Drupal specialized companies start betting big on the community, the pressure on the project created by this growth will only continue to increase proportionally.

What does this actually mean? Well, in the past few years it has meant:

Despite these changes though, in many ways the Drupal project appears very much the same as it did a few years ago. Yes, every release the software really does get that much better. More patches, better patches, rinse, repeat. But this kind of relatively painless growth is only possible because the open-source method has created an incredible medium of software production that can relatively easily scale to meet the demands of virtually any size project.

But past a certain point the open-source method runs it’s course. The demands of supporting communities, even if they are largely web based, catches up with the code. We clearly reached this point with the Drupal project a little more than a year ago. These new type of challenges the Drupal community has been confronted with in the past year will become the major challenges that the community will face. And as Drupal continues to double, they will double.

But of course, so will Drupal.

Drupalcon Boston Recap: Bringing Guests to the Drupal External Data Party

Matt Cheney

This year’s Drupalcon was the biggest Drupal Party to date with over 800 attendees and many different sponsors (including Chapter Three of course). Drupal rocked Boston all week and gave everyone in the community a chance to catch up and keep abreast of some of the cool new stuff going on in the Drupal World. Plus, there was some scrumpcious and tasty vegetarian food on the scene.

In my Drupalcon rockstar moment, I took the stage and gave a session with Drupal Genius Neil Drumm and Digital Newspaper Extraordinaire Ken Rickard on Using External Data Sources with Drupal (slides here). The general idea is that Drupal is marvelous for content management, but becomes even better when it integrates with data from external sources and Drupal allows a lot of different ways to make that happen.

Ken kicked off our session by laying the groundwork for why using external data is important and transitioned into talking about some of the basic tools (drupal_execute, drupal_http_request, database switching) and techniques (lazy instantiation, hook_search) needed to make it all happen. He has a lot of good experience around using external data sources from his work in the newspaper world and provided a detailed orientation to the 150 odd people who attended our session.

Neil talked about his work with a wonderful organization called Map Light that records and analyzes information about campaign contributions and congressional votes. For that project Neil had to import *millions* of pieces of information and developed a couple modules to assist him in his work. Job Queue is his module that helps to import external data in batches (instead of all at once) and Import Manager allows administrators to monitor and manage the overall import process.

For my part, I concluded the session by discussing a few specific case examples of how to integrate external data into a Drupal website. I started with an example, which was dear to my heart as a librarian and admirer of philosophy, was to use the Swish-E Module (which I maintain on Drupal.org) to full text index a folder of philosophical essays in .PDF format and make them available via the Drupal search. The second example (see below) was probably the coolest and involved some data mining magic to use the Data Miner API to take a Drupal user’s MySpace name and automatically download their picture from MySpace for display on their user profile. This general technique I was calling “Data Enrichment” and could be used to enhance the data a Drupal site has around either users or specific pieces of node content. Careful consideration here needs to be made to respect both the terms of service and privacy of your users. The final example I presented had to do with some client work Chapter Three did involving the migration of 20,000+ pieces of raw HTML content through a cool audit system set up as several Views and managed by the Workflow System. This system seemed to have a lot of practical value for people and I got a lot of questions about it after the session.

All in all, Drupalcon was awesome and we are looking forward to Drupalcon Europe later this year and Drupalcon San Francisco in 2009.

example of using external data

Two New Screencasts in the Drupal Dojo

Josh Koenig

Yesterday I ran an impromptu lesson in the Drupal Dojo building on last week’s introduction of Druapl 6.0’s new theme layer enhancements, namely built-in template files and automatic preprocess_functions(). We covered a topic my colleague Matt blogged about a couple weeks ago: using template files to take control of forms, which is a great way to take your UI to the next level by making it much more designer-friendly.

Check the screencast here: Fine-tuning the UI: Theming Forms With Templates In Drupal 6.0. If you’re curious about that technique in version 5, Matt’s blog post is a good place to start.

Drupal Dojo

Also, by popular demand I made a short (6 minute) mini-lesson explaining the virtues of devel.module, again in the 6.0 context with the theme_developer tool featured prominently.

Drupal 6.0: More Designer-Friendly Than Ever!

Josh Koenig

With the release of Drupal 6.0, there have been major steps forward in the theme layer. Two of the most important are the standardization of template files and their associated pre-process functions, and the addition of theme.info files which allow the overriding of whole core stylesheets.

This Sunday I gave a 45 minute overview lesson on these topics for The Drupal Dojo. There will be more later, but in brief I think with this core advance, all that remains for Drupal to be a truly designer-friendly platform is better documentation of best practices.

Check out the screencast for details.

HOWTO: Fully Theme and Customize the Drupal User Registration Form

Matt Cheney

Just a little to the left please. Flip it around. Put that on top of this. Call it by a different name. It is the little changes, that seem trivial and small, that often end up being real headaches to make and support our clients in making. Do we really want to try to build capacity with clients by teaching them to adjust #weight in hook_form_alter?

The Drupal Theming System is pretty powerful and, when done right, can offer a good avenue for our clients and their staff to edit, modify, and change their own website content. Its a lot easier to modify HTML files than Drupal module files.

A good example of where this kind of process is needed is on the user registration page. There are a lot of little bits of language and ordering to change and add, but to do so in Drupal module code can get a little hairy. Observe our technique to abstract the user/register form into a flat template file (while maintaing most of the other good Drupal goodness).

Step One: Create a theme override in your module code for the user/register form that executes a _phptemplate_callback to use a separate template file.

<?php
function theme_user_register($form) {
 
$vars = array();
 
$output _phptemplate_callback('user_registration_form', $vars);
 
$output .= drupal_render($form);
  return
$output;
}
?>

Step Two: Expand the theme override function made in step one to remove the titles and descriptions Drupal provides for the form elements. We do this in the theme function (instead of in a hook_form_alter) to preserve the original field titles so they can be used as part of any error messages coming out of form validation.

<?php
 
foreach($form as $key => $value) { // loop through top level
   
if (is_array($form[$key])) {
     
$form[$key]['#title'] = '';
     
$form[$key]['#description'] = '';
      foreach(
$form[$key] as $key2 => $value2) { // loop through second level
       
if (is_array($form[$key][$key2])) {
         
$form[$key][$key2]['#title'] = '';
         
$form[$key][$key2]['#description'] = '';
        }
      }
    }
  }
?>

Step Three: Create "rendered" versions of each of the form elements and set them as variables that can be passed to the template file.

Note: This can also be done with a generic foreach loop (similar to the one in step two) that renders each form element automatically.

<?php
 
// Set up the Vars Array
 
$vars = array();

 
// Render Specific Fields You Want on Your Registration Form
  // note - the specific location of the element in the form array varies
 
$vars['name_element'] = drupal_render($form['account']['name']);
 
$vars['mail_element'] = drupal_render($form['account']['mail']);
 
// continue for each field you want...

  // Don't Forget the Submit Button 
 
$vars['submit_button'] = drupal_render($form['submit']);

?>

Step Four: Create a template file in your site's theme directory to build the user/register form with the customized variables we defined in step three.

Note: This file needs to be the same name as specified in the _phptemplate_callback (example: user_registration_form.tpl.php).

<div class="user-register-element">
  <label>Enter a screen name:</label>
  <div class="user-register-element-input">
    <?php print $name_element; ?>
  </div>
  <div class="user-register-element-description">
    Screen names can be up to 13 characters in length.
  </div>
</div>

<div class="user-register-element">
  <label>Enter an Email:</label>
  <div class="user-register-element-input">
    <?php print $mail_element; ?>
  </div>
  <div class="user-register-element-description">
    Emails must be valid.
  </div>
</div>

<?php // continue on for each rendered form element ?>

The drupal magic here is that the user registration form is now uniquely customizable by anyone who can edit the theme template. This allows for customized "prompts" for each profile field element, without changing the site-wide field name in admin/user/profile, and it allows for customization of the username and email titles and descriptions.

This technique will need to be modified to support external modules that modify the user/register form like LoginToboggan. It also needs to take into account things like "required" fieldstates.

HOWO: Use Drupal For HTTP Authentication

Josh Koenig

Very often, a Drupal website is just one of many tools being deployed on a complex project. For instance, on Chapter Three’s development servers, we keep our own SVN repositories to track custom modules and theme development.

Also often, miscellanious web services like this will want to use the standard HTTP Authentication system. Most simply this is the familiar pair a .haccess and .htpasswd file protecting a directory. Easy to set up, but it requires an admin to keep yet another list of usernames and passwords somewhere on the system which over time becomes quite a pain.

Today, while noodling with some authentication scripts for the Drupal Dojo, I decided to see if Drupal’s own user table could be used as an authentication source for these tasks. Turns out it can, and it’s pretty useful too.

Drupal User Authentication
First off, this requires mod_auth_mysql to be set up in your Apache server. There are packages for most systems, as this is a common and widely used Apache module. Once this is done, use the following code in a .htaccess file or Apache <Directory> or <Location> directive:

AuthName "Use Your Drupal Login"
AuthType Basic
AuthMySQLEnable On
AuthMySQLHost <hostname>
AuthMySQLDB <database>
AuthMySQLUser <user>
AuthMySQLPassword <password>
AuthMySQLUserTable users
AuthMySQLNameField name
AuthMySQLPasswordField pass
AuthMySQLPwEncryption md5
require valid-user

Replace the hostname, database, user and pass values just as you would when configuring your drupal installation’s setting.php file. This will let Apache access the same users table from Drupal and authenticate against it!

Limiting Access By Drupal User Role
For extra credit, you can restrict valid logins to a particular user role by replacing the AuthMySQLUserTable directive above with these two lines:

AuthMySQLUserTable "users, users_roles"
AuthMySQLUserCondition "users.uid = users_roles.uid AND users_roles.rid = 3"

The above assumes that your “admin” role has role id (rid) 3. Your mileage may vary here, and savvy SQL query writers will immediately see how you can use these two directives to limit access in all sorts of ways.

For admins with a lot of experience with mod-auth-mysql, this is all pretty obvious, but I hadn’t seen documentation specific to Drupal anywhere on the web. Hopefully this will simplify your life as much as it’s already simplifying mine!

Drupal Administration: Keeping it Simple

Matt Cheney

Much like the parent who gives their child the keys to the family car, there comes a time in our client engagements where we set up administrative accounts for our clients to begin managing their own content. At Chapter Three we call this Capacity Building and try to make the process as smooth and intuitive as possible. The problem is the default Drupal administration interface makes this difficult.

In general, the Drupal administration navigation menu (see right) is simply too complex to be really intuitive. There are all sorts of options (read noise) available that have little relevance to the particular administration needs of our clients. Some of this menu can be distilled down through permissioning, but with general permission categories in Drupal like “access administration pages” its not possible to remove all the options. Plus, many of the most relevant options are buried several layers deep in the navigation. Its unlikely our clients will regularly find them on their own.

In the past we have build a static “administration page” where we listed the major administration pages and provided links to each, but with our latest project (that had a number of different editors and content managers who all needed to update the site) we wanted to improve our business practices and give our clients a better way to manage their website. The solution we came up with was to provide a constantly present top menu that would only appear for site administrators and would allow them easy access to their specific administration options in a nice drop down menu. We populated the menu through the Drupal menu system with the 20 or so administration pages that were needed to manage the site. This menu display was accomplished by using the SimpleMenu module and can be seen below.

To manage the individual pieces of content on the site we built one, general purpose “Content Management View” using the wonderful Views module. The idea here is to provide a consistent UI to manage each type of content and to allow site administrators to filter, search, and sort that content for their editorial and review purposes. Setting this interface up as a View allows us a lot of flexibility later to add additional administrative options and support different content types.

The end goal is to make it as easy as possible for our clients to easily work with the Drupal CMS and to manage their specific content. This kind of system is something we intend to refine and deploy in future sites.

Syndicate content