Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POC of a i18n system #1232

Closed
wants to merge 1 commit into from
Closed

Conversation

yohanboniface
Copy link
Member

Hi!

While working on a i18n feature for Leaflet.Storage, I though it should be more convenient to have all Leaflet plugins share the same system. That's why a suggest to add it in Leaflet core instead of making a plugin. Making a plugin (say Leaflet.I18n) means making it a dependency for all the other plugins, so I think it will not work.

So here is a suggestion.

The API is:

  • to make a string translatable, just call L._ (shortcut for L.i18n), like this:
L._("The phrase I want to be translatable");
L._("A complex sentence with a {variable}", {variable: "my value"});
  • one or more locale/{locale_code}.js should be provided, something like:
var mylocale = {
    "Simple phrase to translate": "Une simple phrase à traduire",
    "A sentence with a {variable}": "Une phrase avec une {variable}",
};
  • the locale must register itself, doing something like:
L.registerLocale('fr', mylocale);

This can be done more than once. For example, every plugin can add it's translations for some locale without overriding all the already registered strings. However, if the same string for the same locale is registered twice, the last wins.

  • end user must load the locale/ files provided by Leaflet, or plugins
  • end user must set his locale, doing so:
L.setLocale('fr');

And then all the translatable strings available will be translated :).

Of course, i18n is optional: unless one locale has been set, the behaviour is unchanged.

Insolved:

  • Not sure of the better way to make the locale available in the dist/ module. I just think that each end user must only load the locales he wants

Of course, some documentation of this will be needed, if merged.

Thanks for reviewing!

Yohan

@mourner
Copy link
Member

mourner commented Jan 31, 2013

I'm not sure if Leaflet needs an i18n system when it almost has nothing to translate in itself... (There are 3 link titles and they're not very important too). I'd suggest making a plugin or using one of the other generic solutions like i18n.js for this.

@mourner mourner closed this Jan 31, 2013
@yohanboniface
Copy link
Member Author

Well, let me argue a little bit more about this :)

The main purpose of my PR was not focused on the Leaflet internal needs, but more in providing a standardized basic i18n system (but in the same time, it could be also quite nice to get "zoom in" translated in say Chinese ;) ) for the Leaflet ecosystem.

What I mean is that, with a i18n plugin, or worse case with an external library, this means that every Leaflet plugin will have to add a dependency if it aims to be translatable. And the more plugins, the more different systems will be used, so someone who wants to use several Leaflet plugins will have to face the situation of adding maybe several external translation libs.

Non having a centralized solution will, I think, occur in plugins maintainers not to translate their plugins, because "dunno which solution to choose", or "don't want to add an external dependency", or "I don't care about this".

The translation is always internal, so this means that you cannot provide a i18n system for a plugin without being intrusive. So if the maintainer doesn't want to translate a plugin for the above reasons, it will be impossible to do it externally, and it will be hard to convince him.

I think that, the more Leaflet become mature and used, the more providing a standardized i18n system will be important for its ecosystem. Well, I think translation is part of a mature ecosystem. And I'm close to think that it has to be in the core, for the above exposed reasons.

@mourner what do you think? :)

@mourner mourner reopened this Jan 31, 2013
@mourner
Copy link
Member

mourner commented Jan 31, 2013

OK, will reconsider taking the plugin ecosystem into account. Thanks for a thorough explanation.

@yohanboniface
Copy link
Member Author

When you'll reconsider this PR, you can have a look at this simple tool I'm working on for the i18n system of https://github.com/yohanboniface/Leaflet.Storage to create and update the "locale" files: https://github.com/yohanboniface/Leaflet.Storage/blob/master/bin/i18n.js
Basically it just parses the code to find calls to L._ and dump a JSON in a file to later editing by a human, but this prevent form having to read the code to know which string needs to be translated.

@tmcw
Copy link
Contributor

tmcw commented Apr 5, 2013

I'm 👎 on this - the plugin ecosystem should be smart about dependencies - they could use browserify to have multiple require('translationsystem') calls merge into one dep, or they could just agree to use similar dependencies and always keep externals in a build step or ext/. There should be, for instance, an AJAX library bundled with leaflet just because many plugins use one - it'll naturally fall out of date because a bespoke-ajax-in-a-mapping-library will be less relevant to other users than a focused-ajax-library.

@yohanboniface
Copy link
Member Author

