WordPress.com hits on Tumblr on Twitter

This happened:

WordCamp Seattle Contributor Day

Over 60 developers, designers and documenters came out on a beautiful Sunday to learn and make WordPress better. This is an amazing community, and it’s always such a pleasure to see it in action.





What I’d learn if I were starting over today as a web developer

Lately I’ve been thinking of how much things have changed since I got my start on the web in the late 1990s/early 2000s, and in particular how things have changed for the beginning developer from then to now.  Nowadays, the n00b faces a huge and growing array of choices — languages, frameworks, version control systems, hosting and deployment services both on the cloud and off.  Starting out is both hard (paralysis of choice) and way more exciting than it used to be.


In 1998, if you wanted to learn how to build things online your choices were  limited.  For most of us who operated outside the world of Microsoft (which btw was enjoying the peak of its dominance at the time), this meant learning some combination of HTML, perl/PHP/C, and a relational database like mysql — and of course the apache web server.  JAVA was also increasingly popular on the web at the time, and if you were learning web development in an enterprise setting, you might well have learned that instead.  Everything else was a kind of bonus:  JavaScript was too immature to be called essential, and although the CSS standard was defined in the mid 1990s it was at this time still very poorly supported by browsers (I indeed only learned CSS in the early 2000s, thanks to Eric Myer’s classic book.)  At that time, JavaScript developers were still regarded as  the tricksters of the web — people who could make web pages do funny but rather non-useful things, while the early acolytes of CSS were considered frustrated idealists whose time may or may not ever come.

Flash forward to now.  Here’s where I’d start if I were starting over:

1.  JavaScript
Perhaps the most profound change from that era to this is has been the explosive growth of JavaScript.  This in turn as given rise to the huge tidal-wave of frameworks that have appeared on the scene over the last  8-10 years.  For me, the first real sign of JavaScript’s permanence was the emergence of jQuery in 2006/2007, but nowadays it’s frameworks like Google’s angular.js that have further accelerated the pace of change.  Ever since jQuery, developers have become used to yanking around the DOM and writing asynchronous apps, but the current crop of frameworks are beginning to absolve the developer of the responsibility, need and even ability to track the state of the underlying permanence layer, and have tilted web development away from the transactional apps of yore and toward the idea of the single-page app.  How data gets from the browser to the server, thence to the database and thence back from it and to one or more clients — all of this is largely brokered behind the scenes by the JavaScript framework, and no longer requires the same kind of attention from the developer.  This set of issues (application state, client to server communication, how databases were reading and writing etc.) used to be the bread and butter of web development … but increasingly these interactions just sort of “happen” if you use and develop on the frameworks in the right way.

There’s more to say about this of course (I’m way oversimplifying.)  And of course there’s also the whole issue of  node.js and the as-yet-still exploratory invasion of the server by JavaScript, a territory traditionally reserved for the P-languages — PHP, perl, Python etc …  We’re at the point now where you can run the same JS application ob both the client and server … same code.  All this is to say that the world has changed in a pretty huge way.

And so, the first thing I’d do (after learning basic markup and CSS skills) is learn JavaScript from the ground up.  For many developers of a certain age, like me, a remedial education in the fundamentals of the JavaScript language and its implementation in the browser has been necessary (for which, btw, there are a couple of really good resources.)  I believe that for new devs, it’s probably where the action should begin.

2.  node, jQuery, Angular.js and perhaps a JS meta-language.

Node is JavaScript’s server-side colony, and it’s thriving.  I’d learn it as soon as I could as a new developer, and deploy it in place of a LAMP or similar stack.

On the client, there are a ton of frameworks out there, and far be it from me to elevate one over the other … that said, I think jQuery is an essential tool nowadays, and I’d learn it early in my career if I were starting today.  Same goes for Angular or another of the very new frameworks.  I’d also get to know at least one JavaScript meta-language like CoffeeScript (ie:  something that compiles to JavaScript.) because I think people will become increasingly intolerant of JavaScript’s at-times-annoying syntactic qualities.  Here’s hoping that one of these frameworks (perhaps it will be CoffeeScript) will emerge as a kind of standard.

3.  HTML5, CSS3 and one of SASS/LESS/Stylus etc.

Not much to say here — there’s no doubt that you still need skills like these to make stuff on the web.  In fact, correct, syntactic markup is far more important now than it ever was when I was starting out.    As a n00b, I’d want to quickly transition from writing vanilla CSS to a framework like LESS.  Clearly some of what CSS3 and HTML5 can do has yet to come fully true in all browsers, but depending on your audience, it’s worth using them anyway.


