Cleaning up the Upcoming Events block in Drupal

We use the Events module to manage workshops here in the Teaching & Learning Centre, and use the “Upcoming Events” block to display the next few workshops on our website. Works great, but the default text leaves a bit to be desired. By default, it shows the event title, and “(2 days)” – which indicates that the event begins in 2 days.

But, it could also mean that the event lasts for 2 days.

So, I just added a trivial change to the event.module file, adding the following line of code at line 1847 (on my copy of the file, which was checked out on June 4, 2007):

$timeleft = 'starts in ' . $timeleft;

That changes the text indicator in the “Upcoming Events” block to read:

(starts in 2 days)

Which is much clearer in meaning. Easy peasy. I just have to remember to edit the module after updating, if this doesn’t make it in…

CRUD in Drupal

No. Not crud. CRUD. Create, Read, Update, Delete. The basic operations a web app needs to do on database records.

I’ve been working on the Provisionator module, which helps with institutional-scale deployments of Drupal sites on a shared hosting server. The module began life as a separate PHP application, and evolved into a Drupal module wrapping those functions. It essentially managed a table within a Drupal site’s database, adding rows for each website deployed.

I was just working on adding the rest of the CRUD support (it already handled Create and Read OK, but not Update (edit) nor Delete). I was looking for The Drupal Way when it hit me. I don’t know why I didn’t see it before.

I don’t need to manage a table, nor do I need to manually implement CRUD operations.

All I need to do is define a custom content/node type, and let Drupal take care of the basic CRUD operations. The Provisionator module will then simply implement relevant bits of the node API and have it get called when nodes of the appropriate type are inserted, edited, or deleted. I can add whatever “fields” I want as properties of the custom node type, so it should be easier to extend than the current hard-coded table.

I’m going to attempt converting to the Drupal node + hooks + node API pattern ASAP. I think it’s going to be relatively straightforward, and offers some pretty cool benefits. Instead of having an essentially static list of sites in a custom database table, I’ll be able to add sites (as nodes) to various taxonomies, enable comments on the site node, and easily implement various permissions (user can create sites, user can list sites, user can edit all sites, user can edit own sites, user can delete all sites, user can delete own sites, etc…)

No. Not crud. CRUD. Create, Read, Update, Delete. The basic operations a web app needs to do on database records.

I’ve been working on the Provisionator module, which helps with institutional-scale deployments of Drupal sites on a shared hosting server. The module began life as a separate PHP application, and evolved into a Drupal module wrapping those functions. It essentially managed a table within a Drupal site’s database, adding rows for each website deployed.

I was just working on adding the rest of the CRUD support (it already handled Create and Read OK, but not Update (edit) nor Delete). I was looking for The Drupal Way when it hit me. I don’t know why I didn’t see it before.

I don’t need to manage a table, nor do I need to manually implement CRUD operations.

All I need to do is define a custom content/node type, and let Drupal take care of the basic CRUD operations. The Provisionator module will then simply implement relevant bits of the node API and have it get called when nodes of the appropriate type are inserted, edited, or deleted. I can add whatever “fields” I want as properties of the custom node type, so it should be easier to extend than the current hard-coded table.

I’m going to attempt converting to the Drupal node + hooks + node API pattern ASAP. I think it’s going to be relatively straightforward, and offers some pretty cool benefits. Instead of having an essentially static list of sites in a custom database table, I’ll be able to add sites (as nodes) to various taxonomies, enable comments on the site node, and easily implement various permissions (user can create sites, user can list sites, user can edit all sites, user can edit own sites, user can delete all sites, user can delete own sites, etc…)

Bad Behaviour 2.0.7 for Drupal

I had been running an out of date version of Bad Behavior on my blog because the Drupal module requires BB 1.2.4 – but I think the evil spambots were getting around that old version.

