Working on a good way to do translation in Flarum. The plan is to use YAML as it's easy to read and understand for non-programmers.

There are a lot of differences in pluralization/genderization between languages which ideally we'd like to make possible. The easiest way to do this is to let language packs implement their own logic. Here's an example:

# Namespace translations
core:

  # Machine key names (less likely to change than English key names)
  all_discussions       : All Discussions
  sort_recent           : Recent
  sort_replies          : Replies
  sort_newest           : Newest
  sort_oldest           : Oldest
  mark_all_as_read      : Mark All as Read

  # Language packs are extensions. Thus, they can extend Flarum's JS/PHP code.
  # They will be able to define custom methods for pluralization. The default
  # implementation will be simple:
  #   n != 1 ? 'plural' : 'singular'
  replies_suffix:
    singular            : reply
    plural              : replies

  # Another example, where the plural function would be overridden to provide
  # Russian pluralization rules:
  #   (n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10

    Almost reminds me of how easy esoTalk is to translate, might even be easier to translate than esoTalk is.

    That's sounds good!
    I will keep the Chinese translation.
    :-)

    @Toby

    Thank you it's great proposal!

    Format of translation isn't problem. I care more about performance impact on script side than anything else. Translators can handle everything 🙂 I hope using YAML format wouldn't slow down anything? I ask, because I see trends, to use almost pure php, in some of new projects.

    Pluralization rules

    I guess, with this solution we can have any custom based on ranges/rules? So we can support any language that we want without limits?

    Toby Can you show, how real example will look like instead of 0,1,2 with this rules you put in comment?

    Time

    For time, I used normally http://timeago.yarp.com/
    Here, on esoTalk time informations are refreshing by server/php. I don't know how Flarum does it, But JS can handle it without refreshing data from server (faster!) and most fun, in realtime. So we would see accurate info refreshed every minute. Also, it is great example how time info translation works in different languages.

    Gender

    Just perfect!

    Thank you!

      @amdad So with pluralization, whatever the function returns is then used to looked up the sub-definition. In that example, the function returns 0, 1, or 2 which correspond to foo, bar, and quz respectively. You will be able to make these keys whatever you like (the English example uses "singular" and "plural").

      Thanks for reminding me, there will definitely be a way to translate timestamps. Right now for timestamps we're using moment.js, although we might be able to get away with using a smaller library like the one you've linked, I'll look into it 🙂

        Toby But as I see it's not working/refreshing in real-time in browser.

        Toby Of course, I get it. I just ask for more advanced example with e.g. Russian language. But we may wait with is to later.

        • Toby replied to this.

          The example I gave is for Russian (from here) 🙂

          That's great! Simple to understand!

          6 days later

          Update: I've finished laying the groundwork for translation. The implementation is slightly different to what I proposed in that language packs will not be extensions, but will rather be a part of the core + each individual extension.

          This means that genderization will be an extension, and the locales in core will be able to take advantage of it if it is enabled. Just a heads up: This extension is low priority and will not be ready for beta, we'll get to it eventually though.

            As an open source software translator, I like to manage my updates when I want to. If locales are in the core and that I want to update my translation, my changes will be only available when a new Flarum version will be released, right?

            I think translation are like extensions and new versions should be available independently of the software (to fix a typo or to improve a translation for example).

            PS: I'm an official phpBB translator (two languages packs which are ones of the most downloaded/used) ready to contribute to Flarum.

              Toby I used to be like that in other systems I work with. That's ok.

              Toby Low priority for beta and HIGH priority for final. If we need this extension enabled to fully working translations.

              It's a little bit weird. Cause when we say, if you want install translation to language X you need first install and enable extension Y to support it.

              I even would keep gender extension as part of core installation of Flarum just disabled by default. When you install a language that use it, then it would switch to ON, if added language needed it.

              Updates

              Qiaeru As a translator of different kind of software, 100% agree with this. Only default English should be shipped in core. Others as extensions to easier update. Or other form to update only translation/s.

              Overrides

              Flarum as others should have option to override language strings to make installation more custom/specific.

              Thanks for the feedback guys.

              Qiaeru Welcome! Thanks for your enthusiasm 🙂

              Qiaeru Fair point.

              My main concern with language packs being separate extensions is (a) the fact that they would need to contain translations for a broad but arbitrary selection of extensions (so everyone gets a whole bunch of code they don't need), and (b) the disparity it would create between versions of core/extensions. So for example: If someone updates core, but needs to hold back on upgrading an extension for whatever reason... but then the language pack has been updated for core and also for the extension, so now it's impossible for this person to have the correct combination of translations for core vs. extension.

              One solution is to separate out the language packs into extensions per extension (e.g. a Core French Translation extension + a Categories French Translation extension). But I feel like this just introduces too much complexity, having to manage all those extensions individually.

              Another solution (that I'm proposing) is to make translations a fundamental part of their parent package (core/extension). Translators work together with package authors to keep translations up-to-date. We would certainly ensure for core / first-party extensions that translation changes are released quickly as point updates (e.g. 1.0.x). This is the cleanest solution in my opinion. The correct version of the translations are tied directly to the version of the code. And another benefit: every Flarum instance is localizable by default, as a user you don't have to depend on the forum admin to install a language pack that you might want to use.

              What do you think @Franz?

                Good point.

                I think the core translation should not include translations of extensions, that would be unnecessarily too "heavy".

                Toby That solution is nice and user-friendly.

                However, it's important to know your policy about translations. I suppose you planned to have translation updates sent via PR on GitHub concerning the core? If so, how do you manage multiple contributors? There are multiple ways to translate something, but the key to have a good translation is consistency. So, in my point of view, a translation "manager" for each language (or a dedicated team) will be great to ensure that translation updates sent via PR are consistent. For example, in French, "Register" can be translated "S'enregistrer" et "S'inscrire". Both are good. But it will be so "unprofessional" if the French translation uses "S'enregistrer" in some places and "S'inscrire" on another.

                On phpBB (and I don't say it's the perfect solution, I'm just giving an example here), each translation is managed by the author. He can add co-authors if he wants to. Authors and co-authors are the only ones who can send their translation package into a validation process managed by the Translations & International Support Teams Manager, a member of the official team who ensures that the translation does not contain additional code and meets the coding guidelines. This validation is now automatic thanks to a code checker and TravisCI. If everything is okay, the translation is validated and available for download on the official website.

                The issue with this solution is that the manager is alone and when the software is updated, all translators send at the same time their updated translation. It may then take about ten days before your translation is validated when the software is already released (so the only translation available is outdated).

                The translation in the core can solve that, because translators are supposed to work with developers. When there is a new language entry, translators are supposed to translate it ASAP and send their update. However, the real issue here is how can you handle abandoned translations? Kick it out of the core? Replace untranslated entries into default English ones?

                Each solution has its advantages and disadvantages (I contribute to the translation of open source softwares for ten years so I'm used to that heh), and I hope we will find a solution to suit users, developers and translators. I'm pleased to talk about this with you. 🙂

                I think I'm against including language packs in core. It's just near impossible to keep them up-to-date for all releases. Granted, we'd probably have foreign languages fallback to English anyway in case of missing strings, but it would still leave a bad feeling when an "official" language pack randomly has English strings all over the place.

                The best solution in my eyes would be a translation repository (which extensions could also use) where appropriate language packs (for any combination of extension and language) could be downloaded. But that's a lot of ecosystem work that we probably couldn't afford to spend much time on right now.