Last Week in WordPress Core

Hi Everyone! It’s finally time for another update. This is the first Last Week in WordPress Core for WordPress 4.1! I know there hasn’t been one for ages, but after talking with @dh-shredder at WordCamp Europe I’m confident that we’re able to change that.

Let’s have a look at the changes between September 23 and today:


  • If the current user does not have the delete_posts cap on the current post type, don’t list delete or trash as bulk actions for the relevant context of Post list table. [29757] #20175
  • TinyMCE: when pasting/inserting content before a view, add new paragraph above it and insert the content there.
  • TinyMCE: Use Tahoma for RTL in general and Arial for Hebrew in editor styles. [29773] #29553
  • Fix tapping on the menu in iOS and Android [29770] #29365
  • Don’t display an empty comment author IP link on Comments screen. [29774] #29766
  • In the form handler logic for edit-tags.php, don’t redirect until $_REQUEST['paged']has been checked. All switch cases (except edit) now use break instead of exit. [29782] #16162
  • Show the number of approved comments instead of all comments on the dashboard in the “At a glance” section. [29785] #26738

Bundled Themes

  • Prevent the arrow in “Continue reading” links from wrapping to a second line. [29771] #27908
  • Twenty Fourteen: Include Latin Extended font subset for Lato. [29772] #29690


  • Add two properties to media.model.Attachments.propmap: include and exclude, which are aliases for post__in and post__not_in. This allows you to instantiate a library that includes and/or excludes specific attachments by passing a single ID or an array of IDs. [29759] #26587
  • Disable multi-file uploading in iOS 7.x Safari as it prevents uploading of videos. [29776] #29602
  • When the modal is open, don’t respond to arrow keys when <textarea> has focus. [29777] #29725
  • Add size to the UI for Gallery Settings in the media modal. Ensure that the TinyMCE view is refreshed when size changes. [29779] #18143


  • wp_extract_urls() needs to also grab URLs with query strings and hashes. [29756] #29314
  • In wp_ajax_replyto_comment(), if $_POST['comment_type'] is set, use it for the value of $comment_type, which the compact() call has assumed is set since [8720]. It never was. [29758] #29704
  • Ordering by RAND():
    The shortcode callbacks for gallery and playlist check for 'RAND' == $atts['order'], which isn’t a valid value for order. Remove those checks and update the docs.
    In WP_Query, if the value of orderby is rand, order is irrelevant and should be unset. [29760] #29629
  • Add safeguards for when ext/hash is not compiled with PHP. [29761] [29751] #29518
  • Improve and clarify inline commenting inside the check_comment() function. [29763] [29762] #29734
  • Create correct permalinks for child posts of hierarchical post types when default permalinks are used. [29765] #29615
  • Allow bookmarks to be ordered by link_description in get_bookmarks(). [29778] #29763
  • In paginate_links(), ensure that query string args are propagated to the resulting paginated links. [29780] #29636
  • The joys of wptexturize(): [29781] #29557
    • Revert parts of [28773] and [28727] and [29748].
    • Do not ignore unclosed HTML comments.
    • Do not break unregistered shortcodes, e.g. [hello attr=”value”], or when there is extra whitespace, e.g. [ hello ].
    • Do not break HTML in shortcode attributes, e.g. [hello attr=”<”].
  • Use SSL for all references to [29787] [29788] [29789] #27115
  • Change the default orderby value in wp_get_nav_menus() to 'name'. [29792] [29796] #29460

Thanks to @hauvong, @dlh, @mvd7793, @nerrad, @pavelevap, @loushou, @avryl, @TobiasBg, @DustinHartzler, @dominik.schwind, @afercia, @ryelle, @richardmtl, @noplanman, @wonderboymusic, @obenland, @miqrogroove, @ixkaito, @benjmay, @mantismamita, @nikolov.tmw, @shooper, @shooper, @voldemortensen, @igmoweb, @curtjen, @simonwheatley for their core contributions!

