Just a Theory

By David E. Wheeler

New Bricolage Website Launched!


The launch of the new Bricolage Website went off without a hitch yesterday. The lack of sleep getting it all just so was worth it, in the end. And I’m very very pleased with the new site. It looks good, it’s easy to navigate, it has really nice semantic XHTML 1.1 that degrades nicely in older browsers (check it out in Netscape Navigator 4.x or in lynx!

The new content on the site is good, too. There’s a lot more information for people who have heard of Bricolage and are hitting the site for the first time to try to learn something about it. We now explain what it is and what it’s for on the home page, and have a nice set of pages describing the benefits of Bricolage, listing the sites known to be powered by Bricolage, and providing screenshots to give folks a feel for how nice the Bricolage UI is. Special thanks to Marshall Roch for providing the new design and the home page content.

This is the first Bricolage Website to be managed in Bricolage itself. I decided to create the new site for a number of reasons, but two of the more important ones were: to have a nice example for conference and client presentations; and to be able to release the Bricolage Mason templates that generate the site. These templates have now been released and are available for download on the Bricolage Website. I’ve worked hard to try to make them really good examples of best practices in using Bricolage so that people can download them, study them, and be able to start writing smart templates for their on Bricolage implementations. So enjoy!

Looking for the comments? Try the old layout.

More about…

New Bricolage Website Beta

After a couple of weeks of hard work, with lots of assistance from Marshall Roch, I’m just about ready to launch the new Bricolage Website. Thanks to hardware and hosting provided by NetStumbler.com, we now have a fully functioning Bricolage installation and Web server for the bricolage.cc domain.

The new site will launch just before my OSCON talk on Wednesday. In addition to having the great Web standards-compliant layout (thanks Marshall!) and a decent amount of extra content, the templates for the site will be made available for download, too. The templates will make a great “best practices” example, both for bricoleurs and Bricolage evaluators. I think they nicely show off the flexibility of the Bricolage CMS platform.

So do you want to see the beta? I’m making it available only to my fellow Bricolage developers and to you, the readers of my blog. Just point your browser at www.bricolage.cc, and then just s/www/beta/ to see the new site. I’m not providing a direct link to it here because it’s going to go away on Wednesday and I don’t want to get any 404s. Feel free to send me feedback on the new site–anything about it: design, layout, XHTML, CSS, etc.

Looking for the comments? Try the old layout.

More about…

See “OutFoxed”


I’m going to have to order the “Outfoxed” DVD and give it a look. It got a great writeup in the New York Times.

(Via Lessig Blog)

Looking for the comments? Try the old layout.

MoveOn.org Voter Registration Party

We just hosted our first MoveOn.org voter registration party. (You are registered to vote, aren’t you? If not, register register here.) Julie did all the hard work of organizing the party, preparing the munchies, going through MoveOn’s rather overwhelming and confusing instructions to make things simple for the rest of us, and getting the lists of unregistered voters to call. She’s great at the organizational stuff, and that the party was a success is due to her hard work.

We had 10 participants, and each of us called 24-36 people, mainly women in Florida who didn’t vote in the last presidential election. We registered three voters. Yes, only three! Most of the phone numbers we called were disconnected or wrong numbers. We left messages on several answering machines. And when we did get through to people, we often got replies such as:


“I’m not interested.”

“I don’t believe that my vote counts for anything.”

“I don’t believe that women should be allowed to vote.” [Yes, a woman said that.]

“Please don’t call again.”

“I’m registered. I vote. I always vote!”

Rather incredible, really. So how was it a success, you ask? Well, MoveOn ran out of numbers for us to call. After we went through all the numbers we had, they had no more to offer. Over 15,000 people signed up to participate in today’s event. Probably more actually participated, since we, at least, had 2-3 people participate who hadn’t signed up. And we did manage to register a few voters, and leave messages on answering machines telling folks to visit the MoveOn PAC Web site or their local department of motor vehicles to register. We’ll know for sure what happened when MoveOn reports the results in the next few days, but if we managed to register only 5,000 voters, it could make a difference in the outcome in November. And that’s what we’re really hoping to achieve.

Looking for the comments? Try the old layout.

Bricolage 1.8.1 Released

The Bricolage development team is pleased to announce the release of Bricolage 1.8.1. This maintenance release address a number of issues in Bricolage 1.8.0. Here are the highlights:


  • More complete Traditional Chinese and Simplified Chinese localizations. Also, the Mandarin localization now simply inherits from the Traditional Chinese localization.
  • make clone now copies the lib directory and all of the bin scripts from the target to the clone, rather than from the sources. This allows any changes that have been made to scripts and classes to be properly cloned.
  • When installing Bricolage, it will now allow you to proceed if the database already exists by asking if you want to create the Bricolage tables in the existing database. Suggested by Mark Fournier and Marshall Roch.
  • The installer is now a bit smarter in how it handles loading the log_config (or config_log, as the case may be) module.
  • Added language-specific style sheets. This is especially useful for right-to-left languages or for languages that require special fonts.
  • The “New Alias” search interface now displays thumbnails when searching for media documents to alias and the USE_THUMBNAILS bricolage.conf directive is enabled.
  • Aliases can now be made to documents within the same site.
  • The SOAP interface for importing and exporting elements now properly has “key_name” XML elements instead of “name” XML elements. The changes are backwards compatible with XML exported from Bricolage 1.8.0 servers, however.
  • Added move() method to the virtual FTP interface. This means that to deploy a template, rather than having to rename it locally to append “.deploy” one can simply move in FTP to its new name with “.deploy” on appended to the new name.
  • Document expirations are now somewhat more intelligent. Rather than just scheduling an expiration job only if there is an expiration date the first time a document is published, Bricolage will now always schedule an expiration job for a document provided that one does not already exist (scheduled or completed) for the same time and for one of the file resources for the document. This should allow people to more easily and arbitrarily expire content whenever necessary.
  • Burner notes now persist for all sub burns (triggered by publish_another() and preview_another() in a single burn.
  • Added ability to create and manage groups of objects for several different types of objects. Also added the ability manage group membership within the administrative profiles for those objects. This change makes it possible to give users permission to administer subsets of objects. The new groupable objects are:
    • Preferences
    • Groups
    • Alert Types
    • Element Types
    • Keywords
    • Contributors
  • Alert rules are now evaluated within a safe compartment (using Safe.pm) to prevent security exploits.
  • The Bulk Publish admin tool is no longer limited to use only by members of the Global Admins group. Now anyone can use it. All one needs is READ permission to the categories of stories, and PUBLISH permission to the stories and media documents to be published.

Bug Fixes

  • Eliminated “Bareword “ENABLE_HTMLAREA” not allowed while “strict subs” in use” warning that prevented startup for some installations.
  • Changes made to user or contributor contacts without changing any other part of the user or contributor object are now properly saved.
  • The upgrade to 1.8.0 now correctly updates story URIs that use the URI Suffix of an output channel instead of using the URI Prefix twice.
  • Aliases of Image, Audio, or Video media documents no longer remain stuck on desks.
  • Related media and story subelements of media documents now work properly.
  • Calls to preview_another() in Bric::Util::Burner will now use any templates in the current user’s sandbox and properly burn them to the preview root rather than to the staging root used for publishing.
  • Contributor fields for roles other than the default role now properly store and retain their values.
  • The virtual FTP server now properly checks out templates when a template is uploaded and is already in workflow.
  • Uploading a non-existent template via the virtual FTP server now correctly creates a new template. The type of template depends on the name of the template being uploaded, and for element templates, on whether there is an element with the appropriate key name. The user must have CREATE permission to All Templates or to the start desk in the first template workflow in the relevant site.
  • Reverting a document or template to the current version number now properly reverts all changes to the time the user checked out the document or template. Reversion is also a bit more efficient in how it looks up the previous version in the database.
  • The SOAP server now rolls back any changes whenever an error is thrown. This prevents problems when a few objects are created or updated before an exception is thrown. Now any error will cause the entire SOAP request to fail. Thanks to Neal Sofge for the spot!

For a complete list of the changes, see the release notes and changes list. For the complete history of ongoing changes in Bricolage, see Bric::Changes.

Download Bricolage 1.8.1 now from the SourceForge download page or from the Kineticode download page

About Bricolage

Bricolage is a full-featured, enterprise-class content management and publishing system. It offers a browser-based interface for ease-of use, a full-fledged templating system with complete HTML::Mason, HTML::Template, and Template Toolkit support for flexibility, and many other features. It operates in an Apache/mod_perl environment and uses the PostgreSQL RDBMS for its repository. A comprehensive, actively-developed open source CMS, Bricolage was hailed as “Most Impressive” in 2002 by eWeek.


–The Bricolage Team

Looking for the comments? Try the old layout.

More about…

iPod Threatens UK Military Security

20 GB iPod

Following up on my screed against the idea of the “iPod security threat”, James Duncan Davidson sent me a link to this story about how the UK military has decided that the iPod is a security threat.

“With USB devices, if you plug it straight into the computer you can bypass passwords and get right on the system,” RAF Wing Commander Peter D’Ardenne told Reuters.

“That’s why we had to plug that gap,” he said, adding that the policy was put into effect when the MoD switched to the USB-friendly Microsoft XP operating system over the past year.

Huh. Do you mean to tell me that if you plug into the USB port of a PC that no one is logged in to, you can get access to the contents of the PC without logging in? You know, that sounds more like a Windows security flaw than an iPod problem. I mean, it’s reasonable for the military to ban external media in order to prevent their personnel and contractors from copying sensitive data onto personal devices for unknown purposes. But this Windows security hole seems, well, huge.

And the truth is that these articles that single out the iPod as a security threat are being disingenuous, in that it’s much easier and much cheaper to use a USB Flash Drive. Furthermore, this banning of storage devices really only keeps honest people honest; those who really want to copy sensitive information to take home will figure out a way to do it if they’re motivated enough.

So yeah, highly sensitive security establishments should ban personal external storage devices to keep honest people honest, but really, they should also fix the real security problem with their operating system of choice.

Looking for the comments? Try the old layout.

Gartner: iPod is a Security Threat

20 GB iPod

Well, this is entertaining. It seems that the Gartner Group has decided that iPods are a significant security threat. I think it’s great that a company like that makes its money by telling people that, yes, you can copy files between your PC and your iPod, and that poses a serious security threat. Please.

The problem, of course, is not the iPod. Or digital cameras. Or floppies. Or CD burners. No, the problem is people. I prefer to build a company that trusts its employees. Novel concept, I know. So here’s the mantra: iPods aren’t security threats; employees are security threats.

Now, I had to think carefully about posting this, because it reminded me, suddenly, of the old gun nut statement that guns don’t kill people, people kill people. The reason why I’m willing to use it for the iPod and not guns, however, has to do with design. Guns are designed to kill. It kind of makes the statement moot. I mean, what would you expect people to do with them? iPods, however, are not designed to breach security. They’re designed to listen to music, to store files, to copy your calendar, etc. Now, whether an individual person decides to use the iPod in breach of a company’s security protocols is a matter independent of the iPod’s design and intended use.

So the mantra holds: iPods aren’t security threats; employees are security threats. But guns, yeah, they’re pretty much designed for killing.

Looking for the comments? Try the old layout.

Apache::TestMB Released!

As I mentioned last week, I’ve been working on a subclass of Module::Build that supports testing with Apache::Test. Today, Geoff announced the release of Apache::Test 1.12. This release includes the new Module::Build subclass, Apache::TestMB. Now anyone using Apache::Test to test their module can convert the build system to Module::Build.

To set an example, I’ve just released MasonX::Interp::WithCallbacks using the new build module. The conversion was simple; in fact, I think that Apache::TestMBis easier to use than Apache::TestMM (which integrates Apache::Test with ExtUtils::MakeMaker). My Makefile.PL had looked like this:

#!perl -w

use strict;
use ExtUtils::MakeMaker;
use File::Spec::Functions qw(catfile catdir);
use constant HAS_APACHE_TEST => eval {require Apache::Test};

# Set up the test suite.
    require Apache::TestMM;
    require Apache::TestRunPerl;
    Apache::TestMM->import(qw(test clean));
} else {
    print "Skipping Apache test setup.\n";

my $clean = join ' ', map { catfile('t', $_) }
  qw(mason TEST logs);

    NAME        => 'MasonX::Interp::WithCallbacks',
    VERSION_FROM    => 'lib/MasonX/Interp/WithCallbacks.pm',
    PREREQ_PM       => { 'HTML::Mason'             => '1.23',
                                'Test::Simple'            => '0.17',
                                'Class::Container'        => '0.09',
                                'Params::CallbackRequest' => '1.11',
    clean               => { FILES => $clean },
    ($] >= 5.005 ?    ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM    => 'lib/MasonX/Interp/WithCallbacks.pm',
        AUTHOR           => 'David Wheeler <david@kineticode.com>') : ()),

The new Build.PL simplifies things quite a bit. It looks like this:

use Module::Build;

my $build_pkg = eval { require Apache::TestMB }
  ? 'Apache::TestMB' : 'Module::Build';

    module_name        => 'MasonX::Interp::WithCallbacks',
    license            => 'perl',
    requires           => { 'HTML::Mason'             => '1.23',
                                'Test::Simple'            => '0.17',
                                'Class::Container'        => '0.09',
                                'Params::CallbackRequest' => '1.11'
    build_requires     => { Test::Simple => '0.17' },
    create_makefile_pl => 'passthrough',
    add_to_cleanup     => ['t/mason'],

Much nicer, eh?

Looking for the comments? Try the old layout.

A Quick Trip to Alamosa

Milagro’s Coffeehouse

Last week, I went on a brief business trip for Kineticode to Alamosa, Colorado. The client was Adams State College, which is planning to use Bricolage to manage all of its content. Alamosa is a sleepy little town of 8,000 people 22 miles north of the border with New Mexico, situated in the largest valley in the world, I’m told. You can get any kind of food you want there, as long as it’s Mexican food, and the high altitude (ca. 2300 m) makes the tequila work wonders on one’s equilibrium.

Mostly I just worked with our clients, but I did manage to take a couple of photos, but I did manage to get a couple of photographs with my Nokia 6600. The “cool” coffeehouse in Alamosa is Milagro’s Coffeehouse, but to judge by their sign, I wasn’t sure I wanted what they were selling.

The flight home

Alamosa has a very small airport. When I flew in on the little prop plane from Great Lakes Airlines, I was one of two passengers. On the way out (I flew through Denver), there were five of us. I thought the engine looked cool out my window, so I turned on my phone (bad David!) and snapped another shot.

Looks like I might be returning to Alamosa soon to do some training. Maybe I’ll be able to get some more pictures; the sunsets are quite lovely there.

Looking for the comments? Try the old layout.

Module::Build + Apache::Test is Nearly Here

Over the last couple of days, I whipped up a new class to be added to the Apache HTTP Test Project. The new class, Apache::TestMB, is actually a subclass of Module::Build, and finally provides support for using Apache::Test with Module::Build. You use it just like Module::Build; however, since a lot of modules choose to install themselves even if Apache isn’t installed (because they can be used both inside and outside of mod_perl, e.g., HTML::Mason), I’m suggesting that Build.PL files look like this:

use Module::Build;

my $build_pkg = eval { require Apache::TestMB }
  ? "Apache::TestMB" : "Module::Build";

my $build = $build_pkg->new(
  module_name => "My::Module",

Pretty simple, huh? To judge by the discussion, it will soon be committed to the Apache::Test repository and released to CPAN. My MasonX::Interp::WithCallbacks module will debut with a new Apache::TestMB-powered Build.PL soon afterward.

Looking for the comments? Try the old layout.

How Do I Know Whether NTPD is Working?

Well, after figuring out how to configure NTPD, it appears to be working well: there are two processes running, and there’s a drift file. However, the drift file just has “0.000” in it, and ntpq doesn’t seem to know much:

% ntpq -p timed out, nothing received
***Request timed out

So, how do I know if it’s working? Is it working? Shouldn’t ntpq -p be more informative?

Looking for the comments? Try the old layout.

More about…

Fun with Module::Build Argument Processing

I’ve spend the better part of the last two days working on a custom subclass of Module::Build to build Bricolage 2.0. It’s going to be a lot nicer than the nasty custom Makefile that Bricolage 1.x uses. The reason I’m creating a custom subclass of Module::Build is to be able to do a lot of the extra stuff that building Bricolage requires. Such as:

  • Copying configuration files from conf/ into blib
  • Copying configuration files from conf/ into t for testing
  • Copying configuration files from comp/ into blib
  • Modifying Bricolage::Util::Config to contain a hard-coded reference to the location of bricolage.conf once Bricolage has been installed
  • Modifying the contents of bricolage.conf to reflect build options (forthcoming)
  • Modifying the contents of httpd.conf to reflect build options (forthcoming)

I’m sure there will be more as Bricolage develops (such as building the database!), but this is enough for now. I’ve also been hacking on Module::Build itself to add features I want. For example, I want users to be able to pass options to Build.PL when they call it, so that it can do silent installs. As it is, you can pass options now, but Module::Build’s option processing lacks flexibility. For example, you can pass options like this:

perl Build.PL opt1=val1 opt2=val2

And Module::Build will store the options in a hash like this:

{ "opt1" => "val1",
  "opt2" => "val2" }

It understands options that use --, too; This invocation

perl Build.PL --opt1 val1 --opt2 val2

produces the same hash. But be careful how you specify arguments! For example, Modul::Build doesn’t understand unary options or options that use both -- and =>! To whit, this invocation

perl Build.PL --loud --opt1=val1 --opt2=val2 --foobar

Yields a hash like this:

{ "loud" => "--opt1=val1",
  "opt2=val2" => "--foobar" }

Certainly not what I would expect! So to get great flexibility, I sent a patch to the Module::Build mail list adding a new parameter to new(): get_options. This is an array reference of options that will be passed to Getopt::Long::GetOptions() before Module::Build parses arguments. It stores the results in the same hash as Module::Build normally does, and options not specified in get_options will be processed by Module::Build just as before. But it gives a whole lot more control over what gets grabbed. For example, if I were to try to get that last example to do what I want, all I’d need to do is pass in the appropriate Getopt::Long specs:

my $build = Module::Build->new(
    module_name => "Spangly",
    get_options => [ "loud+", "opt1=s", "opt2=s", "foobar" ],

Now, the hash yielded is:

{ "loud"   => "1",
  "opt1"   => "val1",
  "opt2"   => "val2",
  "foobar" => "1" }

Isn’t that nicer? And because the full suite of Getopt::Long specification is supported, you can get even fancier:

my $loud = 0;
my $build = Module::Build->new(
    module_name => "Spangly",
    get_options => [ "loud+" => \$loud, "foobar!" ],

Now this invocation:

perl Build.PL --loud --loud --nofoobar

…sets the $loudscalar to 2, while the args hash is simply { "foobar" => "0" }. Cool, eh?

Now I’ve just been discussing the patch with Dave Rolsky on the mail list, and he argues that, while this is a good idea in principal, he’d rather see a data-structure based argument list rather than Getopt::Long’s magical strings. Perhaps Module::Build will end up “Borging” some of the ideas from Getopt::Simple. But either way, I think that better argument processing is on the way for Module::Build.

Looking for the comments? Try the old layout.

More about…

david.wheeler.net Content Migration

I’ve completed the migration of all of the content from my old site, david.wheeler.net. All requests to that domain will get a permanent redirect to this site. Where possible, I tried to make the old URLs redirect to the new URLs. So if you try to connect to david.wheeler.net/osx.html, you should be automatically redirected to www.justatheory.com/computers/os/macosx/my_adventures.html. The same goes for the following documents:

If you happen to notice that I missed anything, comment on this blog entry to let me know.

Looking for the comments? Try the old layout.

NTPD Configuration on FreeBSD and Red Hat Linux

Well, I got no responses to my request for assistance setting up NTPD on FreeBSD, but today I must’ve just been Googling better, because I found the resources I needed.

The most important site I found was the NTP configuration page from Computer Facilities Management at the University of Washington. It was valuable because it provided some simple ntpd.conf file samples that set up ntpd to run only as a client. So no I’m confident that no one will try to connect to my servers and cause any mischief. The CFM NTP page also helpfully pointed out that I could easily enable ntpd on my Red Hat box by typing chkconfig ntpd on.

Another interesting site I found is www.pool.ntp.org. The cool thing about using pool.ntp.org as the time server to synchronize my servers to is that it distributes the load to lots of time servers. So I set up my ntpd.conf files to point first to pool.ntp.org, and then to two geographically close servers.

And finally, this DynDNS page gave me the instruction I needed to get ntpd running on FreeBSD. All I had to do was add xntpd_enable="YES" to /etc/rc.conf. I restarted my box, and now I’m in business!

Looking for the comments? Try the old layout.

More about…

Bricolage 2.0 UML Diagram

I’ve just finished updating the UML diagram for the design of Bricolage 2.0. It’s not completely comprehensive, mainly because the lines would start criss-crossing all over the place and no one would never be able to make any sense of it, including me! Notably, I’ve left out the links to Bricolage::Biz::Site, Bricolage::Biz::Class, Bricolage::Party::Person::User, and Bricolage::Party::Person::Contributor. But it’s pretty clear how they hook up if you study the classes, since they contain the appropriate *_guid attributes. And that’s all those of us who will be writing Bricolage will need.

I’m happy to get this largely done. The technical specification is also largely complete. I’m going to fill in a bit on Bricolage::Client::CLI right now, but otherwise, it will probably be stable for a while. It will change of course, because it’s not completely comprehensive, and there will be things that I haven’t thought about as I’m starting to code. But that’s probably a ways off, as there is quite a lot to get going with right now.

I’m not sure if I’ll update the functional specification anytime soon. It’s really out of date, but would take up quite a lot of time to rewrite, and for what benefit I’m not really sure at this point. The technical spec contains most of the information I need. Perhaps it will be time to update the functional spec once the API is nearing completeness and I start really working on the UI.

In the meantime, it’s time to get back to hacking!

Looking for the comments? Try the old layout.

How do I Configure NTPD?

So I need simple instructions to get NTPD running on FreeBSD. It should function solely as a client, and not accept connections from other servers. I could also use the corresponding instructions for Linux (and don’t say “RPM”!). I’ve found an awful lot of information online about NTPD, but the simple instructions for setting up a secure NTPD to start when the system starts up are sorely lacking. Part of the problem with regards to BSD may be my not yet fully understanding how FreeBSD startup stuff is supposed to work, but I also can’t find simple instructions for how to configure ntptd to operate only as a client.

Links and instructions gladly accepted.

Looking for the comments? Try the old layout.

More about…