Comment on Greenpeace’s Planet 4 technical discovery findings

Greenpeace has been undergoing what seems to be a pretty open process in developing Planet 4, the plan for redesigning A series of posts have been published on Medium providing details on the discovery process and some of the decisions that have been made.

A few days ago, Davin Hutchins posted “Why Greenpeace and WordPress need each other“, which shares some thoughts on why WordPress is the right choice for a new CMS platform and how Greenpeace and the WordPress community share a similar set of goals in their respective domains.

A few weeks ago, Kevin Muller posted “Checking technical options, we discovered…“, which dives into the more technical details of the stack. This links to a pretty great slide deck that shows how much research went into the technical discovery process.

Both posts, and the process in general, are looking for input, so I’m going to toss out some initial thoughts I have in response after reading through all of that material. I’m going to start with the most reactionary first and then work my way through the mundane. 🙂

And to Greenpeace – Hi! I’m happy you’re moving forward with WordPress!

Customizing WordPress

The word “fork” comes up at some point in the technical discovery post and “customized version of” appears in Davin’s post. Those start raising a yellow flag for me. Not because I think forking is bad, as that’s the heart of free and open source software, but because I think it would be the wrong technical decision.

The WordPress core project has hundreds of contributors and ships 3 major releases a year. As soon as a fork happens, a maintenance burden begins. This maintenance burden grows as things are built into the forked version that do not make their way into the upstream project.

That said, having your own production version of WordPress managed in git makes complete sense. This is a common practice, and something we do with our multi-network multisite WordPress platform at Washington State University.

This provides the ability to test patches in production or release hotfixes while you’re waiting for contributions to be merged upstream. It also makes management of local, staging, and production environments easier across the team.

Multisite vs Single Site

This list of pros and cons in the slide deck is a good one. I have quite a bit to say about multisite, as I think it’s a good enough decision for something like this. I’ll break it down to a couple points:

  • If you foresee using the same set of plugins on every site, or making the same set of plugins available for every site, multisite is a good answer.
  • If it makes sense for a global set of users to have access to multiple sites, multisite is a good answer.

There’s always more detail, but those are pretty good initial gut checks.

I’d be less concerned about the performance issues. Today’s modern LEMP stack is pretty dang good at serving requests and from a maintenance perspective I’d rather manage one installation than many.

For reference, WSU’s installation of WordPress has 57 networks, 1500 sites, and serves about 2.5 million page views a month on one server. is a single installation of WordPress with many millions of sites, spread out across many thousands of servers.


The slide deck mentions a couple things. Here are a couple more (very much my opinion):

  • Use something for object cache, and get a good object cache plugin. See plugins for PECL memcached and PECL memcache.
  • Use Batcache for page caching before moving on to something more complex like Varnish. This uses your object cache to cache pages and is super straight forward.
  • HyperDB is worth paying attention to when using multisite. This will help you scale.


Don’t install too many plugins and be focused with the ones you do install.

WordPress is extremely extensible and has a great plugin ecosystem, but when approaching a project this large you’ll want to be sure that any plugin you install goes through a code review focused on security and performance. This also helps with developer familiarity when things go wrong.

Here are the basic criteria we use at WSU when vetting plugin requests.


The slide deck briefly mentions a REST API, but it’s not entirely obvious that it means the forthcoming WordPress REST API, which will be shipping next month in WordPress 4.7.

This should be a very useful tool in building custom applications that use data throughout the Greenpeace network. Use the built in routes and create your own custom routes rather than developing a new API on top of WordPress.


And (of course) the last important note is community.

At the very least, pay attention to the notes that are frequently published on Make/Core, the official blog for WordPress core development. As things move forward, raise bugs and enhancements, submit patches, etc…

The easiest way to reduce maintenance burden when extending WordPress is to be familiar with WordPress.

Everyone contributing to WordPress is also interested in the ways that people use and extend WordPress, so please keep sharing your work as you build Planet 4 out. And as Petya mentioned on Twitter, it’d be great to hear your experience at next year’s WordCamp Europe or any other.

Please feel free to ask for more detail if you’d like! 💚☮

Becoming a better WordPress Developer

I wrote this as a post for a friend a bit ago with the intention of cleaning it up to publish at some point. I kind of like the informality, so I’m mostly leaving it as is. Enjoy!

Reading core code was a big step in becoming a better WordPress developer.