Revisions covered: [29756] to [29799]. For the complete list of commits to trunk, check out the log on Trac. Interested in joining in? Write or test a patch for 4.1. Also don’t miss the weekly meeting today 20:00 UTC

#4-0, #week-in-core

Language chooser in 4.0

As mentioned in previous posts, WordPress 4.0 includes a language chooser. After selecting a language WordPress will download and install the language pack on the fly. The rest of the install process will then be in that language.

Language Chooser in WordPress 4.0

Language Chooser in WordPress 4.0

A summary

To make this possible we introduced some helper functions or changed existing functions.

translations_api() is based on plugins_api() / themes_api() and retrieves translations from the WordPress Translation API. The first argument $type must be core, theme or plugin. $args is used for additional arguments. For example $args['version'] should be specified for all types. Types theme and plugin must set slug too.

wp_get_available_translations() function is a wrapper for translations_api() and returns core translations for the current installed version. The API result is cached for 3 hours.

As soon as a language is selected and the Continue button is clicked, WordPress will download the language pack in background, wp_download_language_pack() does this with the help of Automatic_Upgrader_Skin and Language_Pack_Upgrader.

Because translations are installed on the fly we had to enhance the existing load_default_textdomain() function. It now supports an optional $locale parameter to allow to switch the default translation. ([29630])

The WPLANG option is now set in single sites too and is populated on upgrade, based on the value of the WPLANG constant, which is now deprecated, see [29630]. get_locale() now includes the global $wp_local_package variable (used in localized packages) and an existing but empty WPLANG option can override the WPLANG constant as an empty WPLANG option is equivalent to en_US.

wp_dropdown_languages() replaces mu_dropdown_languages(), which had many issue like not supporting variants of the same language (like en, en_GB, en_CA and en_AU). The new dropdown is populated by the translation API.

Asynchronous translation updates

In WordPress 3.7 we had introduced Language_Pack_Upgrader::async_upgrade(). Asynchronous translation updates will run after a theme or plugin is installed or updated. What’s the purposes of async updates? One, when you install or update a theme or plugin, you’d expect to get the translations updated for that theme or plugin. But all out of date translations are updated here (even when that plugin or theme was already up to date), in order to capitalize on the fact that we have a filesystem connection (which may be via user-submitted FTP credentials).

In WordPress 4.0 this asynchronous update will no longer run on version-controlled installs. You can also use the async_update_translation filter (which corresponds exactly to the auto_update_translation filter) to disable it, see [29694].

// Disable asynchronous and automatic background translation updates
add_filter( 'async_update_translation', '__return_false' );
add_filter( 'auto_update_translation', '__return_false' );

Other notes

  • Localized packages will skip language chooser, see [29705].
  • For BC it’s allowed to choose a language specified by the WPLANG constant (but not installed), see [29691].
  • General Settings includes an option for the Site Language in single sites now too.
  • WPLANG section from wp-config-sample.php is removed, see make/polyglots post.
  • On install, WordPress will skip the language chooser if it has no access to the filesystem without asking for credentials, see [29673].
  • For a peek at what’s to come in 4.1, check out #29395.

#4-0, #dev-notes, #i18n

The props list has been updated on the…

The props list has been updated on the 4.0 credits page. If you haven’t updated your display name yet, you should totally do that on your support forum profile.

#4-0, #credits

4.0 release plan update

If you’ve been following along with IRC and Trac activity over the last 24 hours, you’ll have noticed that there’s been a lot of it. We’ve had a number of issues pop up, and thus did not reach the targeted freeze of 16:00 UTC on 2014/09/02. If you haven’t been following along, I highly recommend it 🙂

Given that, our new release target is shifted back one day to 16:00 UTC on 2014/09/04. We’ll still kick off two hours beforehand with various pre-launch checks and tasks. This means code freeze by 16:00 UTC on 2014/09/03 – just a few short hours from now. I would also like to run a number of those pre-flight checks in the hour or two before freeze to give us an early chance to squash anything that may come up during those. To that end, an RC2 has been built for final testing.


A more powerful ORDER BY in WordPress 4.0

