An Apprenticeship Assessed

It’s been an exciting ten months working alongside the Nerds at INN. I’ve learned a lot since I started and had the opportunity to work on a lot of exciting projects in the process.

In particular, I built out two WordPress plugins designed to interface with Google’s tools for publishers. The first, DoubleClick for WordPress, serves DoubleClick for Publisher ads without dealing with the underlying ad codes. I later added built in targeting, making it easier for a small organization to sell and manage inventory without dealing with code.

The second, an Analytic Bridge for WordPress, connects with Google Analytics to pull and cache metric data for use. It’s currently used to run the popular posts widget on member site Nonprofit Quarterly.

I also did some early work integrating unit tests into our development process and built another WordPress plugin to serve quizzes in post sidebars. More recently, I rewrote a significant amount of our Link Roundups plugin (formerly known as Argo Links) to get it ready to submit to the WordPress plugin directory.

Between these projects I spent some time learning the nuts and bolts of Largo and work on a number of bug fixes and new features for the most recent releases. I also worked on a handful of help desk tickets and consulting related projects as the team got busier.

In the process I learned an invaluable amount about WordPress best practices, especially when creating plugins and building extendable themes. I also learned a significant amount about Google’s APIs, which offer an incredible amount of functionality, but not without a lot of time investment.

When I started my apprenticeship or daily scrum hangout consisted of only myself, Adam and Ryan. There’s at least eight faces in our morning meeting now, an incredible indication of how quickly the team I’m leaving today has grown.

As I start a full-time job building healthcare software for Epic Systems in July, I have every bit of confidence this team will continue the fantastic work happening now and deliver some truly powerful tools to non-profit newsrooms of all kinds.

I won’t be joining those morning scrum meetings anymore, but hope to still contribute a pull request or two from now and then. You can follow me on twitter @willhaynes, or send me an email at I’m always happy to talk.

Nerd Alert Issue 25: We think you’re pretty cool