One must be able to manipulate the persistence layer — to store and retrieve data.  That’s why I learned SQL in 1997.  Were I starting today, I’d delay learning that arcane art until I really needed it.  Instead, I’d want to become familiar with the JSON standard very early — which nowadays stands in for SQL in a whole bunch of contexts, and really can hardly be avoided.  Storing and querying data can now often be accomplished through encoding and sending an object in JSON to an endpoint of some kind.  This is particularly true in cloud contexts, with platform APIs,  and with so-called noSQL databases.  My main experience lies with MongoDB, but there are obviously many others.   There are certainly other ways to tie the persistence layer to the model  (Mongoose for node and mongodb is an example) … but a familiarity with JSON and its associated tools remains an essential tool in many many contexts these days where data retrieval and manipulation is required.

And … that’s it!  That’s where I’d start.  In fact, there’s no reason that with the skills I list above, one couldn’t build quite a career nowadays.  Sure, eventually you’d probably need to add at least one server-side language to this list — one of the P’s or else Ruby (though I think that’s a cult) … and perhaps SQL would still enter the picture before long … But even without these four items, (and with an underlying facility with *nix operating systems and git) a web developer could go seriously far in life.

I can’t help but reflect for a moment about what’s not on this list … basically everything that I learned early on … C++, PHP, perl, apache, SQL, mysql  …  Making a list like this is useful not only as a thought exercise, but perhaps also as an reminder of exactly how fast things are changing these days.

So … would you learn if you were starting over today?

Embed A MoveOn Campaign: New Plugin

MoveOn Petitions

It’s fun to actually get to write and release a WordPress plugin at work! I just finished the initial commit on the MoveOn Campaigns Plugin … a fun little plugin for embedding MoveOn Petitions in your blog or website.  A couple takeaways from writing this:

  • I was reminded that the use of a plugin code template is well worth it.  For a while now I’ve been using Daniel Convissor’s excellent template.
  • The WordPress widget API is extremely easy to use.  The basic technique is to extend the base widget class, which in most cases really only means implementing 3 functions and a constructor.
  • It can be tricky working with widgets with non-tiny minimum widths.  Every widget has a de facto minimum with   … but it seems that in at least some themes (2010,11,12) the sidebars assume somewhere around 210-30px as the maximum working width.  This means that any iFrames/content inserted into those columns will need to not exceed this, which for us required a bit of adjustment.

If you find yourself interested in this, you can  follow developent or contribute here:  https://github.com/mattoperry/moveon-campaigns

WordPress homepage settings trick: a simple, portable way to show a static homepage and a blog index

I’m sure there are quite a few ways to do this, but here’s the problem I recently encountered, and a solution.

I wanted to make an entirely portable theme with a non-standard (meaning not just a blog list) homepage, and a blog archive page (ie — an archive of all my posts) at a particular non-root URL — in my case http://www.something.com/blog.  I think this is a pretty common scenario, and the usual way to deal with it is to use the settings under Settings -> Reading -> Front page displays:

Screen Shot 2013-05-31 at 6.34.49 PM

So you’d create a couple pages, perhaps named “home” and “blog”, and use these and the home.php and front-page.php templates to create the desired effect.  But this solution did not make me entirely happy for a couple of reasons:

  • I find WordPress’ behavior under various combinations of these settings and various presences/absences of theme templates to be overly-complicated.  As you can see from reading about these settings, there are several combinations of conditions that can obtain, and the template cascade becomes a bit hard to describe in general.
  • Perhaps more importantly, I was going for portability here and did not want to require the presence of particularly-named pages for my URLs to work.  (Nor did I want the theme to create these pages on install — problems abound with that.)

Instead, I came up with the following solution, which I’m sure is not unique, but I’m quite sure is not really that well known.  (I’ll also note loudly that from a performance and technical point of view, it’s entirely possible that this technique may have various dark cosequences, and I welcome comments to that effect if I’ve overlooked something.)  

So here’s how to do this:

1.  Leave the Front Page setting on “your latest posts“.

2.  Include a front-page.php template in your theme.  This will always display when WordPress thinks you want the homepage.  In this template include the markup etc. for your homepage.

3.  Now the fun begins.  We need to trick WordPress into showing us the blog index page on a URL without using a page.  In my case, I use archive.php for listings like this, but in your case it might be something else, like index.php or whatever.  In functions.php, add the following code:

