I've long been a user of Meetup.com, and was even a meetup organizer for the Philadelphia WordPress meetup group. Those days have long passed, and Meetup.com has changed a bit, but I still like the idea of a tool that will help organize a group online.

Usually before I start a project, I'll have some idea in mind, but will not really do anything with it. Just like any invention, I will see some need, and try to fill that need with code. Eventually, for some projects, some catalyst will cause me to solidify those ideas and begin writing actual code.

I got an email today that made me think that the time for this idea has come.

After that catalyst, I usually head to my favorite online reverse dictionary to look for a good name. What I'm looking for is often a name that means what I'm trying to produce, but in an oblique enough way that the domain name is still available for registration. After all, pretty much every English word is already registered as a dot-com.

So into Onelook's reverse dictionary I dropped the phrase "meeting place". And by sifting through that list, I found a name that has a domain that is not already registered.

I dropped the new name into my GoDaddy account, and bought the dot-org. I figure that this will be another open source project, so a dot-org is a good way to go. Besides that, the dot-com was not available.

Anyway, while registering the domain, I configured the DNS at one of my hosts to house the new domain, and point it to one of the VPS accounts I have with them. I had already set up Apache on that server for a virtual document root, so configuring it for hosting the new domain was simply a matter of creating a couple of new directories.

I confirmed through the GoDaddy purchase process, and within 30 seconds my domain was up and running.

Immediately after that, I created a Googl Code hosting account in the name of the project, and gave it a brief description. I will provide more detain there soon, but I wanted to get a placeholder for the project online quickly.

Now that the hosting for both the site and the code are taken care of, I can concentrate on narrowing the scope of the project to something that people can deploy.

People might think that it's more important to work out the project functionality beforehand, and I can see some credence in that. Still, as I've said, I've been thinking about this project for a while and working with something for a long time that is similar but not open source. Giving it a name really solidifies it in my mind as an actual project. Rather than calling it "the as-yet-unnamed meetup.com replacement", I can now call it Pnika, a modern day Pnyx.

I posted links to a couple of the things I've written here into forums, announcing somewhat that the site existed before I was really ready to make it fully public. Part of the reason I was keeping things under wraps is because I wasn't sure what exactly I was going to write about here.

Primarily, this blog is about development. Mostly web development. It's not really about announcing or finding news, although more post may deal with new tools. It's really going to be about code that I write.

What you can come to find here though, is the whole process. There are a lot of sites that explain how to do a thing, but they don't really get into why they did it or how they decided to do one thing over another. What I hope to do here is give a larger glance at my whole process. So expect to find not only code here, but also diagrams, specifications, and the thought processes that go into them.

Hopefully by experiencing more of what I'm thinking when I start coding, you can learn more about what goes into the code without just having it blindly handed to you. I will likely talk more about the social aspects of coding too, including licensing and collaboration. As a benefit to me, I get to write out more of these processes and develop a solid strategy for implementation that I can use in my personal and paid work.

I hope you enjoy it.

Today, I wrote three new Habari plugins. They're all fairly simple, but they each use some techniques that plugin developers might like to know. So I'm going to take a few posts here in a series to outline how I go through the construction of these plugins.

The first plugin I'll start with is one that will be of particular use here on RedAlt, a code highlighter.

With this plugin, I'd simply like to take a chunk of code that's output inside of "code" tags and print it nicely formatted and colorized so that it's easy to read. With the prettify project on Google Code, neatly licensed under the ASL just like Habari and eventually my plugin, I should be able to accomplish this fairly easily.

Basic Framework

So, let's start out with the basic plugin framework:

'Prettify', 'url' => 'http://habariproject.org/', 'author' => 'Owen Winkler', 'authorurl' => 'http://asymptomatic.net/', 'version' => '1.0', 'description' => 'Displays pretty source code in the site output', 'license' => 'Apache License 2.0', ); } ?>

