Cultural awareness

I had a chance to sit down and talk with Arun Pereira, author of The Culturally Customized Web Site: Customizing Web Sites for the Global Marketplace recently. He has studied the use of the web by different cultural groups, and come to the conclusion that translation is only a part of the picture; a website should be presented differently to an individualistic American vs. a collectivist Asian. I found that interesting, as I hadn't thought about it much before. Applying that thought to Drupal, the t() function becomes less important, though still essential, and theming becomes more important.

[ Submitted by John on Fri, 2006-12-29 11:08. | | ]

Drupal book


Yowza! Lookee here! And here.

[ Submitted by John on Wed, 2006-11-29 21:04. | | ]

Serving static files with Apache and directories with url aliasing in Drupal using mod_rewrite

A common task is to move a static site to a Drupal site. For example, you might have

/site/
/site/2004
/site/2004/index.html
/site/2004/page_1.html
/site/2004/page_1_image.jpg

You think to yourself, "I'll just leave the image files on the existing filesystem. They don't really need to go into Drupal anyway." So after your content migration is complete your content is in Drupal but you've got the following left in the directory:

/site/
/site/2004
/site/2004/page_1_image.jpg

What happens when someone tries to go to http://example.com/site/2004/ ?

They get either a directory listing or a Forbidden message, depending on how you have Apache's Indexes directive set for that directory or its parents. But you don't want that! You want it to pass through to Drupal, where you've created a url_alias entry so that all the old URLs, including directory URLs get mapped to Drupal nodes.

Suddenly you come upon a clever idea. Why not just edit the relevant portion of Drupal's .htaccess file to stop Drupal from aborting the rewrite if the path points to a directory?

# Rewrite current-style URLs of the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

becomes

# Rewrite current-style URLs of the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

All is happy. Happy happy. Your files are being served, Drupal is handling requests with url aliasing, but wait! What's this? Going to

/site

Results in a Bad Request error from Apache. But

/site/

works fine. What's going on? It's a long story, but basically the DirectorySlash magic is happening before mod_rewrite can get ahold of the request (because mod_dir runs before mod_rewrite). Here's the answer:


# Fake out DirectorySlash so that Drupal can serve up the directory.
# Don't use [L] here as we pass on to the next rule.
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.+)$ $1/

# Allow apache to serve up existant files directly but pass
# everything else to Drupal, including 'directory' requests
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php?q=$1 [L,QSA]

Thanks to noodl in #apache for this solution. chx notes that you need [L, QSQ] instead of [QSA] on your last rewrite rule.

Note that this is an either-or situation. You can't serve some former-directories-which-are-now-URL-aliases from Drupal and leave other directories with index.html files in them and have Apache serve those. When you try to hit http://www.example.org/somedirectory/ you will not get http://www.example.org/somedirectory/index.html; instead you will get Drupal's 404 handler.

[ Submitted by John on Thu, 2006-11-09 16:51. | | ]

Safari contextual menu for applying Drupal patches

I wanted an easy way to test patches, so here's what I did.

Downloaded OnMyCommand.

Copied the OMCEdit application folder to Applications.

Ran the script Install OnMyCommandCM (I checked it out in Script Editor first.)

Logged out and logged back in.

Followed this tutorial.

I created a contextual menu item named Apply patch to Drupal installation with the following code:

#!/bin/bash
DRUPAL_HOME=/Library/WebServer/Documents/
cd $DRUPAL_HOME
touch drupaltemp
rm -R drupaltemp
cp -R drupal drupaltemp
cd drupaltemp
osascript -e 'tell Application "Safari"' -e 'get source of document 1' -e 'end tell' | perl -0ne 'print "$1\n" while (/a href=\"(http:\/\/drupal.org\/files.*?)\">.*?<\/a>/igs)' | tail -1 | sed "s/\(.*\)/--url \1/" | curl --config - > patch
bbedit patch
patch -p0 < patch

Now when I right-click on an issue and choose Apply patch to Drupal installation, the script:

  • Creates a working copy of Drupal.
  • Obtains the source of the current page from Safari.
  • Parses out URLs that designate patches (begin with drupal.org/files).
  • Find the last one, since there may be multiple patches in the issue.
  • Download the patch.
  • Open the patch in BBEdit.
  • Apply the patch to the working copy of Drupal.

