Take string off the static file on /js/pages/me.js

RESOLVED FIXED

Status

Webmaker
webmaker.org
RESOLVED FIXED
5 years ago
5 years ago

People

(Reporter: alicoding, Assigned: alicoding)

Tracking

Details

(Whiteboard: 20130729 p=1)

Attachments

(1 attachment)

(Assignee)

Description

5 years ago
https://github.com/mozilla/webmaker.org/blob/master/public/js/pages/me.js#L56

The above text needs to be off the static file and place them in the views folder as we need to localize the string.

We would need to come up with another solution for popup.

:k88hudson suggested that we may use the same approach of the login when we are removing our account.
(Assignee)

Updated

5 years ago
Assignee: nobody → ali
Status: NEW → ASSIGNED
(Assignee)

Updated

5 years ago
Whiteboard: 20130729 p=1
We had a meeting today to discuss how we want to handle client-side access to localization data.  Up to this point, most of our work has been possible with pure server side templating.  However, we are aware of cases where being able to do this from script on the client side is necessary.

Our current thinking is to make it possible for script to request the localization strings for the current locale via an HTTP GET request to the server.

1) On the server side, apps support a new GET route, named `strings` or something:

// Send the entire string catalog as JSON to the client.
// We expect the web page to ask for a particular locale
// or for the headers to include it. If neither of these
// happens, we'll default to en_US.
strings: function( req, res ) {
  res.jsonp( i18n.getStrings( req.params.lang || req.lang || 'en-US' ) );
}

2) Where possible, we render the locale info into the page's <html> element such that scripts can discover the current locale being used:

<html lang="{{ lang }}" dir="{{ lang_dir }}">

3) We create a new requirejs module, `localized.js`, which is capable of determining the current locale for this page, and requesting the strings from the server.  Something like this:

/* localized.js -- this can get minified into our app's code */
define(['jquery'], function($) {
  // XXX: should we bundle the default lang (en-US) strings in here statically
  // so we always have at least those loaded? 
  var catalog;

  // Get the current lang from the document's HTML element, which the
  // server set when the page was first rendered. This saves us having
  // to pass extra locale info around on the URL.
  var lang = $('html').attr('lang') || 'en_US';
  $.ajax({
    type: 'GET',
    url: '/strings/' + lang,
    async: false,
    jsonpCallback: 'jsonCallback',
    contentType: 'application/json',
    dataType: 'jsonp',
    success: function(json) {
      catalog = json;
    },
    error: function(e) {
      console.log("Error" + e);
    }
  });
  
  return {
    // XXX: do we want to always return an empty string, or is null OK?
    // XXX2: should we call this `gettext` instead of stringFor?  Might make more sense.
    stringFor: function(key) {
      if (!catalog) {
        console.log("String catalog not fully loaded yet.");
        return null;
      }
      return catalog[key];
    }
  };
});

4) We use `localized.js` in client-side JS:

<html lang="en-US">
...
<script>
define(['jquery', 'uri', 'localized'],
  function ($, URI, localized) {
    ...
    if (confirm(localized.stringFor('areYouSure'))) {
      ...
    }
  }
);
</script>

What do we think about this?  I don't think we can do a pure object (i.e., instead of having an object with a function, stringFor), since we have to return something from require before the loading of the json is finished.
Blocks: 877232
Flags: needinfo?(gavin)

Comment 2

5 years ago
Lets call the returned method simply "get".

IE: localized.get('areYouSure')
Flags: needinfo?(gavin)
(Assignee)

Comment 3

5 years ago
For #3 I think it will be very important to have at least en-US loaded, so that if some of the string is missing or not localized yet then it will use the en-US version for that string.
Let's also add some logic so we know *when* the strings are loaded, something like:

/* localized.js -- this can get minified into our app's code */
define(['jquery'], function($) {
  var _catalog,
      _readyCallback,
      _isReady = false

  function ready() {
    // Register a callback to happen when the DOM is also up (might
    // already be up, in which case it will happen now).
    $(function(){
      _isReady = true;
      _readyCallback && _readyCallback();
    });
  };

  // Get the current lang from the document's HTML element, which the
  // server set when the page was first rendered. This saves us having
  // to pass extra locale info around on the URL.
  var lang = $('html').attr('lang') || 'en_US';
  $.ajax({
    type: 'GET',
    url: '/strings/' + lang,
    async: false,
    jsonpCallback: 'jsonCallback',
    contentType: 'application/json',
    dataType: 'jsonp',
    success: function(json) {
      _catalog = json;
      ready();
    },
    error: function(e) {
      console.log("Error" + e);
    }
  });

  return {
    get: function(key) {
      if (!_catalog) {
        console.error("String catalog not found.");
        return null;
      }
      return _catalog[key];
    },

    // Localized strings are ready
    ready: function(cb) {
      // When the DOM is ready, trigger the callback to indicate
      // that strings are also ready.
      _readyCallback = cb;
    }

    isReady: function() {
      return _isReady === true;
    }
  };
});