The above code essentially tells Habari all about this plugin. Without this function, the plugin won't run. I create a directory in user/plugins named "prettify" and save this file as "prettify.plugin.php" for a starting point. The ".plugin." part of the file is what keys Habari that this file is a plugin and is a candidate for activation.

In future releases of Habari, the primary source of the information provided by the info() method will be instead via an xml file that is packaged with the plugin.

Add Dependent Files

Next, we need the plugin to actually do something. I know I'm going to use the CSS and JavaScript from the Prettify project on Google Code, so I know I need to at least add those files to the page output.

How do I add those files to the output? I use another plugin hook:

public function action_template_header() { Stack::add('template_stylesheet', array($this->get_url(true) . 'prettify.css', 'screen')); Stack::add('template_header_javascript', $this->get_url(true) . 'prettify.js', 'prettify', 'jquery'); }

This chunk of code does two very basic things, but may seem a little complicated.

First, the function action_template_header() connects the plugin to the "template_header" hook. This hook executes in the theme when the template executes $theme->header();

The two lines in the function add things to a Habari Stack. A Stack is just a term for a list of things that you are usually going to output. Stacks have a couple of nice features that I'm using in addition to naming the Stack itself. They let you name the item that you're inserting as the third parameter, and they let you name dependencies of that thing in the fourth parameter.

In the case of the css file, I'm just adding the file to the stack and don't care about the name or the order. In the case of the Prettify javascript library file, I'm naming the stack item "prettify" and I'm making sure that it is loaded after any item in the stack named "jquery", which we'll be using later.

When the rest of the theme class executes, the stacks will be appropriately output according to the formatting specified in the theme class.

One handy thing here that's easy to overlook is the $this->get_url() method. In this case, $this is an instance of the plugin, and so the get_url() method is in the base Plugin class. The function returns the URL of the plugin directory, which is really useful to know if you need to link to a file that is distributed with the plugin.

With just this code, the plugin outputs the required javascript and css to support the Prettify Google project.

Implement Highlighting

With the dependent code being output properly, I need to add code to make use of it. I'll have to change the action_template_header() function slightly to make the requisite calls to the prettify javascript library.

I want to make sure that I don't call the prettify code before the whole page loads. I can do this easiest with jquery, which is often used for other features in the theme. I'll add that to the dependencies in the javascript stack, and add the code to make the prettify library colorize my code:

public function action_template_header() { Stack::add('template_stylesheet', array($this->get_url(true) . 'prettify.css', 'screen')); Stack::add('template_header_javascript', Site::get_url('scripts', true) . 'jquery.js', 'jquery'); Stack::add('template_header_javascript', $this->get_url(true) . 'prettify.js', 'prettify', 'jquery'); Stack::add('template_header_javascript', '$(function(){ PR_TAB_WIDTH = 2;prettyPrint()});', 'prettify_inline', array('jquery', 'prettify')); }

My new code chunk is "prettify_inline", which is dependent on both jquery and our previously added "prettify" stack item. Note that the value added to the stack is raw javascript, not a URL to a javascript file like the other values. Habari sorts this out automatically and uses the appropriate tag formatting on output.

The inline code here sets the tab width to 2 (the default is 8) and executes the prettyPrint() command, which finds all of the code blocks using the class "prettyprint" and colorizes them. This is done inside of a jQuery function that executes after the DOM for the page loads.

Tricky Line Numbers and Entities

This might be good as-is, but I would really like to add line-numbers to the output. There are a number of ways to do line numbers. Some people use the ordered list HTML tag, some people use tables. There are drawbacks to both of those. The method I'm currently preferring is using a floated list of line numbers that sits to the left of the lines.

So what I want to do is create a second code element before the code that is being highlighted, and then put the same number of numbers in it as lines in the highlighted code block. I'd prefer not to do this in the raw HTML output.