I remember having a self realization moment a few years ago where I knew that if I reached a point where I never referred to the Codex to figure out how to handle something, then I had become good at this stuff. My self-test wasn’t necessarily that the arguments for register_post_type() are locked in memory, but that I know how to get the answer from core code.

My biggest step toward becoming more familiar with core code was the introduction of an IDE into my toolset. I prefer PHPStorm, but Netbeans is great and open source.

The ability to click on a function I was using to jump to the code in core has gone a long, long way for me. Having functions autocomplete and tell me what to expect in return has been huge in understanding how all the pipes are connected. I know not everyone loves that world and would rather spend time in a text editor, but I’ve been much more efficient since I switched from Sublime Text.

I guess at some point you transcend to Nacin level and have it all memorized.

Previously: Thoughts on Contributing to WordPress Core

My first contribution to core (which I talk about in that post), was a direct result from reading core code. We were pouring over different possibilities and a typo just appeared. Now that I’m familiar enough with the codebase, there are probably some areas I could stare at for an hour or two and find similar little nuggets. See the documented return value(s) in get_blog_details() as an example of a patch waiting to be discovered. 😉

And actually, now that I’m trying to think of more examples, read that post. The “Types of Trac activity in Jeremy’s perceived order of difficulty” is important. The tedious task of going through Trac tickets is more fun when you comment on things. And every time you comment on something you become more familiar. Testing and trying to reproduce outstanding bugs will go a long way as well. Once you have the patch applied locally, there’s a good chance you’ll see something to change.

And that’s where the advice cuts off. There’s plenty more, but reading core code alone will get you started. 🛩

How we’re using the WP REST API at Washington State University

As I write this, we have the WP REST API enabled for 1083 sites across 54 networks on our single installation of WordPress at Washington State University.

It’s probably worth noting that this only counts as one active installation in the repository stats. 🙁 It’s definitely worth noting how we use it! 🙂

Our primary use for the WP REST API is to share content throughout the University via our WSUWP Content Syndicate plugin. With the simple wsuwp_json shortcode, anyone is able to embed a list of headlines from articles published on

And just by changing the host, I can switch over and embed a couple of recent headlines from

Having the ability to share information across the University is very useful to us. It helps various groups and sites throughout the ecosystem feel more connected as visitors and as site owners.

Of course, we could have used a pre-existing syndication format like RSS as a solution, but a REST API is so much more flexible. It didn’t take much work to extend the initial plugin using things like register_rest_field() to support and display results from the central people directory we have in progress.

Jeremy Felt

That’s me, pulled in from our people API.

This kind of data flexibility is a big part of our vision for the future of the web at WSU. Soon we’ll be able to highlight information for research faculty that may help to connect them with other groups working on similar topics. We’ll have ways to create articles on the edge of the network and have them bubble up through the various layers of the university—department, college, central news. And we’ll be able to start tying data to people in a smarter way so that we can help to make sure voices throughout the university are heard.

And that’s just our first angle! One day I’ll expand on how we see the REST API changing our front end workflow in creative ways.

Thoughts on merging the WP REST API plugin

Daniel asked for official feedback from WordPress core committers on the REST API. Here goes. 🙂

I’ve been thinking a lot about this over the last week since last week’s status meeting. And I think I can sum up my thoughts in a nutshell now.

I’m in favor of the REST API team’s proposal to merge the endpoints for the primary objects in WordPress—posts, comments, users, terms—when they’re ready.

When the endpoints for these objects are ready, I would like to see them merged early in a release cycle.

With these primary endpoints in, front end workflows can immediately start to take advantage. This is something groups have been doing for years with custom code already. Getting these groups to use the same structure is valuable.

Exposing all of wp-admin via the REST API is important for the future. I would like to see more discussion from groups planning on creating these interfaces. Determining what the most valuable endpoints are for creating initial versions of these custom admin interfaces could help guide iteration while also allowing progress on those interfaces to begin. Ideally, there should be a wider discussion about what this all means for the default WordPress admin interface.

In general, I think these status meetings should happen more often so that any disparities of opinion are not as surprising to the community at large. A good definition of what “ready” means for each endpoint would be valuable as well.

Configure Nginx to allow for embedded WordPress posts

The ability to embed WordPress posts in WordPress posts is a pretty sweet feature from 4.4 and I’ve been looking forward to finding ways of using it throughout WSU. Today, when I tried it for the first time, I got an error because of our strict X-Frame-Options header that we had set to SAMEORIGIN for all page views.

