Proud of my Dad

I got a nice surprise today. My Dad, who just received his first personal computer as a gift from Jeff, called me on Skype. It was his second unaided video chat ever (Jeff appropriately got the first ;) I have to say that I was a little amazed, but there is a popular theory that he just plays dumb with computers. Anyway, I think that he's got a bright future as a geek!

Just got back in town from our wedding back in Iowa. Thus the ungeeklike lapse in blogs and tweets this past week. I promise a whole spread of photos as soon as they arrive!

Creating a colorable theme

I've always been fascinated by the color module. If you've ever selected a color palette for the Garland theme, you know how cool this module is. So a couple of weekends ago I decided to buckle down and figure it all out. It wasn't the easiest module to learn, but I have to say it felt really, really good when I finally got it to work. It's not overly complicated, but there are a lot of configurations to keep track of.

I kind of liked my experimental theme, so I started using it for myself and contributed it on drupal.org as Aquanaut.

If you want to get started with the color module, I highly recommend reading this doc page. It covers all of the basics. A couple of things that I learned:

  • Format your CSS file so that multiple CSS selectors/pseudo classes are on the same line:
      /** Don't use this format **/
      a:link,
      a:visited {
        color: #336699;
      }
     

      /** Use this format instead **/
      a:link, a:visited {
        color: #336699
      }
     
  • The first color palette in the schemes array in color.inc simply defines the color picker values. If you select the default (first) color pallette, color module ignores it and loads the style.css and images from your theme directory.
  • A really easy way to create default theme images is to set up the base.png and color.inc, pick a color palette using the color module, save the changes, then copy the images from your files/color directory into your theme directory.
  • Each fill color can only be used once, so organize your base.png wisely if you need to use a color for two different image slices.

Happy theming!

What's with the new design?

Yes, the colors are a bit much, but it's a very exciting design for me. This is my first theme using Drupal's color module. I've been meaning to learn how to use it for quite some time. So, last weekend I sat down and decided to not get up until I had it down. This was no small task as this was one of the more complicated Drupal APIs that I have yet to learn. It's not that difficult to understand, there are just a lot of moving parts. I'll do a more extensive blog post about the inner workings of the theme, but in short, you can pick the background color, link and text color, and pick a gradient for the top-right block using a simple color picker. I'm hoping to polish this one up and submit it to drupal.org as my first contrib theme!

DrupliconOne of the most fun parts of the project was to create a colorable Druplicon. I traced some of the highlights and shadows from the Druplicon in Illustrator, then added these to my base.png for the color module. Now, when you color your theme, the Druplicon becomes the same color as your site links!

I'm super excited about having this in my arsenal because it provides some elegant, helpful features when handing off a site to a non-technical administrator. You really don't even need the complicated background images. You can use the color module for something as basic as just letting them select the link and text colors. Very cool stuff!!

Using Drupal's Batch API

I don't know how I went so long without implementing Drupal's Batch API, but finally had a chance to play with it yesterday and had a Drupal Aha! moment. This particular API is very handy and surprisingly easy to implement.

We've been working on a way to synchronize a bunch of development environments using SVN and make it quick to deploy a new install of the site we're working on. The first step was to use the Import/Export module to dump content types, views and taxonomy definitions to text files. This way we could commit them to the repository and quickly build the framework for a fresh install of the site. Just install Drupal, then run the import function for the content types, views and taxonomies.

This was all great until we started exporting complex content types. It turned out that the system would fail if we tried to do more than one at a time, which meant going through the tedious effort of exporting... one... at... a... time.

Batch API to the rescue!

The Batch API module lets you easily set a batch of callbacks that Drupal will run one at a time, thus avoiding script timeouts for laborious tasks. The batch can be naturally set up in your form submit handler, or can be called in any other function by adding one extra line of code.

<?php
// Set up the Batch API
$batch = array('operations' => array(),
 
'finished' => '',
 
'title' => t('Exporting to files'),
 
'init_message' => t('Starting the export'),
 
'progress_message' => t('Exported @current out of @total'),
 
'error_message' => t('An error occurred and some or all of the exports have failed.'),
);
?>

