Documentation

Using logrotate and drush for daily Drupal backups

If you've got Drush installed—and you really should—you can use the following recipe to setup a backup system that will maintain daily backups for the last two weeks. Most of the logrotate configuration is based on a Wikibooks book that I found.

Flash CS4 Gotchas

I've been banging my head against Flash for the last few days and started trying to document a few things.

Can't import fl.controls

For some reason Adobe didn't include them by default so you'll need to add the path to the project.

  1. Open the File > Publish Settings... menu item
  2. Click the Flash tab
  3. Click the Settings... button
  4. Click the Source Path tab
  5. Click the + button and paste in: $(AppConfig)/Component Source/ActionScript 3.0/User Interface

Can't use a Tween on a scrollRect

The Tween class can only change a simple property and the scrollRect need to be changed and the reassigned before it will update. The solution is to add new property to the class and Tween that instead:

  
public function get scrollX():Number {
  if (this.scrollRect) {
    return this.scrollRect.x;
  }
  return 0;
}   

public function set scrollX(value:Number) {
  var r:Rectangle = this.scrollRect;
  if (r) {
    r.x = value;
    this.scrollRect = r;
  }
}

Then you can use a Tween:

  tween = new Tween(this, "scrollX", Strong.easeOut, scrollX, scrollX + 100, 1, true);

Also, you'll want to keep a reference to the Tween object so that it doesn't get garbage collected half way through the animation.

Can't use named HTML entities

Flash's TextField only supports a small subset of named HTML entities (< > & " '). If you're displaying HTML from users or a CMS you'll find that things like ° slips by so you'll need to convert the named entities to their numeric versions.

Drupal 6 on OS X 10.6

Running Drupal on OS X 10.5 was a pretty huge pain in the ass. It's much easier in in 10.6 since it includes PHP 5.3 with GD and the PDO out of the box. And Drupal 6.14 resolves the PHP 5.3 incompatibilities.

In this guide I'll walk through the process I used for reinstalling OS X, then installing MacPorts and using it to install MySQL.

Note: I've shortened this up a bunch since it was first posted (originally it was using PHP 5.2 from MacPorts). I also want to make it clear that I am familiar with MAMP but would rather punch myself myself in the face than use it. If you'd like to go right ahead since it's probably easier, and as evidenced by the commenters below, you're in good company. But I'm going to continue to compile my own so I know where everything ends up.

Rainboduino programming via FTDI FT232RL cable

Rainboduino + FTDI FT232RL cable
I bought one of the Rainbowduinos a while back but hadn't tried programming. Turns out it's a bit of a trick. They (sort of) document the process with a Seeedunio but I don't have that particular board one so I decided to try to figure out how to do it using the FTDI FT232RL cable I'd bought from adafruit industries.

After finding the FTDI pinout on the datasheet and discovering that RTS is used to signal reset by the Arduino IDE I came up with the following wiring diagram.

Connect the cable pins on the left to the board pins on the right. Note: that you need to connect GND and VCC even if you're externally powering the Rainboduino.

1 GND Black  <-> GND
3 VCC Red    <-> VCC
4 TXD Orange <-> RXD
5 RXD Yellow <-> TXD
6 RTS Green  <-> DTR

You should now be able to use the Arduino IDE to upload code. Make sure you select the correct serial port and ATmega168 as the board type.

Drupal performance tuning on MediaTemple

First off make sure you've got the root account enabled and the developer tools enabled.

Install APC

Ideally you'd use PECL to install APC but it won't compile on MT's servers.

I was trying to use these instructions for installing APC but found that they no longer worked.

Download the source and extract it:

cd /usr/local/src
wget http://pecl.php.net/get/APC-3.0.19.tgz
tar xvzf APC-3.0.19.tgz
cd APC-3.0.19

Compile and install the extension:

phpize
./configure --enable-apc --enable-apc-mmap --with-apxs2=/usr/sbin/apxs --with-php-config=/usr/bin/php-config
make install

Tell PHP to load the extension and restart the webserver:

echo "extension=apc.so" > /etc/php.d/apc.ini
/etc/init.d/httpd restart

Tweak your Apache config

Disable ETags by adding:
FileETag none
to Drupal's .htaccess file.

Comparing a node's values with its previous version on save

There was a great question on Drupal developers mailing list the other day—one to which I've "rediscovered" the solution to a few times—so I wanted to make sure that everyone was aware of it.

The basic question is:

When a node is being saved, how can you see what values have changed?

The short answer is:

Use the 'presave' operation to load a copy of the node before it's saved, stick it back into the node object, and in your 'update' operation code compare the "before" and "after" versions:

<?php
/**
* Implementation of hook_nodeapi().
*/
function example_nodeapi(&$node, $op, $a3, $a4) {
 
// We want to compare nodes with their previous versions. Ignore new
  // nodes with no nid since there's no previous version to load.
 
if ($op == 'presave' && !empty($node->nid)) {
   
// We don't want to collide with values set by other modules so we'll
    // use the module name as a prefix and a long name to be save.
   
$node->example_presave_node = node_load($node->nid);
  }
  elseif (
$op == 'update') {
   
// On update we pull the previous version out of the node and compare
    // it to the newly saved one.
   
$presave = $node->example_presave_node;
   
// Pretend we're comparing a single value CCK number field here.
   
$field_name = 'field_example';
    if (
$node->$field_name != $presave->$field_name) {
     
drupal_set_message(
       
t("The node's value changed from %previous to %current.", array(
         
'%previous' => $presave->$field_name[0]['value'],
         
'%current' => $node->$field_name[0]['value'],
        ))
      );
    }
  }
}
?>

