Preferred Languages Chat Summary: October 26

After introducing the Preferred Languages project less than two weeks ago, we held our first meeting on Wednesday. This is a summary of the Preferred Languages chat from October 26. (Slack log)

Attendees: @casiepa, @chantalc, @petya, @swissspidy


After going through initial feedback on the introduction post, there was a short recap of ideas that have been suggested so far:

  • Have a translated setting of preferred languages, where the translators would define the locales they should “fall back” to in case there’s no translation available. E.g. de_CH states to prefer de_DE and de_DE_formal after that.
    • Pros: simple solution, no UI changes needed
    • Cons: very subjective, unclear how the expected translations would be installed
  • Rely on the Accept-Language header every browser sends, which is set based on the user’s system preferences.
    • Pros: no UI changes needed, it’s a reliable standard
    • Cons: no support for formal language variants, unclear how the expected translations would be installed
  • Extend the UI to allow setting multiple preferred languages
    • Pros: leaves the choice to the user, clear how to install the expected translations, could be used together with Accept-Language
    • Cons: makes the UI option more complex

Besides that, it was suggested to display a note to the user when there’s a missing translation to encourage them to translate WordPress. However, this can be worked on independently in #23348.

Before we get into details and possible solutions, more (non-technical) research needs to be done. We’re mostly interested in how other platforms and content management systems handle this. Think Wikipedia, Facebook, Drupal, Joomla, and so on. WordPress isn’t the only system facing this situation.

Research results can be shared in the comments to this post. Every help in that regard is highly appreciated! So far I’ve collected some information about Drupal and Joomla. After that, I’ll publish the results in a separate blog post.

The next meeting will be on Wednesday, 9 November 2016, 17:00 UTC in the #core-i18n Slack channel.

#feature-projects, #i18n, #preferred-languages, #summary

WP_Taxonomy in 4.7

Similar to how WordPress 4.6 introduced WP_Post_Type, version 4.7 will introduce a new WP_Taxonomy class. This changes the global $wp_taxonomies to an array of WP_Taxonomy objects.

WP_Taxonomy provides methods to handle rewrite rules and hooks. These methods are used internally by register_taxonomy() and unregister_taxonomy(). Each taxonomy argument is now a property of WP_Taxonomy.

The following function has been changed to return a WP_Taxonomy object:

  • get_taxonomy()

The following hook parameters are now a WP_Taxonomy object:

  • The second parameter $taxonomy of xmlrpc_prepare_taxonomy.
  • The second parameter $tax of term_search_min_chars.

The following function accepts a WP_Taxonomy object now:

  • get_taxonomy_labels()

Just like with WP_Post_Type, introducing such a class makes further improvements much more feasible.

For more background on the change, see #36224.

#4-7, #dev-notes

Preferred Languages

With the introduction of language packs two years ago ([29630]), it’s easier than ever for users to change the main language of their site. However, in some cases a single locale (i.e. the language variant, like Canadian French) is not enough.