orderby is the argument passed to WP_Query to tell it what column to sort on when it is creating the ORDER BY clause for its generated SQL. The default value for orderby is post_date.

The default sort order for a column in MySQL is ASC (ascending), with smallest values first. For the reverse, DESC is used. You can sort on multiple columns, and each column can have its own sort order.

The default value for the order argument inside WP_Query is DESC. ~23% of the internet automatically queries posts in reverse chronological order because of this. order can only be one of 2 values: DESC or ASC.

orderby accepts a string, representing a column on which to sort:

$q = new WP_Query( array( 'orderby' => 'post_title' ) );

// or an alias
$q = new WP_Query( array( 'orderby' => 'title' ) );

Both will produce an ORDER BY clause like:

ORDER BY post_title DESC

orderby will also parse a space-delimited set of columns:

$q = new WP_Query( array( 'orderby' => 'title author' ) );

Prior to 4.0, there was a problem: the value for order would only be applied to the last value that you passed in that space-delimited list, producing an ORDER BY clause like:

ORDER BY post_title, post_author DESC

Remember that the default sort order for a column in MySQL is ASC, so queries like that can get weird real fast and produce unexpected/unpredictable results. If no value is passed for order for a column in the generated SQL, the column will be sorted in ASC order. This was not so clear to all developers. #26042 was a joy to debug.

In 4.0, when you pass a space-delimited set of values, your sole value for order will be applied to all of your values that are parsed for orderby. This was fixed in [28541].

So that’s pretty good, but it doesn’t allow you granular control over the sort order for each column. The syntax doesn’t allow itself much room for extending.

Enter [29027].

In 4.0, you can now pass an array to WP_Query as the value for orderby. The syntax looks like:

$q = new WP_Query( array( 'orderby' => array( 'title' => 'DESC', 'menu_order' => 'ASC' ) ) );

This allows you to control the generation of the ORDER BY clause with more specificity:

ORDER BY post_title DESC, menu_order ASC

Pre-4.0, you would have had to use some gnarly filters on the SQL statement or a specific clause. No bueno.

To see the internals, check out the new protected methods in WP_Query: ->parse_order() and ->parse_orderby.

Happy WP_Querying!

#4-0, #dev-notes, #query

RC1 is here Proposed agenda for today’s meeting…

RC1 is here! Proposed agenda for today’s meeting:

  • What’s come up in the hours since RC1 was released?
  • Keep an eye on support forums and bugs reported against trunk. Great time for triage of non-4.0 tickets as well.
  • Plugin developers: update your readmes and add an icon!
  • Interesting post on wp-hackers. Feedback welcome.
  • Codex page.
  • Any blog posts we need to write for developers?
  • Are there any plugins we need to ship to show off or extend 4.0 features?
  • Release plan.

#4-0, #agenda

I’d like to hold an impromptu scrub of…

I’d like to hold an impromptu scrub of remaining 4.0 tickets in about an hour at 20:00 UTC. @nacin and I triaged most tickets earlier today and feel confident that we can finish everything out and get to RC.

#4-0, #bug-scrub

Introducing plugin icons in the plugin installer

WordPress 4.0 comes with a redesigned plugin installer. Just now we’ve added one of the finishing touches to this project — plugin icons.

Plugin authors, If your plugin is compatible with WordPress 4.0, it only takes a few moments to change a readme “Tested up to:” value to 4.0. Compatibility information is prominently shown in the new plugin installer, so you’ll definitely want to update this value. For your plugin to stand out, you’ll also want to give your plugin an icon. Read on…


Beautiful, auto-generated icons

Default icons are generated using the GeoPattern library by Jason Long of GitHub. If you have a banner image, it is automatically sampled to determine the primary color for the pattern, using Tonesque from @matveb. (Cool, huh?)


Making your own icon

Plugin icons are 128 pixels square. HiDPI (retina) icons are supported at 256 pixels square. Like banners, these go into your /assets directory and can be either a PNG or JPG. So just create assets/icon-128x128.(png|jpg) and/or assets/icon-256x256.(png|jpg) and you have an icon.

