mozilla / persona-gmail-bridge

An experiment in building a minimal identity bridge for Gmail
Mozilla Public License 2.0
12 stars 6 forks source link

Extract and localize strings #4

Closed callahad closed 11 years ago

callahad commented 11 years ago

Once we finalize strings for the failure and id mismatch pages, we should work to get them localized.

seanmonstar commented 11 years ago

./node_modules/.bin/extract-pot -l locale . throws esprima js parsing errors. fiddling the excludes doesn't fix it. changing the target throws an error from xjsgettext that input is missing.

wut.

callahad commented 11 years ago

Working fine for me at the moment, though it is missing some of the strings in /bin/sideshow.js

./node_modules/.bin/extract-pot -l i18n . && cat i18n/templates/LC_MESSAGES/messages.pot:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-06-24 09:50+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: /home/dan/Projects/Mozilla/sideshow/views/error_mismatch.ejs:3
msgid "You're currently signed into Google as %s."
msgstr ""

#: /home/dan/Projects/Mozilla/sideshow/views/error_mismatch.ejs:6
msgid "If you want to use %s, log out of Google and sign in again."
msgstr ""

#: /home/dan/Projects/Mozilla/sideshow/views/error_mismatch.ejs:10
msgid "Force Google logout"
msgstr ""

#: /home/dan/Projects/Mozilla/sideshow/views/error.ejs:3
msgid "Something went wrong. Please try again later."
msgstr ""

grep -r gettext bin lib views:

bin/sideshow.js:  res.render('authenticate', { title: req.gettext('Loading...') });
bin/sideshow.js:        title: req.gettext('Error'),
bin/sideshow.js:        res.status(500).render('error', { title: req.gettext('Error') });
bin/sideshow.js:      { title: req.gettext('Error'), errorInfo: 'Invalid or missing claim.' });
bin/sideshow.js:        { title: req.gettext('Loading...'), success: false });
bin/sideshow.js:        { title: req.gettext('Error'), errorInfo: error.message });
bin/sideshow.js:        { title: req.gettext('Loading...'), success: true });
bin/sideshow.js:        { title: req.gettext("Accounts don't match"),
views/error_mismatch.ejs:<p><%- format(gettext("You're currently signed into Google as %s."), ['<b>' + escape(proven) + '</b>']) %></p>
views/error_mismatch.ejs:<p><%- format(gettext("If you want to use %s, log out of Google and sign in again."),
views/error_mismatch.ejs:  <button id="tryAgain"><%= gettext("Force Google logout") %></button>
views/error.ejs:<p><%= gettext("Something went wrong. Please try again later.") %></p>
seanmonstar commented 11 years ago

Exactly what I noticed as well. It's not finding the values in our bin file.

ozten commented 11 years ago

One way to debug this would be to look at jsCmd in node_modules/.bin/extract-pot when you run it. Is the find path above these .js files?

callahad commented 11 years ago

As far as I can tell, extract-pot is failing to look at .js files.

It fails silently if it finds .ejs files in the directory folder passed on the command line:

$ ./node_modules/.bin/extract-pot --locale=locale views bin

$ ./node_modules/.bin/extract-pot --locale=locale bin views

input argument is required

Usage: jsxgettext <input>... [options]

input     input files

Options:
   -o FILE, --output FILE     write output to specified file
   -p DIR, --output-dir DIR   output files will be placed in directory DIR
   -v, --version              print version and exit
   -k WORD, --keyword WORD    additional keyword to be looked for
   -j, --join-existing        join messages with existing file
   -L NAME, --language NAME   recognise the specified language (JS, EJS)
callahad commented 11 years ago

FWIW, the find command that it executes right before failing is:

find /Users/dan/Projects/Mozilla/sideshow/bin -name '*.js' | grep -v node_modules | grep -v .git

which returns:

$ find /Users/dan/Projects/Mozilla/sideshow/bin -name '*.js' | grep -v node_modules | grep -v .git
/Users/dan/Projects/Mozilla/sideshow/bin/sideshow.js
seanmonstar commented 11 years ago

I've noticed the same error when trying to extract that file directly: extract-pot --locale=locale bin/sideshow.js

ozten commented 11 years ago

I'd print the value of jsCmd and then manually run those steps.

jsxgettext will get /Users/dan/Projects/Mozilla/sideshow/bin/sideshow.js as the input. I look at that to find the source of the bug.

Sorry i18n-abide hasn't seen much usage in extracting client side strings.

callahad commented 11 years ago

Okay, that error appears if no ejs files are found in the first argument:

When trying to extract from bin/, it first calls jsxgettext for js files, which returns nothing on err, stdout, or stderr.

It then tries to call jsxgettext for ejs files, but because there are no ejs files in bin/, jsxgettext blows up.

callahad commented 11 years ago

So we've got two problems:

  1. extract-pot croaks if it doesn't find an ejs file somewhere in the first path.
  2. jsxgettext isn't successfully extracting strings from bin/sideshow.js

For the latter, we can manually invoke jsxgetext and see what happens. If you remove the output path arguments, you get down to extract-pot basically calling:

node_modules/i18n-abide/node_modules/.bin/jsxgettext --keyword=_ -L JS --from-code=utf-8 --output=- ./bin/sideshow.js

Which doesn't find any strings.

Manually munging bin/sideshow.js via s/req.gettext/gettext/g makes it work.

callahad commented 11 years ago

So, the problem is that jsxgettext fails to recognize req.gettext('foo'), though it does recognize gettext('foo') in the same file.

Trying to pass --keyword=req.gettext does not resolve this.

callahad commented 11 years ago

So, at this point, I can manually extract all the strings, but that's a super fragile way to go. :)

ozten commented 11 years ago

but that's a super fragile way to go. :)

It would be great to file a bug.

seanmonstar commented 11 years ago

Looks like this line looks for gettext, but doesn't match: https://github.com/zaach/jsxgettext/blob/master/lib/jsxgettext.js#L37

zaach commented 11 years ago

Ah, the problem is that jsxgettext looks for a CallExpression, but req.gettext parses as a MemberExpression according to the ES grammar. I'm not sure how xgettext handles this, but either way it seems like a good use case to support.

In the meantime, you could bind req.gettext to a local variable gettext within your request handlers.

(And don't hesitate to ping me if you encounter weird jsxgettext bugs :)