Add as many functions to the batch queue as you need:

<?php
// Add an array declaring the callback function for your
// batch process and an array of callback arguments
$batch['operations'][] = array('your_batch_function', array($arg1, $arg2));
// add whatever logic you need
$batch['operations'][] = array('another_batch_function', array($arg1, $arg2));
?>

Tell the Batch API that you are finished:

<?php
if (!empty($batch['operations'])) {
 
batch_set($batch);
 
// batch_process() only needed if not inside a form _submit handler :
 
batch_process();
}
?>

drupal_execute() is not happy

One problem that I ran into along the way was the discovery that drupal_execute() has some compatibility issues with the Batch API. If I tried to use drupal_execute() in my batch callbacks, it would fail. Luckily there was a link to this tip to pause the batch that allowed the batch functions to use drupal_execute() with no complaints.

<?php
function your_batch_function($arg1, $arg2) {
 
// Pause the batch
 
$batch =& batch_get();
 
$ref = $batch;
 
$batch = null;

 
// run your code with drupal_execute()

  // Unpause the batch
 
$batch = $ref;
}
?>

Batching makes me happy

So, I just got done batch exporting 88 items including 19 super complex content types, 64 views and 4 vocabularies (one containing over 100 terms) and all it only took a few clicks. The Batch API is an amazing time saver. Combining it with some other awesome community tools like Import/Export gives me time to go take a much needed coffee break :)

Finally a better silverwear separator and some carving experiments

We've been using this hacked together silverware separator for the past couple of years. We made it out of a reclaimed dish drying rack, and as clever as it was, functional it was not. So, after several not so subtle hints, I decided to buckle down and make a new one today. I started out by cutting some rabbets and dadoes into some 1/4" oak strips. I bought a Stanley hand miter saw last year that I really like. It's got simple saw stop that really helps with cuts like this. Once I got everything ready to glue, I realized that I didn't have any way to clamp something this big. I tried to imagine what Dave, Melissa's Dad, would do as he is the jig master. After some thought, I put together a little gluing jig from scraps that kept it tight and square. Worked like a charm!

It is currently in use, but not quite finished. We opted to not use the tung oil and wait to get some food-grade oil. So, it might be awhile before it's done.

I also had a chance today to play with a new toy. It's a set of Power Grip carving tools that I grabbed last weekend from Rockler for $35. I opted for them because they were relatively cheap. The other brand, Two Cherries, that they carry cost $30-$50 per tool, so it made more sense to learn with something a bit more affordable. I was very impressed with them - incredibly sharp and accurate. I'm having a hard time imagining what would make the other tools that much better.

Dropdown Drupal menus with accessibility-friendly image links

I just finished up the preliminary work on a new site where the client wanted drop down menus and fancy image links for the top-level menu items. The requirements were to use the Drupal menu system to maintain permissions on the links, but also use stylized images for the main menu links. It took a bit of searching, but the solution was pretty elegant thanks to the Drupal community.

The drop downs were easy. I used the Nice Menus module for the first time and immediately fell in love with it. It provides up to 99 blocks to which you can assign Drupal menus. The menus can drop down or fly out, depending upon your design. Plus, you can stylize them to your hearts content to match your theme. So, the only real problem was how to use images for the top level menu.

There are apparently a few ways to solve this problem. My first attempt was to just use CSS to size the menu items, hide the menu text and place a background image for the element. This seemed to be the least obtrusive method for Drupal, but flaws emerged with compatibility and accessibility. Firefox seems to like color: transparent; but IE does not. They both seem to like text-indent: -1000px; but with either of these solutions the links completely disappear when you turn images off :(

Luckily, I stumbled upon this comment which details the use of theme_menu_item_link() to swap the menu title field with the description field and allow it to use HTML for display. After implementing the function in your template.php file, you can type your HTML img tag into the description field, and your hover text into the title field when creating a menu item.

Now, you have an accessibility friendly menu which uses Drupal permissions, image tags with alt text and an anchor tag with title text. You just have to do a little bit more CSS cleanup to get the drop downs to match your theme and you are golden!

Many thanks to the Drupal community on this one!!

A tapered column and a slice of humble pie

Sometimes you just have to take deep breaths. This is what I told myself today after completely ruining a project in the finishing stage. Learning how wood grain behaves has been a humbling and frustrating process, but I'm getting there. Don't get me wrong, I absolutely love the process, but I seem to have a tough time leaving well enough alone. Sometimes, one more pass is one too many.

So, after starting from scratch, I was able to finish shaping my first tapered column lamp base. After doing it a couple of times, I'm starting to get a good feeling for the hand plane. Melissa noticed that this lamp base was much more defined than my first attempt. It's not perfect, but I shouldn't complain too much. I'm sure the next one will be even better :)