So, I just took a stab at updating my copy of bad-behavior.module to work with the latest and greatest Bad Behaviour 2.0.7. I’m not sure if I’ve missed anything, but if seems as though it’s suddenly become successful at blocking the annoying Apkakkallli spambot that has been attempting to vandalize my blog for the last few days. The server seems much more responsive, at least. Maybe it’s successfully banning evildoers?

Or, it could be just banning everyone but me? Can anyone see this? Did I bork the site and/or Bad Behavior? Stupid spammers are such a frakking waste…

I had been running an out of date version of Bad Behavior on my blog because the Drupal module requires BB 1.2.4 – but I think the evil spambots were getting around that old version.

So, I just took a stab at updating my copy of bad-behavior.module to work with the latest and greatest Bad Behaviour 2.0.7. I’m not sure if I’ve missed anything, but if seems as though it’s suddenly become successful at blocking the annoying Apkakkallli spambot that has been attempting to vandalize my blog for the last few days. The server seems much more responsive, at least. Maybe it’s successfully banning evildoers?

Or, it could be just banning everyone but me? Can anyone see this? Did I bork the site and/or Bad Behavior? Stupid spammers are such a frakking waste…

Provisionator on Drupal CVS

I've just moved the Provisionator module onto Drupal.org's CVS server. The current version of the module is far from complete, but it does function. Specifically, it does:

  • create database for new site
  • populate database with selected mysqldump template file
  • copy template site directory (with settings.php, files, modules, themes)
  • modify settings.php as needed
  • create symlink to expose Drupal via Apache for the new site (as a subdirectory of a server, currently)
  • add a new record to the database, describing the site
  • list all records in the Provisionator database table

It's got a lot of room for improvement, and more than likely needs some tightening down for security and Doing It The Right Way, but it works. It also currently assumes MySQL, and a very specific shared hosting pattern where Drupal isn't in wwwroot itself, but is exposed by adding multiple symlinks within the wwwroot directory.

I'm having difficulty creating the actual Project on Drupal.org – I get an Access Denied error. So, until that's resolved, it's available via CVS at least. Once the Project is created, there will be an issue tracker, etc…

Oh, and don't laugh too hard at the code. I know most/all of it could be done cleaner/better/faster, but I'm cobbling it together as I learn. Also, I'll be working on better documentation so others can use the module or contribute code.

PS. Man, does CVS suck! I’ve been using SVN for source code management for over a year. Feels like being dropped back in MS-DOS or something now that I’m using CVS again. Ick. Hopefully, Drupal.org will migrate to SVN sometime soon?

Update: The permissions issue on my Drupal.org account has been cleared up, so Provisionator.module is now on the air!

I've just moved the Provisionator module onto Drupal.org's CVS server. The current version of the module is far from complete, but it does function. Specifically, it does:

  • create database for new site
  • populate database with selected mysqldump template file
  • copy template site directory (with settings.php, files, modules, themes)
  • modify settings.php as needed
  • create symlink to expose Drupal via Apache for the new site (as a subdirectory of a server, currently)
  • add a new record to the database, describing the site
  • list all records in the Provisionator database table

It's got a lot of room for improvement, and more than likely needs some tightening down for security and Doing It The Right Way, but it works. It also currently assumes MySQL, and a very specific shared hosting pattern where Drupal isn't in wwwroot itself, but is exposed by adding multiple symlinks within the wwwroot directory.

I'm having difficulty creating the actual Project on Drupal.org – I get an Access Denied error. So, until that's resolved, it's available via CVS at least. Once the Project is created, there will be an issue tracker, etc…

Oh, and don't laugh too hard at the code. I know most/all of it could be done cleaner/better/faster, but I'm cobbling it together as I learn. Also, I'll be working on better documentation so others can use the module or contribute code.

PS. Man, does CVS suck! I’ve been using SVN for source code management for over a year. Feels like being dropped back in MS-DOS or something now that I’m using CVS again. Ick. Hopefully, Drupal.org will migrate to SVN sometime soon?

Update: The permissions issue on my Drupal.org account has been cleared up, so Provisionator.module is now on the air!

Comment Notification by eMail now available again!