@tmcw I get your point, and you certainly are right. But I feel that it is theoretical. Going this way will result, imho, in plugins generally not being translated, for the reasons exposed above. And this would make me sad. This would make me sad, because when I do code, I do code for humans. And humans massively speak something else than English.

@tmcw
Copy link
Contributor

tmcw commented Apr 10, 2013

I understand and support translatability and the need for translations - but implementing i18n in Leaflet is not the only way to get there. Why not try writing a guide for how to make a translatable Leaflet module, and an example translated module (like just a single button with translated text, to demonstrate how this works), and see if it's possible to establish a best-practice?

@ghost ghost assigned mourner Apr 20, 2013
@mourner
Copy link
Member

mourner commented Apr 20, 2013

I think I'll have to agree with Tom. Translation in JS is a very simple thing, it often comes down to a function like the following, and there's no need to make it complicated — establishing a best practice will be enough:

function _(str) {
    return (translations[locale] && translations[locale][str]) || str;
}

If we can get by without added complexity, we should, otherwise Leaflet will turn into OpenLayers.

@mourner mourner closed this Apr 20, 2013
@yohanboniface
Copy link
Member Author

@mourner @tmcw yeah, I agree with the arguments of keeping Leaflet core light.
I'm just quite sure that this will result in Leaflet plugins not being translated.
Anyway, I know that when @mourner and @tmcw have arguments against your PR, it's better to abdicate ;)
By the way, I'm still in Haiti, so without proper time, electricity and decent Internet to start working on the best practice guide. If someone fill inspired, go for it ;) Otherwise I'll be back in Internet superhighway mid May, maybe with time and energy for this.

@yohanboniface
Copy link
Member Author

I've extracted the 20 lines of code from Leaflet.Storage and created a stand alone plugin: https://github.com/yohanboniface/Leaflet.i18n
Just in case it can be helpful for others, and can prevent everyone from adding the same lines of code everywhere ;)
Maybe it will be useless, but seen from Leaflet.Storage work, a third party plugin doesn't cost anything. So let's see.
To be continued :)

@frodrigo
Copy link

Even if there is really few texts string in Leaflet it could be nice to allow a way to I18n. At least with the same way as in Leaflet.Draw, by building en object where string are centralized and can be overwrite. Actually is not way to translate or customize at all.

@rastapopougros
Copy link

So, many years later, it seems @yohanboniface was right… no trans system directly inside core (and promotion of it) = no translations nowhere.

Zoom in, Zoom out always only in english, no arabic, chinese, french, spanish…
Same for "Full Screen" which is a very common plugin. And so on…

Sometimes we can change strings manually via options, but it means every single software that uses Leaflet, has to re-implement i18n and above all have its own list of translations, instead of mutual locales files.

I'm just a user/integrator, so to quote @yohanboniface : sad for humans :(
(and +1 for his request, still relevant)

@tmcw
Copy link
Contributor

tmcw commented Oct 27, 2016

above all have its own list of translations, instead of mutual locales files.

I'm not seeing how this could possibly work. What's the alternative to plugins managing their own locale files - a central repository? Would that central repository contain all hundreds of Leaflet plugins, including the dead ones? Would it have a point release every time any of those plugins updated a source string?

You can read this situation as either

  • Leaflet made the wrong choice, if it had adopted a translation system, plugins would have adopted it
  • Nobody in the plugin ecosystem has stepped up and promoted a translation system, or set an example by translating their plugin

I find it easier to believe the latter.

@rastapopougros
Copy link

What's the alternative to plugins managing their own locale files

It's a misunderstanding. I talked about other software which include and use Leaflet, absolutely not about plugins.

It's precisely inside each Leaflet plugins, using a common API provided by the core, that I would love to have translations (and inside the core package for "Zoom in" and "Zoom out").

For the moment, those other softwares or all projects (website etc), they all have to have their own translations for each core leaflets string + plugins strings, duplicated in hundreds, or thousands. Instead of having those translations in leaflet core, and in leaflet plugins, only once.

Concretely, each project with non english humans have to translate "Zoom out", "Full Screen", etc, in arabic, french, chinese… and stores and maintains those translations only inside that project, and overload strings for core and plugins to incorporate them.

I was talking about

  • having arabic or spanish translation of "Zoom out" only once in the whole community (=> in the core)
  • and having arabic or spanish translation of "Full Screen" only once in the whole community (=> in this plugin, and same for all other plugins)
    And not in each project who uses them. :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants