CitizenSpeak Colophon

CitizenSpeak: your campaign
There were two projects in getting CitizenSpeak up and running: Developing the CitizenSpeak module and creating the CitizenSpeak site. While they were intertwined, they also provided distinct educations.

I found that the I18n module can serve dual purposes; it provides the Spanish language interface to the site as well as allowing us to customize standard English language messages. This is handy if you want customized labels for things, or your site isn’t as averse to capital letters as the Drupal project.

As an aside, only recently did I learn that name “I18n” is an abbreviation for the “Internationalization,” since “nternationalizatio” is 18 letters. I guess I just never bothered to count.

I was also happy to learn how to customize the output of other modules. The PHPTemplate and Smarty engines allow designers to customize how specific node types are displayed, what information is available to templates, and override any theme() call.

There are some lessons learned from what I did wrong, too. The first was choosing Smarty as the theme engine. While I’ve had good luck with Smarty in my own projects, the majority of work being done with Drupal seems to use PHPTemplate.

There’s nothing wrong with Smarty, the PHP library. For Drupal, however, there is a lot more support available for PHPTemplate, and PHPTemplate more likely to be kept up to date. Drupal’s PHP functions are more than adequate for theming, which negates Smarty’s advantage of having view-centric functions available to it.

I also wish I had created a site-specific module. A module is a great place to create custom pages and blocks, to use callback hooks like hook_nodeapi() and hook_user(), and to collect helper functions. A lot of things I did by customizing the display interface and variables could have been more elegantly handled by simply creating a module for the CitizenSpeak site and stashing everything there.

That about wraps up my posts on building CitizenSpeak. Please visit the site (maybe even click that donate button on the right), and thanks for reading.

Developing the CitizenSpeak Module

CitizenSpeak: your campaign
Yes, another CitizenSpeak post. I’ll probably do one more after this about how the site is configured, and then updates as events warrant. This time I want to talk about developing the module.

I’ll admit that it’s been a while since I started working on the CitizenSpeak module. Part of it was that I was donating a lot of the development effort and only getting paid for implementing the site. That means that keep-George-off-the-streets programming took priority over this.

Another part was that I hit a mental wall with Drupal’s module format. Having a monolithic .module file was not working for me, but I found that when I split it into several topical files it got much easier to deal with. If you look at the source code you’ll see that I’ve split functions into files by topic.

I even went one step further. A lot of Drupal hooks send an operation as the first parameter, take a look at hook_user() for an example. If you look at the CitizenSpeak implementation of hook_user(), it’s just a stub that calls other functions:

function citizenspeak_user($op, &$edit, &$user, $category = false) {
$function = "citizenspeak_user_" . $op;
if (function_exists($function)) {
return call_user_func_array($function, array($edit, $user, $category));

I then moved all the functionality out of giant switch() statement suggested by the docs and into individual functions in citizenspeak.user.php. The function arguments are redundant, but the manageable code is worth the repetition.

By moving everything out of the core file, I found it a lot easier to deal with the development and get into the groove. If I had one thing to tell someone getting started with Drupal module development, it would be that.

Looking ahead at the development, there are two big tasks. The CitizenSpeak module needs an API that will allow other modules to interact with it. The goal is to allow other modules to hook into the forms, campaign sending and reporting. One of the big things that everyone wants is CiviCRM integration and the CitizenSpeak API hook will allow that to happen. The other big task is to update the module for 4.7, which features new email and form APIs.

More About the CitizenSpeak Update

CitizenSpeak: your campaign
In the announcement yesterday I wrote that I would be blogging more about CitizenSpeak, and with this post the prophesy has come to pass.

Organizations have had tools like Capitol Advantage to create advocacy campaigns for quite some time. Those tools aren’t necessarily accessible for small or ad-hoc efforts due to the cost involved. CitizenSpeak offers a subset of their features — email-only campaigns and reporting — for free.

Now, when a blogger gets a bug up their butt about something that needs public outcry to fix (i.e. a proposed porch-couch ban in Ann Arbor, MI) they have a tool that will let them create a campaign and send all their readers to join in.

Even better, since its a GPL licensed module, anyone with a Drupal or CivicSpace can create their own campaign center. It can also build on things we chose to leave out of the site; things like categories, comments or any of the add-on modules that Drupal supports.

I can’t wait to see what other sites do with the module.

CitizenSpeak Re-launches!

CitizenSpeak: your campaign
Remember when I begged for money months ago? Well it payed off, and now the new CitizenSpeak has re-launched.

Briefly, CitizenSpeak is a site that allows people to create and host email campaigns. It allows ad-hoc organizing around any issue that puts a bug up someone’s butt. I’ll probably blog more about it later this week. In the meantime, check out the site or the open source Drupal module that I built for the site.

Big thanks to Jo Lee for being CitizenSpeak, Eric Gundersen at Development Seed for his fantastic design work and Embolden Design for providing hosting!