Firefox add-on ScreenGrab! is a huuuge timesaver

I don't know how many times I've had to paste together five screen captures to make a single image of a web page. For some reason, I never really went out looking for a solution. So, yesterday I had to do a bunch of these and finally decided that /someone/ must have come up with a good solution for this.

Yes they did.

ScreenGrab! https://addons.mozilla.org/en-US/firefox/addon/1146

This add-on is quite simple. You can either save a screen capture as a file or copy it to the clipboard. You also have the option of capturing a complete page, the visible section, a selection or the current window.

Super handy.

Alter Drupal Email Messages

I just had a requirement to add some text to the body of Drupal's outgoing emails. Turns out it's not too tough using hook_mail_alter(). I started out by using var_export() and drupal_set_message() to find out more information about the array that Drupal creates for the message:

<?php
/**
* Implementation of hook_mail_alter().
*/
function your_module_mail_alter(&$message) {
 
// For example, submit the contact form and you
  // will be able to see the $message array

 
$v = var_export($message, true);
 
drupal_set_message("message: " . $v);
}
?>

The email text is constructed from an array of elements, so adding a new element to the email body is just a matter of adding an element to the body array:

<?php
/**
* Implementation of hook_mail_alter().
*/
function your_module_mail_alter(&$message) {
 
// Add a link to the user's profile in the message body
  // when you submit the site wide contact form:

 
switch ($message['id']) {
    case
'contact_page_mail':
      global
$user;
      if (
$user->uid != 0) {
       
$message['body'][] = 'Profile: [your-site-address]/user/' . $user->uid;
      }
    break;
  }

}
?>

You could just as easily use this for a variety of other cases. For example, you could add conditional recipients, do custom logging, or even use the message content as a conditional trigger. Lots of good stuff there.

Walnut lamp base and learning to plane

So, I've got all of this kiln dried walnut from my good friend Gouge. I've been sitting on it for awhile. Dave helped me plane some of it and turn it into a pretty sweet couch table, but I haven't been sure what to do with the rest. I'm currently exploring options for making lamp bases, and also looking for an excuse to learn how to hand plane. Perfect!

Without having a decent work bench, I needed a way to hold things in place because planing requires a lot of force. About halfway through the project, I decided to make a jig that really saved the day. It's a pretty simple thing that I can clamp to the front of my bench and it has an sliding "vice" that kind of takes the place of a proper vice and bench dogs. Hey, for an apartment workshop on a budget, what are you going to do?

Planing the wood was a trip because I've never done it before. It took a lot of getting used to. Changing the depth of the blade is wicked sensitive and takes ultra fine adjustment to get it right. After a half hour of chattering and sliding, I finally got into a rhythm. I even got pretty good at shearing cross grain without much chipping at all. I swear that I spent about eight hours sanding it today, but I'm really happy with the results. I gave it a first coat of tung oil and it absolutely brought the wood to life.

The next step for this base is to attach some copper pipe that I picked up from the hardware store, which I might or might not patina first. I've got a cheap lamp kit for the electric. Now, I just need to make a cool shade!

The next version is going to include a tapered walnut column that will probably be a bit tougher. Nonetheless, I'm excited to give it a try.

Syndicate content
I am a web professional working for an awesome company called Acquia. I build websites using Drupal. Most days find me in Massachusetts with my wife, Melissa.