Thanks to some great work by Christoph C. Cemper, there is now a module available to enable email notifications for comments by anonymous users (which, on my blog, is everyone but myself) on a Drupal blog. There should now be a “follow comments by email” checkbox underneath the comment submission form, which adds the much-missed feature.

It needs a (minor?) change to the stock comment.module, but Christoph provides a modified version of that. Hopefully the changes aren’t drastic enough to make upgrading Drupal less straightforward.

Thanks to Christoph for his quick work on this (he started on it last night, and has a usable module available before noon today!) I owe you a beer or two for this!

Thanks to some great work by Christoph C. Cemper, there is now a module available to enable email notifications for comments by anonymous users (which, on my blog, is everyone but myself) on a Drupal blog. There should now be a “follow comments by email” checkbox underneath the comment submission form, which adds the much-missed feature.

It needs a (minor?) change to the stock comment.module, but Christoph provides a modified version of that. Hopefully the changes aren’t drastic enough to make upgrading Drupal less straightforward.

Thanks to Christoph for his quick work on this (he started on it last night, and has a usable module available before noon today!) I owe you a beer or two for this!

CCK and Computed Fields

I’ve been using the great CCK module on a bunch of projects (including this blog, for my bikelog). It’s really cool in that it lets you construct custom content types within the Drupal admin interface, without having to touch any PHP code. It’s like having your own personal microformat manager – it could handle things like compound content on a web page (and generate the editing form so you just fill in the blanks – abstract, body, url for more info, email contact, etc…) and I think it could even handle something like a simplified LOM for a “learning object repository”.

One thing I wanted to do on my bikelog was to automatically calculate average speed. I have fields for “duration” and “distance” so entering a value for “average speed” is redundant. Better to just derive the value from the known values already entered.

Which is where the really cool Computed Field module comes in. It’s a contributed module for CCK, and lets you do all kinds of funky things by writing PHP code to perform operations to generate the value of a field. These operations can include calculations on the other fields, or even more complicated things like, I suppose, performing a lookup on wikipedia or something…

After adding the Computed Field module, I just edited my “bikeride” CCK content type to add a new “computed” field called “average speed”. It’s got a “computed code” value, which is executed whenever a value needs to be derived. I just used this:

$node_field[0]['value'] = ($node->field_distance[0]['value'] / $node->field_duration[0]['value']) * 60;

I gave it a data type of “float”, a length of “10,2” and a default value of 0. I told the module to store the value in the database, so I can use the computed field with Views.module as well (in this case, it performs the computation on edit, and stores the result in a field just as any other CCK field would do). I also flagged the field as being sortable, in case that helped Views.module at all.

The end result is a tiny bit of work entering a simple PHP calculation, and then the module takes over the monotonous and redundant calculation work. All I do is enter the base data, and it can derive the rest from that.

I’d imagine this type of derived field could be really useful in an event manager – looking up the number of registrations and updating an “available seats” field, for instance. Or, in a store or inventory system to calculate prices and stock counts. It’s a really cool addition, and although the setup interface (manually entering PHP code) isn’t something you’d unleash on a noob, it’s simple enough to set up and forget about.

I’ve been using the great CCK module on a bunch of projects (including this blog, for my bikelog). It’s really cool in that it lets you construct custom content types within the Drupal admin interface, without having to touch any PHP code. It’s like having your own personal microformat manager – it could handle things like compound content on a web page (and generate the editing form so you just fill in the blanks – abstract, body, url for more info, email contact, etc…) and I think it could even handle something like a simplified LOM for a “learning object repository”.

One thing I wanted to do on my bikelog was to automatically calculate average speed. I have fields for “duration” and “distance” so entering a value for “average speed” is redundant. Better to just derive the value from the known values already entered.

Which is where the really cool Computed Field module comes in. It’s a contributed module for CCK, and lets you do all kinds of funky things by writing PHP code to perform operations to generate the value of a field. These operations can include calculations on the other fields, or even more complicated things like, I suppose, performing a lookup on wikipedia or something…