To do this, I'm going to filter the content of the post, and wherever there is a line break, I'm going to replace that with a br tag with a specific class name. This will let me insert real HTML breaks and count the exact number of breaks in the code with javascript so I can insert line numbers.

Also, when I add content to a post that I intend to syntax-highlight, I want Habari to automatically turn any HTML code inside that block into entities. This will make it easier to paste code that contains HTML tags, since I won't have to convert them into entities myself.

To do this, I will add to the filter some code that turns any code within the prettyprint code tags into its HTML entity counterpart.

Here's the code that does it:

public function filter_post_content_out($content) { $content = preg_replace_callback('%(<\s*code [^="">]*class\s*=\s*(["\'])[^\'"]*prettyprint[^\'"]*\2[^>]*>)(.*?)()%si', array($this, 'content_callback'), $content); return $content; } public function content_callback($matches) { $code = trim($matches[3], "\r\n"); $code = str_replace( "\r\n", "\n", $code); $code = htmlentities($code); $code = str_replace( "\n", "
", $code); return $matches[1] . $code . $matches[4]; }

The filter_post_content_out() method attaches to a plugin hook that executes when the post content is output, typically via echo $post->content_out; using the content_callback() method as the replacement function for preg_replace_callback().

The only really tricky bit here is the regular expression that captures the code blocks, and only if they have the "prettyprint" class assigned to them.

I also need to add the javascript code to count the breaks and output the line numbers, which results in this final version of action_template_header():

public function action_template_header() { Stack::add('template_stylesheet', array($this->get_url(true) . 'prettify.css', 'screen')); Stack::add('template_header_javascript', Site::get_url('scripts', true) . 'jquery.js', 'jquery'); Stack::add('template_header_javascript', $this->get_url(true) . 'prettify.js', 'prettify', 'jquery'); Stack::add('template_header_javascript', '$(function(){ $("code.prettyprint").each(function(){ l=$("br.pretty", this).length+1;oz="";for(z=1;z<=l;z++) oz+="z+" "; $(this).wrap("

").before(""+oz+""); }); PR_TAB_WIDTH = 2;prettyPrint()});', 'prettify_inline', array('jquery', 'prettify')); }

The Final Plugin

So all of that gets basically what I want. I made a few tweaks to the prettify CSS so that it looks nice within the site. It's the CSS that does the expanding of the code on hover in Firefox. Apart from that the two extra files come straight from the Prettify Project of Google, and the last file, the prettify.plugin.php is this one here:

'Prettify', 'url' => 'http://habariproject.org/', 'author' => 'Owen Winkler', 'authorurl' => 'http://asymptomatic.net/', 'version' => '1.0', 'description' => 'Displays pretty source code in the site output', 'license' => 'Apache License 2.0', ); } public function filter_post_content_out($content) { $content = preg_replace_callback('%(<\s*code [^="">]*class\s*=\s*(["\'])[^\'"]*prettyprint[^\'"]*\2[^>]*>)(.*?)()%si', array($this, 'content_callback'), $content); return $content; } public function content_callback($matches) { $code = trim($matches[3]); $code = str_replace( "\r\n", "\n", $code); $code = htmlentities($code); $code = str_replace( "\n", "
", $code); return $matches[1] . $code . $matches[4]; } public function action_template_header() { Stack::add('template_stylesheet', array($this->get_url(true) . 'prettify.css', 'screen')); Stack::add('template_header_javascript', Site::get_url('scripts', true) . 'jquery.js', 'jquery'); Stack::add('template_header_javascript', $this->get_url(true) . 'prettify.js', 'prettify', 'jquery'); Stack::add('template_header_javascript', '$(function(){ $("code.prettyprint").each(function(){ l=$("br.pretty", this).length+1;oz="";for(z=1;z<=l;z++) oz+="z+" "; $(this).wrap("

").before(""+oz+""); }); PR_TAB_WIDTH = 2;prettyPrint()});', 'prettify_inline', array('jquery', 'prettify')); } } ?>

Future Improvements

I'd potentially like to add a couple of things to this plugin, both relating to downloads. I'd like to be able to link a code block to a download, so if you click a link near the code, it would download that code.

It might also be useful to have a button or link that automatically copies a code block to the clipboard. For right now, that would include some Flash (because you can't access the clipboard from javascript), and I'm not really too interested in that right now.

Having the code output expand and contract or enable vertical scrolling on user interaction would probably be a useful addition.

It might also be nice to have some settings that allow the code to link to cross-references. For example, it would be useful if PHP functions and keywords linked to their documentation on the php.net site. It would be even more nice if the code could link to a documentation center of my choosing, although I don't know of a documentation standard or API that would make that easy enough to enable as a web service. Still, it might be worth thinking about.

I've been using a little trick on my blog to link to items at Amazon with my affiliate code for quite some time, and although there are probably tools that would let you select products more easily, I've found that I like convenience and brevity of my method well enough.

I simply add this new rewrite rule to my root .htaccess file:

RewriteRule ^az(.*)$ http://www.amazon.com/exec/obidos/ASIN/$1/asymptomatic-20 [R,L]

My affiliate code is "asymptomatic-20", which you can easily replace with your own. (Or not!)

Then, to create a link, use whatever linking method you usually use, but instead of including a full Amazon affiliate link, simply copy the ASIN or ISBN of the item, and put "/az" in front of it. So to create a link to the PHP 6 and MySQL 5 for Dynamic Web Sites: Visual QuickPro Guide, just link to: /az032152599X

Simple enough. Perhaps I should write a Habari plugin that does this and includes a Silo so that product search can happen inside the Habari admin. Ah, a future project.

There has been some growing concern lately that Automattic is taking steps to kill the "Premium Themes" marketplace. Whether this is true, who can say? Being in compliance with the GPL is easy, and you can still make money from the process. There are two ways.

The first way is the ugly way, from a development point of view. You release your theme as GPL, and then charge for support of that theme. This way is ugly because you can't simply do your work, release your code, and watch the cash roll in. If people pay for support, presumably you're offering them some service in addition to what they're getting for free. Perhaps this means free updates, although those updates would inevitably be covered under the GPL. More likely support would include customization, access to developers who can customize, access to support forums, and tutorials that show you how to use or customize the theme. Is there enough value there for users to pay for? Maybe.

What people seem to really like about the concept of making money from theming is that they can create something and then sell licenses to it that allow people to use that work. They're selling themes like they are a physical object, one chunk of cash per one chunk of code. The trick is that unlike candycanes or dolls, there isn't a separate physical thing exchanged in each sale. The thing you're selling with software is typically the license to use it, not the software itself. The GPL under which all WordPress themes must be releases says that you can charge for access to the work, but you can't restrict re-sale. And since you can't re-license your themes to use a more restrictive license (because that would violate the WordPress license terms themselves), you're pretty much stuck in this situation.

The second way to make money is by using the Street Performer Protocol. The way this works is that you set a high bar for a price for the theme you want to release. Post teasers for your work where people will see them. Advertise the theme, perhaps show it in action (although this may lead to theft, so maybe not). Within the theme page, link to the sale page. The sale page would say something like this:

Contribute as much money as you want toward the purchase of this theme. When I reach my goal of $XX, I will release the theme to the public under the terms of the GPL so that anyone can use it, and I will send you an email telling you that the theme is now available.

When you get your high bar's worth of cash, release the theme. What's nice about this is that you're completely GPL compliant, and you've sold your theme in a safe way. Even better, you can still offer support services, as with the prior option.

There are services that help enable this method of selling so that you don't have to do it all yourself, and can even refund people's money if they don't reach the bar.

This is a much better model than debating whether GPL necessarily applies to CSS, HTML, and images. It gets money paid for work as if it was done for a contract, but allows you to build work in advance and benefit the community as a whole after you get your just payment.