Make WordPress Core

Tagged: i18n Toggle Comment Threads | Keyboard Shortcuts

  • Pascal Birchler 7:26 am on October 18, 2016 Permalink |
    Tags: , i18n   

    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!

    • Chantal Coolsma 7:42 am on October 18, 2016 Permalink | Log in to Reply

      I will definitely help testing this when it is available for testing.

    • Pascal Casier 8:04 am on October 18, 2016 Permalink | Log in to Reply

      Count me in !
      This is very useful for smaller teams e.g. fr_BE to be able to have fr_FR translations if the plugin/theme is not yet translated into fr_BE
      But also for a ‘startup’ locale like nl_BE where people could already switch from the beginning to nl_BE but still have nl_NL as backup language while nl_BE is started.
      However please remember the final goal is that the plugin/theme gets translated into the main language of the site, so warnings/indications that it uses the backup language should be indicated somewhere and point to e.g. GlotPress where people could contribute.

      • Pascal Birchler 8:31 am on October 18, 2016 Permalink | Log in to Reply

        However please remember the final goal is that the plugin/theme gets translated into the main language of the site, so warnings/indications that it uses the backup language should be indicated somewhere and point to e.g. GlotPress where people could contribute.

        The user’s desire is to simply have a great experience with functioning translations. A warning doesn’t sound like a great experience, but we can try to pick this topic up during the chat. It sounds more like a case for #23348 / #33007 though.

    • Torsten Landsiedel 9:21 am on October 18, 2016 Permalink | Log in to Reply

      I think Bernhards Plugin is working for most uses cases here:

      And if you need more, there is a filter for doing a “fallback chain”.

      I don’t know if it is needed to provide a UI to configure a fallback chain (as seen in the screenshots) as I don’t think it is needed by the majority os users.

      I really would like to see this in core and I’m happy to help with testing it.

    • pix365 9:48 am on October 18, 2016 Permalink | Log in to Reply

      I’d go for this be in the core – With the provision that it has ta UI. Why? as i think this provides a simpler management work-flow that will suit none tech savvy users, without this UI, how would one change the preferred languages and their order? ( custom coding, I guess.)

    • Ryan McCue 9:56 am on October 18, 2016 Permalink | Log in to Reply

      Sounds great to me! Is there any sort of standard that lists sets of languages with fallbacks that could simplify the UI here? (i.e. “de-ch should fallback to de-de”) Having the UI available still would be nice for the case where you know two unrelated languages, however, so I think the UI does make sense.

      • Pascal Birchler 10:10 am on October 18, 2016 Permalink | Log in to Reply

        I initially suggested something similar in the ticket:

        Why not create a new translatable string for a fallback chain. For example, in de_CH_formal we’d say we want to fall back to de_CH, de_DE_formal, de_DE — and of course to en_US in the end. This information could be translated on translate.wordpress.org by each locale.

        Leaving such a decision to translation maintainers or even plugin developers wasn’t perceived as a great idea back then, as it might not work under all circumstances. Using such a list to help simplify a UI might be worth exploring though.

        • Bernhard Kau 11:27 am on October 18, 2016 Permalink | Log in to Reply

          I liked the idea of a translatable string, as the translation maintainers usually know best which fallback chain is best. Adding a filter would also enable a developer to change it.

      • Mike Nelson 4:30 pm on October 18, 2016 Permalink | Log in to Reply

        +1 to having core just have default fallbacks if possible. If that’s able to serve 90% of users, then I think its reasonable for the other 10% to use a plugin which gives them a UI for customizing the fallback behaviour

      • Ze Fontainhas 7:51 pm on October 18, 2016 Permalink | Log in to Reply

        Much as I completely understand the drive for “standard fallbacks”, I’m not sure I love the idea, as it very much sounds like an engineering solution to a problem that isn’t one, or at least one that can’t be tackled by an algorithm. My problem with the approach is that it tries to impose hierarchy (i.e. “this language/variant is more… something than this other language/variant”), when not only does such hiereachy exist in real life, but simply cannot exist. To give an example, it is perfectly reasonable to imagine that users of pt_PT (Portuguese, Portugal) would fallback to pt_BR (Portuguese, Brazil) and that users of pt_BR would fallback to pt_PT. In fact, we (pt_PT) do it quite often, as do they (pt_BR). Why would one of those two be more…something than the other?

        • Bernhard Kau 10:52 pm on October 18, 2016 Permalink | Log in to Reply

          If we have a translatable string, each language pack could define it’s own fallback chain. So pt_PT could have pt_BR and pt_BR could have pt_PT.

          I agree that it’s not possible to have a perfect hierarchy, as this just doesn’t exists. But making it possible for the GTE to define a standard and adding a filter to enable (plugin) developers to change it, looks like a pretty good idea to me. And all is better than the current, non-existing, fallback to English.

          • Ze Fontainhas 10:58 pm on October 18, 2016 Permalink | Log in to Reply

            Fine, but

            > each language pack could define it’s own fallback chain.

            Let’s bring in another variant of pt_, say pt_AO (Angola, non-existant as of yet, but the case can be made with all the es_ variants). I, as a language pack admin, wouldn’t want to impose my vision (because it *is* a vision, and a subjective one at that) that the chain should be, say, PT, BR, AO. Why not PT, AO, BR?

            I think it’s for each user/site admin to determine that.

            • Bernhard Kau 11:03 pm on October 18, 2016 Permalink

              Which they could do using the filter or a plugin.

              Decisions, not options 😉

              I would bet any other software that has a fallback did make that decision.

            • Ze Fontainhas 11:20 pm on October 18, 2016 Permalink

              Please, it’s not an option, it’s a decision. It’s just one that isn’t up to the language pack admin to make.

        • Samuel Wood (Otto) 11:54 pm on October 18, 2016 Permalink | Log in to Reply

          Ze, computers can’t make the decision for you. A hierarchy must exist so that the computer knows what to do. Therefore, somebody must make the decision.

          If there is no pt_pt, but there’s both pt_br and pt_ao available, which do you use? Some logic must exist to make that choice.

          Putting such a thing back on the user is avoiding the problem instead of solving it.

          • Ze Fontainhas 12:18 am on October 19, 2016 Permalink | Log in to Reply

            > computers can’t make the decision for you

            Nor ought they, and that is precisely my point. For a user, the fact that a “language pack admin” or “a computer” made that decision is the same: it is all “computer says x”.

            > Some logic must exist to make that choice.

            Indeed it must. I’m saying is that that logic will inevitably be the site’s administrator’s, not someone else’s (me, the language pack admin.) I’m saying that it is not possible to guess that logic for every single site administrator (and sorry, no, filters and more plugins are most clearly *not* editorial tasks.)

            Look, I’m wasn’t being religious about this, sorry if it came across that way. I will of course embrace the consensus decision, as always. It’s just that making these kinds of (eminently editorial) calls in spite of the sites’ owners gives me an itch.

            • Samuel Wood (Otto) 1:24 am on October 19, 2016 Permalink

              The site administrator is the “user” in my view. Sorry if that wasn’t clear.

              I’m cool with ways to override things, naturally. But a default should exist so that people don’t have to make that choice if it’s pretty standard for most cases.

    • Jonathan Bardo 12:55 pm on October 18, 2016 Permalink | Log in to Reply

      I like the idea of a chain of fallback that we would be able to reorder as the user see fit. I also don’t think there is a universal pattern here and we shouldn’t assume anything when it comes down to what is the best fallback for any geographic location.

    • Greg Ichneumon Brown 3:28 pm on October 18, 2016 Permalink | Log in to Reply

      Have you already looked at HTTP_ACCEPT_LANGUAGE? I don’t see it used anywhere in core. Those FF and Chrome settings get converted to HTTP headers which then define fallbacks. We use this on wp.com for trying to select the best language for a user during initial signup. Ping me on .org Slack for example code if that helps.

      I don’t know the extent to which users properly set multiple fallback languages though.

      • Samuel Wood (Otto) 11:57 pm on October 18, 2016 Permalink | Log in to Reply

        They often don’t, but I’d say that is a valid use case for choosing default languages to display in admin on a per user basis, if such a thing happens. But maybe not the best choice for deciding fallback to other language variants.

    • John Blackbourn 4:29 pm on October 18, 2016 Permalink | Log in to Reply

      As Greg mentioned, the browser language settings get sent with each request via the HTTP_ACCEPT_LANGUAGE header. It would be very worthwhile researching whether these settings could be used either as a seed for the user’s settings in WordPress, or whether it could be used as the actual language stack in place of a new UI in WordPress, or as a fallback for when the user has yet to set their language stack in WordPress.

    • Patrick Robrecht 5:23 pm on October 18, 2016 Permalink | Log in to Reply

      +1 for language fallbacks in the core. I don’t see any need for a fallback list UI for the list as fallbacks seem be quite clear:

      • For de_CH_informal the fallback list could be (in this order) de_DE (informal), de_CH_formal, de_DE_formal
      • For de_DE_formal the fallback list could be de_CH (formal), de_DE (informal), de_CH (informal)

      i. e. choosing other locales of the same language, but for languages with formal and informal versions consider about the formal/informal variant if available.

      As @casiepa I think that it’s important to show administrators if a fallback is used such that I’m informed if the de_DE is used instead of de_DE_formal as a company having set the German “Sie” as language might not want to use the “du” variant as fallback. If they get notified, then can check whether this is relevant for the plugin they use or simply contribute the missing translations.

      +1 for showing a hint “X isn’t available in your language yet. Translation is at y % – you can contribute translations at “. X could be WordPress itself or any plugin or theme.

    • Dirk Weise 6:10 pm on October 18, 2016 Permalink | Log in to Reply

      I’d rather see my native language in my blog’s backend when I log in from a Chinese internet café to update my page with my latest impressions instead of having to guess what I’m doing. I think this header is more useful for displaying a fitting front end language to a visitor than choosing an administration page language.

    • Knut Sparhell 3:54 am on October 19, 2016 Permalink | Log in to Reply

      Both language preference and most of the fallback question was solved over 20 years ago and communicated over HTTP_ACCEPT_LANGUAGE. If user language option is not set, and the preferred language in HTTP_ACCEPT_LANGUAGE is installed, use that, top down.

    • Dominik Schilling (ocean90) 11:04 am on October 19, 2016 Permalink | Log in to Reply

    • Juniper 7:24 pm on October 20, 2016 Permalink | Log in to Reply

      Great brainstorming on an excellent idea! Configurable language-variant stacks.

      The data themselves could be stored as a simple string ‘aa_ee, aa_bb, cc_gg’ on three levels: WordPress defaults set in code or database, site defaults defined in wp_config or set in wp_options, and user defaults in usermeta; then concatenated to prefer user stack then site stack then wp stack.

      The add/remove/order UI could make it easy to select a language family (a cluster of related language-variants) at one go and then order & remove individual variants within it.

      Like it or not, we can’t avoid setting fundamental defaults for the underlying code to guide fallbacks in case none of the requested variants are available, even if doing so might feel like linguistic bias. If a stack consists of ‘de_ch_formal, de_ch’ but no Swiss German variant is available, I’d hope the software would be clever enough to default to any DE on hand before it defaulted to EN. But if EN is not the underlying default, what will be? Since we can’t avoid that ultimate bias, I figure we might as well create a variety of biases from which to choose; in selecting a language-specific version of WordPress to install or download, one implicitly selects a set of language stack defaults that is biased toward, variously, English or Chinese or Portuguese, etc.

      Pascal – “improving the experience for WordPress users who use the product in non-English languages, of which multiple locales may exist.” I would prefer, “who use the product in languages for which multiple locales exist.” Prithee don’t omit English from consideration of significant locale variants. Even if the variations are more often orthographic (spelling) rather than lexical (word choice), the differences do matter.

      Perhaps this goes without saying, but I easily see the same mechanism catering to both back-end and front-end users. While a language-selection UI may become part of the standard back-end admin settings it also could and arguably should have (perhaps as a bundled plugin) a stylable, configurable widget to be used by website visitors to set their language preference in the front end. In such a widget, storing its data in a cookie if the user isn’t logged on, the default presentation could simply be a single-selection menu of available language groups and/or variants as pre-selected by the site admin without any of the back-end’s stack-editing complexity.

  • Dominik Schilling (ocean90) 7:28 pm on October 10, 2016 Permalink |
    Tags: i18n,   

    JavaScript Internationalization 


    Over the last few releases, WordPress has made huge steps in prioritizing internationalization and localization throughout around core. To name a few highlights: language packs for core, language packs for plugins and themes, a language chooser, just-in-time loading for translations, and a user-specific language setting. But core isn’t the only place improvements have been made.

    translate.wordpress.org is the platform for making WordPress available in as many languages as possible. Did you know that WordPress 4.6 is currently translated into 72 – s e v e n t y t w o – languages? Recently the number of unique translators passed the 10k mark. 🌎🌍🌏

    The platform is powered by GlotPress, a collaborative, web-based software translation tool.

    Internationalization is not a feature, it fixes a usability issue for many users whose primary language is not English. And that’s about 47% of our users.

    The next big thing

    As of today, WordPress doesn’t support a proper internationalization API in JavaScript. There are two, 4-year old tickets, #22229 and #20491, which request such an API. (The former one was closed as a duplicate of #20491 since an internationalization API in JavaScript should provide support for plurals by default.)

    And that’s what this post is about: JavaScript Internationalization.

    @swissspidy and I (@ocean90) have been thinking about and working on this topic, and now is the time to gather feedback on the direction and get help from everyone interested.

    As you may have noticed in the prequel, internationalization spans more than WordPress core. We’ve split the task into four areas: Core, GlotPress, wp-i18n-tools, and language packs.

    Jed and wp.i18n (Core)

    Since we didn’t want to reinvent any wheels, our proposal is to use Jed as the base library. Jed provides “Gettext Style i18n for Modern JavaScript Apps”.

    wp.i18n will be a wrapper for Jed and should be used by WordPress and plugins/themes. One of the biggest benefits of leveraging Jed is that the actual implementation is very similar to the one we already have for PHP code. The latest patch currently introduces these API functions:

    • wp.i18n.getLocale()
    • wp.i18n.loadLocaleData( data )
    • wp.i18n.addTranslations( domain, data )
    • wp.i18n.__( text, domain )
    • wp.i18n._x( text, context, domain )
    • wp.i18n._n( single, plural, number, domain )
    • wp.i18n._nx( single, plural, number, context, domain )
    • wp.i18n.esc_attr__( text, domain )
    • wp.i18n.esc_html__( text, domain )
    • wp.i18n.esc_attr_x( text, context, domain )
    • wp.i18n.esc_html_x( text, context, domain )
    • wp.i18n.numberFormat( number, decimals )
    To do
    • Rethink WP_Scripts::load_translation_file() and get_js_i18n_data(), add tests.
    • Get feedback on the proposed API. (That’s this post!)
    • Apply the new API in our JS files.
      • There’s a POC patch that can be worked upon.
      • Do not forget: Underscore templates.
    • Include date of json files in update requests for language packs.
      • See wp_get_installed_translations().
      • See wp_get_json_file_data(), maybe json_decode() might be enough for this case.
      • What’s the format for meta data? See this GitHub issue for discussion.
    • sprintf() in JavaScript – useful for core?

    GlotPress (translate.wordpress.org)

    Jed supports JSON for translation files. GlotPress currently doesn’t support exporting translations in a JSON format. But there is a pull request which adds the required functionality to GlotPress. The format is going to support “simple” JSON (key -> value) and a Jed 1.x compatible format. The latter will be used by wp.i18n.

    To do
    • Get the PR merged. Done. 🎉
    • Find a solution for the missing meta data, see the GitHub issue mentioned before.
    • To enable exports like “get all translations for file common.js”, the current filter system in GlotPress needs to be improved to support search only in file references and search for multiple file references.

    wp-i18n-tools (Meta)

    A script named MakePOT parses PHP files to extract the original strings and their file references. This script needs to be extended to also parse JavaScript files. A POC has been created.

    To do
    • Convert the POC into nice code with tests.
    • Fix #20881 because it’s important for the GlotPress export that all file references remain.

    Language Packs (Meta)

    Currently a language pack includes a .po and a .mo file. Support needs to be added so that a .json file gets bundled if a project has translations for JavaScript files.

    To do
    • Export Jed files when JS translations exist.
    • Include JSON file in language packs.
    • Update API to support version checks for JSON files.


    Thanks for reading, now it’s your turn. 🙂 Do you have any feedback? Are there things we should do differently? Do you have resources to help us? Please let us know in the comments!

    There are currently no meetings scheduled but we’re happy to discuss any topics in #core-i18n. Just say “Hi”!

  • Pascal Birchler 4:49 pm on July 6, 2016 Permalink |
    Tags: , , i18n   

    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 WordPress.org’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

    jQuery UI datepicker localization in 4.6

    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.


  • Torsten Landsiedel 4:23 pm on July 6, 2016 Permalink |
    Tags: , , , i18n   

    jQuery UI datepicker localization in 4.6 

    In WordPress 4.6 (#29420) localization defaults were added for the jQuery UI datepicker based on the current locale using the new wp_add_inline_script() function. With 4.6 you can enqueue the datepicker and you are set. It works out of the box.

    Instead of using the language files from the jQuery UI project the necessary information, mainly from the WP_Locale class, is directly passed to the datepicker. The list of localized information: closeText, currentText, monthNames, monthNamesShort, nextText, prevText, dayNames, dayNamesShort, dayNamesMin, dateFormat, firstDay, and isRTL.

    If you are using the files from jQuery UI in your theme or plugin, please be aware of this change. With 4.6 you can omit calling these files and enqueue the default datepicker which will use the built-in defaults from WordPress.

    If you want to change the defaults or add custom settings, you can still use all the arguments from the datepicker. WordPress only sets sane defaults for the chosen locale. But you should check if jQuery UI datepicker is enqueued and you should check if the browser is showing a native datepicker (like Chrome).

    @ipstenu has scanned the plugin repo for plugins including the jQuery UI files. The following plugins can be changed to use WordPress’ own translations.

    Advanced Booking Calendar, Albo Pretorio On line, Altos Toolbar, AWPCP – Classifieds Plugin, Appointment Calendar, Banner Garden Plugin for WordPress, BBS e-Popup, Beaverlodge Maintenance, Beaverlodge Menu Styler, BigContact Contact Page, Blog Post Calendar Widget, Booking Calendar Contact Form, Events Calendar, Class Booking, Contact Form 7 IE DatePicker and Number Spinner Fix, Custom fields, Datepicker i18n, Easy Calendar, EEXCESS, Event Post Type, Events Made Easy, Events Manager, Social Marketing Scheduler, FormCraft – Form Builder, Date Picker in List Fields for Gravity Forms, Gravity Forms (Spanish), Gravity Forms (nl), inquiry form creator, Jet Event System for BuddyPress, JQuery Accessible Accordion, JQuery Accessible Autocomplete, JQuery Accessible Button, JQuery Accessible Carousel, JQuery Accessible Checkbox, JQuery Accessible Datepicker, JQuery Accessible Dialog, JQuery Accessible Menu, JQuery Accessible Progressbar, JQuery Accessible Slider, JQuery Accessible Tabs, JQuery Accessible Tooltip, JQuery Accessible Tree, Js-appointment, LearnPress – WordPress LMS Plugin, LePress, List Urls, Livemesh SiteOrigin Widgets, Lodgix.com Vacation Rental Listing, Management & Booking Plugin, MailChimp List Subscribe Form, Social Media Share Buttons | MashShare, Member Register, Membership 2, Meta Collections, mind-body, Tribulant Newsletters, Orbis, Order Delivery Date for WooCommerce, OpenWebAnalytics, Pay2Post, PDF Catalog, Pronamic Events, RPB Calendar, Vinum Master Tracking Plugin, Simple Ads Manager, Simple Photos Contest, Sk Multi Tag, Solidres – Hotel booking plugin for WordPress, Cubilis Fastbooker, Surbma – Datepicker localization for Gravity Forms, teachPress, TemplatesNext ToolKit, TheNextTable, Toolset Types, Uiform – Cost Estimation & Payment Form Builder, Uiform – Form Builder, Vacation Rentals, Video Central for WordPress, Visual Form Builder, Webagency Widget – Website builder, WEeventscalendar, WooCommerce Checkout Manager, WooCommerce Quick Donation, WP Agenda, WP-AMD – Global JS and CSS handling, WP Any Form, WP Contact Slider, wp-creator-calculator, WP-CRM – Customer Relations Management for WordPress, WP FEvents Book, wp-greet, WP-Invoice – Web Invoice and Billing, WP Maintenance, WP Online Store, WP-Property – WordPress Powered Real Estate and Property Management, Wp-Recall, WP Scripts Updater, WP Swiper, wpShopGermany Free, and XO Event Calendar.

  • Dominik Schilling (ocean90) 12:42 pm on April 22, 2016 Permalink
    Tags: , i18n   

    I18N Kickoff for 4.6 Chat Summary 

    This is a summary of the I18N Kickoff chat from April 21st.

    Attendees: @petya, @SergeyBiryukov, @swissspidy, @ocean90

    JavaScript i18n

    User Admin Language

    • #32879 was closed as a duplicate of #26511.
    • Having a switch_to_locale() function is a precondition for #29783 and thus this feature is part of the 4.6 milestone.

    Language Packs

    • To push language packs to the next level, #34213 (Change priority for loading theme/plugin translations) and #34114 (Remove the requirement to call load_plugin_textdomain() or load_theme_textdomain()) are part of the 4.6 milestone.
    • #34213 should go in early.
    • #34114 needs a refresh and the tests should make use of the WP_LANG_DIR constant.

    Database Collation

    • No decision was made for #32405 because @pento wasn’t around.

    Other Tasks

    • @swissspidy mentioned #18146 (Add user-level timezone setting) as an UX improvement similarly to #29783
      • @ocean90: “Have to read that ticket in detail but one of the biggest task is probably to define the line between user setting and site setting.”
    • @SergeyBiryukov volunteers to expand https://make.wordpress.org/core/handbook/best-practices/internationalization/
    • @SergeyBiryukov mentioned #13651 and that it should finally get fixed.
      • @ocean90 will review the latest patch.
    • @ocean90 mentioned that the i18n report has a lot of tickets by @ramiy related to “Avoid using HTML tags in translation strings*” which need to be reviewed. One of the reasons why it’s good to have the handbook page ready as soon as possible.
    • @ocean90 mentioned Ginger-MO https://github.com/dd32/ginger-mo, “a minimal .mo reader (with support for PHP & JSON representations), multiple text domains, and multiple loaded locales in the future” by @dd32.
      • @swissspidy asked what this would mean for #17268.
      • (after the chat) @dd32: “As for Ginger-MO, my main intention was so we *didn’t* have to use the native gettext tools. I built it with one aim – To get English (US) and non-English pageloads closer to eachother in terms of performance.”

    Bug Scrub

    It was decided that the first bug scrub for the i18n component is on Tuesday April 26th, 2016 at 18:00 UTC.


    Full meeting logs: https://wordpress.slack.com/archives/core-i18n/p1461243825000006

  • Dominik Schilling (ocean90) 8:31 am on April 20, 2016 Permalink
    Tags: , i18n   

    I18N Kickoff for 4.6 

    This Thursday, 21 April, 13:00 UTC we’ll have an I18N chat in #core-i18n to discuss the roadmap and ideas for 4.6.

    Some of the bigger tasks on which could be worked during the cycle:

    JavaScript i18n:

    • #20491: Introduce JavaScript i18n functions
    • #22229: Plurals in JavaScript

    User Admin Language:

    • #29783: Main ticket
    • #26511: Separate locale for the admin toolbar
    • #32879: Live switching Language

    Language Packs:

    • #34213: Change priority for loading theme/plugin translations
    • #34114: Remove the requirement to call load_plugin_textdomain() or load_theme_textdomain()

    Database Collation:


    There are currently 77 open tickets in the I18N component which we should try to reduce. It would be nice to get our long planned handbook page about best practices for Internationalization in core (see also Spelling) finalized too.

    Please share in the comments below if there are any specific features and tickets that you want to contribute in this next release. Otherwise, please also join us in #core-i18n chat to discuss.

  • Dominik Schilling (ocean90) 12:13 am on September 5, 2014 Permalink
    Tags: , , i18n   

    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.
    • eliheiss 12:38 am on September 5, 2014 Permalink | Log in to Reply

      Very cool! This means great things in the future for WordPress in non-English speaking countries.

    • camu 1:21 am on September 5, 2014 Permalink | Log in to Reply

      I can’t wait to be able to implement something like this in my plugin 😉 So that I don’t have to ship all the .po/mo files every time.

    • Michael Beil 3:36 am on September 5, 2014 Permalink | Log in to Reply

      thanks for the update @ocean90.

    • Ansel Taft 4:36 am on September 5, 2014 Permalink | Log in to Reply

      Is there a parameter that can be set in wp-config.php to pre-select the default language(s)?

    • pavelevap 10:42 am on September 5, 2014 Permalink | Log in to Reply

      OK, thank you for info, it makes sense! But I do not understand following issues:

      1) There are language packs (only WP core localization files) and localized packages (the whole localized build). So users will download de_DE for 4.0 version (localized package) and they will never see language chooser? They have to download original English version to using language packs? So localized versions will be removed in the future?

      2) Language packs are created automatically? Is there any period, for example once a day (24 hours)? Or whenever something changed in GlotPress?

      3) Language packs are not updated automatically in background on website? Only when installing/updating plugin/theme? Is there any chance how to enable it automatically in background (like minor WordPress releases)?

      • Dominik Schilling (ocean90) 9:48 am on September 6, 2014 Permalink | Log in to Reply

        1) Yes, localized package won’t see the chooser. But it will be improved and yeah, the main goal is to remove localized packages. But this needs its time. And manpower.

        2) Yes, they’re created automatically, see make/polyglots post: “Percent completion is checked periodically and language packs are then built.” (The interval is currently controlled manually by us.)

        3) Language packs are updated automatically. It’s enabled by default.

    • weblizar 10:04 am on September 6, 2014 Permalink | Log in to Reply

      I have an issue regarding WordPress 4.x Translation function. Translation working on all previous WordPress version 3.x but not working with latest once.

      I had posted the my issue on WordPress Forum.

      Link: https://wordpress.org/support/topic/plugin-translation-not-working-in-wordpress-4x

      Someone please look at this.

    • springoOo 9:26 am on September 7, 2014 Permalink | Log in to Reply

      Hello, I’m wondering is there a way to select the language programmatically? I Mean how i can override the wplang option throw the theme? to change for the visitor not all the installation?

      any help?


    • Karalius 5:30 am on September 9, 2014 Permalink | Log in to Reply

      ok. i installed in english, but now i wanna to change Site Language into Lithuanian. HOW to do that?


      • Dominik Schilling (ocean90) 4:17 pm on September 10, 2014 Permalink | Log in to Reply

        See [29691] and #29456.

        • Define WPLANG in wp-config.php
        • Go to wp-admin/options-general.php
        • Select your WPLANG at Site Language
        • Go to wp-admin/update-core.php
        • Click “Update translations”, when available
        • Core translations files are downloaded, when available
    • szaqal21 12:33 pm on September 10, 2014 Permalink | Log in to Reply

      Karalius I think you won’t be able to do that until you will manually download your target language and copy it to languages dir then it will show up in the language select list. I don’t understand it, I thought that select language list will have more languages that those in languages dir by default and after selecting particular language files will by downloaded…

    • geoffmartinmorris 4:47 am on October 29, 2014 Permalink | Log in to Reply

      Hi, I made a fresh install of wordpress 4.0 via Quick Install on my cpanel and didn’t have any option for languages. I also don’t have the option available in General Settings, what’s the easiest way to fix this?

    • centurypixel 1:18 pm on November 2, 2014 Permalink | Log in to Reply

      It is interesting that until I add the define(‘WPLANG’, ‘tr_TR’); in the wp-config.php file, the General Settings will not display the ‘Site Language’ option.

      Another thing is that, for example, I have the ru_RU and tr_TR .p and .mo files in the themes root folder. Because the WPLANG is set to tr_TR the ‘Site Language’ option gives me 2 English (United States) and Turkish option, but will not give Russian option as it is not defined in WPLANG. But I do have the ru_RU .po and .mo files there.

      I am a bit confused about how this all works.

      • centurypixel 1:21 pm on November 2, 2014 Permalink | Log in to Reply

        Sorry, I meant that the Site Language drop-down gives me 2 language options, English (United States) and Turkish, but does not recognize the Russian .po and .mo files. I am guessing because WPLANG is set to tr_TR in wp-config.php?

    • kalico 9:14 am on November 12, 2014 Permalink | Log in to Reply

      With sincere apologies (and a request for redirection) if this is the wrong place to share the following information: my autoupgrade failed with the message “Could not copy file.: wp-admin/js/language-chooser.min.js”. This resulted in a partial upgrade (newly overwritten files were not reverted to the old version), complete with WSOD on site and admin pages. I proceeded to do a manual install, and everything restored perfectly. Since this appears to be a new file in 4.0, I’m guessing a permissions/ownership problem on my side may have prevented copying the new file to the server (we’ve had related issues). Any suggestions would be most welcome, so that I might avoid this issue in the future.

      • John Blackbourn 4:09 pm on November 12, 2014 Permalink | Log in to Reply

        Hi kalico,

        We would love to get some more information on this problem, as a WSOD is the last thing we want users to see, even when an upgrade goes wrong. Could you open a bug report on our issue tracker please? https://core.trac.wordpress.org/newticket. Information such as your OS, the name of your web host, what version of PHP you’re running, and your site’s domain name (I believe there are some limited logs we can pull from the WordPress.org API if we know the domain name).


  • Andrew Nacin 7:48 pm on July 2, 2014 Permalink
    Tags: , i18n   

    Here’s where we are on the five goals for internationalization outlined previously:

    1. The first step installing WordPress should be to choose a language. The rest of the install process would then be in that language.

    First pass done in #28577. There is a list of things to do in the ticket, which includes:

    • Improved error handling when the API or filesystem isn’t accessible. Working on this.
    • Bring this to setup-config.php. Working on this.
    • Place browser-based language suggestions at the top. Working on this.
    • Use better markup rather than simple select/option HTML, currently being worked on by @jorbin.

    2. You should be able to choose/switch a language from the general settings screen, after which the language pack should be downloaded.

    This simply requires replacing mu_dropdown_languages() with a new method that handles uninstalled languages gracefully. This is easy to implement and relies on much of the same code as the install process, so it’s simply on hold until that’s done. I’ve also worked out a UX flow with @sonjanyc.

    3. You should be able to search from the dashboard for plugins and themes that are available in your language.

    This is handled on the WordPress.org side. The updated plugins screen will need to pass a new argument to filter by language, and then remove that argument if the user requests showing plugins in any language. We’ll need to hack in readme/description translation support but that’s a small API change and otherwise WordPress.org work, not core work.

    4. All localized packages should be able to be automatically generated and made available immediately as part of the core release process.

    A script for this is written. While it needs more work, it was used as a test to build 3.9.1 packages, which are doubling as 4.0-alpha testing packages. This does not require changes in core.

    5. Localized packages should only be used for initial downloads from WordPress.org. Instead, language packs should be transparently used for updates.

    This is ready. A flag needs to simply be flipped in the API.

    Ongoing problems to solve:

    • I have a proposal to type up for how to handle readmes, license files, etc., in both core and plugins. Requires no core changes.
    • No one has picked up the plan to limit the code modifications still done in some locales. This may end up being a July project for me.
    • The relevant APIs we need in core were deployed to WordPress.org. Also, the plugin and theme directories are fully internationalized; we need to get those strings to translators and shoehorn them onto existing international sites.
  • Andrew Nacin 7:41 pm on May 21, 2014 Permalink
    Tags: , i18n   

    Internationalization goals for 4.0 

    Every few releases we’ve made a major push for improved internationalization. In 3.7, that was laying the groundwork for plugin and theme language packs (more on that soon). In 3.4, it was reducing all of the customizations that many localization teams needed to make. (There’s a page on that here.) In 4.0, I’d like to close the loop on a lot of this. Here’s what I’d like to accomplish, and I’ll need a lot of help.

    1. The first step installing WordPress should be to choose a language. The rest of the install process would then be in that language.
    2. You should be able to choose/switch a language from the general settings screen, after which the language pack should be downloaded.
    3. You should be able to search from the dashboard for plugins and themes that are available in your language.
    4. All localized packages should be able to be automatically generated and made available immediately as part of the core release process.
    5. Localized packages should only be used for initial downloads from WordPress.org. Instead, language packs should be transparently used for updates.

    That’s the what. The how poses extensive challenges.

    1) Choosing a language when installing WordPress. The rest of the install process would then be in that language.



    Split workflows: One issue that came up in #26879 (“friendlier welcome when installing WordPress”) is that setup-config.php is often not the initial entry point. A user installing WordPress through a hosting control panel is likely to be dumped onto the install screen (if not the dashboard directly).

    Thus, we need to keep in mind that either screen might be the “intro” screen. This introduces technical challenges: If the user’s first step is setup-config.php, we don’t actually have WordPress fully loaded at this point, which makes actually installing a language pack more difficult. The install step has WordPress loaded in full, just without database tables. We should look into making setup-config.php load “all” of WordPress to make these environments easier to code.

    Different approaches: There are two different ways to approach this: download language files immediately upon selection, or bundle barebones language files of the install screens for all supported languages. The latter is not the easiest thing to do (due to error messages and such, strings can come from all over) and also adds a delay to the adoption of new languages. The former would mean that we would want to pull a languages list from WordPress.org. (If we cannot reach WordPress.org, we would have no way of downloading the complete language pack, so this is not a big deal.) It’s still a bit of a challenge due to the split workflows problem.

    Recommending a particular language: WordPress.org already recommends a language based on the browser’s settings (Accept-Language header) as well as using a more rough lookup based on IP address blocks. (HTML5 location could be used, but unless we’re also going to use that to set the user’s timezone, it seems excessive for a “choose your language” for the moment, especially since location is not as preferred anyway.)

    Both would require the client to hit WordPress.org via JavaScript, versus a server HTTP request. We can do a server-side HTTP request to generate the list, then a client-side request to float recommended ones to the top. It’s possible to do it in two steps: the Accept-Language mapping can be done locally, while the IP-to-location table on WordPress.org has 2.9 million entries and would require a round-trip. Of course, if a user has downloaded a localized package directly from a local WordPress.org site, that would be the top recommendation.

    Note that by language or locale we also must consider other translation variants, as there may be a language like Portuguese available in multiple locales (Brazil, Portugal) and further broken down by formal and informal variants. Each of these would be listed as their own “language.” c.f. #28303

    2) You should be able to choose/switch a language from the general settings screen, after which the language pack should be downloaded.

    WordPress MU had this feature and it still exists in multisite (though it’s pretty broken in terms of how it handles locales, #13069, #15677, #19760). This however only worked for already installed locales.

    For single-site, the available languages should be fetched from WordPress.org and cached in a transient. (#13069 suggests using the GlotPress locale list, but as indicated above, we’d want to handle newly added or updated languages. This can then be displayed in a dropdown on the General Settings page. Upon selection and “Save Changes,” the language pack would be downloaded and enabled. We would likely use the oddly named “WPLANG” option since it’s what MU adopted and uses at both the site and network levels.

    If we can’t reach WordPress.org, or if a filter is applied, then only installed languages will be listed. (An untrusted multisite network will likely have a default filter in place, to match existing behavior.) We should try to cache failures to .org (generally — not just here) so things aren’t terribly slow when developing a site without internet. We could possibly lazy-fetch the list only when the user expands the dropdown (or clicks a “Change” link or something).

    Note this does not address two situations in particular: user-specific languages, or using the dashboard in English. These will be easier to do thanks to improvements in 4.0, but there still exist a number of edge cases where persistent translations can “bleed” into other situations. Examples include a comment moderation email being emailed to an English speaker but sent in the language of the logged-in commenter; or a string stored in the database like image metadata. When using a plugin, these are “edge cases.” When core adopts them, these become “bugs.” We will need to introduce a locale-switching method not unlike switch_to_blog() and also identify and work around any “persistence” issues. Not for 4.0, though we can get started on the groundwork.

    3) You should be able to search from the dashboard for plugins and themes that are available in your language.

    With language packs (more on that soon), plugins and themes will be able to be translated into any language. The goal would then be to have “localized” plugin and theme directories on the translated WordPress.org sites, listing just the plugins or themes available in their language. Note that even a plugin or theme without strings have a name and description that can be translated.

    The plugin and theme install screens in the dashboard should similarly gain this ability. In all cases, there would be an option to expand the search to plugins/themes available in any language, of course — along with the invitation to translate them.

    We will need to figure out how to make readme files translatable, which get parsed for the plugin directory (and eventually themes will gain these as well, possibly as part of these initiatives).

    4) All localized packages should be able to be automatically generated and made available immediately as part of the core release process.

    A localized package should merely consist of core WordPress plus a few translated files (the readme, the license, and the sample config file) and the PO/MO files. No other alterations should occur, which means translation teams will only need to translate, and builds can be automatically generated and made available immediately as part of the core release process.

    Local modifications. Before 3.4, every install needed to make modifications to WordPress as part of their localized package, whether by actually replacing core files or using a {$locale}.php file. By my audit, this now applies to only 14 locales.

    At the very least, we can allow the current system to work as-is for these locales. Ideally, though, we address the specific concerns of each locale and bring as many as possible into the fold. They include:

    • Some CSS modifications we can incorporate into core.
    • Workarounds for declension issues in a few locales, specifically regarding the names of months. #11226, also #21139, #24899, #22225
    • Adding major locale-specific oEmbed providers. #19980
    • Transliteration such as Romanization for Serbian. We can handle this by having two variants of Serbian, the way we have formal and informal European Portuguese. (But we’d automate these language packs, rather than forcing translations to happen twice.)
    • Significant changes in Uyghur (#19950), Farsi, Chinese, and Japanese (including the multibyte patch plugin).

    Additional concerns:

    License. Many locales also have an unofficial translation of the license. We should be able to collect any of these in a repository and include it automatically in a package. (Note that link is an explainer; no GPL version 2 translations are available from that page.)

    Readme. Some locales directly translate readme.html. Others add a second file and use one of two forms: the translated word “readme” (example: leame.html would be Spanish) or using a suffix (“readme-ja.html” for Japanese). We should standardize this somehow. Technically the readme changes with each version due to the version bump, but we can automate that. Bigger readme changes are fairly rare, but we’ll still need to figure out how to have these translated and tracked.

    wp-config-sample.php. This one is especially interesting. If a user has chosen a language on install, we don’t need the readme or license but we do need this file, as setup-config.php will display its contents in a textarea if we’re unable to write the file. We can store this file as a single translated string in a PO/MO file (in some automated fashion) or as part of the API response. We will also need some kind of way to translate and track this file to be included in localized packages that are downloaded.

    5) Localized packages should only be used for initial downloads from WordPress.org. Instead, language packs should be transparently used for updates.

    The WordPress.org API is set up to return a series of update “offers” — one of each type (“latest” a.k.a. reinstall, “update” and “autoupdate”), in both the site’s language and in English. This results in awkward double-upgrades even when no strings have been changed (updating first to English, then to the locale when it is available for that version) and is a lame experience. While auto-generating localized packages immediately will help, there’s no reason to actually use localized packages for updates. Any locale without local modifications can be set up as a language pack now.

    As of 3.7, WordPress core supports receiving instructions for language packs. We’d simply stop issuing localized package offers, start issuing language pack offers, and rip out some code on update-core.php that has been handling the multiple-offer dance. This is the easiest of the five 4.0 tasks but is dependent on the very complex fourth task.

    Next steps.

    Here’s an overall outline of the things we need to do. I’ll be creating relevant core and meta Trac tickets in the coming days, and I’ve also referenced a few related tickets I was able to find.

    Biggest problems to solve:

    • Figure out how to handle readmes, licenses, and wp-config-sample.php. This includes plugin (and theme) readmes as well. Remember we don’t want plugin developers to need to be involved in any way; and also that updates to these files will need to be handled elegantly (such that we have both ‘stable’ and ‘development’ tracks).
    • Eliminate all code modifications across all locales (as much as possible). Related, #20974.

    WordPress.org/API work:

    • Create an API for core to use to fetch available locales for download.
    • Create an API for core to use to recommend a locale based on browser settings/location.
    • Auto-generate localized packages and core language packs.
    • Serve core language packs for updates, not localized packages. Related: #23113, #27164, #26914, #27752.
    • Mirror the plugin and theme directories to locale sites, with full translations (including readme data) and with selective searching.

    Core work:

    • Add the ability to install a new language pack on demand.
    • Add a “switch to language” method, for languages that are installed. #26511
    • Add a screen that allows a locale to be chosen. May need to change how setup-config.php bootstraps WordPress.
    • Add a language chooser to the General Settings screen. #15677
    • Support searching for plugins/themes in a particular language, as well as leveraging translated data fields that come through from the API response. This mostly just means sending back the site’s language to WordPress.org. It also requires UI to reveal results from any languages. We could possibly filter/hide/show on the client side, if results were not paginated.
    • Take a machete to update-core.php’s localized build handling once everything else is done. Related: #25712, #28199.
    • MB Creation 7:47 pm on May 21, 2014 Permalink | Log in to Reply

      Evening Andrew,

      I think the what is awesome. I’ll try to think about and contribute to the how !
      Keep up the good work.


    • Charleston Software Associates 7:53 pm on May 21, 2014 Permalink | Log in to Reply

      Perfect timing!

      I am in the midst of testing an issue with my plugin that occurs when a user is not using English as the native language. Without boring anyone with the details, I found the need to quickly and easily switch from a native German to English version of WordPress to run through my test cycle for the upcoming patches. After the 4th edit of wp-config.php I was thinking “why the heck isn’t there a select language option on the General Settings of WordPress?”.

      Now I know why.

      I am going to talk to one of my lead contributors whom is my go-to “language issues” guy from the Netherlands and see what we can contribute to this endeavor. As I reach out to non-English-speaking customers this is an area we have been focusing on this year.

      Getting things like the up-front presentation, especially readme.txt, is probably the most prominent barrier to acceptance of the plugin in other languages.

      If we can continue the integration of things like WPML hooks, language files, and more localization hooks we may just be ready to attract more international users about the time 4.0 rolls out.

      Looking forward to bigger & better things with WordPress in the coming years!

    • Casey Driscoll 8:58 pm on May 21, 2014 Permalink | Log in to Reply

      This is really well done and thought out Nacin, nice work.

    • glueckpress 9:15 pm on May 21, 2014 Permalink | Log in to Reply

      Given this is huge already the question might be either out of scope, or of perfect timing: can we sneak a post language feature into 4.0? We’ve already been working on a plugin, the only thing is final implementation should happen in `WP_Post` which cannot be extended via plugin. Anyway, here’s what we’ve come up with so far. https://github.com/glueckpress/wordpress-post-language

      Regarding contributions to the roadmap above I’ll be happy to pitch this for the WordCamp Hamburg Contributor Day; as it looks like there’s going to be multipersonal unique language intelligence available.

      • Andrew Nacin 9:56 pm on May 21, 2014 Permalink | Log in to Reply

        I don’t see this as part of 4.0’s roadmap. It’s in the same boat as other things I mentioned like per-user languages, having the dashboard in English, and the like. For the moment, it’s a bit of a case of “cart before the horse,” but I think it makes a great plugin for now and could be considered for inclusion once we’re farther along.

    • terraling 9:21 pm on May 21, 2014 Permalink | Log in to Reply

      Hi Andrew

      Great to hear that internationalization will be getting so much attention with 4.0, but… (there is always a but).

      As is, it is nigh on impossible to make a multilingual site with WordPress. You can have a WordPress install in any language you like, as long as it’s only one language.

      Of course you can, as I have, customise wp-config.php or use plug-ins so that different users can see content on the front-end in different languages, but it’s only surface deep.

      Have someone write a post in English and then someone else who views the site in Spanish comment in pigeon-English on the post, the post author will receive the comment notification email in Spanish.

      It’s as if someone Polish sends you a friend request on facebook and the request email comes through in Polish. (And this is exactly what happens if you set up a multilingual BuddyPress site. Speaking with the developers they say it is pretty much impossible to fix without changes to WP core.)

      I’m not qualified to help make those changes, I’m afraid, but I think they are as important as the steps you’ve outlined above.

      • glueckpress 9:33 pm on May 21, 2014 Permalink | Log in to Reply

        Just think of the possibilities opened by a simple select box that sets a post as being written in a given language … now I’ll quit spamming. 😉

      • Andrew Nacin 9:50 pm on May 21, 2014 Permalink | Log in to Reply

        This post extensively covers this under task #2. See the final paragraph in that section.

        • terraling 8:05 am on May 22, 2014 Permalink | Log in to Reply

          Sorry Andrew, not sure how I missed those details.

          It requires storing a default language setting for each user. Rather than individual plug-ins producing their own solution, it would be great if the where and how could be standardised in core.

          • Andrew Nacin 3:54 pm on May 22, 2014 Permalink | Log in to Reply

            As indicated in the post, there are a lot of issues with doing this for now. If a plugin does it, it’s safe to call them “edge cases,” but once core does it, those edge cases become “bugs.” We would need to fix a number of issues of persistence and context before doing anything in core.

    • michalzuber 3:35 am on May 22, 2014 Permalink | Log in to Reply

      Wow, great. Like the first and second step. How much time did it take to write this, did you have a draft and worked on it? 🙂

      • Andrew Nacin 3:53 pm on May 22, 2014 Permalink | Log in to Reply

        It took about two or three hours to write, but of course we’ve been thinking about these problems for a long time.

    • Rami Yushuvaev 7:37 am on May 22, 2014 Permalink | Log in to Reply

      Nacin, the readme changes with each version due to the version bump is unnecessary. You need to remove the version number from the readme file.

      • Mike Manger 11:02 am on May 22, 2014 Permalink | Log in to Reply

        I think including the version number gives some context to the system requirements and update instructions for the specific version (“If you are updating from version 2.7 or higher”, PHP 5.2.4 is required for version 3.9).

      • Andrew Nacin 3:50 pm on May 22, 2014 Permalink | Log in to Reply

        As indicated in the post, “Technically the readme changes with each version due to the version bump, but we can automate that.” We should keep the version number but make it unnecessary for you to update it.

    • Fernandot 6:02 pm on May 22, 2014 Permalink | Log in to Reply

      Great, great, great!

      and … 


      This have been one of my everlasting wishes 🙂

    • Mariano Perez 6:30 am on May 23, 2014 Permalink | Log in to Reply

      This will bring the software to a higher level. Great decision.

    • Paal Joachim Romdahl 11:04 am on May 23, 2014 Permalink | Log in to Reply

      Thank you for sharing Andrew! In this process are there plans on having the default WordPress phrases on the frontend also change depending on language selected?

      • Andrew Nacin 5:22 pm on May 23, 2014 Permalink | Log in to Reply

        I’m not sure what this is referring to… But yes, the language selection would be equivalent to the WPLANG constant — it would apply to everything (themes, plugins, core; dashboard, frontend).

    • niknetniko 10:14 am on May 24, 2014 Permalink | Log in to Reply

      This is all very nice!

      I have a little question: you’re going to make WordPress download the correct languages pack when the user chooses a language, so: will this apply to plugins as well?

      If you download a plugin from within the WordPress admin area, would it be possible to only download the correct language pack with it?

      For example, if my WordPress installation is in Dutch and I install a plugin, it would download the plugin and only the Dutch language files. The same would happen when you change the language from the options.

    • Nashwan Doaqan 2:10 pm on May 25, 2014 Permalink | Log in to Reply

      Great!! .. Good News!! 🙂
      I will be happy to help you on this..

    • Charles Frees-Melvin 1:24 am on May 26, 2014 Permalink | Log in to Reply

      When dealing with plugins or themes and localizations. It should be added to a GlotPress entry that can be set, to list the fall back language if the prefered localization is not available for the plugin or theme. Like for en_CA to use a en_UK or en_AU before settling with an en_US. Or a pt_BR to settle on using a pt_PT if it exists.

    • Misamee 6:06 am on May 27, 2014 Permalink | Log in to Reply

      Thanks Nacin: the whole post sounds really intriguing!

      I’m working on WPML development and I’d like to keep an eye on three of these changes in particular.

      1. The first step installing WordPress should be to choose a language. The rest of the install process would then be in that language.
      2. You should be able to choose/switch a language from the general settings screen, after which the language pack should be downloaded.
      3. […] language packs should be transparently used for updates.

      As for the first and second points, we may use the WPLANG value as a default language, if define (something that we don’t currently do now).
      Each time this value get changed, WPML would need to know it: I suppose than a simple action would be enough for WPML to get the new information, and set it as a default language, rather than continuously checking if WPLANG got changed.

      As for the third point, if the core, a plugin or a theme gets a new language or an updated language, WPML could use this information (e.g. when user select to handle translations via WPML, rather than via po/mo files). Again, an action would be really helpful.
      Unlike the previous action, here I’m imagining something a bit more specific:

      // string $context: ‘core’ | ‘theme’ | ‘plugin’
      // mixed $data: null | plugin or theme data
      add_action(‘language_pack_downloaded’, $context, $language_code, $data);

      Of course, these are just suggestions: anything that could provide the information that a language pack got downloaded should be enough.

      By the way, there is any way to get all trac items related to the internationalisation changes in 4.0?

    • Amit Kvint 4:22 pm on June 1, 2014 Permalink | Log in to Reply

      Great work, looking forward to enjoying it.

    • Kaspars 8:17 am on June 3, 2014 Permalink | Log in to Reply

      I think you meant localization (l10n) instead of internationalization (i18n).

      • Andrew Nacin 1:12 pm on June 3, 2014 Permalink | Log in to Reply

        Well, it’s a mix. Generally, software does internationalization and translators do localization, as also indicated in the article you linked. Some of our work here does involve making changes to how WordPress is localized (such as integrating locale-specific tweaks) but for the most part internationalization is what’s happening here — making changes so it can later be localized.

    • Torsten Landsiedel 2:25 pm on June 4, 2014 Permalink | Log in to Reply

      @nacin: It would be great if someone have a look at this ticket for WordPress 4.0 again: https://core.trac.wordpress.org/ticket/17268
      This would be really awesome and important for non-english WordPress sites.

    • sonjanyc 10:10 pm on June 9, 2014 Permalink | Log in to Reply

      I’m happy to help with design for this (UI/UX)! After talking to @nacin yesterday, I’ve started working on wireframes and mockups. I’ve put together the flow for the installation process (both for manual WordPress install and 1-click-install).
      Installation flow: http://sonjaleix.com/wp-content/uploads/2014/06/i18n_W4.0_v0.1_flow.jpg

      Ideally we ask the user in the first step of the installation process to choose his/her language so the installation process is already translated. I’m not sure from a dev point of view if we can already install/download the language pack in that stage, but if not, we should at least have all installation screens translated.

      Since we have 135 languages (current list), the dropdown will be pretty long. I like the way apple translated the “Call-to-Action” in the example @nacin posted above, but I think it will be easier for the user to find and select his/her language, if the dropdown list only contains the names of languages. Hence see attached initial mockup.

      Mockup 1: http://sonjaleix.com/wp-content/uploads/2014/06/wp-install_language_select-1.jpg
      Mockup 2: http://sonjaleix.com/wp-content/uploads/2014/06/wp-install_language_select-2.jpg

      Looking forward to getting some feedback.

    • lonchbox 6:20 pm on June 10, 2014 Permalink | Log in to Reply

      This sounds great! :D, also think this option will give us a more accurate data of the real language usage of WordPress. Because most of the spanish language sites use english core 🙂

    • sonjanyc 1:50 am on June 25, 2014 Permalink | Log in to Reply

      @nacin Let me know how I can help pushing this forward on the UX/UI front. Is there a ticket in track for this or all conversation here so far?

    • Victor J. Quesada 8:53 pm on August 6, 2014 Permalink | Log in to Reply

      nice. great!

  • Andrew Nacin 7:42 pm on February 8, 2012 Permalink
    Tags: , i18n,   

    Team Update: i18n

    Our first two-week cycle comes to a close. Very successful, with more than 20 tickets outright closed, and more in the pipeline or nearing completion. Some highlights since last week’s update:

    • Fixed localization issues when a plugin calls wp_enqueue_script() too early. #19959, #11526
    • Fixed ajax calls for IDN domains (broken in IE and Opera). We partnered with Ryan on this one, to introduce a new ‘relative’ scheme for the URL functions. #18952
    • Hebrew letter nun no longer breaks search results. (Good UTF-8 fix.) #19033
    • We finished off #19852 and, again, #18180, #19924, and #19600
    • Commas (when used to separate tags) were internationalized. A very helpful fix for a number of locales. #7897
    • Finalized RTL styling changes in #19598
    • Made the TinyMCE spellchecker dropdown localizable #19962
    • The document for translators is current (view it here)
    • Awaiting feedback from translation teams in #19980, #8759, and #19601
    • Ryan and I want to revisit #19599

    Our next cycle will start in a few days. It will focus on the raw implementation of language packs. Dion will be spearheading the upgrade/install bits while I continue to work on infrastructure as well as the contents of said packs. For now, Sergey is looking at transliteration and character conversion, while I will work on #19597 and #15858.

compose new post
next post/next comment
previous post/previous comment
show/hide comments
go to top
go to login
show/hide help
shift + esc
Skip to toolbar