The Life of Alex King

NB: This is in response to: http://alexking.org/blog/2015/08/24/rememberances. Alex King passed away on 2015 September 27 after battling cancer for more than two and a half years. Alex was one of the original WordPress developers, and leaves a lasting legacy and impact on the WordPress community.1

Dear Caitlin,

I met your dad at the 2009 WordPress Denver meetup, a “conference created for enthusiasts, users, developers, designers, and fans of WordPress“. It was basically a time to geek out with fellow programmers, developers, and bloggers. I must have know of Alex before I actually met him because I wrote this in my blog:

“It was also great to finally meet Alex King and most of the rest of his crew (Devin, Shawn, Sean, Gordon, and Jeremy) at Crowd Favorite. They did a great job organizing the event and without them this would have never gotten off the ground. I also think that if I ever got tired of engineering and wanted to do web development full time, Alex/Crowd Favorite would be the first person I’d talk to.

Interesting side note: Alex grew up in Seattle just around the block from me. Small world, eh?” (Source: https://andrewferguson.net/2009/03/06/wordcamp-denver-2/)

This was six years ago and I was just about to graduate from the Colorado School of Mines. I moved back to Seattle, not far from where Alex grew up, and have been working at Boeing as an engineer (still not tired of it). I have continued to follow Alex and have have some interaction with him over the years, mostly support related questions. We were, at best, acquaintances.

But that’s not the point. This is:

Over the years, there have been maybe — maybe — five or so people I would go and work for blindly if they called me up…Alex was one of them.

The importance of this sentiment cannot be overstated. There was something very special about him outside of the specialness I’m sure he had as a husband and a father. He was a strong, but humble leader who had vision. He cared about those around him in a way which was empowering and inspiring. And the world was better for it.

Alex actually did offer me a job (or at least an interview…it’s been a while since that conversation, so I may have mis-remembered). I turned it down because I was already committed to Boeing at the time. I’ve always had some regret over that choice — though regret isn’t quite the right word, more a sadness and frustration that I couldn’t be in two places at once.


Andrew Ferguson, PE

  1. Source: Rest in peace, Alex King 

One Site To Rule Them All

I’ve spent a good chunk of time this week transitioning AFdN from a standalone WordPress site to be part of the ferguson.pw WordPress Multisite cluster.

This is more cool for me than you because I now only have to manage one WordPress installation for everyone, rather than two or more installations. Huzzah!

Some lessons learned:

  • Multisite cookies are the suck. Towards the end of the migration I ran into an issue where draft post previews were not working. I started running through my checklist of things that could be the cause, but nothing made sense. I eventually created a new user — notandrew — to see it was an issue limited my “super-administrator” capabilities and to my surprise notandrew could see the previews just fine. So I nuked all cookies for ferguson.pw domain and lo and behold everything worked.
  • When migrating a Standalone WordPress site to a Multisite and mapping the domain back to the original URL you can use the following Nginx rewrite to prevent breaking anything1:
            #rewrite for WordPress single site to multisite
            location /wp-content/uploads/ {
                    rewrite "^(/wp-content/uploads)/([0-9]{4}/[0-9]{2}/.*)" $1/sites/$blogid/$2;

    Note: this is also predicated on using the Nginx Map{..} directive.

  • There’s a long standing bug with Nginx regarding the use of alias versus root. In the end I was able to use alias2 to host a special directory for TweetNest. Here’s the solution I ultimately arrived at:
            location /tweetnest {
                    alias /path/to/example.com/html/tweetnest;
                    rewrite  ^/tweetnest/sort /tweetnest/sort.php;
                    rewrite  ^/tweetnest/favorites /tweetnest/favorites.php;
                    rewrite  ^/tweetnest/search /tweetnest/search.php;
                    rewrite  ^/tweetnest/([0-9]+)/([0-9]+)/([0-9]+)? /tweetnest/day.php?y=$1&m=$2&d=$3;
                    rewrite  ^/tweetnest/([0-9]+)/([0-9]+)? /tweetnest/month.php?y=$1&m=$2;
                    location ~ \.php$ {
                            fastcgi_split_path_info ^(.+?\.php)(/.*)?$;
                            fastcgi_pass unix:/var/run/php5-fpm.sock;
                            fastcgi_index index.php;
                            include /etc/nginx/fastcgi_params;

I also took the opportunity to clear out some cruft and update some look and feel stuff: redish/orangish theme, update profile, etc. Nothing should be broken, but you never know. Enjoy your weekend.

  1. in theory 

  2. which I believe is the correct way 

Countdown Timer v3.0.6

Sometime in June of 2012 I released version 3.0 of Countdown Timer. Before that, the last major release was version 2.4 in April of 2010.

I’ve just been busy with other things1. The other reason was that the program had grown from it’s modest roots as a single 321 sloc2 program to a multiple files (80% PHP / 20% JS) with 1,450 sloc. Managing all the files, testing, and integration is — well — hard and not fun. And no one pays me to do it.

It’s taken some time, but I’ve more or less completely redesigned how I develop PHP. I’ve switched to using Aptana, Git Hub, and FirePHP — a PHP integration into FireBug. This was a multimonth project to slowly learn a new way of developing, but it’s been fun! I just spent most of May 2012 essentially rewriting how Countdown Timer works. All the logic is ultimately the same, much of it was converting function and variables into appropriate classes. I’m somewhat particularly happy about being able to extend the DateTime class and use that, although the lastest bug fix release (v3.0.6) was released because of my new found hatred for the DateTime class.

Another big change from 2.4 was taking advantage of some of WordPress’ core i18n3 updates which make handling date and time information a bit easier. Version 3 (and the subsequent dot fix updates) haven’t been a big flashy update, things are more or less where you left them, but you should hopefully see some little things that make you smile and make your life easier. It’s always a challenge to keep making something truly better, but I still have a couple of things I want to implement. However, Countdown Timer is on GitHub and WordPress TRAC, I don’t want this to be code that’s hidden in a cave, so please fork, patch, push and pull away.

Anyway, version 3.0.6 is now out. It fixes some crazy bug with that developed sometime after PHP 5.2 was released that caused the “white screen of death.” There were three issues that I found:

  • WordPress is calling the sanitize callback twice…not sure if this is new behavior or not, but it was breaking things because the second time it was being called it was trying to sanitize a different type of input. I’ll probably need to rewrite the sanitize function in the future.
  • The DateTime class has been expanded and some of the new functions clashed with stuff I had written. PHP can’t overload functions, so instead it just barfs.
  • For some reason, if certain, presumably optional, methods of the new PHP DateTime class are missing, PHP will also barf. In particular, date4, timezone_type5, and timezone.

Anyway, several hours were spent backtracing the errors and providing suitable fixes. So, enjoy!

As per tradition:

Read more or download version 3.0.6!

Also, please consider that I spend several dozens hours making updates for each release…have you donated recently?

  1. which is to say that Countdown Timer has been pushed lower down my priority list 

  2. source lines of code 

  3. internationalization 

  4. which was never supposed to be exposed 

  5. also maybe a bug? 

Milestone for WordPress self-hosted v0.9

The website I made for Rachel and myself is, of course, run on WordPress. After looking through some themes, I eventually settled on the Forever theme. Forever is a WordPress.com theme, but can be downloaded via SVN from
https://wpcom-themes.svn.automattic.com/forever/1 so someone can use it on a self-hosted WordPress installation. Everything was going great, but I couldn’t find the plugin for this really neat widget they have that counts down to The Big Day:

It’s called Milestone and as of January 2012 it was supposed to be included in a future release of Jetpack, the official WordPress plugin for things of that nature.

But here we are in August and there’s no plugin.

And I don’t know what the timeline is for actually releasing it.

So I did what any engineer would do when they don’t want to wait, I made my own version. There’s decent enough documentation on the backend and the front end is just stylized with CSS. It’s a pretty simple implementation and only took a few hours to crank out. There are some more things I want to add and tweak, like adding a drop down calendar select and better input checking, but it will work for now.

Here’s how it looks:

Milestone clone

It’s a quick solution that I hope others will enjoy too. I also got a chance to try out using a deploy script to help automate the push from GitHub to SVN. This could help a lot of things go smother.

Read more or download v0.9!

  1. svn co http://wordpress.org/extend/plugins/milestone/ 

Using Shortcodes in the_excerpt

I was working on a project for a client that requested using shortcodes in the_excerpt:

From codex.wordpress.org:

Displays the excerpt of the current post with […] at the end, which is not a “read more” link. If you do not provide an explicit excerpt to a post (in the post editor’s optional excerpt field), it will display an automatic excerpt which refers to the first 55 words of the post’s content. Also in the latter case, HTML tags and graphics are stripped from the excerpt’s content. This tag must be within The Loop.

You’ve probably encountered this functionality when you’ve done a search on a WordPress site or viewed an archive, the post will often end in “…”

From a programming standpoint, there was a point in time where if you wanted to have shortcodes used in an excerpt for WordPress, all you had to do what include this in your code1

add_filter( 'the_excerpt', 'do_shortcode');

However, I found out that at some point in the last few years since I tested the above system, the way in which WordPress process shortcodes has changed. I poked around a little bit in the WordPress TRAC, but didn’t see anything that would explain it. I suspect it might be a filter order, but I’m not sure and I decided that investigating the root cause at this point wouldn’t make a difference (although I would like to find out eventually).

Here’s what I learned and how I solved the problem.

When you have not provided an explicit excerpt, WordPress creates one via wp_trim_excerpt2:

function wp_trim_excerpt($text = '') {
	$raw_excerpt = $text;
	if ( '' == $text ) {
	$text = get_the_content('');
	$text = strip_shortcodes( $text );
          $text = apply_filters('the_content', $text);
          $text = str_replace(']]>', ']]>', $text);
          $excerpt_length = apply_filters('excerpt_length', 55);
          $excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
          $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
      return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);

The way wp_trim_excerpt gets called is not super intuitive, but looks like this:

the_excerpt3 calls get_the_excerpt4 via filter hook

wp_trim_excerpt is hooked into get_the_excerpt via a filter hook defined in /wp-includes/default-filters.php5

A quick glance at the code for wp_trim_excerpt reveals that strip_shortcodes is run immediately after getting the content of the post. Also, there is really no way to filter this out easily unless you rewrite the entire function, which is what I did:

remove_filter( 'get_the_excerpt', 'wp_trim_excerpt'  ); //Remove the filter we don't want
add_filter( 'get_the_excerpt', 'fergcorp_wp_trim_excerpt' ) ); //Add the modified filter
add_filter( 'the_excerpt', 'do_shortcode' ); //Make sure shortcodes get processed

//Copy and paste from /wp-includes/formatting.php:2096
function fergcorp_wp_trim_excerpt($text = '') {
	$raw_excerpt = $text;
	if ( '' == $text ) {
		$text = get_the_content('');
		//$text = strip_shortcodes( $text ); //Comment out the part we don't want
		$text = apply_filters('the_content', $text);
		$text = str_replace(']]>', ']]>', $text);
		$excerpt_length = apply_filters('excerpt_length', 55);
		$excerpt_more = apply_filters('excerpt_more', ' ' . '[...]');
		$text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
	return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);

So there’s the solution. It’s definitely a bit longer than the way it used to work, but it should do just fine.

  1. functions.php or elsewhere 

  2. WordPress 3.4.1: /wp-includes/formatting.php -> line 2096 

  3. WordPress 3.4.1: /wp-includes/post-template.php -> line 240 

  4. WordPress 3.4.1: /wp-includes/post-template.php -> line 258 

  5. WordPress 3.4.1, line 147: add_filter( ‘get_the_excerpt’, ‘wp_trim_excerpt’ );  

Servers Moved

I’ve been moving around some of the technological assets under my control. I completed a Registrar switch in May. I’ve been working the last month to move servers. I’m still with BlueHost because they are great, I just moved to a box with fewer people on it (i.e. less resources to share). I also get my very own IP address and SSL certificate!

I just completed the switch of AFdN (which was the last asset on the old server) this afternoon. Everything should be okay, but if not, please let me know.

For those interested, here’s what I did (over SSH from the new server):

ssh old_server.com 'cd ~/www/; mysqldump -u username -p mysql_wp > dump.sql;'
rsync -av --exclude 'notthisfolder' -e ssh old_server.com:~/www/ ~/www/.
mysql -u username_new -p mysql_wp < ~/www/dump.sql
rm ~/www/dump.sql

Some resources I used:


Calculating Downloads

I recently hit 70,000 downloads on Countdown Plugin, a small plugin I wrote for WordPress about five years ago. Actually, the timer is older than that. I’ve only been using WordPress since my freshman year of college (spring semester circa 2005), before that I had this crazy home brew content management system. Part of that system included the original source of Countdown Timer. When I made the move to WordPress, I forked the code and made it into a WordPress plugin. The basic and display of the timer has remained relatively similar, although the code has pretty much been rewritten.

Download stats with 10- and 40-day moving averages

I digress. Having 70,000 is a great accomplishment. However, it’s not a very telling metric. What I really want to know is how many people are using the plugin currently?

In order to get an idea of how many active users there are, I looked at two pieces of data:

  • Temporal downloads prior to my last release
  • Temporal downloads subsequent to my last release

The theory is that when a new update is released, an upgrade notice goes out to all users of the plugin. This is the cause of the massive spike in downloads. By eliminating the background noise downloads (i.e. people just trying it out), I can calculate the area under the curve and get a rough estimate of the number of users.

I fit a power regression line to the subsequent downloads with an R2 value of 0.83, which is a little lower than I would have liked, but still usable, described by the equation:615.16x^{-0.481}

The average downloads for the 24 days prior to the release were 81.375 downloads/day. Using WolframAlpha, I solved for the intersection of the two lines:
x = \frac{308915776 \cdot 26^{114/481}}{5405625 \cdot 5^{76/481} \cdot 93^{38/481}}\approx 67.0498

The bounds of my function are now 0 (the day that the plugin was released) and 67 (the day the plugin will again be at ~81 downloads). It’s just a mater of integrating the function and subtracting out the base downloads:

\left (\int_{0}^{67}615.16x^{-0.481}  \right ) - \left (81.375\cdot67  \right ) = 5056.675

5,000 seems to be about the base number of users at this point. It will be interesting to see how this number changes over time. Especially since I have the historical data and could analyze how long it takes downloads to return to normal.

5/11/2010: Here’s the data I used: downloads.csv


Countdown Timer v2.4

Just over a year ago I released Countdown Timer v2.3.5. I’ve had the fortunate opportunity to participate many great things over the last year, which is probably why there hasn’t been an release since.

Anyway, I’ve been slaving away at this release for the last three weeks:

Weeks of 2010 - Blue = Internet Applications (i.e. Chrome, Firefox, IE); Red = Development Applications (i.e. Dreamweaver); Tan = Utilities (i.e. PuTTY, FileZilla, etc)

Weeks of 2010 - Blue = Internet Applications (i.e. Chrome, Firefox, IE); Red = Development Applications (i.e. Dreamweaver); Tan = Utilities (i.e. PuTTY, FileZilla, etc)

I probably spent close to twenty hours, committed over 50 revisions, and had 865 lines changes in the core code1. For all this change behind the scenes, you expect to see some changes in the actual interface. Amazingly not.

Most of the work had to do with bringing the code up to WordPress 2.9/3.0 standards. This will ensure that this plugin continues to work well in to the future. As well as trying to keep up with best practices for WordPress Plugin coding.

The other major update dealt with adding CSS hooks to the html elements so that they can be customized better/more fully. In doing this, I also rewrote part of fergcorp_countdownTimer_format to make it less repetitive. This, unfortunately, caused a minor issue with using the [fergcorp_cdt_single date="ENTER_DATE_HERE"] shortcode that has the li-element included; I’ll fix that in a dot-dot release (i.e. 2.4.1).

The settings for Countdown Timer moved the WordPress Tools to Settings in the Admin Menu and you only need to be an Options Manager instead of Administrator to update the options. I think the only other change worth mentioning is that there is now an option to parse shortcodes in the_excerpt. Note that enabling this functionality will parse all shortcodes, not just ones related to Countdown Timer.

As per tradition:

Read more or download version 2.4!

  1. There’s only 1000 source lines of code [SLOC] to begin with, so this is sort of substantial