If you want to use Habari as a platform rather than just a blog, as I talked about in my previous post, it's likely you'll come across the situation where you want people to be able to register with your site. To allow this, I've written a simple registration plugin. Activate the plugin and put $theme->registration('group_name') in your template, and you'll get a form for new users to sign up, and they'll be placed in whatever group you specify, in less than 90 lines of code.

As usual, the plugin, which I've creatively named Register Plugin, is in the -extras repository, but I thought I'd talk about what it involves.

First up, when the plugin is activated, we create a UUID, a random string, that we'll use as a secret key. We store this as a site option, and we'll use it a bit later for hashing group names.

public function action_plugin_activation( $plugin_file ) { if ( Plugins::id_from_file(__FILE__) == Plugins::id_from_file($plugin_file) ) { // Store a secret key for hashing group names Options::set('register_secret', UUID::get()); } }

Next we use the FormUI class to create a registration form.

public function get_form( $group ) { // Create the registration form, and add a CSS class $form = new FormUI('registration'); $form->class[] = 'registration';

// Add a field for the email address // The 'null:null' tells FormUI not to store the submitted values $form->append('text', 'email', 'null:null', _t('Email'), 'formcontrol_text'); // Get FormUI to make sure it's a valid address $form->email->add_validator('validate_email'); // Add a field for the username $form->append('text', 'username', 'null:null', _t('Username'), 'formcontrol_text'); // Get FormUI to make sure the username is filled in and available $form->username->add_validator('validate_required'); $form->username->add_validator('validate_username'); // Add a password field, which is required $form->append('text', 'password', 'null:null', _t('Password'), 'formcontrol_text'); $form->password->add_validator('validate_required');

// Store the group to be added, all secreted up $form->append('hidden', 'group_name', 'group_name'); $group_hash = md5($group); $form->group_name->value = $group_hash; $form->append('hidden', 'group_digest', 'group_digest'); $form->group_digest->value = $this->hmac($group_hash); // Create the Register button $form->append('submit', 'register', _t('Register'), 'formcontrol_submit');

// Tell FormUI to process the submitted form // with the register_user function in this class $form->on_success( array( $this, 'register_user' ) ); // Return the form object return $form; }

Most of that is pretty straightforward FormUI stuff, which is documented on the wiki (though I do love how easy validation is). The interesting part is were we secret up the group name, because of course we don't want to have people adding themselves to the admin group. We send a hash of the group name, along with a digest of the hash. We create the digest as follows.

function hmac($data) { return md5(md5($data) . Options::get( 'title' ) . md5(Options::get('register_secret'))); }

We hash the data and secret, with a little salt, for which we've used the blog title. We send the digest and the hashed group name with the form, and test it when we get it back, like this.

public function register_user( $form ) { // Get all the groups $allowed_groups = array(); foreach ( UserGroups::get_all() as $group ) { $allowed_groups[] = $group->name; } // Make them accessible via the hashed group name $allowed_groups = array_combine( array_map('md5', $allowed_groups), $allowed_groups ); // Recreate the digest of the submitted group // If it matches the digest, we're all good $group = ''; if ($this->hmac($form->group_name->value) == $form->group_digest->value) { $group = UserGroup::get($allowed_groups[$form->group_name]); } else { die('You naughty hacker!'); }

// Create a new user, with the submitted data $user = new User( array( 'username' => $form->username, 'email' => $form->email, 'password' => Utils::crypt( $form->password ) ) ); // Add the user to the group if ( $user->insert() ) { $group->add($user); Session::notice( sprintf( _t( "Added user '%s'" ), $form->username ) ); } else { $dberror = DB::get_last_error(); Session::error( $dberror[2], 'adduser' ); } } And the magic bit that makes it available as a theme function is this. public function theme_registration( $theme, $group ) { $this->get_form($group)->out(); }

As I said, it's very simple at the moment. The only complexity is in all the hashing, for which I thank Matt Read (aka BigJibby).

Other things that I might add include moderated registrations, email confirmation, optionally disallowing users to be added to groups that have super user access, and a registration content type so that you don't have to edit templates at all. Hopefully I haven't made the simple plugin sound complex.

[Update: As Owen points out in the comments, as we can set options in the FormUI object that are stored locally and not tainted as user input, we can safely store the group name there, rather than passing it to the user encrypted. The registration plugin in the Habari extras repository now does this. Thanks, Owen.]

On my recent post Stalking Habari comments, I stuffed around with and reordered screenshots of tweets to make a coherent conversation. In the comments, Sean Coates said, "You should be using my Twitter Silo." It's in the Habari extras repository (direct link), so I checked it out.

After activation, you need to configure the silo with your Twitter username and password. On the publish page, the silo has a tab along with your other silos. You can see this in the screenshot below. You'll also see that there are three directories.

Your own tweets.
twitter-silo.png

Your friends' tweets.
twitter-silo-friends.png

Custom tweets, where you simply enter the URL of a particular tweet.
twitter-silo-custom.png

And this is Sean, talking about how beer is a soporific, as inserted by the silo.

So, yes, I should have used the Twitter Silo.

I've decided to follow the new versioning scheme being used on the Habari extras repository for all of my plugins and themes (the ones I have to host myself since licensing restrictions mean I can't put them in extras itself). The lack of a proper versioning scheme meant that I'd made changes to the TinyMCE plugin targeted to Habari 0.6-alpha that weren't compatible with 0.5, the current stable release. To rectify the situation, I've released a 0.6 version and a 0.5 version. You can find them on the TinyMCE plugin page. Thanks to Ian Barber for the backwards patch, and Mike Lietz for troubleshooting.

If you have any requests for these plugins, please let me know.

There have been some major changes to Habari since the last update of the TinyMCE plugin, so I've updated. It's still not perfect, but it works with the newest version of Habari. As usual, if there's anyone willing to take over maintenance and development of the plugin, let me know. I'm happy to give advice, but I'm finding it hard to find the time to put into improving it.

These are the changes in version 0.4, which you can download from my TinyMCE plugin page:

  • Updated configuration to work with updated FormUI.
  • Play nicely with Monolith.
  • Reformat code to meet Habari's code standards.

It seems like an eternity ago that the Habari admin was replaced with Monolith, and all in all, I think it's a good thing. We've had some great additions to the Habari community who have been really kicking it along and ironing out the bugs.

Though I did miss though the incoming links on the dashboard. You might call me vain, but it was nice to be able to see who was linking to my site. Sometimes they were new Habari users who were using one of my plugins or themes, and I could pop over and say hi and thanks. Sometimes they were complaining about one of those same plugins or themes, and I could pop over and say hi and thanks, and hopefully fix the problem.

I've been sick the last few days and needed something braindead easy to do, so I bring you the incoming links module plugin for the new Habari dashboard. No caching or error handling yet, but I might get that finished before you read this post.

As with any plugin that licensing allows me, it's in the Habari extras repository.

I've updated the Publish Quote plugin for Habari, and donated it to the Habari community. It now takes advantage of features added in Habari 0.5 alpha, so that you can set a template for the title as well as the content and specify tags that should be added to your quote entries.

Let me know if you have any feature requests. It would also be great to hear from anyone who's using the plugin.

As Habari moves towards its first non-alpha release—the 0.5 beta is due out on 15 May—we can expect more users that aren't developers to try out the software. We need to make sure that the early experiences these users have is as positive as possible. Of course, being beta, there are still going to be issues, as well as the learning curve of using a new piece of software. As the community is pretty developer heavy at the moment, new folks are usually developers too, and if they are having issues they simply jump onto #habari and talk to other developers live. It's a great way to make people feel part of the community.

However, IRC isn't ubiquitous. A lot of new users won't have even heard of it. But we want them to be able to have this positive introduction to the Habari community too. To this end, and thanks to the good folk from Mibbit, I've written a plugin that embeds the Habari channel in the admin. Activate the Live Help plugin (available from the extras repository), go up to the Admin menu and select Live Help. And here's a screenshot, #habari in Habari.

Rick Cockrum writes about wysiwyg editors for Habari, noting that Habari's editor uses raw HTML by default. That might be fine for techie geeks, but is unlikely to go far in the long run.

The first option you have is to use an alternative HTML-izible markup, and there are plugins available for Textile and Markdown (actually two for Markdown, here and here, though I really wish they could merge into one version). That may still be too geeky for most.

The second alternative is to use one of the recently released WYSIWYG plugins, of which there are three. First, the TinyMCE plugin, which I've released myself, though at some point I'll probably donate it to the community. Second, the NicEdit plugin, started by Christian Mohn. Third, jwysiwig. Both NicEdit and jwysiwig are now in the Habari community repository and owned by the Habari community. However, I've done significant coding on all three of these, so if you have any comments or feature requests, please let me know.

So, back to Rick's post. He accurately points out some shortcomings of each of the editors, and in a comment I added some more, which I'll briefly recap. None of the plugins are very configurable. Only TinyMCE is resizable. jwysiwig doesn't work with the media silos (a huge sin, because I think the media silos are a killer feature). Once Habari 0.4 has been released (soon, soon, I hope) I'll try to fix all of these issues.

Additionally, TinyMCE is not tiny, but there isn't much I can do about that.

Actually, the biggest driver for me doing any work on them at all would be for people to let me know that they're using them.

If the TinyMCE plugin is a bit heavy for your preferences, Christian Mohn (aka h0bbel) has just checked a NicEdit plugin into the Habari extras repository (download a packaged version from http://habariproject.org/dist/plugins). I did a bit of the coding, so if you have any feature requests, let one or both of us know. Specifically, there are currently no configuration options. If you don't configure you just get the most basic functionality. If you configure and hit save, you get the full panel. Hey, let's call it a work in progress.

Thanks to feedback from Owen Winkler, Matt Read and starjive, I've made some improvements to the TinyMCE plugin for Habari. Most significantly, it now supports Media Silo plugins, such as Flickr and Viddler (in the forthcoming 0.4 release if you're not running out of subversion).

Details:

  • Support MediaSilo input.
  • Allow for plugin to be in directories other than /user/plugins.
  • Only send JavaScript if this is the publish page.
  • Add resizable option.