ether / ep_email_notifications

Subscribe to a pad and recieve an email when someone edits your pad
Apache License 2.0
10 stars 14 forks source link

Implement i18n for the email itself #13

Open floweb opened 11 years ago

floweb commented 11 years ago

Hello,

In this plugin, there are some locales to translate some stuff (like the pop-up, etc...), but it doesn't translate the email itself (which is sent to the recipients), because the strings are hard-coded in the JavaScript.

Is it possible to implement i18n for the email too ?

JohnMcLear commented 11 years ago

Should be

--- Original Message ---

From: "Florian Le Frioux" notifications@github.com Sent: May 23, 2013 8:32 AM To: "JohnMcLear/ep_email_notifications" ep_email_notifications@noreply.github.com Subject: [ep_email_notifications] Implement i18n for the email itself (#13)

Hello,

In this plugin, there are some locales to translate some stuff (like the pop-up, etc...), but it doesn't translate the email itself (which is sent to the recipients), because the strings are hard-coded in the JavaScript.

Is it possible to implement i18n for the email too ?


Reply to this email directly or view it on GitHub: https://github.com/JohnMcLear/ep_email_notifications/issues/13

quenenni commented 11 years ago

Should be.. indeed.. I'll try to do it as soon as I find time to do it :)

floweb commented 11 years ago

Thank you @JohnMcLear and @quenenni !

JohnMcLear commented 10 years ago

Bump @quenenni :)

quenenni commented 10 years ago

Ola,

Sorry, I know I'm a bit slow for this one. Things are I'm working now on ep_tables to fix it. I nearly finished that. Then I'll try to help to fix the ep_userpad plugin, then I'll do this. I'm slow coz I've plenty of other stuffs to manage.. but it'll be done at some point.

quenenni commented 10 years ago

I'm starting now.

But I'm already blocked.

@JohnMcLear : How do you have the localization system working on server side scripts? https://groups.google.com/forum/#!msg/etherpad-lite-dev/NI4NKrI_tUg/3ix3yEgddnYJ talks about that problem. Do you know what files to include are needed to have it? html10n.js, l10n.js & the locale file... something like that?

JohnMcLear commented 10 years ago

Ugh good question, html10n.js and the locale file I need but @marcelklehr did the implementation so might know more..

marcelklehr commented 10 years ago

html10n.js as is works in the browser only. It should be rather easy to extract the necessary parts out of there and use them on the server. You'll need some mechanism for loading locales (which is gonna be different from the clien-side implementation), the rest (i.e. the builder that creates the message dictionary and the macros) should work on the server as well. Of course you can only translate html on the server if there is a DOM, alternatively you can use html10n.get to get the strings.

quenenni commented 10 years ago

Hello Marcel. Thanks for your help.

I must say it's not as easy as it sounds. I checked the html10n.js and I couldn't understand half of it (macros? plural? ..)

And I still could find a way to have the browser Accept-langage on server side.

So finally, I decided to manage it by myself by sending the preferred langage used by the browser in the form via:

var locLang = (navigator.language) ? navigator.language : navigator.userLanguage;

Then, in the server script, I wrote the function:

var npm          = require("../../src/node_modules/npm/lib/npm.js"),
jsonminify   = require("../../src/node_modules/jsonminify"),
fs           = require("fs");
....
getLocaleFile = function(locale) {
  var localeFilename = npm.dir + "/ep_email_notifications/locales/";
  if (locale.indexOf('-') > 0) {
    localeFilename += locale.substr(0, locale.indexOf('-')).toLowerCase() + ".json";
  } else {
    localeFilename += locale.toLowerCase() + ".json";
  }
  var ep_EmailStr;
  try{
    if (!fs.existsSync(localeFilename)) {
      //set default to engish locale
      localeFilename = npm.dir + "/ep_email_notifications/locales/en.json";
    }
    //read the locale sync
    ep_EmailStr = fs.readFileSync(localeFilename).toString();
  } catch(e){
    console.error('Locales files are missing in ep_email_notifications');
  }
  // try to parse the locale file
  var ep_EmailObj;
  try {
    if(ep_EmailStr) {
      ep_EmailStr = jsonminify(ep_EmailStr).replace(",}","}");
      ep_EmailObj = JSON.parse(ep_EmailStr);
    }
  }catch(e){
    console.error('There was an error processing your settings.json file: '+e.message);
  }
  return ep_EmailObj;
}

It works. By calling this function with the value of LocLang (from the client) as param, I have all the translations I need.

There is, unfortunately, one problem I can see. 'navigator.language' only give the first preferred langage, not all.

So, if the client has as preferred language in its browser:

Any idea how I can have all the preferred langages from the browser? Or, isn't there a way to get the 'Accept-Langage' from the request to the server (stored in some object in the context)?

marcelklehr commented 10 years ago

This is what I had in mind, although your solution doesn't deal with plural expressions and arguments (see https://github.com/ether/etherpad-lite/blob/develop/src/static/js/html10n.js#L751). (A macro is a function that takes the message id, a parameter and some options, supplied in the message string. See for example the definition of the plural macro: https://github.com/ether/etherpad-lite/blob/develop/src/static/js/html10n.js#L659 -- also see the README for more information https://github.com/marcelklehr/html10n.js)

The largest part of html10n.js are the plural rules of the different languages. Reading the code from the bottom up might help with understanding.

I think the browser won't load the page in german either. This is how etherpad determines the language to use: https://github.com/ether/etherpad-lite/blob/develop/src/static/js/l10n.js The language ranking is only supplied in http requests, afaik. Depending on where your code is executed you might have access to the request headers, yes.

quenenni commented 10 years ago

Thanks for your explanations.. It helps a lot.

I tried to take and modify your html10n.js file to make it server side workable, but up to now, without success.

I used it this way:

var html10n      = require("html10n.js");
...
...
html10n.localize(userInfo.email_locale);
console.log(html10n.get("ep_email_notifications.msgMailSubscription"));

And I have the error:

TypeError: Object #<Object> has no method 'localize'

My probelm, I think, is the way I define the object (the first line)

Could you give it a look and see if you can pinpoint my error? http://pastebin.com/X2nQM0PD

Thanks

marcelklehr commented 10 years ago

Yes, node.js expects commonJS module definitions. You need to explicitly set the object you want to return with require().

module.exports = html10n;

This should be enough.

Also, you need to provide a Loader implementation. All a loader needs to do is provide a loader.load(lang, cb) method and expose the raw strings at loader.langs[lang][stringID]. The original loader fetches the strings via ajax requests, but you should be able to use your implementation. html10n.build() will apply the fallbacks, so you don't need to worry about that.

.. and you should strip out any calls to html10n.translateElement()