Files Aren't Visible From All Domains Of A Site

I had a fun afternoon a few months back when all the imagecache images broke on a site I'd just taken live. I've just figured it out, so I'm telling you about it.

This was the situation:

  • subsite.client.com was where I was developing the site, one of a family of multisites.
  • subsite.com was a parked domain that went to just this site. It was this I'd just pointed to the IP of the box and that wasn't showing any images.

On the development domain, all worked fine. On the subsite domain, nothing.

The problem is that if you go to admin/settings/file-system you get a different thing depending on the domain! Each time, you get 'sites/CURRENT_DOMAIN/files', and the reason is this function:

function file_directory_path() {
  return variable_get('file_directory_path', conf_path() .'/files');
}

So if the files directory has not been explicitly set and you're just relying on defaults, you're getting the wrong one.

I don't follow the internal workings of the file system or imagecache (or even symlinks which I consider dark magic on the commandline) to know if this breaking of imagecache is a bug or not.

But at least this is a ten-second fix on future sites. You'll find me here reading this post when I next have to set one up.

Multisite On localhost Without Virtual Hosts

I've been putting off setting up multisite on my localhost for ages, mostly because in the past I've found getting Apache virtual hosts to work can be a bit tricky: not impossible, but the sort of thing where I could easily lose an hour on a minor thing I've forgotten to do. And after all, with a shiny new iMac and a hard drive whose proportions I can't even remember, why not just 'drush dl' all over again?

But I'm actually working on a multisite project at the moment, and suddenly getting this to work becomes more interesting than having another SVN copy of my code kicking around.

Given multisite can respond to subfolders, I was wondering if this could work when Drupal itself is in a subfolder, like this:

- webroot
-- drupal-1
-- drupal-2
-- drupal-multisite

Turns out it can. Suppose you want a new subsite called 'drupal-subsite'. Here's what to do in your webroot:

ln -s drupal-multisite drupal-subsite
cd drupal-multisite
mkdir sites/localhost.drupal-subsite
cp sites/default/default.settings.php sites/localhost.drupal-subsite/settings.php

Your lolcathost(*) sees just another subfolder that's a site; the symbolic link sends you to the existing Drupal folder; and finally, the multisite system sees that you're browsing 'localhost/drupal-subsite' and selects the localhost.drupal-subsite folder as the one holding your site.

You can also have your subsite explicitly sit below the main site like this:

- webroot
-- drupal-1
-- drupal-2
-- drupal-multisite
--- drupal-subsite

In which case your sites folder is localhost.drupal-multisite.drupal-subsite and the symlink should be inside the multisite folder:

cd drupal-multisite
ln -s . drupal-subsite
mkdir sites/localhost.drupal-multisite.drupal-subsite
cp sites/default/default.settings.php sites/localhost.drupal-multisite.drupal-subsite/settings.php

So when I next get a moment I'll consolidate the various test sites I have, and when I have more than one patch on the go that I want to keep segregated, I can just add a multisite, get a fresh CVS copy of the code, and get going.

I've added details to the documentation too.

(*) yes, I keep typing it like that.

Counting Hooks

This (fairly long) one-liner counts the number of implementations of each hook in your Drupal installation:

ack "Implements? hook_" | perl -e 'while (<>) { m[(hook_\w+)] and $hooks{$1}++; } foreach (keys %hooks) { print "$_ - $hooks{$_}\n"; }'

To count only install file hooks, which was what I was doing, give ack the option "-G '.install'" thus:

ack "Implements? hook_" -G '.install' | perl -e 'while (<>) { m[(hook_\w+)] and $hooks{$1}++; } foreach (keys %hooks) { print "$_ - $hooks{$_}\n"; }'

You can probably adapt this for grep. Ack is far better though (proper regular expressions and sensible assumptions for starters).

Unfortunately, now I've taken ten minutes to do this, I've completely forgotten what I needed to count hooks for. So I'm posting this so by the time I remember I can come back to it!

Edit: Oh yes. I was generating a list of hooks implemented in .install files (just a list, the count is bonus) to check I'd covered everything in my patch for hook locations in the documentation.

Six Reasons To Get A Handbook Page For Your Module

Checkout view being currently disabled in ViewVC is a very good opportunity to remind everyone that linking to your README.txt file in CVS does not count as documentation on your project page!

Here are some things I, or anyone else, can do with a proper documentation page in what used to be called the handbooks section of drupal.org:

  • Correct it.
  • Expand on it.
  • Clarify things for newbies.
  • Add a section listing modules that works with yours that users might be interested to know about, thus helping a tiny tiny bit to make sense of the Big Lego Box.
  • Share some of the things I've done to theme your module.
  • Add to a section on troubleshooting, and hopefully keep some of the more recurring issues out of your queue (or at least give you somewhere to point to in slightly self-righteous manner ;)

In short, with a little bit of seeding (some basic explanations of the concepts of your module and some instructions), you open it up to a whole community of potential writers and editors. Which is a concept we should all be familiar with!

If you say that keeping a documentation book page in sync with your CVS readme file is too much of a hassle (and who said it should be in sync anyway?) then it's because you've not thought about the benefits.

Nodes As NIDs

Is it just me who finds this poor style and potentially confusing:

<?php
function my_function($nodes) {
  foreach (
$nodes as $nid) {
   
// do stuff
 
}
}
?>

To me, a variable names $nodes will be an array of nodes -- that is, node objects. If it's an array of nids, I would call it $nids to avoid confusion about what we have there.

I'm curious if other people agree (in other words, is it worth my time writing a patch for core or will it just lead to bikeshedding?)

In general, though, I think it's a good idea for variables to be named in such a way that describes what they hold; also for the same data to have the same variable name as it travels through functions. In other words, avoid this:

<?php
function foo() {
 
bar($ponies);
}

function
bar($caterpillars) {

}
?>

Unless there's a good reason, say if bar() is generic and can accept any animal. In which case, call its parameter $animals, obviously.

Pages

Subscribe to Joachim's Drupal blog