Totally untested code! :)

But that's the idea, so you can do this:

function init(){
  var s = localized.get("some-key");
  ...
}

// Wait for DOM + Localized strings to load before starting app
localized.ready(init);
If you want to always have the en-US strings loaded in, you'll have to have requirejs load the <path to srcdir>/localized/en_US/messages.json.  Not hard, but it takes a bit of work to get the path munging right, since it's not going to be in the same level as the other scripts.  It's also going to mean a bit of magic that has to get maintained, others will have to not break (e.g., moving paths, renames).  I'm not sure it's necessary if we do this ready-callback method.
Blocks: 899165
:aali, :humph said:

`It's also going to mean a bit of magic that has to get maintained, others will have to not break (e.g., moving paths, renames).`

The biggest headache I've observed with localization has been maintenance after the fact.  I know that it's more because of changes to the site's copy, and layout changes and things like that, but easier to maintain is usually better.
(Assignee)

Comment 7

5 years ago
I think I have a good reason why we want to have at least English version to always be there.

This is not something I like at all, but I have to do more research of how web crawlers are doing this stuff.

----

I was looking at how webmaker.org is on most of the search engine since last month when I looked at it only Google.com and ask.com has the latest version of the site. So, I have that sitemap setup and did some ping to few of them, so that they know we are more up to date than what they have in their archives.

Yesterday when I looked at it again I see all of them now have the latest version of webmaker.org which is very good! but.... I notice that the snapshots of the pages are the one that showing only the key name and not the value. Index page for example: 

We should see something like this on the header:

`Make Something with Webmaker. We're a global community that doesn't just use the web, we make it by creating, remixing and teaching. Sign up and start making!`

But what I see on the archive page: 

`indexHeader`


And what we see on the google page (and the other) 

popcorn make by @webmaker created a month ago. This summer, people around the world will be meeting up, making cool stuff together and sharing it all ...

The above is the information of the first make. (Title and Description)

So, obviously Google needs to find enough information to index that to their front page and the first makes is what they found.
The SEO stuff is a separate issue, and we should file a bug to update our sitemap.xml with hreflang info for each locale we serve, which will help these spiders find the right language info--Ali, want to file/fix that?

The reason we don't need to bundle the default strings is that a) we won't start the app until the ready callback is fired in the localized module; b) we'll always load the default strings if no locale info is given on the headers/url.

Also, the strings where we'll do client-side lookups are those that need to get changed dynamically, that is, we'll render 90% of things server-side with templates, and that's what Google will index.  I question how Google is seeing things like `indexHeader` if we're doing server-side templating.
>>We should see something like this on the header:

>>`Make Something with Webmaker. We're a global community that doesn't just use the web, we make it >>by creating, remixing and teaching. Sign up and start making!`

>>But what I see on the archive page: 

>>`indexHeader`


:humph, :aali: Could this be a potential security flaw?
This also required me to patch i18n-abide to allow strings to get passed out of the module, see https://github.com/mozilla/i18n-abide/pull/46.

I've got a patch for this done, so I'll steal, and post it once this is landed upstream.
Assignee: ali → david.humphrey
WIP patch here - https://github.com/mozilla/webmaker.org/pull/313 still blocked on getting that abide patch landed.
(Assignee)

Comment 12

5 years ago
This bug is no longer depend on any of the other tickets and now can be done individually. :humph do you want me to take over this one and complete that?
He's on vacation, so go for it
Assignee: david.humphrey → ali
(Assignee)

Updated

5 years ago
Status: ASSIGNED → RESOLVED
Last Resolved: 5 years ago
Resolution: --- → FIXED
(Assignee)

Updated

5 years ago
No longer blocks: 877232, 899165
Attachment mime type: text/plain → text/x-github-pull-request
You need to log in before you can comment on or make changes to this bug.