Simple loop to update nodes

For some reason I find myself rewriting this little bit of code every time I need to update a bunch of nodes on a site. Going to post it here to save myself some time. Be aware that this might time out if you've got a large number of nodes, designed for up to a couple hundred nodes:

<?php
// TODO: Set your basic criteria here:
$result = db_query("SELECT n.nid FROM {node} n WHERE n.type = '%s'", array('task'));
while (
$row = db_fetch_array($result)) {
 
$node = node_load($row);
  if (
$node->nid) {
   
$node->date = $node->created;

   
// TODO: Test and set your own value here:
   
if (empty($node->field_task_status[0]['value'])) {
     
$node->field_task_status[0]['value'] = 'active';
     
$node = node_submit($node);
     
node_save($node);
     
drupal_set_message(t('Updated <a href="!url">%title</a>.', array('!url' => url('node/'. $node->nid), '%title' => $node->title)));
    }
  }
}
?>

Simple Arduino serial communications

I've been playing around with some Arduino stuff I bought from adafruit industries and needed to rough out some serial communications between the Arduino and Processing. This just sets the Arduino up to echo characters back at the Processing sketch which buffers a line of output and displays the last line from the serial port.

Creating a CCK field in hook_install()

My rule of thumb for deciding what to post on this blog has been to document anything I've spent more than an hour trying to figure out. Today I've got a good one for anyone trying to create CCK fields as part of a module's installation process.

Back in Drupal 5 the Station module was made up of lot of custom code to track various values like a playlist's date or program's genre and DJs. During the upgrade to Drupal 6 I migrated that data into locked, CCK fields that were created when the module was installed. As people started to install the 6.x version of module I began getting strange bug reports about the Station Schedule that I couldn't seem to replicate on my machine.

Everything is an update

For some work projects we've started making all the configuration changes via update functions. These get checked into version control and from there deployed to the staging site for testing, and then eventually deployed on the production site. The nice thing about update functions is that you can test it on staging and be sure that exactly the same changes will occur on the production site.

Here's a few examples, I'll continue to update it as I get more good examples.

Installing a module

Simple one liner to enable several modules:

<?php
function foo_update_6000(&$sandbox) {
 
$ret = array();
 
drupal_install_modules(array('devel', 'devel_node_access'));
  return
$ret;
}
?>

Themeing a specific CCK field

I wasted more time that I want to admit do trying to figure this out. I was trying theme a specific CCK field named field_images on all the nodes where it appears. The devel_themer module was listing content-field-field_images.tpl.php as a candidate:

But after copying CCK's content-field.tpl.php into my theme and renaming it I couldn't seem to get the theme to pick it up. Roger López gave me the frustratingly simple answer on irc: "i think you need to have both templates in place"... duh. Copied content-field.tpl.php into my theme and everything worked great.

Getting PHP + GD + PostgreSQL working on OSX 10.5 (aka recompiling everything)

Finding myself in need of a PostgreSQL server to test some patches for Drupal core, I've decided to do a follow up to my guide to getting PHP + GD + MySQL installed on OS X.

Fortunately for me John VanDyk wrote up Beginning with Drupal 6 and PostgreSQL on OS X 10.5 Leopard which covers the nitty gritty of getting PostgreSQL server installed. He doesn't address recompiling PHP so I'll pick up the story there.

Last Updated: June 1, 2009

HOWTO: Views 2 Relationships

After getting sick of closing issues in various module's issue queues that boiled down to people not knowing how to use Views 2's relationship feature I decided to make a screencast explaining it:

http://drewish.blip.tv/file/1593750/

I think I need to get a microphone, and figure out all the features of the tool I was using but I'm excited to do more of these.

Update: The GotDrupal folks have a much more detailed—and more understandable—screencast on this topic: http://gotdrupal.com/videos/drupal-views-relationships

Migrating from D6 upload.module to filefield.module

So building on my last post for creating CCK fields, here's some code I whipped up to migrate from the D6's core upload.module to the filefield.module. This isn't general purpose code but might help someone else out. The catch is I'd built a video node with and was using the upload module to attach exactly two files, an image and a video. The new node will have separate thumbnail and video fields. If you'll be moving to a multi-value field this code won't work for you.

The gist is the same as before, setup your field for video and your field for images then export using:

<?php
var_export
(content_fields('field_web_video', 'video'), 1);
?>
and
<?php
var_export
(content_fields('field_video_thumb', 'video'), 1);
?>

Then roll that into an update function that also moves the file data around in the database. Code is after the jump.

Building the C2 Morse code trainer on OSX

I was trying to install Ward Cunningham and Jim Wilson's Morse code trainer on OS X and it looks like their .dmg file doesn't work on the new Intel machines. Here's what I did to get it to build.

Syndicate content