You also have another option: SVG. Vectors are perfect for icons like this, as they can be scaled to any size and the file itself is small. For an SVG file, you simply need an assets/icon.svg file.

We may implement SVG-to-images fallbacks in core for browsers that don’t support them, so if you go the SVG route, I’d suggest also turning your SVG into a PNG. (SVG takes precedence.)

Jetpack uses an SVG icon:

Some tips when designing an icon

  • Keep it simple! The Android and iOS Human Interface Guidelines both have some fantastic design tips.
  • Avoid text, especially since these may be seen at smaller sizes in other contexts (and in languages other than English). And because this is an icon, not an ad.
  • Use the right image format for what you’re doing. Don’t use JPGs for simple designs; don’t use PNGs for photos.
  • Optimize your images! Use something like ImageOptim or your favorite web app, CLI tool, etc.
  • Please no WordPress logos. Come up with your own brand. (If you already have a banner image, you likely already have a head start here.)
  • If you haven’t worked with SVGs before, they’re pretty cool. Here’s a tutorial from Chris Coyier.
  • Keep in mind this is an icon for your plugin, not a display ad.

Some examples

Akismet, Jetpack, and Hello Dolly already have icons. You can see their assets directories herehere, and here.

Thanks to the hard work of Alex Shiels (@tellyworth) for implementing this!

#4-0, #dev-notes, #plugins, #upgrade-install

All hands on deck for 4.0 Beta 4 and RC 1

We’ve been pushing really hard to get to a place where a final beta and then RC phase are appropriate for the 4.0 development cycle.

This impacts a few things:

  • The release date (currently scheduled for August 27, in just two short weeks).
  • Finalizing help and about page text, and thus string freeze (and, therefore, translators).

With the help of everybody who’s contributed to this release thus far, we’ve done a really great job with the features we’ve been working on and the overall ticket queue for this milestone. All of that said, we need your help to get the following done:

Needed to reach the final beta

  • #28328: Focus on editing, while editing (editor scrolling improvements). There is a comment that outlines a few things we feel need at least consideration before we consider this release-worthy. @stephdau has been working through patching – testing of patches is greatly appreciated, as are bug reports (as always).
  • #28842: Media Grid: Bulk selection mode. User testing and further feedback have led us to give a separate selection mode another try. @ericlewis has been doing very heavy lifting throughout the cycle on the feature. There is a patch for testing (not for commit) along with some observations on ticket. Once again, testing and UI/UX observations are very welcome. If you would like to help with patching, please let us know and we can coordinate to avoid duplicate efforts.

Needed before RC1

  • Commit or punt all tickets currently slated for the 4.0 milestone. Anybody can help by testing/writing patches or marking tickets for commit or punt using keywords. If you’re not sure, feel free to ask in IRC, on ticket, or just move to the next one.
  • Triage all tickets reported against trunk. This is especially important in the RC phase, as we need to monitor things reported against trunk for bugs introduced in the cycle, particularly regressions. Many tickets opened against trunk will apply to earlier versions – please change the version field as appropriate to reflect that. It may help to filter out anything already milestoned for 4.0 or Future Release.
  • QA sweeps across browsers and devices, particularly on new features and checking CSS for anything introduced that may not work in IE8 or in some cases IE7. For instance, any usages of CSS calc() need to have a fallback for IE8 and older.

If you’d like to tackle something you see here and would like a little more direction to get started, please leave a comment below or head over to #wordpress-dev in IRC. One or more core developers is likely to be around at most hours.

Finally, for today’s dev chat at 2014-08-13 20:00 UTC, let’s take a quick look at the above, note any other blockers we see, and get people assigned to tasks/tickets as we can.

#4-0, #agenda

Proposed agenda for today’s dev chat * 3.9.2…

Proposed agenda for today’s dev chat:

  • 3.9.2 and 4.0 beta 3 are out:
  • What’s left for beta 4 (likely to be the last)? What’s the timing on that and RC 1?
  • 83 open tickets left for this release.

Please propose any other items you might have in the comments.

#4-0, #agenda