(Remember, we're hiring!)

Hot Links

What we're reading this week

  Adam: DataMade’s Cathy Deng has some fantastic tips for writing documentation or communicating about technology generally. Which reminds me... if you love writing documentation, you can join our team and do it full-time.

  Ben: Remote work comes with its share of difficulties, such as meeting across time zones, keeping up-to-date, and maintaining a culture. Pajamas.iois a series of interviews with people who work remotely, and some advice on how to do it. Sometimes, they wear pajamas.

  Dani: Make stunning, CSS-customizable maps with Tilemill, a lovely Mapbox tool with awesome documentation.

  David: A door as a design metaphor for software. If only all navigation was so intuitive.

  Kaeti: White space is not just an aesthetic choice — it influences comprehension, alters user behavior, and directs attention to the most important elements on a page.

  Meredith: The Superscript Conference: Arts Journalism and Criticism in the Digital Age is being held May 29 and 30th in Minneapolis, with panels discussing credibility, the role of nonprofit publishers, the impact of platform on community building and cultural response. The conference is offering those not able to attend a number of ways to follow along including: a livestream, a live transcript, and the blog mentorship program.

 Nick: What will happen when the 3.5 million human truck drivers in the US are replaced by robots?

  Ryan: In copyright news — since software has become an integral part of motor vehicles, and manufacturers own the copyrights for said software, GM posits that “owners” are really only licensing the right to use the car and its software when purchasing a new vehicle. Read more about the potential consequences for car enthusiasts, independent mechanics and car owners here.

  Will: This Wired piece titled “Not Every Product Needs to Be Beautiful” makes a lot of good points about maximizing limited resources as a small team (in this case, design) to focus on the right things at the right time. It’s also a reminder that good product design is about far more than pretty pixels and css.

  Bert: Practicing my hurdles.


Work we admire by out journalism peers

We're big fans of Sunlight Foundation's data-driven projects, including theirnew campaign fundraising tool. The code, of course, lives on GitHub.


Some other stuff

Gather ye rosebuds

LISTEN: Here's some country soul for your soul.

COOK: Throw some chipotle-mango chicken on the grill this weekend.

WATCH: What happens when Daft Punk meets the Charleston? This, of course.

GIF: Rawr.

Nerd Alert Issue 24: Unofficially summer

Happy Memorial Day, y'all!

Hot Links

What we're reading this week

  Adam: Aaron Williams, a developer at the Center for Investigative Reporting, has a great roundup of open source tools for expediting news graphics, including a walk through of the workflow they use at CIR.

  Ben: North by Northwestern’s Housing Guide is a guide to the dorms at Northwestern University, run by the campus independent newspaper. It’s updated by students, but the best thing about it is that North by Northwestern put the code behind it on GitHub, for any and all campus media to learn from.

  Dani: With most online technical guides aimed at the hard sciences, theProgramming Historian compiles technical resources for people in the social sciences and could be a good starting guide for journalists and news teams.

  David: Medium is adapting to become less of a blog network and more of a network like Twitter. New tools launched by Medium lower the barrier to participation, but Mathew Ingram explores how this could further dilute the culture Medium worked so hard to establish.

  Kaeti: This discussion of when and how to use relative vs. absolute timestamps will be of particular interest to the many publishers we work with.

 Nick: What will happen when the 3.5 million human truck drivers in the US are replaced by robots?

  Ryan: Royal Society Open Science published a study from a group of researchers in London charting the evolution of popular music. With their algorithm, they determined that pop music of the 1980s "became most homogenous period in music over the last 50 years" and rap and hip-hop "kicked off the most recent surge in musical diversity" in the early 90s. Read the full study here.

  Will: Nieman Lab published a letter sent to Quartz staff calling the platform, among other things, "an API." Similar arguments have been made calling BuzzFeed a "tech company." I think there’s a lot to gain from looking at media from this perspective.

  Bert: Cleaning up California's Coast.

We made a thing

What we're reading this week

New and improved documentation! Ben and Ryan attended a Write the Docs conference early this week making significant progress to our documentation framework.

Shout Out

Work we admire by our journalism peers

A shout out to the other projects that joined us this past week for OpenNews code convening in Portland. Thanks for the support and inspiration. Working alongside you was great fun.

Some other stuff

Gather ye rosebuds

LISTEN: Through NPR’s full archive of First Listen programs.

COOK: Coconut Cream Pie. Mmm.

WATCH: How to keep your dog amused.

GIF: Have a great Memorial Day!

Nerd Alert Issue 23: Join our band?


I for one like Roman numerals.

Hot Links

What we're reading this week

  Adam:Time is the raw material of creation.” A great reminder to sometimes say no to things to protect your time and stay focused on the work you are best suited for. (one of the reasons we fight so hard to avoid unnecessary meetings)

  Ben: Ever wondered why computers handle images differently than your eyes do? Scott Sievert explains how computers store colors and how they blend.

  Dani: As a machine learning and social experiment, Microsoft released how-old, an age-detecting web app. The company assumed, in the age of privacy infringement fears, that people wouldn't want to put their own images up. But, at least half of the people who used the app - including some members of the INN nerds team - uploaded their images to see how old an algorithm thinks they are. Social media burst with tweets and posts regarding the inaccuracy of the algorithm, calling it (and Microsoft) a jerk! But an algorithm is only a mathematical model with as much power as we grant it.

  David: What is your brand's animation identity? As I jump in on style guide discussions at INN, I've been curious about the role of animation in guiding users through news products and establishing identity. This post oncreating easing curves for user interfaces is a good primer.

  Kaeti: This Dear Design Student column makes the point that working hard is better than talent, and I agree wholeheartedly. Design is a learned skill. It's about practice and solving problems and, most importantly, communication.

  Meredith: Thoughtful user feedback can help  guide the development of news apps. An NYU student researched the NYT Now App, became a regular user and wrote this review.

 Nick: On the cusp of becoming a parent, I have been thinking a lot about embodying the spirit of new beginnings and childishness. I especially like the concept of Beginner’s Mind in the context of Zen.

  Ryan: From Jon Peterson, an interesting post on roleplaying games, fantasy fiction and their part in the history of the internet. Read how the emergence of RPG's and fantasy fiction mislead the FBI and ultimately contributed to a more open web.

  Will: A fellow student of mine at the University of Wisconsin was recently interviewed by Poynter about his experiences as “a (formerly) pissed off journalism student.” He’s got a lot to say — both good and bad — about being a student in the ever changing field of journalism.

  Bert: Out of office on a road trip.

We made a thing

Our projects, manifest

Busy week!

First of all, a reminder that we’re hiring! Looking for someone obsessed with documentation and customer support to join the team and help us improve the way we support our members, clients and users of the products we build.

In other news, we’re excited to see Twin Cities Public TV piloting the WordPress plugin we built for the Public Media Platform.

We also spent some time this week doing some spring cleaning in our team docs repo, and added new sections on using Git, how to write a great pull request and how our team approaches giving (and getting) constructive feedback.

Finally, we have two team members moving into new (larger) roles this week: Ryan Nagle is our new Director of Technology and Ben Keith, who joined us about a year ago as an intern, is now joining the team full-time. Coincidentally, Ryan and Ben will also be attending the OpenNews Code Convening and Write The Docs Conference next week to work on improving our Largo developer documentation.

Some other stuff

Gather ye rosebuds

LISTEN: How 'bout some Bychkov?

COOK: Tacos for breakfast, lunch, dinner and dessert.

WATCH: Have you seen The Blues Brother's (this week?). It's on Netflix.

GIF: "Who did this to me?"

Nerd Alert Issue 22: Calling all cool kids


(Psst, we're hiring!)

Quick Links

What we're reading this week

  Adam: As someone who used to work a lot with audio, I’m really excited to see the resurgence in podcasting that’s been happening recently, but I’m especially excited about the possibilities of using audio in interactive pieces that live in the browser. For a great overview of the current state of in-browser audio, Tyler Fisher (from NPR’s visuals team) has a great rundown of what they’ve learned.

  Ben: `git blame` tells you who last changed a line of code, but what if you want to see how that line has evolved over time? Try git’s line log search. You can see the history of a function with `git log -L :function_name:path/to/file.txt`

  Dani: The New York Times visualizes the Best and Worst Places to Grow Up, a map of US counties, income mobility, and poverty. This tool is a great example of how visualization and data analysis can be used to track and tackle social issues.

  Kaeti: This week I took a moment to reread our team manifesto. It was a good reminder of why we’re doing this work and what we’re striving to be.

  Meredith: One of the most successful children's book authors, John Green, shares a a few ideas about measuring love and distractions.

 Nick: Are you one of those nerds who loves finding a “shortcut” to solving a problem that ends up taking an order of magnitude longer, but is somehow deeply satisfying nonetheless? Check out this write up on using Mathematica for finding the optimal search strategy in Where’s Waldo? books.

  Ryan: IPython notebooks now render inline on Github. Take advantage of this great education and documentation tool!

  Will: This week I discovered the scrapers behind Sunlight Foundation’s Open States Project. If you’re anything like me and you like to see how curated data is collected — or you want to build your own scrapers for government data — check it out.

  Bert: Someone build me some wings!


Work we admire by our journalism peers

DocumentCloud announced a new version of their WordPress plugin this week, with support for shortcodes, and oEmbed support for Document Cloud docs.

Some other stuff

Gather ye rosebuds

LISTEN: Make your own tunes this week.

COOK: Cheesecakedillas sound delicious.

WATCH: Typeface. A 2009 documentary centered around the Hamilton Wood Type and Printing Museum in Two Rivers, Wisconsin.

GIF: Oh boy oh boy oh boy oh boy.

Nerd Alert Issue 21: May Day, May Day!


May is here! Hope your week's weather forecast is as happy as this.


What we're reading this week

  Adam: Some great lessons for news organizations from this article on “content-first design” by Steph Hay, one of my favorite bits: “The goal of the prototype is to write the conversation we want to have with someone, then design an experience that best brings that conversation to life, no matter the technology.” What would it look like for news organizations to start the design process by thinking about the conversation they want people to have about their stories instead of the typical homepage, article page, etc.?

  Ben: Is CSS programming or isn’t it? Harry Roberts makes the case for thinking about CSS as a gigantic collection of IF statements. And that’s enough to make me reconsider how I write my stylesheets.

  Dani: A good tip from yhat: 11 Python libraries you might not know.

  Kaeti: As we start building our own style guide, we are thinking a lot about how it will work. This article is a helpful breakdown on how a style guide or pattern library can fit into your team’s process. We’ll aim for hippie colony and see how it goes. (And, as usual, it’ll be open source and we’ll share what we learn along the way.)

  Meredith: Both leaders and citizens are using data to impact change.   Cincinnati, home of my favorite fictional radio station is launching CityStat to move toward positive outcomes, and Emanuel Feld used data a to create a call to action to plant more trees in his neighborhood.

 Nick: You only have to know one thing: you can learn anything.

  Ryan: Tyler Fisher's Source Post Audio in the Browser: Horrors and Joyshas leveled up my knowledge of web audio, making sense of the cloudy world of browser support and (usable) third-party libraries. This is particularly relevant to my interests as I continue work on the PMP WordPress plugin.

  Will: Despite how much technology goes into building a car, it's incredible how closed the software that runs them can be. Rumors suggest Tesla may be allowing hackers at Defcon to "tinker" with their vehicles this year — a bold push to opening their systems and building better cars. As a related bonus, if you've never read "The State of In-Car UX" not much has changed since it was published last April.

  Bert: Do you even lift?

This week's guest contributor: Sean Kirkby, reporting intern at the WCIJ

Long-form stories and data visualizations have their perks, but art can also provide an effective window into controversies. That could be reporting about people giving away personal data — including the last four digits of their social security number — for actual cookies at a New York arts festival. Or it could be a road trip with half a cow, 1,000 balls of wool and other sculptures that reflect investigative reporting on water issues.

Each week we ask someone from outside our team to contribute a link, tool or idea. Are you our next guest star? We think you might be. Send us a note at


Our projects, manifest

We're excited to announce version 0.2 of the Public Media Platform WordPress plugin. Read the release docs here, the readme here and read about what else happened at PMP this past month.


Gather ye rosebuds

LISTEN: Listen to all of Wikipedia's recent changes. More soothing than you'd think.

COOK: Try this recipe for Lemon Caraway cookies. Literally pulled from my grandma's recipe box.

WATCH: All 43 Foundation episodes — a podcast where tech entrepreneurs spill the beans on their successes and failures.

GIF: Slow and steady.

New Plugin — Easier DoubleClick Ads for WordPress

This week we’re happy to announce a new WordPress plugin to make serving DoubleClick ads easy.

In the past we’ve used (and will continue to use) Automattic’s ad code manager to control ad tags. This plugin comes with a plethora of options, including support for different providers. While its fine for some users, for most of our applications it’s downright unwieldy.

We designed our plugin to be lighter-weight and to work out of the box with as little setup as possible. The minimum needed to start serving ads is to define your network code and place a widget in a sidebar. Then you set options for the DFP identifier and size of the ad spot and that’s all there is to it.

Responsive ads

It’s easy to serve different size creatives at different breakpoints. For example, in a leaderboard spot, it’s possible to add one widget to display 300x50 sized creatives on mobile and 728x90 size creative on tablets and desktops. Only one will be loaded and counted as viewed in DFP, depending on the breakpoint.


This plugin sends information about the page to DFP to make targeting specific sections and pages of a site easy.

  1. inURL: Target a piece of the page path. (eg. targeting the string /dvd would match, and
  2. URLIs: Target the entire page path. (eg. targeting the string /books will only match and not
  3. Domain: Target based on the domain. (eg. run different advertising on and
  4. Query: Target a ?query var. (eg. target the url with the targeting string movie:12)

See the documentation for more information on how to set these values up in DFP. We’ll be adding targeting criteria for post category, post type, template type and other criteria specific to WordPress in the future.


If you don’t maintain widget areas in your theme, you can hard code breakpoints and places ad units directly in your template files.

Defining breakpoints is simple. We suggest you do this for users in your theme’s functions.php since most users will not know pixel values for the theme's breakpoints.

function ad_setup() {

   global $DoubleClick;

   // Optionally define the network code directly in functions.php.
   // $DoubleClick->networkCode = "xxxxxxx";

   /* Define Breakpoints */
   $DoubleClick->register_breakpoint('phone', array('minWidth'=> 0,'maxWidth'=>720));
   $DoubleClick->register_breakpoint('tablet', array('minWidth'=>760,'maxWidth'=>1040));
   $DoubleClick->register_breakpoint('desktop', array('minWidth'=>1040,'maxWidth'=>1220));
   $DoubleClick->register_breakpoint('xl', array('minWidth'=>1220,'maxWidth'=>9999));


To place an ad in a given location, just call place_ad on the global $DoubleClick object.

   // Places a 728x90 leaderboard ad for all breakpoints but mobile.

That’s it. We’re excited to see how you use it! Download the plugin from Github here.

My Apprenticeship With INN Nerds – Part 2

It’s been a little over four months since I joined the Nerds team at INN as their second software apprentice. With just about four months to go, now is a good opportunity to reflect and set goals before the end catches up.


News Quiz/Interactables. For one of my first projects, I wrote a WordPress plugin wrapper around Mother Jones’ news quiz library. During the process we talked about what a framework for registering and maintaining more interactive features in the future would look like. This Winter I hope to build out those ideas.

Unit Tests. Early on, I researched options for building unit testing into our theme development process and wrote about it here. Since then Ryan Nagle has built this into our deploy tools and written up some testing examples. Much of Largo still needs tests written, which I want to make a point to help with.

Analytic Bridge. Born out of a weekend project, I wrote a WordPress plugin that pulls and relates metrics from Google Analytic to post objects in the WordPress database. As a proof of concept, I adapted this into a Popular Post widget (a highly demanded feature by members), but the functionality could be used in a variety of applications.

I expect to work out the bugs and extend the features of this plugin in the next couple of weeks, as well as tweak the algorithm to make the popular posts widget ready for prime time.

Fixes/enhancements to Largo. Recently I’ve been picking up some tickets related to getting our Largo Project ready for version 0.4. Learning a lot about the codebase in the process, this Spring I’ll no doubt have the opportunity to contribute more.

Documentation. Documentation for Largo currently exists in three or four different places. Since the addition of our Support Specialist Meredith Melragon to the team we’ve doubled down on our efforts to keep and update complete documentation for both administrators and users.

Recently I’ve been working with Meredith to add python driven sphinx to our deploy tools. The benefits of documentation being versioned along with our code, yet accessible as compiled html means all our contributors have access to writing docs and end users have a single web source to find help. One of the biggest unresolved issues is how to incorporate our existing php block comments into these docs, a problem I hope to research and solve.

This kind of stuff sound like fun? Looking for something to do this summer? Find out how you could be INN's next software apprentice here.

Unit Testing Themes and Plugins in WordPress


Over the past few weeks, we’ve been investigating the best way to incorporate a WordPress testing framework into our development process. With few developers out there writing tests for their plugins (and even fewer testing themes), we want to share our tribulations as we figure the process out.

Fortunately, WordPress ships and supports a unit testing framework. Unfortunately, this framework is designed mainly for development on WordPress core and not directly for WordPress plugin and theme developers. However, with enough prodding, it is possible to write your own tests on top of this library.

Step one: Installing PHPUnit

The PHPUnit library provides a base framework for writing tests in PHP. WordPress develops its own testing platform on top of this library.

Assuming you’re on a *nix system, installing PHPUnit is as simple as:

chmod +x phpunit.phar
mv phpunit.phar /usr/local/bin/phpunit

See the PHPUnit installation notes for installing the framework on Windows or including it with composer.

Step two: Pull in the WordPress framework

Before we go any further, I should note that wp-cli ships with a handy command that does a lot of this grunt work for you. However, it currently supports tests for plugins only (not themes). If that’s all you need, it’s the fastest way to get started, but the steps below should give you a better understanding of what’s happening behind the scenes and give you a setup that can be customized for your specific development environment.

WordPress bundles its testing framework in with its core development tools svn repo. We can download just the tools we want by checking out the includes directory. It’s up to you where you want to organize your testing library. For the sake of this tutorial, we’ll assume you clone it into your root WordPress directory.

cd <wproot>
svn co

You’ll need a second WordPress config file named wp-tests-config.php as defined here:

Configure the database details as you would a normal wp-config.php. It’s important to use a secondary database, as WordPress drops and recreates tables as part of its tests. In addition, ensure that ABSPATH is pointed to the correct WordPress install to use during testing.

Step three: Hook it all together

What we do now is create a phpunit.xml file. This file is what PHPUnit uses to load the testing environment and run its tests. It doesn’t matter where you create this file, but for the sake of this tutorial we’ll add it to the WordPress root directory (the same place we downloaded the WordPress test framework).

			<directory prefix="test-" suffix=".php">./tests/</directory>

Now, if you run PHPUnit from the command line —

cd <wproot>

— you should see this on the command line.


If errors are thrown, check that your paths all point to the correct place.

Step four: Building tests

What we’ve got so far is the included framework that ships with WordPress. First, our phpunit.xml file is specifying a bootstrap.php file to load and install WordPress. Then, it's looking in ./tests/ for files in the format test-*.php to run actual tests. Since we don’t have any tests yet, no tests are executed.

This base configuration is only running tests on WordPress core functions. In order to test our own plugin and theme functions, we must create our own bootstrap.php file to specify which theme and plugins to activate before installing WordPress. Create a new file called ./tests/bootstrap.php. In this file, include the following:


require_once dirname( dirname( __FILE__ ) ) . '/includes/functions.php';

function _manually_load_environment() {
	// Add your theme …
	// Update array with plugins to include ...
	$plugins_to_active = array(

	update_option( 'active_plugins', $plugins_to_active );

tests_add_filter( 'muplugins_loaded', '_manually_load_environment' );

require dirname( dirname( __FILE__ ) ) . '/includes/bootstrap.php';

Update your phpunit.xml file to include this new bootstrap file, instead of the WordPress default.

Now you have everything you need to write unit tests on your theme. Create a new file named ./tests/test-sample.php and write your first test:

class SampleTest extends WP_UnitTestCase {
	function testSample() {
		$this->assertTrue( 'Your Theme' == wp_get_theme() );
		$this->assertTrue( is_plugin_active('your-plugin/your-plugin.php') );

Running phpunit now, you should see the following:


That’s it! You’re now able to write your own test functions to test your code.

Final words

It’s important to note that while this is one way to organize your testing code, it might not be the best for your development environment. You might, for example, prefer to keep your test suite (./tests/) in the root of a theme or plugin directory, so that it is included in version control. Or you might want to keep tests completely outside of the WordPress directory.

Diving deeper, you might want to activate and deactivate plugins directly in the testing classes to test what happens when plugins aren’t loaded. You might want to maintain multiple test suites for different plugins or themes.

Lastly, now that you are set up to write unit tests, you might be asking how you should go about writing a test. We’ll cover some unit testing best practices over the coming weeks as we write our own tests for our codebase. For now, take a look at some test classes that WordPress has written to get a feel for how tests are built.

Quiz Your Readers: Our New WordPress Plugin To Create Simple Quizzes

Today we're excited to announce a new embeddable interactive quiz tool built using Mother Jones' handy quiz tool but adapted specifically for the Largo platform and available now for any WordPress site.

[quiz key="0AvfAWkLLRik_dGtjRVNUamJwbE1wRWxtVVRURG1UU0E" layout="sidebar" answerstyle="alpha" align="alignright" title="Take the Quiz!" description="Think you've got what it takes?" source="Wikipedia" byline="Will Haynes/INN"]

Built on top of Mother Jones’ NewsQuiz.js library, this WordPress plugin allows you to build a quiz in Google Drive and embed it with a shortcode into a WordPress post. This could be used to test readers’ understanding of material, or just to expose them to the questions in an interactive way.

Grading of questions happens inline, at the bottom of the widget. Settings exist to control both the size and flow of the plugin, as documented in the project readme.

Try out the example quiz embedded in this post, or check out how INN member Youth Today is using it to support a piece exploring how the income gap affects scoring on college entrance exams.

To see how to build a quiz of your own using this plugin, how to format your Google spreadsheet, etc. please see Mother Jones’ documentation for the original quiz library.

We’re hoping to build more interactive features for Largo in the future.

So if you have an idea for what we should build next or suggestions for how to improve this tool, let us know in the comments or email us anytime at