Jun 26 2006
Jun 26

I just returned from BarCamp San Francisco , and I'd have to say it was a success.

This was my first BarCamp, so I had no idea what to expect. It really is as simple as it sounds. A bunch of folks show up and schedule events on the spot based on who is present and what they're interested in.

It took place at Microsoft's offices on Mission and Embarcadero. While normally I'd be inclined at this point to offer one of several heartfelt opinions about Microsoft, I'll just say that it was very generous for them to allow us their location for the weekend, and it was very well suited for this great event. <gulp> Thanks, Microsoft.

"Take Aways"

One of the unfortunate survivors of the dot-com bust was a vast set of obfuscated vocabulary collectively known as buzzwords, a value-add semantical meta-markup linguistic solution used to define hi-tech marketecture and other domains. Can you feel the synergy?

Yes, there was no shortage of buzzwords floating through the air, and it's hard to avoid them when they are made up largely of otherwise very usable terms such as "solution" (which now means software application), bandwidth (which now means intelligence or ability ["I don't have the bandwidth to..." actually means "I'm not smart enough to..]") and "orthogonal" (which is used in so many disparate contexts, I don't know what to make of it).

Point being that the following section may be populated with buzzwords, so watch your step.

Talent Co-op

This was probably the coolest concept I came across (read: most relevant to me). The idea of bringing together in a single (virtual) place geographically dissimilar supplies and demands is not new. Elance.com, Guru.com, blah, blah. What hasn't been done, to my knowledge, is this sort of thing without the blatant and irritating commercial aspect to it. Something just plain bothers me about relying on some corporate interloper to supply me with suitable clientèle, particularly when they have no reason to take any concern for the quality of either the supplier or the suplyee.

The internet is too obvious an answer to the problem of many people working (or wanting to work) from Location Unknown doing things they love and are good at, and other people wanting to find good worker units and not really caring where, when or how they work as long as they can do the job.

Citizen Agency is the first effort (that I'm aware of) to bring a bunch of talent together to pool talents, resources and work. The effort is only weeks old, and I believe BarCampSF was the official announcement of the effort.

Micro Formats

Here's an example of something I ignored as more buzzword blather that turned out to actually be something potentially very useful. Microformats is like XML in that it's easy to explain and difficult to completely understand. As I see it, microformats would turn any standard web page into a potential source of data objects like contacts, locations, content objects like reviews, and anything else you might normally look for in a database. Main problem, widespread adoption. Microformats probably won't blossom until these formats are managed behind the scenes by blog software, document editors, email and so on. But I can definitely see that happening, at which point you'll see all sorts of useful tools (first appearing as extended functionality to clients like browsers and email apps). Read up a bit on this so when it finally breaks out, you can say something like, yeah, I saw that coming back in 06.


No need to go into any detail here. Everyone wants to be like MySpace, Flickr, Facebook, etc... I find the subject tiresome myself. The *concept* of community has no meaning or value to me. Implementation of community oriented websites, features and so on is what interests me.


While there was a very nice showing from the Drupal camp. I got to meet Drupal luminaries jjeff, dries, drumm, roland and others. Sporting my own Drupal tag, I struck up Drupal related conversations with most of the folks I met. (I'm hereby pronouncing myself as Drupal's chief petty evangelist.) I don't think I met anyone who wasn't aware of Drupal. Most had at least some direct experience with Drupal. Most folks had a lot of questions about it. Some had the common "I installed it, now what" experience with Drupal. I think we might benefit from expanding, somehow, our efforts to help folks (hi sepeck!) install, use and love Drupal.

The BarCamp experience was better than I had anticipated. I highly recommend you attend one when it hits your town. I'm going to attempt to help organize the first BarCamp San Diego.


Jun 26 2006
Jun 26

My town uses my code : the Ann Arbor District Library uses Drupal for their web interface, including my captcha module!

Jun 20 2006
Jun 20

D'Arcy notes that it has been one month since he's switched over from WordPress 2 to Drupal 4.7 and he's very happy with the change. In comparing the two applications, he writes,

I'd recommend WordPress for new bloggers, but I'd wholeheartedly recommend Drupal for people that want to take advantage of some of the more flexible content management stuff available in a higher-end app. Not a shot against WordPress at all - the two platforms serve slightly different (and complementary) roles.

I agree. But I'd also recommend Drupal over WordPress for newbie bloggers who want to learn an application that they can use for other, not-just-a-blog web projects. In the process of learning Drupal, one gains experience with a tool that has so many other applications.

Jun 15 2006
Jun 15
Vertice sign
Originally uploaded by bmann. />

Well, well....That is a surprise. Adrian must be chuffed :).

Well done Boris. Have you spotted a dikini plaque somewhere? I'll pay in beer.

read more

Jun 14 2006
Jun 14

The Drupal way in programming is 60% about hooks 10% about nodeapi and the rest is ingenuity. That's allright, but one fact has always troubled me. And that is - how much effort is spent on discovering which module implements the hook I need. Far enough, the old caching/memoizing trick does the job to ensure that the cpu time is not expensive. Yeah, but still it's outside simplicity might be, just might be implemented in a more elegant fashion.

Drupal hooks implement a nearly Aspect Oriented API. The cross-cut is the point where the hook is invoked. aspect(cross-cut) === hook. The different aspects are declared as moduleName_hook. The disatvantage is that these are indiscriminate. Hooks are always fired. Pros - simplicty, cons - wasted cpu cycles.

I wonder. Is it possible to achieve a similarly simple syntax, but with the added advantage of not firing unnessesary hook calls.

Problem (1st iteration)

We need to call all functions interested in this particular execution point. The current context and the run history should determine which functions are actually interested in this particular point/label/crosscut.