//set blog_index as a valid query variable
function add_blog_index_var( $v ) {
  $v[] = 'blog_index';
  return $v;

//use the archive template whenever blog_index is set
function set_blog_index_template() {
  if( get_query_var( 'blog_index' ) ) {
    include( get_template_directory() . '/archive.php' );

//rewrites for blog index
add_rewrite_rule('blog/?$', 'index.php?blog_index=1', 'top');
add_rewrite_rule('blog/page/?([0-9]{1,})/?$', 'index.php?blog_index=1&paged=$matches[1]', 'top');

//add filter for query var
add_filter('query_vars', 'add_blog_index_var');

//add action for template swap
add_action( 'template_redirect', 'set_blog_index_template' );

So what does this do?

We first write the add_blog_index_var to add the blog_index variable as a valid query var that will be retrievable by get_query_var() and set-able from the URL. This addition is done below by filtering add_blog_index_var. This is a required internal mechanism that WordPress uses to regulate what variables can make the leap from $_GET to the WP_Query object.

We then write a function called set_blog_index_template that forces the archive.php template to be used if the blog_index query var is set. This function is then attached to the action hook template_redirect.

The only thing left to do is to force WordPress to set this get variable at a particular URL … hence the two calls to add_rewrite_rule … one for /blog/ (in my case … it could be any URI for you) and one for pagination like /blog/page/2/ etc.

Remember to flush rewrite rules before expecting this to work. (See Daniel Bachhuber’s excellent Rewrite Rules Inspector plugin if you need to sort out just what’s going on with your rules.

I hope this is useful to someone out there — it took me a while to figure out a decent way to do this without supporting special pages or futzing too much with the homepage settings.

CodeWithMe Portland

So I’m at code with me in Portland this weekend.  Code with me is a great organization run by Tom Giratikanon and Sisi Wei that pairs technologists and journalists to spread the foundations of HTML, CSS and JavaScript.  Here’s a picture of everyone in the big  (windowless) conference room at the Oregonian.

Code With Me Portland

To understand what a dedicated group this is, you should probably also check out the current weather in Portland, which is — to say the least — spectacular.


Events like this (in foul weather or fair) are really exciting.  You’d think there would be more opportunities for journalists and technologists to not only spend time together, but also trade knowledge and work together.  But really opportunities like these (open, learning, semi-structured events with lots of project time) are pretty rare, and I’m grateful to be involved this weekend.  I’m also psyched to be working with two journalists: Evonne Benedict of King5 TV in Seattle and Rachel Alexander of Whitman College and Union-Bulletin News.  Much fun!

Annoying Robots and the Chameleon Botnet

Yesterday Spider.io announced the discovery of the Chameleon Botnet, a mega-collection of infected Windows machines, based largely in the US.  The purpose of the botnet is/was to generate large amounts of distributed, hard-to-detect traffic over sites displaying certain ads (or ads from certain networks), thereby generating bogus income via a network of 202 bogus content sites and defrauding advertisers out of something like $6 million/month.  The characteristics of the traffic of this botnet are suspciously similar to the sort of traffic I wrote about over a year ago when I worked at Grist.  In particular, the traffic instantiates JavaScript, identifies itself using a particular windows user agent, and is extremely homogeneous —  which is basically what we saw at Grist.  The Chameleon traffic differs in that it evidences real but apparently random mouse and click events:


image:  spider.io

 Random distribution of clicks and mouse traces over a square ad on an infected site:  image: spider.io

… and apparently were confined to the part of the screen containing the ad.

We’ll probably never know if the Grist phenomenon was of this sort, but I think it might be worth developing some sort of detector for botnets of this type if the possibility exists that they are affecting more than the small number that Spider.io’s report implies are affected by Chameleon.  It would seem to me that botnets of this sort have both an incentive and a disincentive to include non-target sites on their hitlist.  The incentive is simply that by including legitimate targets they obfuscate their scheme from advertisers to some extent (though it’s unclear if most advertisers directly review the distribution patterns of their ads through networks.) The disincentive is that targeting legitimate sites carries a risk of detection, though most sites would probably not notice if this were to start happening.

This was of great interest to me (and should really be to anyone who runs a site with significant traffic) because it’s the first public announcement of a botnet capable of running a complete client stack.

I would think that some analytics and advertising platforms like Google would be interested in understanding phenomena of this type better –I’d appreciate any links or info regarding countermeasures or detection of stuff like this.


Get every new post delivered to your Inbox.

Join 557 other followers