After adding the Computed Field module, I just edited my “bikeride” CCK content type to add a new “computed” field called “average speed”. It’s got a “computed code” value, which is executed whenever a value needs to be derived. I just used this:

$node_field[0]['value'] = ($node->field_distance[0]['value'] / $node->field_duration[0]['value']) * 60;

I gave it a data type of “float”, a length of “10,2” and a default value of 0. I told the module to store the value in the database, so I can use the computed field with Views.module as well (in this case, it performs the computation on edit, and stores the result in a field just as any other CCK field would do). I also flagged the field as being sortable, in case that helped Views.module at all.

The end result is a tiny bit of work entering a simple PHP calculation, and then the module takes over the monotonous and redundant calculation work. All I do is enter the base data, and it can derive the rest from that.

I’d imagine this type of derived field could be really useful in an event manager – looking up the number of registrations and updating an “available seats” field, for instance. Or, in a store or inventory system to calculate prices and stock counts. It’s a really cool addition, and although the setup interface (manually entering PHP code) isn’t something you’d unleash on a noob, it’s simple enough to set up and forget about.

Drupal Spam Blocking

I've been running this blog on Drupal for a while now, and am generally quite happy with it. The one thing I'd been missing from my days powered by WordPress was a transparent and effective spam blocker. I was so totally spoiled by Spam Karma 2 that everything else just seems like a kid's toy in comparison.

I'd installed the Spam module shortly after I switched to Drupal, but it never seemed to actually block spam. It is pretty handy at removing it, but the URL and keyword matches didn't seem to actually stop spam.

