Various internationalization (i18n) improvements are in WordPress 6.5, and this developers note will focus on these.
New localization system with improved performance
Over the past year, WordPress contributors have meticulously analyzed performance of the existing i18n Internationalization, or the act of writing and preparing code to be fully translatable into other languages. Also see localization. Often written with a lowercase i so it is not confused with a lowercase L or the numeral 1. Often an acquired skill. system in WordPress and ultimately created a new Performant Translations feature plugin A plugin that was created with the intention of eventually being proposed for inclusion in WordPress Core. See Features as Plugins. that provided a completely overhauled system with significantly better performance. After thousands of beta A pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process. testers and a merge announcement late last year, this new library is now included in WordPress 6.5! See #59656 for all the details.
The Performant Translations plugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party is still useful and will continue to be maintained to build on top of the core Core is the set of software required to run WordPress. The Core Development Team builds WordPress. solution with a distinct additional feature. As is already the case today, the plugin will automatically convert any .mo files to PHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher files if a PHP file does not currently exist. This is useful for sites where translations are not coming from translate.wordpress.org or only exist locally on that server.
This new library is faster at loading binary .mo files and uses less memory. It even supports loading multiple locales at the same time, which makesย locale switchingย faster. In addition to that, it supports translations contained inย PHPย files, avoiding a binary file format and leveraging OPCache if available.
The new library is so fast, in fact, that it paves the way for the Preferred Languages feature plugin to merge translations of multiple locales by default starting with WordPress 6.5.
While this is in large part a silent and backward-compatible under-the-hood change, there are still a few things to be aware of:
New .l10n.php translation The process (or result) of changing text, words, and display formatting to support another language. Also see localization, internationalization. file format
When downloading language packs from WordPress.org The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/, there will be a new .l10n.php file in addition to the .mo and .po files you are already familiar with. If an .moย translationย file has a corresponding .l10n.php file, the latter will be loaded instead, making things even faster and use even less memory.
This is a progressive enhancement Enhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature., so if thereโs only an .mo file but no PHP file, translations will still be loaded as expected. However, the opposite is also true! So you can theoretically use only .l10n.php translation files in your project and features such as the just-in-time translation loading continue to work. Right now, WordPress still expects corresponding .po and .mo files for things like update checks. However, this limitation will be addressed in the future, see #60554 for more information.
Note: if you donโt see any .l10n.php translation files in wp-content/languages yet, it might be that the language pack hasnโt been updated in a while, i.e. there were no new translations.
Hereโs an example of a PHP translation file as supported by WordPress 6.5:
<?php
return [
'project-id-version' => 'WordPress - 6.5.x - Development',
'report-msgid-bugs-to' => 'polyglots@example.com',
'messages' =>
[
'original' => 'translation',
'contextEOToriginal with context' => 'translation with context',
'plural0' => 'translation0' . "\0" . 'translation1',
'contextEOTplural0 with context' => 'translation0 with context' . "\0" . 'translation1 with context',
'Product' => 'Produkt' . "\0" . 'Produkte',
],
];
Note: EOT here stands for the โEnd of Transmissionโ character (U+0004, or "\4" in PHP). Itโs the same delimiter as in gettext used to glue the context with the singularโstring.
Generating PHP translation files
If you would like to generate these PHP translation files yourself, version 4.0 of GlotPress, the plugin that powers translate.WordPress.org, already supports the new .l10n.php format.
In addition to that, WP-CLI 2.10.0 (i18n-command 2.6.0) provides a new wp i18n make-php command to create these PHP files from a given .po file. Examples:
# Create PHP files for all PO files in the current directory.
$ wp i18n make-php .
# Create a PHP file from a single PO file in a specific directory.
$ wp i18n make-php example-plugin-de_DE.po languages
If you are developing a WordPress plugin that deals with translations, you can also use the new WP_Translation_File class to convert an .mo file into a PHP file. Example:
$contents = WP_Translation_File::transform( $mofile, 'php' );
if ( $contents ) {
file_put_contents( $path_to_php_file, $contents );
}
New filters to customize this behavior
If you would like to disable the support for PHP files for some reason; for example, if you donโt have any yet in your project and want to prevent the extra file lookup operation, you can use the new translation_file_format filter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. to change the preferred format (default is php) like so:
add_filter(
'translation_file_format',
static function () {
return 'mo';
}
);
The existing load_textdomain_mofile filter can still be used to filter the .mo file path for loading translations for a specific text domain. However, it only works for .mo files. To filter the path for a translation file, be it a .l10n.php or a .mo file, use the new load_translation_file filter.
Working with the $l10n global variable
Previously, when loading translations, WordPress would store an instance of the MO class in the $l10n global variable. With WordPress 6.5, this will be an instance of a new WP_Translations class that acts as a shim with similar characteristics. If your project directly works with this global variable or the MO class in some way, this is an area to keep an eye on.
Cached list of language file paths
This another slight performance improvement but unrelated to the new localization library covered above.
In places such as get_available_languages() and WP_Textdomain_Registry, WordPress used to directly use the glob() function to retrieve all .mo files in a specific directory. This is important for just-in-time translation loading and generally knowing which translations are installed. However, on sites with a large number of language files, the glob() operation can become expensive.
Because of this, a new caching mechanism was introduced in #58919 / [57287]. The file lookup is now handled centrally in WP_Textdomain_Registry and stored in the object cache in the translations group, with the cache key having the format cached_mo_files_<hash>, where <hash> is the MD5 hash of the scanned directory, e.g. wp-content/languages. The cache is cleared whenever language packs are updated.
Also, the lookup now also scans for .l10n.php files in addition to .mo files, in case only the former exist on a site.
More questions? Please let us know
If you have any questions, please leave a comment below or file a new ticket on Trac under the I18N component if youโve encountered any bugs.
Props to @joemcgill, @stevenlinx for review.
#6-5, #dev-notes, #dev-notes-6-5, #i18n
You must be logged in to post a comment.