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.
- Open the File > Publish Settings... menu item
- Click the Flash tab
- Click the Settings... button
- Click the Source Path tab
- 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 &deg; 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

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 <-> DTRYou 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.19Compile and install the extension:
phpize
./configure --enable-apc --enable-apc-mmap --with-apxs2=/usr/sbin/apxs --with-php-config=/usr/bin/php-config
make installTell PHP to load the extension and restart the webserver:
echo "extension=apc.so" > /etc/php.d/apc.ini
/etc/init.d/httpd restartTweak 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)));
}
}
}
?>Bicycle inflation?
The NY Times—as part of their longtime fixation on Portland—has an article arguing that the price of bicycles is inflated in Portland. There definitely aren't easy deals there, but having now seen the $200 junk bikes that are for sale on the street in Williamsburg I think they are exaggerating. I'm pretty sure that a if they got a ZipCar and drove out to Beaverton they'd find all kinds of deals on jenky bikes.
But here's some of my thoughts (which you can also find on page five or so of the comments):
- Bikes in Phoenix and Austin are going to last a lot longer due to the difference in climate. Seattle and Portland get much more rain that'll rust bikes locked up outside.
- Having bought a bike from Costco back in the day I can tell you that it's either un-assembled or incorrectly assembled, and probably unsafe. Knowing that I'd send my friends to a bike shop.
- You're shopping in the summer. the worst time to buy a bike in portland is when the weather's nice. Wait until the week after the rain starts back up and you'll find a lot more deals—you'll also have a lot easier time finding places to lock your bike
Partying like it's 1999
I just got around to upgrading my website to Drupal 6. In the process I decided that I was going to redo the theme using 960.gs for a nice grid based design and then I got it into my head that I wanted a nice retro 1990 theme. So here it is, my stab at recreating the Netscape 2 experience. I'm not sure how long I'll be able to stand it but I'm going to enjoy it while it lasts.
Update: couldn't handle it anymore, had to "modernize" it a bit.
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;
}
?>A busy week... or two...
The total number of hours I've worked in the last seven days has been hovering between 60 and 70. We're on a deadline so compromised must be made and corners must be cut. Sections of the site are basically large JPGs with image maps of links on top. It looks good but when I peek into .tpl.php my head swims and I feel faint at the though of the kludges in place. It's lead to some fun exchanges:
coworker: "do you ever get to do a project where you don't have to end up hacking it at the end of the day"
me: "yeah the ones that never got finished :)"
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.
Text mode Cover Flow
My side project has been writing some code to display data from iTunes on my Heathkit H19 terminal.
Requirements
You'll need to use MacPorts to install ImageMagick and jp2a:
sudo port install jp2a imagemagickYou need to use Ruby's gem to install ncurses and appscript:
sudo gem install ncurses rb-appscriptThe Code
As of 24 May 2009, I've move this code to GitHub Repository. Now there's publicly accessible version control and people can fork and share changes.