Note: this is actually a workaround. I wanted to modify Safari's contextual menu for links, but was unable to find a way to hook in.

Sadly, this will probably not increase the number of patches I review, as it's not really the patching that takes time. This was more of an, I can't sleep...I wonder if I could create a contextual menu that... kind of a project.

[ Submitted by John on Sun, 2006-10-29 21:09. | | ]

ImageLabeler and tagging games

The biggest obstacle to implementing metadata-driven systems is getting those who have the best knowledge to actually enter the metadata. Entering metadata for content is widely seen as a chore, and that grumbling sound you hear is the sound of all those users whose managers have made the metadata mandatory.

I just stumbled across Google Image Labeler. It turns image metadata entry into a game, where you're paired with another player and compete to produce matching metadata for a given image. (I'm sure Google doesn't throw away the metadata that doesn't match, either.)

There's a good explanation by Michael Mahemoff at Ajaxian.com.

[ Submitted by John on Tue, 2006-10-17 10:05. | | ]

Eudora goes open source

Eudora, the venerable mail client, will be open-sourced and merge somehow with Thunderbird. Specifics are at the Penelope wiki.

I've used Eudora since it first came out. I still do. The only other mail client that has really tempted me is Mailsmith because of its close integration with BBEdit. Unfortunately Mailsmith had no Kerberos support when I checked it out.

[ Submitted by John on Wed, 2006-10-11 22:13. | ]

Drupal 4.6 and PHP 5

I'm running PHP 5.1.6 and wanted to do some testing with the publish and subscribe modules for Drupal. This is the first time I've had PHP5 on my development machine for a variety of mundane reasons. Drupal 4.7 runs fine with PHP5, but imagine my surprise when a fresh install of Drupal 4.6.9 looked like this:

{_BLOCK_.header.logo} {_BLOCK_.header.site_name}
{secondary_links}
{primary_links}
{_BLOCK_.header.blocks}
{_BLOCK_.header.message}...

That's because Drupal 4.6.9 ships with an XTemplate-based theme called bluemarine that doesn't like PHP5. The quick 'n' easy solution was to go to /?q=admin/themes and change the theme to chameleon. (Then I installed the phptemplate engine and used phptemplate from then on.)

Unrelated note: pick up a copy of Apache Security. It's well worth it.

And another unrelated note. In a fit of Drupal server optimization, I installed the FreeBSD port of Zend Optimizer 3.0.1. However, it wasn't long before Apache was segfaulting. It turns out that I compiled PHP with the --enable-versioning flag on (since it's on by default), which is a no-no.

[ Submitted by John on Wed, 2006-10-04 16:01. | | ]

Remote PHP Debugging on Intel-based Macs with Komodo

I got a new computer. Yay! It's a Mac Pro.

So naturally I want to set up my Drupal working environment on it.

However, I use the Zend IDE and the Zend Studio Server debugger will not run on Intel-based Macs. No, seriously. It's inexcusable.

I love my real-time debugging. So I decided to try out Komodo. I've made a point to ask about OS X versions of Komodo at the ActiveState booth for as long as I've been attending OSCON. Now they've got a stable version and it supports Macintel.

Well, almost.

So, starting with my new Mac Pro, I installed XCode Tools to get cvs and all the other command-line niceties. Then I headed off to Marc Liyanage's PHP page to install PHP (even PHP treats Marc's installer as the official binary).

PHP 5 installed fine, but I got this unusual hiccup when starting Apache:

[warn] module mod_php5.c is already added, skipping

Commenting out the line

AddModule mod_php5.c

from /etc/httpd/users/+entropy-php.conf got rid of the warning. I'm guessing that Apache is somehow automatically doing an AddModule when it hits the LoadModule line. Anyway, it works fine.

Next, it was time to set up Komodo for debugging. First I wanted to make sure it found the php5 that I installed, and not Apple's php4. So I did this in /etc/profile:

PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/php5/bin"

and then moved Apple's php binaries out of the namespace:

sudo bash
cd /usr/bin
mv php php-old
mv php-config php-config-old
mv phpize phpize-old