Let’s say a site of mine is running German (Switzerland), which there is a language pack for. However, most plugins only have a German (Germany) translation, or perhaps only even a de_DE_formal translation. As a native German speaker, I’d prefer to read a German (Germany) translation instead of English, if a German (Switzerland) version did not exist. Instead of getting translations as I’d wish (as the translations are very similar), WordPress falls back to the original English strings. That’s a poor user experience for many non-English speakers. Now, since the addition of a user-specific language (#29783), this issue is even more important.

There’s been a long discussion about this issue in #28197, where possible solutions have been suggested without any consensus. Instead of directly talking about how this can be technically implemented, we should first explore the actual user experience problems and see what’s possible and how it might look.

For this, I began researching how other software approach this problem. Those of us interested in this problem can learn from existing solutions and proceed from there.

These screenshots should give you a better understanding of what I’m talking about:

As you can see, these software products create a “fallback chain” for the user’s preferred languages. In theory, I could also set my preferred languages to es_ES -> de_DE -> en_GB -> en_US, if that was the order in which I preferred translations.

To keep momentum and continue thinking through this problem, I want to kick off a feature project, about improving the experience for WordPress users who use the product in non-English languages, of which multiple locales may exist.

Get Involved

Your feedback is incredibly important to ensuring we get this right. Leave any thoughts in the comments below. Would you like to help out? Awesome. Let’s have an initial chat on Wednesday, 26 October 2016, 17:00 UTC in the #core-i18n Slack channel and go from there.

I’ve set up a GitHub repository that can be used as a playground for discussions, prototypes, and eventually a working solution. For this, design and accessibility feedback would be very helpful. I’m confident that we can build something that we can propose for inclusion in a future WordPress release!

#feature-projects, #i18n, #preferred-languages

Shiny Updates v3 Kickoff Chat

While the biggest chunk of Shiny Updates v2 was merged into WordPress 4.6, there were still plenty of ideas that didn’t make it in time. I think it would be worthwhile to bring more shininess to WordPress 4.8 or 4.9. Regular chats have been dormant for a while, but I’d like to continue them starting Wednesday, 19 October 2016, 17:00 UTC in the #feature-shinyupdates Slack channel.

Topics for the first chat will include a brief update on current shiny updates bugs in WordPress core and the planned goals for Shiny Updates v3 (e.g. update-core.php). Some of the ideas can be found on GitHub.

Now is a great time to get involved and help making WordPress updates even more shiny. Please come join us next week and contribute to the continuing abolishment of The Bleak Screen of Sadness™.

#feature-projects, #shiny-updates

Shiny Updates in 4.6

After being approved for a partial merge, Shiny Updates V2 was added to WordPress core in [37714]. Thanks to that change, updating as well as installing and deleting plugins and themes has become much easier for users. With the exception of the wp-admin/update-core.php screen, those actions are now all performed via AJAX, avoiding what we internally called The Bleak Screen of Sadness.

Visual Changes

If you wanna see Shiny Updates in action, check out the merge proposal post which contains screenshots and a video.

Proposal: More Shiny Updates

One big user facing change is about search: There is now an AJAX search on both the Installed Plugins screen as well as the Add New Plugin screen, this means the search results change as you type, drastically simplifying your workflow.

Under The Hood

The JavaScript responsible for shiny updates (enqueued via the 'updates' handle) has been completely revamped to improve the UX across the board by displaying better progress updates and error messages.

If you’re in any way relying on this JavaScript, you will notice that wp.updates.update() has been renamed to wp.updates.updatePlugin(). The same goes for the plugin update success / error callbacks.

In addition to that, callbacks are now passed as arguments to the wp.updates.updatePlugin(), wp.updates.updateTheme() and the like, e.g. wp.updates.updatePlugin( { success: wp.updates.updatePluginSuccess, … } ). The whole code is thoroughly documented.

However, you probably won’t ever need to call these functions directly. Instead, you might wanna hook into the custom jQuery events that are being triggered throughout the code, like 'wp-plugin-install-success'.

Shiny Updates V3

While the last iteration of Shiny Updates has been merged into core, development of the plugin continues to happen on GitHub. If you’re running the Shiny Updates feature plugin on your site, everything will continue to work when using 4.6.

The current version of the plugin now only contains things that didn’t make it into 4.6 and is our base for further development. Feel free to keep it running and provide feedback!

#4-6, #dev-notes, #shiny-updates

Resource Hints in 4.6

Resource Hints is a rather new W3C specification that “defines the dns-prefetch, preconnect, prefetch, and prerender relationships of the HTML Link Element (<link>)”. These can be used to assist the browser in the decision process of which origins it should connect to, and which resources it should fetch and preprocess to improve page performance.

Introduced with [37920], WordPress now has a simple API to register and use resource hints. The relevant ticket is #34292

By default, wp_resource_hints() prints hints for (the CDN) and for all scripts and styles which are enqueued from external hosts.

Developers can use the wp_resource_hints filter to add custom domains and URLs for dns-prefetch, preconnectprefetch or prerender. One needs to be careful to not add too many resource hints as they could quite easily negatively impact performance, especially on mobile, but the filter works like this:

function makewp_example_resource_hints( $hints, $relation_type ) {
	if ( 'dns-prefetch' === $relation_type ) {
		$hints[] = '//';
	} else if ( 'prerender' === $relation_type ) {
		$hints[] = '';

	return $hints;

add_filter( 'wp_resource_hints', 'makewp_example_resource_hints', 10, 2 );

#4-6, #dev-notes, #script-loader

I18N Improvements in 4.6

WordPress 4.6 significantly improves the way translations are loaded for plugins and themes which are hosted in the WordPress Plugin and Theme Directory and using language packs via’s translation platform.

Loading Translations in Different Order

Functions like load_plugin_textdomain( $domain ) and load_theme_textdomain( $domain ) are used to load the translations for a specific text domain, where $domain equals the slug of your plugin or theme.

Up until now, these functions first looked inside the plugin/theme folder for available translations before checking the wp-content/languages directory, where language packs reside. With WordPress 4.6, this order has been reversed.
The translation platform for plugins/themes was opened up in December last year. Since then 15,000 plugins and themes were imported and are now benefiting from automated translation updates. That’s why translation files are most likely to be located wp-content/languages directory, hence this change. See [37414] / #34213.

Just-in-time Loading for Translations

By far the biggest change is that you do not have to call load_plugin_textdomain() or load_theme_textdomain() anymore with WordPress 4.6. Of course the same goes for load_muplugin_textdomain().

Again, since translations files are usually inside wp-content/languages, WordPress now scans that directory for available translations and automatically loads them if it encounters a text domain for the first time. That’s handled by the new _load_textdomain_just_in_time() function which gets called in get_translations_for_domain(). See [37415] / #34114.

This so-called just-in-time loading of text domains works really great and removes one more step for developers to worry about. If you do not want this to happen, however, you can still use the override_load_textdomain filter to load your text domains manually.

Also, if you use unload_textdomain() you will have to manually load translations afterwards if you want to use them again because it keeps a record of unloaded text domains.

Localized jQuery UI datepicker

Other Changes

  • Support for comment number declension in get_comments_number_text(). See #13651.
  • Fallback for TextDomain header field in get_plugin_data(). See #36706.
  • Updated list of continents and cities for the timezone selector. See #37554.
  • Support for the German (Switzerland) locale in remove_accents(). See #37076.
  • Improved support for month name declension. See #36790.


#4-6, #dev-notes, #i18n

Proposal: More Shiny Updates

The Bleak screen of Sadness™ 😢 that users encounter when installing/updating/deleting plugins or themes is a terrible experience WordPress users. It’s not timely anymore and doesn’t reflect the values WordPress strives to adhere to. Instead, WordPress needs a simpler and more straight forward experience when installing, updating, and deleting items.

That’s why the Shiny Updates Team is proposing a merge of the Shiny Updates plugin into WordPress 4.6 💥. We’re eager to hear feedback from WordPress core contributors and users alike.

Old plugin install process

Existing plugin install process, showing The Bleak Screen of Sadness.

Purpose & Goals

The Bleak screen of Sadness™ is disruptive to user workflows, pulling them out of the context of plugins or themes, and dropping them into a screen filled with technical details that most users don’t care about or don’t understand. Shiny Updates deals with these details behind the scenes, maintaining the context of the triggered actions and leaving users with clear actions and results.

This caters to two core principles of WordPress, designing for the majority, and striving for simplicity. Users don’t really care about the internal process of installing or updating themes and plugins. Listing out these technical steps for them is unnecessary at best.

With Shiny Updates these actions also don’t require a page reload anymore, which creates a simpler workflow without context changes and lets users achieve their goals of an enhanced WordPress experience quicker.

We also revamped the whole Dashboard -> Updates page to improve simplicity and make the process of updating translations and WordPress core shiny as well. 🎉

Project Background

Whether it was through the update mechanism available under Dashboard -> Updates or the automatic updates introduced in version 3.7, WordPress has always been encouraging users to update their sites to the newest versions.

Plugin updates have been made shiny in WordPress 4.2, but now we want to extend this to other areas as well. Shiny Updates v2 improves the update process for themes, translations and even WordPress itself, as well as install and delete workflows for plugins and themes.
As of today, the plugin has been downloaded about 8,000 times and is actively installed on over 1,000 WordPress sites. We’ve gotten input from many users and core committers through GitHub and during regular meetings in the #feature-shinyupdates.

You can read more about the shiny updates flow with various visual records on make/test, where we also shared results of the various user tests we did. Doing multiple rounds of user testing has really shaped the whole project and helped us refine the plugin and improve the overall usability of installing updates in WordPress.

Implementation Details

Shiny Updates builds upon the shiny plugin updates feature already existing in core, which basically consists of some JavaScript and Ajax callbacks for updating plugins in the background. As such, it can easily be extended by the new JavaScript parts of Shiny Updates. All new JavaScript functionality is available under the wp.updates umbrella.

Here’s it looks like in action:

In addition to that, we propose a revamped updates overview under Dashboard -> Updates. It’s simpler, more elegant, more shiny:

Shiny Updates Table

With Shiny Updates, the Dashboard -> Updates page gets a much needed overhaul

Relevant Core Tickets

Merging Shiny Updates into core would resolve a long list of outstanding trac tickets related to updates, including #31529, #31530, #31531, #31532, #31534, #31535, #31773, #33637 and #35032. All tickets related to Shiny Updates can be found here.

Remaining Issues

There are a few remaining bugs on GitHub, which will be resolved by Friday, June 3rd. Since the revamped updates table relies on plugin icons being returned by the Plugins API, the API needs to be changed as part of the plugin directory update. The new directory will launch well before the 4.6 release, so that shouldn’t be a big deal. As a bonus, this change would also enable us to fix #30186.

Contributors and Feedback

This is a proposal and is subject to revision based on your feedback. If you haven’t already tried out the plugin, please download and install it from or the comfort of your WordPress admin. You can review the current code and leave feedback at the project’s GitHub repository or in #feature-shinyupdates on Slack.

Thanks a lot to everyone who has been contributing to this plugin since its inception, especially @obenland for leading this project, @adamsilverstein for his numerous contributions, @mapk for helping with testing and UX, and @ocean90 for giving valuable feedback despite being super busy with leading 4.6.

So far we’ve received positive feedback from different core teams like the accessibility and design teams, and we have reached out to @drew who will review the docs once a core patch is ready.

#4-6, #feature-plugins, #merge, #proposal, #shiny-updates

4.5.1 Release Candidate

A Release Candidate for WordPress 4.5.1 is now available. This maintenance release fixes 11 issues reported against 4.5 and is scheduled for final release next Tuesday, April 26.

Thus far WordPress 4.5 has been downloaded nearly 5 million times since its release on April 12. Please help us by testing this release candidate to ensure 4.5.1 fixes the reported issues and doesn’t introduce any new ones.

Notable Bug Fixes

As noted in the previous post about 4.5.1, there are  two more severe bugs fixed in this release:

  • #36545 – WordPress TinyMCE toolbar/tabs unresponsive in Chrome Version 50.0.2661.75 beta-m (64-bit) and
  • #36510 – Twenty eleven page templates with widgets incorrectly styled.

All Changes

Only a few components received changes. Here’s a list of all closed tickets, sorted by component:

Build/Test Tools

  • #36498 Shrinkwrap npm dependencies for 4.5

Bundled Theme

  • #36510 Twenty eleven page templates with widgets incorrectly styled


  • #36457 Customizer Device Preview: Use px units for tablet preview size


  • #36629 Database connect functions can cause un-catchable warnings


  • #36458 Fix support for Safari + VoiceOver when editing inline links


  • #36604 Emoji skin tone support test incorrectly passing in Chrome


  • #36620 Feeds using an rss-http content type are now served as application/octet-stream


  • #36501 Fatal error: Undefined class constant 'ALPHACHANNEL_UNDEFINED'
  • #36578 wp_ajax_send_attachment_to_editor() bug
  • #36621 Don’t cache the results of wp_mkdir_p() in a persistent cache

Rewrite Rules

  • #36506 Duplicate directives in web.config after WordPress 4.5 installation on Windows


  • #36545 WordPress TinyMCE toolbar/tabs unresponsive in Chrome Version 50.0.2661.75 beta-m (64-bit)

Update: We’ve released 4.5.1-RC2, which includes the fix for #36629.

#4-5-1, #maintenance, #release

Embeds Changes in WordPress 4.5

After the introduction of the embeds feature in WordPress 4.4 there have been a few significant changes in 4.5 to make embeds more robust and easier to customize. 🎉

Embed Code Adjustments

Tickets: #35804, #35894

There were two minor changes to the <iframe> embed code:

  1. The iframe’s title attribute has been adjusted to better describe its content for improved accessibility.
  2. The iframe is now hidden using a different technique to prevent images from not being displayed properly in Firefox, working around a known bug in that browser.

Discovery Improvements

Ticket: #35979

Since WordPress 4.4, oEmbed discovery has been turned on by default. Using auto discovery, WordPress tries to find embeddable content when a URL is pasted on a new line in the editor. [36880] prevents timeouts from happening when requesting the URL by limiting the response size to 150KB.

Embedding Static Front Pages

Ticket: #34971

Previously, embedding a static front page was not possible due to not having an /embed/ endpoint. Now embed is a reserved slug that can’t be used for new pages/posts. When is an existing page, embeds fall back to

Embed Template Changes

Displays select embed template and template part locations, as well as various areas of an example embed view. Covers embed.php, the_embed_site_title(), embed-content.php, the_excerpt_embed(), and print_embed_sharing_options().

Tickets: #35322, #35630, #34561

  • The site icon in the embed template used to fall back to an image located inside /wp-admin/. This was problematic when the directory is not accessible to the public. That image is now loaded from inside /wp-includes/.
  • Thanks to an adjusted click event handler, links inside the iframe now work even when they’re inserted dynamically after the page load.
  • By far the biggest changes affect the way the embed template is loaded 💪🏽. Most notably, the old wp-includes/embed-template.php file has been deprecated and split into five new template parts that can be individually overridden by themes:
    • embed.php
    • embed-404.php
    • embed-content.php
    • header-embed.php
    • footer-embed.php

The five new template parts live in /wp-includes/theme-compat/ and allow core to gracefully fall back should themes prefer not to override any or all of them.

Previously, the embed template could only be changed using the embed_template filter. This filter can now be leveraged directly within the template hierarchy via the already-existing {$type}_template filter (where $type equals “embed”).

See get_query_template() and locate_template() for more information.

See [36693] for the relevant changeset.

Embeds in the Template Hierarchy

Ticket: #34278

In addition to the new base embed.php template and related template parts, themes can now implement embed templates for specific post types and post formats within the confines of the template hierarchy. The embeds template cascade looks like this:

  • embed-{post-type}-{post_format}.php
  • embed-{post-type}.php
  • embed.php
  • wp-includes/theme-compat/embed.php

Note that this is the first time direct theme-compat inheritance has been integrated with the template hierarchy. This approach allows core to provide basic, yet standardized templates and template parts for handling post embeds.

To leverage the core embed template parts, simply use standard get_template_part() calls within your themes. The template hierarchy will do the rest.

For example:

  • If the theme is leveraging its own version of embed.php template, it would likely call template parts directly, e.g. get_template_part( 'embed', 'content' );
  • If the theme is relying on the core embed template parts – i.e. not providing its own embed-content.php file – the template hierarchy would fall back to using wp-includes/theme-compat/embed-content.php, and so on.

See [36876] for the relevant changeset.

For more information on extending embeds within the scope of the template hierarchy, check out the new Embeds section in the Template Hierarchy reference in the Theme Developer handbook.

#4-5, #dev-notes, #embeds