So what if:

hook('view','a callback);
//in a code piece far away
invoke('view', .... );

In invoke() we can have something similar to the current code

function invoke($hook,$args) {
while($call = next($hooks[$hook])) {

How to implement hook(...)?

function hook($hook,$callback) {
invoke( $hook, $callback, 'add');

We would need an unhook() though, so that the interest is fully managed.
function unhook($hook,$callback) {
invoke( $hook, $callback, 'remove');

And finally the modified invoke:
function invoke($hook, $args, $op) {
static $hooks;

if($op == 'add') {
//memory waste, but can do for now
$hooks[$hook][$args] = $args;
elseif($op == 'remove') {

while($call = next($hooks[$hook])) {

Order please

Partial order that is. It would be handy to be able to have before($hook) and after($hook) calls. This will allow manipulating the sequence of calls, without modifying the grand plan request workflow.

before($hook) adds the callback before the hook point. The order of the other 'before' callbacks for this hook is unknown.

after($hook) does the same, but after the execution of the hook

The arguments of the callbacks added with before and after are the same as for hook for a given cross-cut/hook point

The implementation is similar to hook

function before($hook,$callback) {
invoke( $hook, $callback, 'add-before');

function not_before($hook,$callback) {
invoke( $hook, $callback, 'remove-before');

function not_before($hook,$callback) {
invoke( $hook, $callback, 'add-after');

function not_after($hook,$callback) {
invoke( $hook, $callback, 'remove-after');
//in invoke, the rest is similar
if($op == 'add-before') {

An interesting 'theoretical' consequence is that this is a kind of a higher-order functions based implementation of aspect style programming in an imperative language. That is if you are into such words. It is more interesting thing to notice is that the $var() syntax allow you to code wanted patterns and execute them later on by simply passing new $var to the pattern function. This technique parallells lisp and scheme style macros, you just can't easily manipulate them.

Second iteration or cleaning up the nest

There are a few problems with the above code. It doesn't reflect faithfully the problem, that is the treatment of arguments and results. It is too verbose and can do with some optimisation.

Let's start with the model. The type of an aspect function is ($args→$result). We are not interested in actual shape of either, but their correct treatment. It suffice to say that the only requirement to both is that they are the same for each separate hook. The shape of the aspect computation is (∥($args→$result))→(∥($args→$result))→(∥($args→$result)), where ∥ denotes parallell or unordered behaviour of a bunch of functions. The last remark is important, since we are introducing order or synchronisation with the before and after operations, but that order is only partial, relevant to the bigger picture. In each phase the order of execution should remain unknown. This doesn't break the abstraction boundaries, which is good. This as well means that the functions in each phase must not change $args and must not overwrite the same part of $result. This restriction won't be enforced for both simplicty and performance, it should be tested with unit tests in real life code. Failing to obey this discipline will cause an unexpected behaviour.

Let's change the code then. What is the shape of a typical before function?
function a_before($args, &$result) {
As it happens the shapes of the at and after functions are the same. We are enforcing a partial order of evaluation and enhancing a function, not changing it's signature.
The evaluator can be written out as looping over each of the different phases
while(current( $hooks[$hook]['before'] )) {
$cb = key( $hooks[$hook]['before'] );
next( $hooks[$hook]['before'] );

while( current( $hooks[$hook]['during'] ) ) {
$cb = key( $hooks[$hook]['during'] );
$cb( $args, $result );
next( $hooks[$hook]['during'] );

while( current( $hooks[$hook]['after']) ) {
$cb = key( $hooks[$hook]['after'] );
$cb( $result );
next( $hooks[$hook]['after'] );
return $result;

This code can be optimised by parametrising the hook selection, add and remove operations, so that we end up with the following short hook invoke function
function invoke($hook, &$args, $op = 'run', $phase = '' ) {
static $hooks = array();

switch($op) {
case 'run':
foreach( array('before', 'at' ,'after') as $phase ) {
while( current( $hooks[$hook][$phase] )) {
$cb = key( $hooks[$hook][$phase] );
$cb( $args, $result );
next( $hooks[$hook][$phase] );
return $result;

case 'add':
$hooks[$hook][$phase][$args] = true;
case 'remove':
unset( $hooks[$hook][$phase][$args] );

We can sweeten the syntax by adding explicit hook_before, after, at and the respective unhook functions, to hide the message passing notation of the above function. For example
function hook_after( $hook, $cb ) {
invoke( $hook, $cb, 'add', 'after');
function unhook_before( $hook, $cb ) {
invoke( $hook, $cb, 'remove', 'before');

Adding honey to the pud

The invoke function does too many things, it is unfortunate. It is a natural 'object', purists of any kind don't go for me, that is not a flame bate. We can use php's object oriented features to make this a bit more abstract and enforce separation of concerns, rather than a static and a switch.

class hook_namespace {
var $hooks;

function run( $hook,$args ) {
foreach( array('before', 'at' ,'after') as $phase ) {
while( current( $this->$hooks[$hook][$phase] )) {
$cb = key( $this->$hooks[$hook][$phase] );
$cb( $args, $result );
next( $this->$hooks[$hook][$phase] );
return $result;

function hook($hook, $phase, $cb) {
$this->$hooks[$hook][$phase][$cb] = true;
function unhook($hook, $phase, $cb) {

While I could have gone oveboard abstracting further and further, the above class is good enough for my personal taste. It is concise. It does what it says on the box. Ok, fair enough, there are bits to keep in your head, but that is (hopefully) allright. The last two versions practically implement the drupal hook wiring without the broadcast effect for trying out all possible hook definitions. On an abstract level it is a tad more powerful. It has the disadvantage that you need to hook up at runtime, not definition time.

If php had more abstract features we could have done more. With a proper macro facility, we could have shifted the work further towards compile time, now there are extra operations to be performed.

To killes - you are more right than you ever thought. The above code is monadic for all practicall purposes. Of course in haskell it will look very differently, but hey it is a step.

Update I realised that it is better to name the class hook_namespace, since the instance of that class is providing a encapsulation of hook in a single scope, it's a bit verobose, but at least a better name. This has the dubious benefit of renaming add and remove to hook and unhook.

Attachment Size aspect.php.txt 1.71 KB
Jun 06 2006
Jun 06

At the Yearly Kos convention on June 8th the CivicSpace community will be teaching a workshop on building netroots campaign websites. Experts will be avaliable all day to teach participants at every skill level. The day will culminate in a barn raising of a real world netroots campaign website thought up by the DailyKos community and built by workshop participants and facilitators.

This thread:


is being used used as a campaign idea incubator with the best concept being built three days from now at the YearlyKos convention. If any of you are DailyKos members we could use your help recommending the thread so that it gets exposure within the DailyKos community, also please submit your ideas if you have them. If any of you want to help out please send me an email and let me know:

  1. If you will be attending YearlyKos
  2. If you want to help facilitate the workshop
  3. What specifically (if anything) you would like to pitch in on.

Hope to I'll see some of you in Las Vegas shortly.

May 24 2006
May 24

What a good occasion. After so much time spent on Google SOC (the bit about Drupal), after dealing with students, mentors, and other creatures. After the results are out, you finish it off with a birthday.

Well done, Happy Birthday Rob. (true or not it is your birthday)

May 23 2006
May 23

I've updated the code. Now the scripts can convert a module into a new module and tpl file.

The script can produce a _widget hook from the old module file.
bash$ ./mparse.php filename option
for example try:
bash$ ./mparse.php path/to/drupal/modules/node.module --all

update: fixed several bugs, so a new file is attached

Attachment Size mparse.tgz 3.46 KB
May 22 2006
May 22

I kind of finished the parser bit of the transformer routines for splitting off the theme functions from the drupal modules. It ended up a bigger thing than anticipated. The parser doesn't handle yet functions returning references.

At the moment only a parser and a pretty printer exists. It can be modified to enforce appropriate style and is not drupal specific.

I'll be adding the module_templates() functions generator this evening and tomorrow and maybe a specific split driver, so you can do the generation of the name.module, name.tpl.php in one pass, rather than running separate programs.

I attach a working as of this morning for your amusement. Warning: ugly code.

Attachment Size mparse.tgz 2.36 KB
May 12 2006
May 12

Alaa - a blogger, an activist, a drupal contributor and more importantly just a man was jailed for being on a demo. Disgusting.

While that doesn't surprise me, things like that happen everywhere, not just in countries with regimes similar to Mubarak's, it still pisses me off.

I can't stand the response of the 'powers of the day' to bully you into submission, if you dare not to support them.

If you happen to be in London on 13/5 and fancy making noise in front of the Egyptian embassy just join the protest.

Oh, yes have you heard the carpet bombers for peace, here's the Egypt version?

May 09 2006
May 09

Spencer Critchley recently interviewed me about CivicSpace, Drupal, and DeanSpace for the O'Reilly OnLamp blog.

May 09 2006
May 09

As I go through a test site for One Inch Frame’s update to Drupal 4.7, I’m doing something different with my wiki nodes and web link nodes. Right now, I’m using to build a custom wikinode type, and am using for the large amount of links that I accumulate in my links directory, the sort of thing that I used to post to del.icio.us. The weblinks module has been discontinued in favor of the , but that promising project is still not ready, and my needs are such that that project might just be overkill. I’ve still got my eye on it, though.

With the 4.7 version, I’ve decide to take a good hard look at the , as it is basically the future of flexinode and Drupal. And it’s also really, really cool.

So I created a simple node type for wikinodes, and a type for web links. One of the things I want to do differently this time around is build in attribution to my web links, so I can give credit to the source where I found the link. So, another CCK content type for web link source is needed, and I can use the built-in ‘nodereference’ field type to link a web link to its source.

And, out of the box, it works great. I can add attribution sources and they show up in a drop-down in the web link content creation form. Super cool. The default look of this field when viewing a web link makes the attribution hotlinked to the attribution’s source node. It boggles my mind to think of some of the ways smart people are going to take advantage of the CCK, and, particularly, its nodereference field type. There’s also a userreference which does the same thing for users, for completeness.

The way CCK-created content looks is a fine default, but, theming them will be necessary in almost every case. Fortunately, the CCK download comes with a theme/ directory with documentation and samples.

So, the first thing I want to do for all my CCKreated (heh, like it? made it up myself) nodes is to remove the label. The CCK allows theming at the field level or up at the node level. To remove the labels globally for all CCKreated content, there’s some code to add to the template.php file, then your PHPTemplate-based theme will call field.tpl.php files to render all CCK fields. Just removing the printing of the label is fine here:

So, my field.tpl.php looks like this:

<div class="field field-type-<?php print strtr($field_type, '_', '-') ?> field-<?php print strtr($field_name, '_', '-') ?>">
<div class="field-items">
  <?php foreach ($items as $item) { ?>
    <div class="field-item"><?php print $item['view'] ?></div>
  <?php } ?>


While that takes care of theming the individual fields, for my web links I want to theme the whole node. PHPTemplate allows for different themes to be applied to different content types, and CCK extends that to its own types. So, to theme a web link CCKreated node, I write a node-content-web_link.tpl.php. This will override the theming of the individual fields, and give me control over the content as a whole. As CCK exposes its fields via a $field_<fieldname> array, this, too, is pretty simple:

<div class="node<?php if ($sticky) { print " sticky"; } ?><?php if (!$status) { print " node-unpublished"; } ?>">
  <?php if ($picture) { print $picture; }?>
  <h2 class="headerstyle"><a href="http://oif.eafarris.com/cck_theming_in_drupal_4_7/<?php print $node_url?>"><?php print $title?></a></h2>
  <span class="submitted"><?php print $submitted?></span>
  <span class="content">
    <p class="weblink_description"><?php print $field_description[0][view] ?></p>
    <p class="weblink_url"><?php print $field_url[0][view]?></p>
    <p class="weblink_attribution">via <?php print $field_attribution[0][view]) ?></p>
  <span class="taxonomy">Categories: <?php print $terms?></span>
  <?php if ($links) { ?><p class="internallinks">&raquo; <?php print theme('links', $node->links, '&nbsp;&middot;&nbsp;')?></p><?php }; ?>

That’s nice, and generic. I need a couple more things to make this just what I’m after:

  • The url isn’t hot. It should be linked to itself.
  • The attribution goes to the attribution node, but I’d much rather it go directly to the attribution’s site, which is contained in a URL field as part of the attribution node.

The first one is very simple, just wrap the url in an href of itself:

<p class="weblink_url"><a href="http://oif.eafarris.com/cck_theming_in_drupal_4_7/<?php print $field_url[0][view]?>"><?php print $field_url[0][view]?></a></p>

Getting to the last part will require a tiny bit of programming. What we want, instead of a link to the attribution node (which is a cck-derived content type of content-web_link_source) we want the link to go directly to the url within that node. To start, we’ll need to call a custom theme function instead of printing the $field_attribution stuff:

<p class="weblink_attribution">via <?php print theme('oif_attribution', $field_attribution[0][nid]) ?></p>

Now, we write that theme function. It goes in template.php, and, for completeness’ sake, we call it andreas03_oif_attribution(), since andreas03 is the name of the theme. It gets the nid of the attribution node passed to it::

function andreas03_oif_attribution($nid) {
  $attribution = node_load($nid);
  $output = '<a href="http://oif.eafarris.com/cck_theming_in_drupal_4_7/' . $attribution->field_url[0][value] . '">' .  $attribution->title . '</a>';
  return $output;

And, there it is. A fully themed CCK node. Drupal is so freakin’ cool. You’ll see these new nodes when I roll out the new version of One Inch Frame, based on Drupal 4.7, which is still several weeks away. There are just so many cool things that I want to do, that are now possible.

May 09 2006
May 09

I've just uploaded into the bryght svn a basic filter, actually a couple of them (I was lazy). They parse a php file, and output (leave out in the case of the no_filter), all functions starting with a given prefix.

I've done it in order to be able to play with separate theme_xxx files.

vlado:~$ no_filter function_prefix php_file
read the php_file, print it to stdout, leaving out all functions starting with function prefix.

vlado:~$ yes_filter function_prefix php_file
read the php_file, print it to stdout, leaving out all functions not starting with function prefix.

both filters know about associated comments, etc...

May 04 2006
May 04

Funny things these summer of code applications. Some of them come a very well thought out projects, others are more like cloudy ideas.

If you want to submit a proposal, and want to be successful, please put a little effort in spec-ing properly. Tangible goals are a very good thing. Good language, not really importnat, just put them in bullets if you fancy it that way.

If unsure, get to #drupal on irc.freenet.org, and ask. Mention SOC and project proposal, and you'll get attention and tlc. That is if you are applying for a drupal project, for others, well don't expect much help in that channel.

Good luck

May 04 2006
May 04

Watch this screencast to learn how to use Drupal to create Google Maps mashups of virtually any arbitrary data or content with no coding in minutes. For the example shown in this screencast I took a csv file of crime data provided by the San Francisco government and turned it into a usable google maps mashup in about 10 minutes.

14 minutes / 60megs

To play along at home you will need to install the following:

Please feel free to leave any comments, questions, or feedback.

May 03 2006
May 03

One of the great features of Drupal is its ability to run any number of sites from one base installation, a feature generally referred to as multisites . Creating a new site is just a matter of creating a settings.php file and (optionally) a database to go with your new site. That's it. More importantly, there's no need to set up complicated Apache Virtual hosts, which are a wonderful feature of Apache, but can be very tricky and tedious, especially if you're setting up a large number of subsites.

No worries, there is a solution.

Create a new LogFormat

Copy the LogFormat of your choice, prepend the HTTP host field, and give it a name:

LogFormat "%{Host}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" vcombined 

Get the script

Next, download the attached script (split-logfile) and store it somewhere like /usr/bin (don't for get to chmod 755 that baby!)

Now, tell apache to use pipe logfiles to your script rather than writing them directly to disk:

CustomLog "| /usr/bin/split-logfile" vcombined 

Restart Apache

/etc/rc.d/init.d/httpd restart

That's it.

Naturally, you may have to modify split-logfile if you don't store your logfiles in the default location.



May 02 2006
May 02

Google accepts studet applications for the summer of code 2006. Drupal has interesting projects for you to choose from. If you are a student anywhere, interested in php and/or drupal development, want to spend your summer coding and earning some money, apply. You might get accepted. If none of the proposed projects interests you, you can suggest your own. Come on, be brave. You can get a rock-star status in a part of the net.

May 02 2006
May 02

Drupal 4.7 is out. It features a lot of genetic improvements. Features support for a lot of hot features, but more importantly, it started the slimming trend.

I'm delighted that although there are loads of additional functionality, the modules are getting slimmer. Probably due to forms api. I hope this trend will continue.

May 02 2006
May 02

On Saturday night Drummy, Tony, and I went to Super Happy Dev House IX. I was a bit drunk. I bet Neil and Tony that I the "business guy" would beat them the "hackers" at hacking. My goal for the night was to integrate the gmaps module with views to allow users to create maps of any view.

I won handily:

The how-to is posted on this handbook page.

May 01 2006
May 01

Wheee! Drupal 4.7.0, the new stable release of the CMS, has been released. After more than one year of development, we are now finally able to enjoy all the goodies which this new release brings.

For German speaking people we can now proudly claim to have a completed translation of the user interface, thanks to all the contributors! If you don't speak German, you can choose from one of the other 40+ translations for your site.

Read the release announcement for more information, I'm off upgrading a couple of sites now ;)

Apr 28 2006
Apr 28

I finally came about to changing the look of this blog. It is a new css-based design. It might get heavyish on some machines+browsers, but to be honest I can't care less about it.

This design is kind of a proof for the themability of drupal. It took me about 20 minutes to convert this from a plain html with embedded stylesheet to page.tpl.php+css.

If I can do it, any monkey should be able to.

Update: thanks to rkerr & |gatsby| I've fugured out that I have a slight problem in IE - unreadable. The bloody boxes and png transparency problems. Now it should be much better.

Thanks guys

Apr 21 2006
Apr 21

This article explains a practical implementation of a technique outlined in the article "Sharing Drupal tables between databases using MySQL5 Views".


You have multiple (multisite) Drupal sites and you would like to manage the content for all of these sites through a single interface. Depending on the nature of a given piece of content, you may want the content published on one, several or all of your subsites, but you do not want to have to create copies of the same content for each site.


Taxonomy plus MySQL5 views. (NOTE: this solution will not work with versions of MySQL prior to 5.)

Assumming you have your subsites properly set up and running, the first step is to create a special vocabulary which you will use to target content.

Go to [your site's baseurl]/admin/taxonomy/add/vocabulary and create a vocabulary. We'll call it simply "sites".

Next, go back to your taxonomy page (/admin/taxonomy) and select "edit vocabulary" for the "sites" vocabulary.

Add a name for each of the subsites you would like to manage. For our example, we'll have two subsites, "foo" and "bar", and one master site, "master".

Now add at least three pieces of test content. Target one piece of content for each of foo, bar and both.

Next, we're going to create a node view for each of our subsites that we'll use to replace the actual node table.

The SQL is as follows:

CREATE VIEW [subsite, eg. "foo"]_node AS SELECT n.* FROM node n, term_data td, term_node tn, vocabulary v WHERE v.name = '[vocabulary name, eg. "sites"]' AND td.vid = v.vid AND td.name = '[subsite vocab term, eg. "foo"]' AND td.tid = tn.tid AND n.nid = tn.nid ;

Because the terms that serve as our subsite labels may very well exist within other vocabularies, we also need to join on the vocabulary table to ensure our solution works reliabley.

Finally, we need to have our subsites use the views we have created instead of our master nodes table, which only the "master" site will have access to directly.

In your drupal's sites directory, you should have directories that correspond to each of your drupal sites (both master and subsites). Edit the settings.php file for each of your subsites, and use the db_prefix variable to point the site to your view. So sites/foo.example.com/settings.php would contain the following:

$db_prefix = array( 'node' => 'foo_', );

At this point, you'll want to disable creation of content from within each of your subsites. You can do this in the from the admin/access page. If you attempt to create content from within the subsites, you'll likely get a 'duplicate key' error.

I hope that explanation is clear. These articles are written rather hastily. If you questions or suggestions regarding this solution, please leave a comment.

Apr 20 2006
Apr 20

Jeff Robbins of Lullabot posted a podcast interview of me here. I babble on for an hour or so about the Dean Campaign, DeanSpace, and CivicSpace.

Apr 11 2006
Apr 11

Drupal is an open-source Content Management System (CMS), which is particularly suited to customization through use of blocks, themes and modules. Drupal's innovative use of taxonomy and its unique menu system allow for effective management of content as a site grows or evolves.

Driving the ongoing development of Drupal is the desire for a simple and powerful framework which developers can work within to create custom web applications without having to build the pieces that nearly all websites have as a foundation (user authentication, content creation interface, layout managment).

And unlike other similar CMSs, Drupal takes its role as a framework very seriously. Take a look at the database structure of any other CMS that has been around for a while, and you'll almost certainly find a labyrinth of tables with mysterious names and seemingly redundant purposes. Drupal's database design is clean and constantly being re-factored. Tables that have outlived their purpose are removed from the schema and the code. Table design is very generic, allowing different types of content and modules to share the same table space.

Drupal also has an actual API. It too is refactored on a regular basis as the web and user needs change. Drupal 4.7, for example, has a completely redesigned Forms API which now allows developers a much broader reach into the entire Drupal framework, allowing her to tweak parts of Drupal that were previously pretty much set in stone.

From a webmaster's point of view, Drupal may not have the most eye-candy or largest feature set when compared to other CMSs. However, there's virtually nothing that can't be built into Drupal, making it the most flexible CMS out there.

Go with Drupal, and you will have no regrets.

Apr 11 2006
Apr 11

A few weeks ago we held our first ever "Drupal Camp" in San Francisco at Compumentor's office. I blogged about this previously when we were hashing out the idea. Today I posted a pretty lengthy report back about it on Drupal.org:


Apr 05 2006
Apr 05

Yes, conceivably within a few years Ruby on Rails could emerge as a dominant web application development environment. But I am betting strongly against it. Why all the hype then? True innovation, great presentation, lots of screencasts & brilliant marketing. But in the end, RoR is fighting an uphill battle. E.G. LISP has a much greater market share than Ruby (.721% vs .2%).

Programming language market share numbers are taken from this study. It covers the languages in general and is not specific to web application development. If anyone has any better analysis please let me know.

*Update*: There is a great blogpost from a Ruby on Rails devotee here that comes away with much the same conclusion but instead of just numbers he provides a well reasoned argument.

Apr 01 2006
Apr 01

Frustrated with the never-ending betas of the imminent Drupal 4.7, I have decided to switch to a better project, Drup.us.

Mar 28 2006
Mar 28

Today, I woke up and decided that I will give my drupal modules away, in the hope that they will be better maintained. If you’re a Drupal developer who would like to take over the Captcha, TextImage and Similar modules, please contact me. Note, I’m not unmaintaining them, I’m only looking for a person who has more time and energy than me to work out the kinks and make the modules work for every Drupal version and not bloat the features and prefers to make things more efficient. If I do not find such a person, I’ll just keep sporadically maintaining them like I was. Interested? Just send me your drupal.org username, and what module you’d like to take over.

Mar 27 2006
Mar 27

Recently, I've had the pleasure to try out something new - reviewing a book before it is published.

I have been acting as technical editor/reviewer (or whatever that's called in English) for the first German book about Drupal, written by Hagen Graf: "Drupal: Community-Websites entwickeln und verwalten mit dem Open Source-CMS". The book covers the Drupal 4.7-beta series and is a good introduction to Drupal and it's concepts. It's a nice book for people who want to learn more about creating websites with Drupal. More details in this post over at drupal.org.

Reviewing books is a lot of fun - I might do that more often in future ;)

Mar 25 2006
Mar 25

Ok, ok, maybe there actually is something to this Web2.0 business. A lot of the Web2.0 hype stems from the maturation of blogging, the software that helps people blog and RSS. All of these are good and bad things. Good in that there's more information available to more people today than ever before. Bad because there's more information available to more people today than ever before. Even before the term "blog" was coined, people were publishing personal journals, ramblings and general rants on the web. It was as true ten years ago as it is now, most of this content is... well... not very interesting to most people. Maybe it's poorly written blather about why someone hasn't posted poorly written blather recently. Or maybe it's well written content on a very specialized topic that is only relevant to a small number of people.

Good, bad, relevant, meaningless, it's all out there somewhere. The key to finding it is RSS. I used to subscribe to the Los Angeles Times. I'd poke through it every day and read a sentence or two and then tossed it in the recycling bin. The fact is, my interest in polotics, world affairs, sports, gardening, real estate and used cars is pretty limited, and that's all you're going to read about in most newspapers. My interests are elsewhere. Software programming, guns, literature, skiing, and so on. The best way to feed my desire for information is to turn to the web. But turning to the web for information is like visiting Niagra Falls for a sip of water. It's just too much. You need something like Google, Yahoo or now RSS to filter the information for you.

Will Web2.0 ever mean anything? Absolutely. I believe Web2.0 will eventually become something even grandma can understand. Presentation will be fast and flexible (AJAX, DHTML). Content will be tightly filtered with RSS. Folks can easily take advantage of all this stuff now with sites such as Bloglines, Feedster (update: now dead) and Feedburner. And all of this falls under the annoying label of Web2.0. This site is dedicated to Drupal. One of the things I wanted to provide was an aggregate feed of the most relevant Drupal news available. So using Drupal's aggregator module, I began creating the Drupal news page. You'd think that would be a simple task, but it isn't. With so many feeds, and so many feeds of feeds, and so much information available, pulling down just the right content is still very hard, and I still don't have the desired page I want. But the fact that it is even possible is something I'm very excited about. Here's a link to the story I was going to originally write about before my ADHD kicked in: The bottom line on blogging.

Mar 24 2006
Mar 24


You have a "master" database that contains data from multiple Drupal sites and you want to share it among them. Normally, you could use table prefixing to allow each of your sites to point to a single table. But what if you do not want content from one site to "bleed" across to the other sites? Let's say you have a network of Drupal sites sharing a user database. You want to share that user's information across your entire network of sites, but only make the information visible from those sites to which the user has subscribed. Or maybe you want to populate baz.com with users who meet some arbitrary criteria. There are lots of possibilities here, but nobody's paying me to write this, so let's get on with it.


Use MySQL5 Views. For our example, we'll use the users table. Our "master" users table (the table that contains all users for all of our sites) resides in a database called "master". The database of the our example site that will have restricted access to our masters users table is called "banana". Assuming you're starting with a fresh instance of the Drupal schema in your database "banana", do this:

use banana;
drop table users;
FROM master.users
WHERE uid IN (
FROM somedatabase.sometable
WHERE uid = 0
OR label = 'foo'

Drupal will use banana.users just as it would a normal users table. No other modifications are necessary. Now only "foo" users will be included in the users table for your banana website. Note: Drupal has a dependency that is not really documented. Every users table must have an entry that contains uid=0. It's a "stub" entry that Drupal needs to function properly when a user is anonymous. A workaround for this dependency is to include "user 0" in the results set that defines your view. See, wasn't that easy? Please post questions here, and I'll update these instructions as needed.

Mar 22 2006
Mar 22

Consider this:

  • My job is to focused around developing web applications that help communities collaborate yet the majority of the day to day collaborative work I am personally involved in is faciliated by standard mailman mailing lists, not community focused web applications. Mailing lists are functionaly no different than they were more than twenty years ago when they were invented.
  • Without a doubt the most pervasive and powerful organizing tool the Dean campaign grassroots groups used beyond Meetup to self organize was Yahoo groups. Yahoo's business is centered around "user produced content" and community. YahooGroups (formerly eGroups) with 50M registered users is their #1 community tool. Yet the toolset has barely changed in the 6+ years since eGroups was bought and made a part of Yahoo.
  • In my experience as a community organizer (DeanSpace, PeopleFinder) I have found that there are only two indespensable tools: wiki's and mailinglists. With both in place 85%+ of your web app needs are covered and groups are more than capable of self-organizing effectively.

So given all this, why does CivicSpace still not ship with working YahooGroups-like mailinglists and wiki support? Good freaking questions. Thankfully, I believe we are finally getting close to an adequate answer....

My first screecast (37 megs 10 min):

This sandbox runs on Drupal 4.7 beta 5. Modules I am using on this site:

  • Og - to create and manage the groups. Thank you Moshe!
  • og2list - to send out mail to group members
  • og_forum - to sync a forum w/ each group
  • og_mandatory_group (4.7 port included below) - to auto-join site registrants with the main group
  • og_intro (in zip below) - to send notices to the main group when users join and new groups are formed
  • Tabs - to draw the fancy ajax tabbed pages on the og nodes. Thanks nedjo!
  • Node Relativity - to handle 'sub groups'
  • Freelinking - to handle wiki-link -> node edit forms and [[wiki link]] fiters
  • Masquerade - to let me test the site as a non-admin user
  • Mailhandler - to post mail to my site off of og email lists (reads a catchall for the domain)
  • Mail Stuffer (in zip below) - my hacky helper module that associates mail sent in to mailinglists
  • Wikipage (in zip below)- to create wiki node types and manage permissions
  • Bookmark - to let users save pages in their bookmarks block

I would highly recommend waiting until og2list is fully baked and until I have a chance to clean up my code before you use this. But if you must I have included all my new modules, slightly hacked modules (ported og2list to 4.7 and added tags support to mailhandler) and my theme .tpl files. This stuff will all make it into cvs some time next week if all goes well.

Attachment Size theme.tar.gz 14.91 KB modules.tar.gz 90.38 KB
Mar 17 2006
Mar 17

I've poured almost three of my life in to CivicSpace waving my hands and willing it into existance. We have a lot to show for it: 30 major software releases, two thousands CivicSpace powered websites, a vibrant and quickly growing user community, and a network of 25+ vendors occupying a solid slice of the marketplace of advocacy / non-profit web technology services. But what we haven't had so far is a solid user facing product - something I can show my mom...

Ten minutes ago I sent a note to our mailinglists announcing that we will shortly begin alpha testing a hosted CivicSpace service and are looking for testers. Three minutes later four people signed up.

The CivicSpace hosted service is almost here and I couldn't be more excited.

Mar 16 2006
Mar 16

Good thing I had a good backup of my www directory and database!

So I tried upgrading Advanced Web Design to 4.7 yesterday. I had all of the 4.7 verions of all the modules and I was all set. One of those moduels was our friend, tax_access. I unpacked the new files into the modules directory and expected everything to be fine.

Tax_access is supposed to use the Drupal update system for upgrades. Right? Wrong. Didn't work here. No big deal. I'll drop the old tables and create the new ones manually. I only have one term restricted, I just re-do the category permissions. But my problem had nothing to do with the tables.

I don't know what tax_access does when you enable it in the settings, but there was some legacy 4.6 version of the module hanging around that I couldn't get past. For whatever reason, it doesn't start using the new module file, when it replaces the old one. Of course this legacy version was not forms API compliant. I could do nothing to get rid of it. So I reverted to my backups.

Anyone using tax_access: Disable the module BEFORE upgrading! Or else the legacy version will come back to bite you in the butt. Apparently this has happened to others, but I didn't find a lot in the forums or issue tracker about it. There's nothing in the documentation.

You have been forewarned.

Mar 15 2006
Mar 15

Today, the folks over at Performancing.com announced the realease of Performancing Metrics, a free new service for tracking statistics for Blogs. Best of all, it's all in Drupal. OK, I'll come clean, I was involved in this project. My primary role was integrating Performancing's existing website with the Metrics tool. The entire toolset runs behind a single Drupal module that acts as a wrapper for what are essentially standalone PHP scripts.

Disclosure out of the way, I've also been using this tool for some of my own websites for the last month or so. When Google Analytics launched, I was able to get an account before they blocked new subscribers due to load issues. I've been monitoring my sites with Google Analytics for about four months. It seems to be a very powerful tool, but to be honest, I don't understand how to use it. There are just too many views and parameters and summaries. Using it, I feel like I did when I first used Vim or MS Word or Paint Shop Pro, overwhelmed and confused. Hey, I just want to write a letter to Mom, and I'm staring what looks like the cockpit of a 747. Similarly, when I look at website stats, I just want to see how many folks are visiting, where they come from, how long they stay, what they like, whether they bothered to leave comments, etc... I don't need a pivot table detailing gross ROI per visitor vectored over a decreasing granular matrix margin. Eeeek! Just show me the big pic and let me get on with my day.

If you're like me, you'll appreciate this new tool. It's light on eye-candy and heavy on simplicity and quick access to what you want to know. It's also somewhat addictive.

To use it, you'll need to sign up over at Performancing.com. Then all you have to do is paste a bit of javascript into your Blogs pages (via templates or footer configuration).

What distinguishes this tool from others is that it's focused on Blogs. The javascript you use will vary depending on which blogging software you're using. This way the javascript is able to glean information from your site that other trackers simply can't. Author names, Comments, Posts, etc...

We're working on making this embedded javascript tracking more effective and specific to the various blog systems, but even this beta version of Performancing Metrics is worth the effort of signing up.

You'll also find lots of cool articles regarding professional blogging. Even if this isn't how you make your living, there is some excellent information that non-professionals can use. Stuff like how to bring more people to your site and how to "monetize" your website more effectively.

Check it out.

Mar 14 2006
Mar 14

Most website's I run will be easily updated once Drupal 4.7 rolls around. In fact, the average website won't need to be updated anytime soon. But for one website in particular, I am already having nightmares. I need to upgrade for a few reasons:

  • I need the extra functionality. There are new features in Drupal 4.7 that will maker certain tasks remarkably easier. For example, the new block regions. More than 1,500 pages all have the same footer in the content area. The owner wonders why she can't change how it reads on all of the pages every now and again (once a month or so). Isn't that the advantage of a CMS? Now it is.
  • My buddy Jeremy is working on a new Ads module. I have been requesting development on the current banner module, which prompted Jeremy to re-write it as an Ads module. The fundamental difference being that ads will be nodes, thereby increasing functionality and enabling the sort of options I am looking for. I am finding myself in GREAT NEED of said increased functionality - the ability for ads to be searchable, and/or matching option, list all option, etc.
  • I am splitting the content (some 1,900 nodes) into two websites and need to do a lot of cleanup. Not a technical issue, but a real one nonetheless. We are facing some real branding and marketing issues which require us (meaning me) to completely revamp the website as a whole. This includes structure, navigation, taxonomy, etc.
  • I want to use some of the new goodies. There are some needed modules and/or module improvements that I see in the repository. I think they will be very helpful to reach my goals for this website.

The headaches come in when I figure that I have some 27 contributed modules (Amazon Tools, Flexinode, Simplenews, etc.) and would like to use another 12 (E-commerce, Blog Theme, User Points, etc.) at least. That's not including some modules I'd like to discard (FCKeditor) in favor of others (TinyMCE). At least I don't have to worry about Menu on the Fly anymore.

There are two possible approaches.

  1. Take the site down for a day and upgrade the usual way. Fool around with the terms and menus, un-publish nodes, whatever - as I go along.
  2. Redevelop the site on my local machine using UniServer and swap a clean, brand-new 4.7 website for the other in the dark of night.

I will have to consider this some more.

Mar 14 2006
Mar 14

Web2.0 is now, and it's here. If you're not Web2.0, you're out like 2005. If you have to ask, you wouldn't understand.

Well, I have to admit, I need to ask. In fact, I have several questions about all this Web2.0 fanfare.

Why should I upgrade? How much will it cost me? How come nobody has it in stock when I try to buy it?

I've been making my living doing web stuff since 1996, and I never got my copy of Web1.0. I didn't even realize it had been released. Now I just sit and nod in meetings where people talk about "synergistic solutions", or throw in a "user comprehensible value prop" in such a way that you just scratch your head and think it must mean something. "This needs to be Web2.0" is a favorite of mine. Whatever Web2.0 is, obviously it's critical to the success of new projects. (I need to remember to remember that for my next project.)

Who owns Web2.0? For now, I guess the safe assumption is that Google does. That would explain both all the ballyhoo as well as the mystery surrounding this next generation breakthrough. Ask someone at work what Web2.0 is and you'll likely get the curly brows and a loud "Pffft!", in which case you just give them a, "... I guess some of the folks in this meeting haven't gotten the Web2.1 pre-release yet ..." and give them the reverse curly brows and a subtle sigh.

Look around for Web2.0 and you will no doubt find everyone talking about it, but you're not likely to actually find an example of it. I found no screenshots on Google Images. No info on where to order it or how to install it. However, I do think I'll be able to recognize it once I find it. I know it will have an "API". I know it will also be very clean because it requires Ajax. It will probably involve pastels contrasted with ridiculously bright primary colors.

It will also have a very fancy look to it. I imagine the email icon above probably isn't very Web2.0. (though I'm not claiming to be a Web2.0 authority, of course.

And I'm sure all the experts would agree that this RSS icon is definitely Web2.0.. However, my failure to convert the white background to transparent is probably more web 1.1 or so.

If you know as little about Web2.0 as I do, I wouldn't worry about it too much. If there's anything to it, I'm sure we'll all be getting 3000 free hours of it in the mail from AOL real soon.

Mar 14 2006
Mar 14

New versions of Drupal are out for the 4.5.x, the 4.6.x and the 4.7.0-beta branches which fix 4 (in words: four) security issues from four different categories, namely: access control bypassing, cross-site scripting, session fixation, and mail header injection.

Upgrade now!

Warning: If you're using 4.5.x, the patches for DRUPAL-SA-2006-003 will not fix the security issue immediately. You have two options: a) upgrade to 4.6.6 instead of 4.5.8, or b) upgrade to PHP >= 4.3.2.

Mar 10 2006
Mar 10

Rumor is spreading of some sort of new analytics tool from the blogging experts over at Performancing. This tool utilizes Drupal and is designed specifically for bloggers. It's a tool similar to others like Google Analytics and Sitemeter. What makes it different is that it is designed to track blogs specifically. Read more about it at Performancing, Problogger and Code Professor.

Mar 07 2006
Mar 07

Had to delete the xmlrpc.php file that come with Drupal because my host was getting slammed by hack attempts - some successful, some not. The naughty installation was 4.3.3 and I have since upgraded to the 4.6.5 version. (Gee, how did that one slip by?) Should be safe now...

In any event, I have been asked very nicely to not upload these files in the future. Will comply... As a result, Drupal ID logins are now disabled at my website.

However, it took me a while to figure out that this file was also related to the Drupal ID login feature, not just the website directory ping. That's not really clear in the documentation. Here I am making a fool of myself trying to login in to the Drupal Sites directory.


About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web