Then, this morning, some spamass decided it would be fun to point his (I'm assuming this jerk is a guy) spambots at my blog. The spam was consistently getting past Spam.module, but it was pretty easy to clean up after the jerk. Still, it's no fun playing mop-up after a cretinous script kiddie, so I rolled up my sleeves to see if I could duct tape a better solution together.

Thankfully, the work had already been done for me, just not updated to Drupal 4.7. The Spam.module for 4.6 ships with a Spam URI Realtime Blocklist module, which will check incoming comments with 6 different realtime-updated shared lists of known spammers.

So, I fired up the Form Updater module, converted the spam_surbl.module code to 4.7, and deployed it. It seems to work so far – of course I'm jynxing it now… I've attached my hack update of spam_surbl.module, which I'm using on Drupal 4.7 here. I'll send a copy to the developer of Spam.module in case he wants to include an updated blocklist module (I didn't convert the .mysql file to an .install autoinstaller, so you may need to run that manually to get the module ready).

I've been running this blog on Drupal for a while now, and am generally quite happy with it. The one thing I'd been missing from my days powered by WordPress was a transparent and effective spam blocker. I was so totally spoiled by Spam Karma 2 that everything else just seems like a kid's toy in comparison.

I'd installed the Spam module shortly after I switched to Drupal, but it never seemed to actually block spam. It is pretty handy at removing it, but the URL and keyword matches didn't seem to actually stop spam.

Then, this morning, some spamass decided it would be fun to point his (I'm assuming this jerk is a guy) spambots at my blog. The spam was consistently getting past Spam.module, but it was pretty easy to clean up after the jerk. Still, it's no fun playing mop-up after a cretinous script kiddie, so I rolled up my sleeves to see if I could duct tape a better solution together.

Thankfully, the work had already been done for me, just not updated to Drupal 4.7. The Spam.module for 4.6 ships with a Spam URI Realtime Blocklist module, which will check incoming comments with 6 different realtime-updated shared lists of known spammers.

So, I fired up the Form Updater module, converted the spam_surbl.module code to 4.7, and deployed it. It seems to work so far – of course I'm jynxing it now… I've attached my hack update of spam_surbl.module, which I'm using on Drupal 4.7 here. I'll send a copy to the developer of Spam.module in case he wants to include an updated blocklist module (I didn't convert the .mysql file to an .install autoinstaller, so you may need to run that manually to get the module ready).

FlickrStickr module ported to use Curl

The FlickrStickr module for Drupal adds the handy Flock-like Flickr Photo Browser, making it easy peasy to add photos from Flickr to content in Drupal. But, the module uses the PHP fopen() command, which is disabled on Dreamhost's servers for security reasons.

So, with some really quick hackery (more like copy-and-pastery, following this example) I ported the module to use curl instead, and it works great. It doesn't seem to be able to insert images into the TinyMCE editor, so you have to toggle back to text mode to insert an image (oh, the irony!)

Basically, the "port" involved changing this:

   $fp= fopen("http://www.flickr.com/services/...reallylongurltruncatedhere...", "r");
   while (!feof($fp)) {
      $buffer= fgets($fp, 4096);
      echo $buffer;
   }

to this:

   $curler = curl_init();
   $urlToCurl = "http://www.flickr.com/services/...reallylongurltruncatedhere...");
   curl_setopt($curler, CURLOPT_URL, $urlToCurl);
   curl_exec($curler);
   curl_close($curler);

There were 2 locations that needed changing. Just search for "fopen" and you'll find them. Use the same pattern of changes for both, and test before deploying.

The FlickrStickr module for Drupal adds the handy Flock-like Flickr Photo Browser, making it easy peasy to add photos from Flickr to content in Drupal. But, the module uses the PHP fopen() command, which is disabled on Dreamhost's servers for security reasons.

So, with some really quick hackery (more like copy-and-pastery, following this example) I ported the module to use curl instead, and it works great. It doesn't seem to be able to insert images into the TinyMCE editor, so you have to toggle back to text mode to insert an image (oh, the irony!)

Basically, the "port" involved changing this:

   $fp= fopen("http://www.flickr.com/services/...reallylongurltruncatedhere...", "r");
   while (!feof($fp)) {
      $buffer= fgets($fp, 4096);
      echo $buffer;
   }

to this:

   $curler = curl_init();
   $urlToCurl = "http://www.flickr.com/services/...reallylongurltruncatedhere...");
   curl_setopt($curler, CURLOPT_URL, $urlToCurl);
   curl_exec($curler);
   curl_close($curler);

There were 2 locations that needed changing. Just search for "fopen" and you'll find them. Use the same pattern of changes for both, and test before deploying.

Access Control Lists in Drupal?

I’ve been trying to figure out a workable solution for a couple of months, and have come up with nothing more than some hacks and approximations of what is needed.

Here’s a use case:

User “A” (let’s call her “Amy”) writes a blog post. She wants it to be readable by her professor (let’s call her “Betty”) and one other student (let’s call her “Carmen”).

But, she doesn’t want the post to be readable by the rest of the class, by students in other classes, nor by the unwashed masses stumbling across a post via Google.

So, Amy wants to grant these privileges to her blog post:
Amy: Read/Write/Delete
Betty: Read
Carmen: Read

Currently, she can create an Organic Group, add the three users to the group (let’s call it “Amy+Betty+Carmen”), and mark it as “not public” and having an audience of “Amy+Betty+Carmen”.

That Organic Groups model works, but for her next blog post, Amy wants it to be available by another student (let’s call him “Dmitry”). So, she has to create a new Organic Group called “Amy+Betty+Dmitry” and add the three users to the group. She then writes a new blog post, sets it to not be public, and have the audience of “Amy+Betty+Dmitry”.

That pattern just doesn’t scale. Each user may have to belong to hundreds of Organic Groups to cover all permutations of sharing and privacy involved with a class or project.

It would be easier if there was just an “Access” section of the blog authoring page, where Amy could just select the users that she wants to add to each of the two non-owner roles (read and edit). This could pose some issues wrt scalability – if there are 100 users in a copy of Drupal, she won’t want to have to scan a list. Ideally, some ajax-powered user search would let her just start typing a person’s name (she may not know their username or email address) and have the system provide a list of matches.

So, the Organic Groups trick works, but doesn’t scale. If Amy wants to allow co-authoring on a post (a book page or something), she needs to start fiddling around with Simple Access (or make sure everyone has “Administer Nodes” privs, which won’t fly in a community based on assumed privacy for some content). Simple Access is tied to Drupal’s concept of Roles, so there may need to be 13 bajillion Roles in the system to cover all permutations (or a Role per user). Doesn’t scale. And, there’s the strange interaction between Simple Access and Organic Groups, where if you want OG to work, you can’t use Simple Access (you have to create a dummy Role called “nobody” with nobody in it for OG to kick in, as Simple Access will override it otherwise).

There are some others who appear to have a similar need. First, there’s the “na-arbitrator” module, which adds access control lists to forum posts (so far) – but it appears to be tied to the concept of Roles, with Users being added as Moderators. Close.

Node Privacy by Role” module sounds close, but again is tied to the concept of Roles, not Users.

There’s the Taxonomy Access module, which would require enforcing a taxonomy and making sure only the appropriate people use a given term in the vocabulary. Don’t think this would scale either.

Then, there’s a rather detailed design spec but it appears to have been orphaned for a year or so… There are some other attempts dating back to 2004, but nothing appears to have been completed.

Perhaps the most promising sounding project is the “Groups” module – but even that hasn’t been touched in 13 months, and doesn’t work with Drupal 4.7

The official Drupal handbook includes a section that touches on this topic, but the solutions provided there don’t offer the level of user-defined granularity. They rely on administrators to set up roles and taxonomies and to manage the interaction between them. What is needed is a way for users to define the exact audience of any node they wish to restrict access to.

Long story short, I have no good idea on how to currently enable per-node per-user access controls in Drupal. I’ve got some projects that will either rely on this, or will benefit greatly from it.

I’ve been trying to figure out a workable solution for a couple of months, and have come up with nothing more than some hacks and approximations of what is needed.

Here’s a use case:

User “A” (let’s call her “Amy”) writes a blog post. She wants it to be readable by her professor (let’s call her “Betty”) and one other student (let’s call her “Carmen”).

But, she doesn’t want the post to be readable by the rest of the class, by students in other classes, nor by the unwashed masses stumbling across a post via Google.

So, Amy wants to grant these privileges to her blog post:
Amy: Read/Write/Delete
Betty: Read
Carmen: Read

Currently, she can create an Organic Group, add the three users to the group (let’s call it “Amy+Betty+Carmen”), and mark it as “not public” and having an audience of “Amy+Betty+Carmen”.

That Organic Groups model works, but for her next blog post, Amy wants it to be available by another student (let’s call him “Dmitry”). So, she has to create a new Organic Group called “Amy+Betty+Dmitry” and add the three users to the group. She then writes a new blog post, sets it to not be public, and have the audience of “Amy+Betty+Dmitry”.

That pattern just doesn’t scale. Each user may have to belong to hundreds of Organic Groups to cover all permutations of sharing and privacy involved with a class or project.

It would be easier if there was just an “Access” section of the blog authoring page, where Amy could just select the users that she wants to add to each of the two non-owner roles (read and edit). This could pose some issues wrt scalability – if there are 100 users in a copy of Drupal, she won’t want to have to scan a list. Ideally, some ajax-powered user search would let her just start typing a person’s name (she may not know their username or email address) and have the system provide a list of matches.

So, the Organic Groups trick works, but doesn’t scale. If Amy wants to allow co-authoring on a post (a book page or something), she needs to start fiddling around with Simple Access (or make sure everyone has “Administer Nodes” privs, which won’t fly in a community based on assumed privacy for some content). Simple Access is tied to Drupal’s concept of Roles, so there may need to be 13 bajillion Roles in the system to cover all permutations (or a Role per user). Doesn’t scale. And, there’s the strange interaction between Simple Access and Organic Groups, where if you want OG to work, you can’t use Simple Access (you have to create a dummy Role called “nobody” with nobody in it for OG to kick in, as Simple Access will override it otherwise).

There are some others who appear to have a similar need. First, there’s the “na-arbitrator” module, which adds access control lists to forum posts (so far) – but it appears to be tied to the concept of Roles, with Users being added as Moderators. Close.

Node Privacy by Role” module sounds close, but again is tied to the concept of Roles, not Users.

There’s the Taxonomy Access module, which would require enforcing a taxonomy and making sure only the appropriate people use a given term in the vocabulary. Don’t think this would scale either.

Then, there’s a rather detailed design spec but it appears to have been orphaned for a year or so… There are some other attempts dating back to 2004, but nothing appears to have been completed.

Perhaps the most promising sounding project is the “Groups” module – but even that hasn’t been touched in 13 months, and doesn’t work with Drupal 4.7

The official Drupal handbook includes a section that touches on this topic, but the solutions provided there don’t offer the level of user-defined granularity. They rely on administrators to set up roles and taxonomies and to manage the interaction between them. What is needed is a way for users to define the exact audience of any node they wish to restrict access to.

Long story short, I have no good idea on how to currently enable per-node per-user access controls in Drupal. I’ve got some projects that will either rely on this, or will benefit greatly from it.

Drupal 4.7.0 Beta 1 + Quiz Module

In a master stroke of synchronicity, I was looking for a download of Drupal 4.7 to test out the Quiz module just yesterday afternoon. This morning, I see that Drupal 4.7.0 Beta 1 was released! So, I grabbed a copy of it and set up a fresh install on my desktop. Some really nice refinements to Drupal. The configuration side of things is starting to make sense. Good to see them giving it some proper love.

I dropped the Quiz module into place, and started creating a quiz. Looks pretty straightforward, and the quiz questions have exactly the kind of functionality that I’ve built into quiz tools previously (for multiple choice quizzes, the ability to have per-answer feedback, random/notrandom, tracking time in quiz, etc…) – but I can’t seem to take a quiz.

I’m sure it’s just a minor hiccough with the new Drupal 4.7.0 Beta 1, or perhaps an incompatibility between the older Quiz module code and the new Drupal code. Once that’s worked out, I think this could be a pretty solid informal testing tool, or a great option for outside-the-LMS testing.

Now, to see if I can convince Quiz.module to start letting people take quizzes…

I’ve also been playing with various CMS options, and so far Drupal is feeling like the right balance between flexibility, control, and ease of use. Joomla just feels to “heavy” for novice users. WebGUI is waaaay to over-the-top enterprise-application heavy (borking MySQL on my desktop box when I tried to test it). Drupal is a nice, light, fluid system…

In a master stroke of synchronicity, I was looking for a download of Drupal 4.7 to test out the Quiz module just yesterday afternoon. This morning, I see that Drupal 4.7.0 Beta 1 was released! So, I grabbed a copy of it and set up a fresh install on my desktop. Some really nice refinements to Drupal. The configuration side of things is starting to make sense. Good to see them giving it some proper love.

I dropped the Quiz module into place, and started creating a quiz. Looks pretty straightforward, and the quiz questions have exactly the kind of functionality that I’ve built into quiz tools previously (for multiple choice quizzes, the ability to have per-answer feedback, random/notrandom, tracking time in quiz, etc…) – but I can’t seem to take a quiz.

I’m sure it’s just a minor hiccough with the new Drupal 4.7.0 Beta 1, or perhaps an incompatibility between the older Quiz module code and the new Drupal code. Once that’s worked out, I think this could be a pretty solid informal testing tool, or a great option for outside-the-LMS testing.

Now, to see if I can convince Quiz.module to start letting people take quizzes…

I’ve also been playing with various CMS options, and so far Drupal is feeling like the right balance between flexibility, control, and ease of use. Joomla just feels to “heavy” for novice users. WebGUI is waaaay to over-the-top enterprise-application heavy (borking MySQL on my desktop box when I tried to test it). Drupal is a nice, light, fluid system…