I logged out and back in to activate the new PATH and tested:

which php
usr/local/php5/bin/php

I put this

<?php
phpinfo();

into /Library/WebServer/Documents/phpinfo.php and sure enough, http://localhost showed me the PHP info page. Good so far. On to installing Komodo.

I downloaded Komodo, copied it to Applications, and clicked on it.
Chose Trial version
Got email with URL for evaluation activation key.
Downloaded EvalLicense-KomodoProfessional-MacOSX.zip
Double-clicked to get ActiveState License Installer.
Double-clicked to install license.

Now I started Komodo. I built the "intelligence database" and set up Langugages - PHP.

Now it was time to set up debugging. I used Languages - PHP - Debugger config wizard to put the debugger's php.ini file into ~/komodo/ini and the debug extension into ~/komodo/extensions. It then informed me that the debugger extension could not be started. I did this many times.

Finally, I got annoyed with the debugger config wizard. Instead, I installed xdebug myself. Here's how. First download xdebug (I downloaded version 2.0.0beta6). Then compile it:

cd xdebug-2.x.x
phpize
./configure --enable-xdebug
make
mkdir /usr/local/xdebug
cp modules/xdebug.so /usr/local/xdebug/

Then I edited /usr/local/php5/lib/php.ini to include the following:

zend_extension=/usr/local/xdebug/xdebug.so
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_port=9000
xdebug.remote_host=127.0.0.1
xdebug.idekey=komodo

While I was editing php.ini anyway, I changed memory_limit to a sane number.

Applied my changes by restarting Apache:

apachectl restart

Next I configured Komodo to listen for xdebug by going to Preferences - Debugger - Proxy. I set Listen for debug connections on port: to 9000.

Then I went to the Debug menu and chose Listen for Remote Debugger.

And, when I went to http://localhost/phpinfo.php in my browser...wah la! Nothing happened. But when I added the xdebug parameter, like this:

http://localhost/phpinfo.php?XDEBUG_SESSION_START=komodo

then Komodo was invoked and I could step through the request, just like in Zend. Whee!

Note: I have confirmed that xdebug.so that is included with Komodo, which Komodo helpfully installs in whichever directory you specify during your time with the Debugger Config Wizard, does not work. That file has an MD5 of 8cca2df563529f950219a86cfadf2e48.

However, the version of xdebug.so I compiled does work.

This writeup dedicated to webchick, who allegedly has lost a good two weeks of her life dealing with remote debugging on Macintel.

P.S. I've tried this with MAMP 1.3.1 and it works fine. Also, it doesn't seem to matter which value I use for xdebug.idekey. Also, if you want to request some pages without the debugger firing up, turn off the Listener under Debug - Listen for Remote Debugger.

Helpful references:

Komodo 3.5 Debugging Documentation
Debugging Drupal with Activestate Komodo
xdebug documentation

[ Submitted by John on Wed, 2006-09-20 13:10. | | ]

MapServer and Drupal

I've been working with MapServer a bit. I needed to spit out maps of states with counties painted different colors depending on a count. Wouldn't it be nice to have a function you could call and pass it the name of the state, an array of county-count pairs, a legend setting which count ranges get which colors, and a width and height? It'd be nice if it had a smart caching function, too.

So I present a tiny but fun maps.module, in a contrib cvs repository near you. And if you're a MapServer wizard, improvements are welcome.

[ Submitted by John on Fri, 2006-07-28 19:05. | | ]

Nutch and Drupal

For the past five weeks I've been working with the Nutch open source search engine and web crawler. Nutch is at the point that Drupal was a year and a half ago. For Drupal, that "meant lots of potential," "poised for explosive growth," and "lacking in documentation." We had the first Drupal conference in February of 2005, and though we expected only a handful of people, many more showed up! I hear that a similar thing happened at the Nutch meetup recently.

Doug Cutting, currently at Yahoo!, is the lead developer. The Nutch project also resulted in an interesting distributed system called Hadoop.

Here's a site running Drupal as the front end and Nutch as the back end. There is currently work being done to integrate Drupal vocabularies and terms with Nutch's search.

[ Submitted by John on Sun, 2006-06-18 07:23. | | ]