New Committers!

Usually, new committers are announced in line with release cycles, but we were all just too excited to wait until the 4.8 cycle started, so here they are!

First up, James Nylen (@jnylen0). James has been a driving force on the REST API, both when it was a feature plugin, and more recently in Core since the endpoints were merged. The tickets and comments he leaves on Trac are always thorough and thoughtful, his patches are consistently excellent, and his attitude is exemplary.

Next, Adam Silverstein (@adamsilverstein). Adam has been a regular contributor for years, bringing significant improvements to the Media Grid, as well as handling large parts of the JavaScript work around the REST API endpoints – both in wp-api.js, and tenaciously working on porting Dashboard features across to using the endpoints.

Rounding out our guest committer list, Felix Arntz (@flixos90). Felix has been a contributor to Multisite for some time now, writing excellent patches, as well as running Office Hours and Bug Scrubs. Not only that, he’s always been willing to jump in and help in any area of Core, showing the same level of enthusiasm and consideration across the board.

Finally, we have a bumper class of guest committers to make make permanent! Pascal Birchler (@swissspidy) and Joe McGill (@joemcgill), Rachel Baker (@rachelbaker), and Mike Schroder (@mikeschroder) are now permanent committers.

Please join me in congratulating James, Adam, Felix, Pascal, Joe, Rachel, and Mike! 🎉🔥⭐️👻💯

#4-7, #commit

WP_Hook: Next Generation Actions and Filters

WordPress 4.7 introduces a significant reworking of action and filter iteration to address bugs that arose from recursive callbacks and from callbacks that changed the hooked callbacks on currently running actions/filters.

What does this mean for you, the plugin or theme developer? In almost all cases, nothing. Everything should continue to run as expected, and this should fix a number of hard-to-trace bugs when different plugins are stepping on each others callbacks.

Who is affected?

If your plugin directly accesses the $wp_filter global rather than using the public hooks API, you might run into compatibility issues.

Case 1: Directly setting callbacks in the $wp_filter array

$wp_filter['save_post'][10]['my_special_key'] = array( 'function' => 'my_callback_function', 'accepted_args' => 2 );

This will no longer work, and will cause a fatal error. $wp_filter['save_post'] is no longer a simple array. Rather, it is an object that implements the ArrayAccess interface.

You have two options to work around. The first (and preferred) method is to use the add_filter() or add_action() functions.

add_action( 'save_post', 'my_callback_function', 10, 2 );

If, for some reason, you absolutely cannot, you can still work around this.