To get around this, I added a block to our Nginx configuration that modifies this header whenever /embed/ is part of the requested URL. It’s a little sloppy, but it works.

Before our final location block, I added a new one to capture /embed/:

# We'll want to set a different X-Frame-Option header on posts which
# are embedded in other sites.
location ~ /embed/ {
    set $embed_request 1;
    try_files $uri $uri/ /index.php$is_args$args;

This sets the $embed_request variable to be used later in our final .php location block:

location ~ \.php$ {
    try_files $uri =404;

    # Set slightly different headers for oEmbed requests
    if ( $embed_request = 1 ) {
        add_header X-Frame-Option ALLOWALL;
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";

    # Include the fastcgi_params defaults provided by nginx
    include /etc/nginx/fastcgi_params;

Now, all URLs except those specifically for embedding are prevented from being used in iframes on other domains.

And here we are!

Still searching for Amelia


We’re hiring a WordPress developer at WSU and you should apply

You may have heard by now, through tweet after tweet after tweet—we’re hiring for a WordPress developer position at Washington State University.

If you have any inclination to apply, you should. We’d love to talk to you about what we’re doing and how you’ll help. I’d love to work alongside you and continue to build great things.

Here’s a brief list of random reasons why this is an excellent opportunity:

  • We do big WordPress and we’re not slowing down. We have a single multi-network installation serving over 2 million page views a month across almost 1000 sites. We have plans for that number to grow significantly in 2016.
  • We work in the open. There are 160 repositories in the WSU GitHub organization. All of our internal work—themes, plugins, the multi-network configuration—is open for sharing with others.
  • We power the university. As the central communications unit, we build sites and power WordPress for everyone. Things like,,,,,, and many, many more will be there for you to enhance and fix. And you’ll be given keys. (I broke all of it for 2 minutes just yesterday!)
  • You’ll be encouraged to explore and reach out. We have a campus thriving with people who are experts at what they do. The conversations you have with them will be inspiring and will lead you to ways to make our web presence more inspiring.
  • If you’re interested in contributing to WordPress core, we’re interested in you contributing to WordPress core. You’ll be encouraged to dive into issues rather than work around them so that fixes to WordPress (and other projects) can be applied upstream.
  • As a state employee, benefits are pretty fantastic. You’ll earn just over 4 weeks of vacation a year. 10 paid holidays, an extra personal holiday, a sick day per month, personal development time, great health benefits, matching 401k, the list goes on… 🙂
  • I will brew you beer. Michelle will make you sauerkraut. Steve will one day make you cheese. Jake will let you sit in with his grad students to learn crazy things about hydrogen. There’s a great community at WSU.

Time to apply! If you have any questions at all about the process or the position, please reach out:

Super Secret Expert WordPress Trac Tips

I thought I had a fourth earlier when I was thinking about this, but I guess not. Here are 3 super secret expert tips. There are probably others. 🙂

Attachment uploads don’t generate notifications

If a tree falls….

Even if you add a note when uploading an attachment to Trac, no notification is generated. Make sure to leave a new comment after uploading so that those subscribed to the ticket are aware of your work.

Auto incrementing attachment names

Someone told me this early or I saw it come through on IRC. Either way, I had no idea at the time and then I was very glad I was in the know.

If you upload an attachment with a filename matching that of an existing attachment on the ticket, the filename will be incrementally updated.

Example: 13237.diff will become 13237.2.diff because 13237.diff already exists. The next 13237.diff will become 1337.3.diff.

This makes it super easy to deal with patches locally. Diff your work to the a filename with the ticket number, upload, and boom!

There are two ways to link attachments, one is cooler than the other

This is a total matter of opinion, but Helen hooked me on it early. I have no idea how many others do this, but I do.

It’s easy to reference an attachment on a ticket by using syntax like this: [attachment:13237.2.diff]. This will create a link automatically with a fancy download icon in the web view that allows you to download the patch in just a click. However, in a notification email, it will appear as just that, [attachment:13237.2.diff].

It’s cooler to reference an attachment on a ticket by using syntax like this: [ 13237.2.diff]. This will link the text of “13237.2.diff” and provide the full link to the patch in email notifications.

Screen Shot 2015-10-05 at 6.53.20 PM

Now anyone browsing their Trac notifications in a mobile email client is only one tap away from a code review. No need to load up the entire ticket!


What WordPress plugins are Excellent++?

I can be no good at plugins. My default answer is an easy “no” when a request is made at WSU to add one to our setup. Each plugin we install adds overhead as the immediate responsibility for maintaining security, performance, and support lies on the web team, not the plugin author.

This is okay and is actually a really great relationship when the plugin is done right. For an Excellent++ plugin, we’ll likely never need support, though we may submit well written bug reports and/or code to resolve issues.

My (current) criteria:

  1. Does one thing very well.
  2. Follows WordPress code standards. Bonus for documentation standards.
  3. Standard core notifications for available updates if hosted elsewhere. Number in a bubble, just like any plugin from
  4. No extra admin notifications of any kind not related to actual relevant admin tasks, except on a settings screen specific to the plugin.
  5. A documented process to contribute code and open issues for bugs via GitHub or another sensible public repository.
  6. If a premium plugin, a single, unlimited license is available for a multi-network, multi-site installation of WordPress. Charge a bunch, but consider that we aren’t likely to use support resources.

I’m sure there are many, many plugins out there that meet this criteria and I’d like to have a list. If you know of one, please add a comment!

Next, I’ll need to make a list of plugins that meet all these criteria and should also have a landing page where it’s easy to contribute dollars. 😉

A Method for Managing Mixed HTTP/HTTPS Sites in Multisite

This is a brief rundown of the method we’re currently using at WSU to manage mixed HTTP/HTTPS configurations in a multi-network WordPress setup.

Our assumptions:

  • Sites that are HTTP (HTTPS optional) on the front end should be forced HTTPS in any admin area.
  • Some sites should be forced HTTPS everywhere. This may be because of form inputs or because it’s a nice thing to do.
  • New domains may not immediately have certificates. We can measure risk and provide brief HTTP admin support—usually with trusted users on a wired network.

To force HTTPS in admin areas, we use the WordPress constant FORCE_SSL_ADMIN. To determine whether this can be enabled, we start with the assumption that it should and then check for a stored option attached to the currently requested domain telling us otherwise.

A bit further down, we use this information to actually set the constant.

This option is managed through our WSUWP TLS plugin, which tracks new domains and allows non server-admins to start the process of CSR generation and certificate upload. Once the domain goes through the entire process and is verified as working, the foo.bar_ssl_disabled option is deleted and admin page loads will be forced to HTTPS.

While the domain is going through this process, it will be accessible via HTTP in the admin, though the cookies generated on other sites will not work as they are flagged as secure. There’s probably some stuff I’m not aware of here, which is another reason to keep this very limited. 😬

Forcing HTTPS everywhere is much easier, as we can redirect all HTTP request for a domain to HTTPS in nginx (or Apache). At that point, we’ll set siteurl and home for the site to HTTPS as well so that WordPress generates HTTPS URLs for everything.

Screen Shot 2015-04-24 at 9.21.18 AM

I love that screenshot.

In a nutshell. Assume all admin requests are HTTPS, but have a config flag that allows you to offer temporary HTTP access. If a domain can be forced HTTPS everywhere, then handle that in the nginx/apache config.

Great WordPress Meetup showing off 4.2 tonight

Two more months and the Pullman WordPress Meetup will be a year old! This is our 3rd release oriented meetup, so we’ve been around since the old days of 3.9.

WordPress 4.2 and more!

Wednesday, Apr 15, 2015, 6:00 PM

Sweet Mutiny
1195 SE Bishop Blvd #1 Pullman, WA

7 WordPress Superfans Went

WordPress 4.2 will be released at the end of April. We can walk through what’s new during the April meetup.A second presentation may fit as well, let’s talk about that during the February meetup.

Check out this Meetup →

We timed tonight’s meetup perfectly with the release of WordPress 4.2 RC1 and I was able to show off each of the new features to the group. There was some fun conversation throughout.

I think the new Press This interface got the best immediate reaction. It’s especially nice for those who have never experienced it before and much better as a new interface to those who hadn’t.

Extended character support for 🍕 was definitely next. It’s nice to talk about improved global support for WordPress in addition to the joy we get from expressive food characters. 😜

Plugin updates are a little hard to get excited about in a meetup environment, but the interface (or lack of redirect) did perk some ears. I know I love not being bounced to a new screen.

I also covered—possibly for the first time—a general overview of the WordPress release cycle and how things have matured over the last couple years. I think covering that along with the various methods to contribute should be good recurring topics, even if they don’t fill up the entire night.

This is what happens when I can’t fit “tonight was a great meetup” into 140 characters. 📜