Websites that write websites

| drupal

“So nat’ralists observe, a flea
Hath smaller fleas that on him prey,
And these have smaller fleas that bite ’em,
And so proceed ad infinitum.”

– Jonathan Swift

One of the things we were daydreaming of having for our Drupal-based project was a meta-configuration system we could use to set up a custom microsite platform, which would then host hundreds of sites. The client was interested in being able to launch thousands of such platforms (hosting hundreds of microsites each). We’ve built four so far, forking the source tree and making all of our customizations in files included in the installation profile or in a few custom modules.

As the cats woke me up bright and early today and I had no defects on my list, I decided to see if I could build that a-la-carte configuration system we had been thinking of: a system that would allow us to choose a set of features and then generate the skeleton of a new project which developers and themers could then flesh out.

I started by refactoring the installation profile I used for a recent site, pulling out all the site-specific information and placing it in a separate file. For ease of use, I put the variables in a settings.inc, which I included in my settings.php together with some clever code to load common variables and domain-specific variables. I refactored the rest of the code into common.inc. When the dust settled, my settings.php was down to two lines: one line to pull in the project-specific includes, and one line to pull in the common set-up code. This was one of the files I was going to write to the disk, so I wanted to minimize the risk of errors by making the file as clean as possible.

Once I sorted out the code, it was time to dynamically generate the settings.inc. After studying aegir‘s provisioning system, I created a simple installation profile that loaded the aegir system and a custom module. I created a form that asked for all the relevant information. Then I wrote the code to generate sites/all/projects/<project>.inc, create the domain directories, and create the appropriate settings.php for each domain.

After I got my New Project Wizard to work, I wrote some code to list the project include files available, and then I tested loading and dumping them to the screen. When I successfully loaded the settings, I revised my project wizard to allow the selection of a previously-created project as a template. After that, I created an edit form that read in the generated project include file and saved the changes back to the file.

It’s a pretty nifty system. I like being able to set all the details I usually forget, like Google Maps API keys and database URLs. I’m looking forward to pushing it even further by being able to select groups of features, if the project managers are interested in it. With a bit more polishing, it could probably wow the client.

Apologies for the lack of code; IBM’s still a little iffy about this kind of stuff. =) Hope you can figure things out with these hints!

You can comment with Disqus or you can e-mail me at sacha@sachachua.com.