if ( ! isset( $wp_filter['save_post'] ) ) {
    $wp_filter['save_post'] = new WP_Hook();
$wp_filter[ 'save_post' ]->callbacks[10]['my_special_key'] = array( 'function' => 'my_callback_function', 'accepted_args' => 2 );

Case 2: Directly unsetting callbacks in the $wp_filter array

unset( $wp_filter['save_post'][10][ $my_callback_id ] );

This will fail for the same reason as case one. To work around, you can use the standard remove_filter() / remove_action() functions.

remove_action( 'save_post', 'my_callback_function', 10, 2 );

Or, if you absolutely must access the array directly:

if ( isset( $wp_filter[ 'save_post' ] ) ) {
    unset( $wp_filter['save_post']->callbacks[10][ $my_callback_id ] );

Case 3: Checking if a hook is an array

if ( isset( $wp_filter['save_post'] ) && is_array( $wp_filter['save_post'] ) ) {
    // do something

This will always return false. $wp_filter['save_post'] is a WP_Hook object. To check if a hook has callbacks, use has_action() or has_filter().

if ( has_action( 'save_post' ) ) {
    // do something

Case 4: Moving the $wp_filter array pointer manually

If you’re calling next() or prev() on the $wp_filter array pointer to manually manage the order that callbacks are called in (or if you’re doing it to work around #17817), you will likely be unsuccessful. Use callback priorities, add_action() / add_filter(), and remove_action() / remove_filter() appropriately and let WordPress manage execution order.

Other Cases

Almost all other cases where you might manipulate the $wp_filter global directly should continue to function as expected. The WP_Hook object implements the ArrayAccess and IteratorAggregate interfaces so that, while it’s not recommended, you may continue to iterate over callbacks in $wp_filter or directly retrieve priorities from the callback array.


While there were many contributors of the course of this ticket, all of whom are listed in the changeset, I’d like to especially thank @jbrinley, for his work in architecting this solution, researching and testing potential compatibility issues, and for authoring the bulk of this post.

What’s Next

We’re confident in how solid the code is for the majority of sites, and for the major edge cases, so now it’s time to add the code to the nightly build, so all y’all can test it against your sites and plugins.

This is being treated as an early commit of a feature project, so the final decision for whether this code will be kept in WordPress 4.7 will be made no later than beta 1, which gives us a month and a half to see how it effects usage in the wider world.

The current nightly build contains this update, for your testing enjoyment.

If you have any feedback on the code, please leave a comment on this post. Please post any bugs you find to Core Trac.

#4-7, #dev-notes, #feature-projects, #hooks, #plugins


What are Reactions?

If you’ve used Slack or Thefacebook recently, you’ll have noticed a new way of interacting and providing feedback – emoji reactions. It works much the same way as a Like button, but provides a wider range of reactions, so readers can give more nuanced feedback, without needing to go to the effort of leaving a comment. This also allows for readers to provide the same level of interaction in situations where a “Like” is an inappropriate message to send, as Eric Meyer describes in his post about Inadvertent Algorithmic Cruelty.

What does it do?

The reactions plugin currently has the following features:

  • Allows for reactions to posts
  • REST API endpoints for storing and retrieving reactions
  • An exceedingly ugly emoji selector

What is still being worked on?

Pretty much everything!

In its current state, the plugin is mostly a proof of concept, in need of significant work improving edge cases, design and User Experience.

Your first step is to install the plugin, as well as the WP-API plugin (the WP-API plugin is currently a requirement to avoid code duplication, that will likely be re-evaluated based on when each plugin might be merged into Core).

Please report any issues on the Github repository, or drop in the #feature-reactions channel in Slack to ask questions or give feedback. It’s also where we have our weekly chats, on Wednesday 23:00 UTC. Thank you!

#feature-plugins, #reactions

🎉 One more committer for 4.4!

Please join me in welcoming a new guest committer for WordPress 4.4 — Ryan McCue (@rmccue)!

Ryan has been contributing to the WordPress world for many years, through various patches, as well as being one of the maintainers of the SimplePie RSS library that WordPress uses.

More recently, he started the WordPress REST API feature plugin, and has been leading the development of it for the past two years, nine months and five days (not that anyone is counting!). As the REST API comes closer to being ready for merge, Ryan having commit access is a natural progression: he can bring his expertise in the REST API directly across to WordPress Core.

Congratulations, Ryan! 🎆💯⭐️⭐️⭐️⭐️⭐️

#4-4, #commit

Committer Reviews of the REST API

With the proposed merge of the REST API base code into Core, I’d like to try something a little bit different. The REST API is potentially going to cause one of the biggest shifts in workflow that WordPress has seen, so it’s important that all committers know how it works, and how it affects the parts of Core that they focus on.

And so, here’s the plan. Before the REST API is merged into Core, it needs a code review from all active committers. The code being proposed for merge has been separated out into its own repo, for your viewing convenience.

There are five areas I’d like to see covered:

  • Docs: Are the inline docs up to standard? What needs to be done before they’re ready? Official tutorials will be helpful, can they be fit into Devhub?
  • Security: Is it secure?
  • Performance: Are there any obvious performance issues in the base code? Are we encouraging plugin developers to write performant custom end points?
  • Ease of Use: Is it easy to write custom endpoints? Do we encourage quality code?
  • Forwards Compatibility: This is a little more nebulous, but can you envisage scenarios where we might need to break backwards compatibility in the future?

Choose one or more of these focusses for your review, and tackle it from that perspective.

You can also have a look at the proposed endpoints in the main repo, (scheduled for a later WordPress version), for inspiration on how it may interact with the areas of WordPress Core that you work on.

Post your review as a comment here, and link to any relevant bug reports or pull requests you submit to the plugin repo.

And finally, please have a think about how this process worked for you. I’d like this to be a model for future feature plugin merges, particularly those that touch many different areas of WordPress Core.

PS: I’m not kidding about all active committers. I won’t hesitate to publicly shame you for holding up the REST API merge. 🙂

#feature-plugins, #json-api, #rest-api


One of the fun bits of the utf8mb4 upgrade is that we can now store emoji! Once your site is upgraded to utf8mb4, it can natively store any emoji character. There were a couple of problems with that, though:

  • Some browsers don’t know how to render emoji 👎, or they have bugs in their implementation 😢. Notably, Chrome either doesn’t work or has bugs, older versions of IE don’t work, and Firefox has bugs.
  • Not all sites will be able to upgrade to utf8mb4, which means they’ll be unable to save emoji characters that they enter.

Not being able to use emoji makes everyone a sad panda (😭🐼), so we need to fix this. There are a few moving parts of our emoji support, so lets go through them.

utf8 backwards compatibility

If a site can’t be upgraded to utf8mb4, we convert emoji to their HTML-encoded equivalent, and store that, instead. From a UI perspective, post editing works as expected 🎉. Because fields need to be white listed to support this, we don’t allow it everywhere – just post_title, post_content and post_excerpt. We also allow it in the site title and the site description.

Browser support

There’s a small compatibility check included on every page, both on the front end, and in the Dashboard. For those interested, this adds 1-4ms (⚡️-fast!) to the page render time – the aim was to keep this as low as possible, to avoid affecting your UX. If you notice a little chunk of compressed JS at the top your HTML, that’s probably it. If you’d like to check out how it works in a more readable format, have a look through wp-emoji-loader.js.

Email ✉️ and RSS 📯 (There’s no RSS emoji, give me a break.)

Of course, the JS shim won’t work in email and RSS. So, we replace all emoji with a static PNG version in those cases.

TinyMCE 📝

In addition to the browser support JS, there’s a TinyMCE plugin that handles keeping emoji looking good, while you type. It’s pretty magical.

Taxonomies and URL slugs

You can totally make taxonomies and URL slugs with emoji in them. Because we love you, and want you to be happy. 😀

So, that’s about it. If you have any questions about the implementation, drop them in the comments below.


#4-2, #dev-notes, #%f0%9f%91%bb, #emoji

The utf8mb4 Upgrade

In WordPress 4.2, we’re upgrading tables to utf8mb4, when we can. Your site will only upgrade when the following conditions are met:

  • You’re currently using the utf8 character set.
  • Your MySQL server is version 5.5.3 or higher (including all 10.x versions of MariaDB).
  • Your MySQL client libraries are version 5.5.3 or higher. If you’re using mysqlnd, 5.0.9 or higher.

The difference between utf8 and utf8mb4 is that the former can only store 3 byte characters, while the latter can store 4 byte characters. In Unicode terms, utf8 can only store characters in the Basic Multilingual Plane, while utf8mb4 can store any Unicode character. This greatly expands the language usability of WordPress, especially in countries that use Han character sets. Unicode isn’t without its problems, but it’s the best option available.

utf8mb4 is 100% backwards compatible with utf8.

Due to index size restrictions in MySQL, this does mean we need to re-create a handful of indexes to fit within MySQL’s rules. Using a standard configuration, MySQL allows 767 bytes per index, which for utf8 means 767 bytes / 3 bytes = 255 characters. For utf8mb4, that means 767 bytes / 4 bytes = 191 characters. The indexes that will be resized are:


And from Multisite:


Of course, the Multisite (and wp_usermeta) keys obey the DO_NOT_UPGRADE_GLOBAL_TABLES setting. The upgrade will only be attempted once, though we’ll probably add a check in a future WordPress version to see if we can upgrade now (say, if you’ve upgraded your MySQL server since upgrading to WordPress 4.2).

If you’re a plugin developer and your plugin includes custom tables, please test that your indexes fit within MySQL’s limits. MySQL won’t always produce an error when the index is too big, so you’ll need to manually check the size of each index, instead of relying on automated testing.

EDIT: One more thing…

If you’d like to upgrade your custom tables to utf8mb4 (and your indexes are all in order), you can do it really easily with the shiny new maybe_convert_table_to_utf8mb4( $tablename ) function. It’s available in `wp-admin/includes/upgrade.php`, and will sanity check that your tables are entirely utf8 before upgrading.

#4-2, #dev-notes, #utf8mb4, #wpdb

Emoji Chat Agenda, February 25, 2015

Here’s the agenda for Wednesday’s Emoji Chat in the #core channel on Slack.

Time/Date: Immediately after the Dev Chat.

  1. Emoji Helper – On platforms that don’t have an emoji keyboard, should we provide one?
  2. Performance – When we’re falling back to Twemoji on large pages, we have to consider how it will perform. Are there faster ways of replacing the emoji characters with images?
  3. Open Floor – There’s still time to rant about the evils of emoji! Let us know how you really feel.

#agenda, #emoji, #x1f4a9

Emoji Chat Meeting Notes, February 12, 2015

The full meeting archive is available here.

1. Why we’re doing this

So, here’s a bit of back story.

As of r31349, WordPress partially supports emoji. ~60% of WordPress sites are running MySQL 5.5 or later (so can be upgraded to store emoji), and ~40% of browsers natively support emoji. Emoji are a wildly popular method of communication, so we can expect them to be heavily used as soon an they’re available. The problem is, 60%/40% means a really bad experience for a huge number of our users, who’ll try to use emoji, and fail.

This is where the emoji feature plugin comes in to play. In order to help the 40% of WordPress sites that can’t be upgraded to store emoji natively, the wp_encode_emoji() function will turn them into HTML entities. Due to the unimaginable joy that character sets brings me, this will only be applied to sites using the utf8 character set, which accounts for the vast majority of WordPress sites – utf8 has been the default character set since r4860.

To help the 60% of browsers that don’t display emoji natively, we’re using the Twemoji image set as a fallback. This lets us show emoji everywhere, without causing extra load where emoji are already supported, mobile browsers being the important example here.

Now, there have been some concerns brought up previously that I’d like to address.

“Is this really appropriate for core?”

Yes. (Obviously that’s my answer, or we wouldn’t be here.) WordPress is is the business of making communication simple and accessible for all. Tech users everywhere have clearly chosen emoji as a means of communication, so it’s up to us to make sure they can do that within WordPress as easily as possible, or risk being left behind.

“Should we be concerned about changing the images in the future? Wouldn’t we be altering users’ content?”

No. By using Twemoji only when we can’t provide native support for emoji, it’s a pretty clear message that while the general appearance of emoji stays the same, the actual sprite used can differ significantly between platforms. (For example, every emoji set except Android uses a left hand for :thumbsup:.) As more browsers add native support for emoji, Twemoji usage will drop, reducing even further any impact we can have on users.

And so, that brings us to today.

2. The current state of the plugin

The plugin is very close to done. The editor plugin needs some attention, which @azaozz will be providing soon. There are a few bugs to discuss, which are mostly around fallback behaviour in browsers that don’t support emoji natively. Apart from that, the basic functionality is pretty much how I would expect it to appear in core. It’s had a brief review from the accessibility team, with only some minor alterations needed. The Twemoji images won’t be included in, as it’s a total of 3.4MB of images. They’re currently hosted on’s CDN, but we’re investigating other options for where to host them, probably the CDN. Given that the wp-admin Dashboard also loads things from Google, I have no problem with hosting them on an external CDN. There will naturally be a filter on the URL, to allow local hosting for sites that don’t want to use the CDN.

One of the major concerns at the moment is that we’re going to be splitting data formats, depending on if the site uses the utf8mb4 or the utf8 character set. utf8mb4 stores emoji natively, while utf8 requires us to HTML encode the emoji characters. In the futures, we’ll look at upgrading sites to utf8mb4 if they’ve upgraded their MySQL since WordPress 4.2, but that leaves the potential for mixed encoding – old posts having HTML encoding, new posts having the native characters. A post will be automatically updated to native upon saving, but do we need to consider upgrade routines, to go through all old posts and convert them?

Export/import also needs thorough testing, particularly when importing and exporting between sites having different character sets.

3. Unicode 8.0: the future of emoji

To talk about the future of emoji, you need to know a little bit of history. At the basic level, emoji are all single characters defined within the Unicode standard. However, they also support modifiers. Modifiers are a second character following the first, which usually causes the two characters to be merged into a single character when rendered. A good example of this is flag emoji.

The character G is U+1F1EC. The character B is U+1F1E7 (these characters are different to their ASCII equivalent). When used individually, they’ll display as that letter. When combined next to each other, they’ll display as the British flag.

So, Unicode 8.0 will two interesting things: a set of 37 new emoji, and skin tone modifiers. When a skin tone modifier character is placed after any face or person emoji, the emoji will show with that skin tone. Unicode 8.0 is due to be finalised in August 2015, so we and (Twemoji) will be looking at adding support for these then.

From a technical perspective, it just means we need to be aware that emoji are not always one character, and the methods for detecting multi-character emoji are about to get more complex.

We’ll also be able to detect if a browser is able to render the new emoji and skin tones, and fall back to Twemoji if they can’t. I don’t have a timeline for when browsers will support the new emoji, so I think it’d be good for us to get ahead of the curve then.

utf8mb4 stores anything in the Unicode address space, including unallocated characters, so I don’t expect any problems with storage of new emoji.

#emoji, #x1f4a9

Emoji Chat Agenda, February 12, 2015

Here’s the agenda for Thursday’s Emoji Chat in the #core channel on Slack.

Time/Date: February 12 2015 23:00 UTC

  1. Why we’re doing this – @pento
  2. The current state of the plugin – @pento
  3. Unicode 8.0, and future plans – @pento
  4. Open Floor/ranting about the evils of emoji – everyone

See you tomorrow!

#emoji, #x1f4a9