JavaScript templating with support for i18n? (and then what?) - javascript

In a distant future I'd like to distribute my multilingual single-page-application, containing all sorts of resources (videos, texts, interactive applications), for both the web and for the desktop (offline). That dream scenario would also allow translators to access a unified translator dashboard, from where all translations, for all formats, could be crowdsourced.
But that is the future.
What I'm looking for short-term is instead an efficient solution for integrating i18n into my JavaScript templates. There should also be some method that can be used when templating is not an option, i.e. when SVG text elements (that should hold translated strings) are added dynamically.
I'm not sure about the pros and cons of doing this server-side (i.e with node.js) - please enlighten me - but it would be nice if the data storage could easily be swapped (from database to files etc.) in case the offline delivery mechanism does not come with database support.
Where should I start, and is there any path that will allow me to build the i18n system incrementally without having to shift the whole paradigm when going from small-scale to big?

An idea could be to define a global shortcut like mapping (for instance) _ (underscore) to the translation method of i18n plugin/library whatever s.t. you can then from your JavaScript code (and thus also from within your template) execute calls like
_("textToLocalize")
which will return the correctly localized text based on the current language.
This method could then contact a REST service (with proper caching) for retrieving the localized strings from the server where they're somehow managed in files/db tables.

Related

i18n: Access locale resolution logic in JavaScript

I'm developing and internationalized Single Page App with 2 sorts of localized text:
'static' text, typically text in my HTML templates.
'dynamic' text, i.e text that lives in the database, typically the description of a product on an e-commerce site.
It's type 2 I'm having trouble with. Say my app officially supports English, French and German, and I get from my database an object such as :
{
description: {
'en': "It's an awesome product.",
'en_UK': "This product is ace.",
'fr': "C'est un excellent produit."
// German's missing
}
}
Now the challenge is to dynamically choose what locale should be chosen for display, given the user's locale and what locales are available in this particular object.
I assume most i18n JavaScript libraries have their own 'locale resolution' logic built-in, but I haven't found one that exposes this logic for the client to use.
Does anyone know a JS library that addresses this, or a good way to solve this issue? (if it's AngularJs-compatible, it's even better).
Thanks in advance!
Disclaimer: I'm a co-author of L20n and one of the developers of
l10n.js used in Firefox OS.
The term that's commonly used to describe this logic is language negotiation.
Most localization libraries should have some sort of language negotiation algorithm included. It can be as basic as trying to match the value of navigator.language with a list of available languages. More sophisticated approaches will look at both the language tag (en in en-US) and the region tag (US in en-US) to try to find a best match.
There's a proposal to expose a language negotiation method on the ECMAScript's Intl object, but for now it's not possible to use its internal logic for this purpose.
Getting the list of languages preferred by the user is not as easy as it should be. There's navigator.language in most browsers (which is the user's preferred language in Firefox and the language of the browser UI in Chrome), navigator.userLanguage in Internet Explorer, and the new navigator.languages which is an ordered list of user's preferred languages.
A server-side alternative is to use the Accept-Language header of the HTTP request which currently is the most reliable way of finding out what the user's preferences are.
Once you have the list of user's preferred languages you can perform the language negotiation.
Here are a few examples of libraries that perform language negotiation:
in-browser-language,
l10n.js used in Firefox OS,
a non-standard extension of the ECMA-402 Intl object which adds Intl.prioritizeLocales.
For your particular use-case, you can choose to do one of the two following things:
perform the language negotiation on the client side using navigator.language || navigator.userLanguage and send a request to the database specifying which language you're interested in, or
send the request with the user's Accept-Language header and perform the language negotiation on the server side, and then query the database for the correct translation.
Both solutions have the benefit of not sending the entire set of translations to the client when only one will be eventually used.
For solution #1, given that you're using Angular, I can suggest using L20n 1.0.x which integrates with Angular via the ng-l20n module. You should be able to use the supportedLocales property to get the negotiated list of languages and use the first element of that list to query the database.
For solution #2, it all depends on your server-side setup, but if you're using node.js, you can try using one of the following modules:
the afore-mentioned in-browser-language,
locale.
Staś Małolepszy's answer is a good reference of the resources available for this problem domain.
However, I found that none of these libraries suited my needs (either because their language negotiation logic was too simplistic, or because it wasn't really exposed).
Therefore, I implemented my own custom solution for language negotiation. You can experiment with it in this Plunkr: http://plnkr.co/edit/Cfv49ZcQWJcqwOXYcjtw?p=preview
The API is a function negotiate(availableLocales, requestedLocales, defaultLocale), a bit similar to the ECMAScript proposal (with the difference that it returns a single locale value, not a list).
// simple cases
negotiate(["fr"], ["de","fr"], 'en'); // => fr
negotiate(["en"], ["de","en-US","en"], 'en'); // => en
// less natural cases, where the solution is more opinionated
negotiate(["fr-FR"], ["fr"], 'en'); // => fr-FR
negotiate(["en","en-UK","fr"], ["fr-FR"], 'en'); // => fr
negotiate(["fr","de"], ["fr-FR","de"], 'en'); // => fr
I made the choice to account for 'locale inheritance' (e.g en-US is derived from en) in a non-trivial, opinionated manner . I do not claim this is in compliance with whatever standards exist on this topic.
It surprised me that I couldn't find any library that provides this sort of functionality. My best explanation is that i18n of dynamic content isn't needed that often.
Finally, as to where I get the list of requested languages, as I was in an Single Page App configuration I chose to send an AJAX request to my server, with the content of the Accept-Language header in the response.

Javascript equilent of Java's Locale package, or client side approach to rendering lang/script/country codes

Doing server side rendering of HTML templates I find myself using Java's Locale class (via various helper functions) to render language codes (ISO 639-1), script codes (ISO 15294), and country codes (ISO 3166) as their name (i.e. "en" -> "English") in a manner that respects the current user's selected locale.
Now, moving some stuff to client side rendering (with Angular JS), I'm a bit unsure of how to approach this. Doing the code-to-name conversion on the server side and sending locale-aware JSON is one option, but it would add quite a lot of complexity to how various bits of data get JSONified (by having to pass the locale through lots of layers of functions, mainly.)
On the other hand, I can see how a full-on client side version of the Java Locale class would involve sending lots of data to the client, most of which wouldn't get used most of the time.
Are there any emerging best-practices for doing this kind of stuff with largely single-page apps, or any super libraries that would solve my problem in well fell swoop?
I am not sure this is the "best practice", but I have also developed a single-page app where I loaded a JSON array with useful JS data on load with ajax. That seemed like the best solution to me if the data is not used right at the beginning of the page.
Otherwise you could just add this script at the end of every page, if you don't mind embedded javascript:
<script>
function get_locale(){
return JSON.parse(/* render JSON.encoded data from server here */)
</script>
Sorry if this not really a definitive answer.

Run Database Stored RegEx against DOM

I have a question about how to approach a certain scenario before I get halfway through it and figure out it was not the best option.
I work for a large company that has a team that creates tools for the team mates to use that aren’t official enterprise tools. We have no access to the database directly, just access to an internal server to store our files to run and be able to access the main site with javascript etc (same domain).
What I am working on is a tool that has a ton of options in it that allow you to select that I will call “data points” on a page.
There are things like “Account status, Balance, Name, Phone number, email etc” and have it save those to an excel sheet.
So you input account numbers, choose what you need and then using IE Objects it navigates to the page and scrapes data you request.
My question is as follows..
I want to make the scraping part pretty Dynamic in the way it works. I want to be able to add new datapoints on the fly.
My goal or idea is so store the regular expression needed to get the specific piece of data in the table with the “data point option”.
If I choose “Name” it knows the expression for name in the database to run again the DOM.
What would be the best way about creating that type of function in Javascript / Jquery?
I need to pass a Regex to a function, have it run against the DOM and then return the result.
I have a feeling that there will be things that require more than 1 step to get the information etc.
I am just trying to think of the best way to approach it without having to hardcode 200+ expressions into the file as the page may get updated and need to be changed.
Any ideas?
IRobotSoft scraper may be the tool you are looking for. Check this forum and see if questions are similar to what you are doing: http://irobotsoft.org/bb/YaBB.pl?board=newcomer. It is free.
What it uses is not regular expression but a language called HTQL, which may be more suitable for extracting web pages. It also supports regular expression, but not as the main language.
It organizes all your actions well with a visual interface, so you can dynamically compose actions or tasks for changing needs.

Localizing strings not stored in a database

We've decided to add support for multiple languages to our web app.
We use Handlebars for templating on the front end, and Node + Jade for templating on the back-end.
For strings that are not stored in the database (all of the strings that are part of the UI), is there a recommended way of going about this? (Does it make any difference whether we add the strings to the templates on the front-end or the back-end?).
One approach I have taken with javascript-based localizations is to create a collection of files (one file per language), each containing a language object that could be loaded either client side or in node to provide the localizations. You just load the file needed based on the language.
This is a simple example:
var localization = {
stringkey1: 'Some string value',
stringkey2: 'Some other value',
// etc.
}
Obviously if you have a large application with lots of strings, you may want to further break up the localizations so you don't need to work with excessively large objects.
The good thing with this approach is that you could use the same localization library both server-side and client-side without any modification.

Jquery/Javascript solution for converting wiki-text to HTML and vice versa?

For my web front end I have to implement subsets of the wiki-syntax in my system. Do I need to manually specify rules and reinvent the wheel? Is there an existing javascript library or jquery plugin that could help out with it?
For example a user enters == Header == Since this needs to get converted to a medium header for example (assuming medium is defined in this context as a span as below)
<span class="mediumHeader" id = "Header">Header</span>
Now when the user edits the above text I'm guessing it'll involve replacing the
<span...> ... </span> with ==...==
Now for every system I design this will be as per 'my rules' and will almost always have to reinvent the wheel. Is there something that I could use to ease this wiki to/from HTML transformation using Jquery/Javascript? I'm sure it's a problem with a known solution.
I would prefer to customize what's acceptable and what isn't i.e. I don't everything to be translated into wiki syntax (or HTML) only subsets of it. Should I just roll my own for my application?
It's been long enough that you may not need this, but yours was the top SO hit when I started looking into it.
There are a couple javascript options - you're probably looking at instaview (check out test/test.js), or maybe Wiky.js (the less fully documented).
If you aren't limited to Javascript, check out the exhaustive list of MediaWiki parsers at http://www.mediawiki.org/wiki/Alternative_parsers - lots of tools for C++, Java, Perl, ruby, and more. That's the link to watch for new developments.
At the time of writing, Parsoid seems to be the only one which translates in both directions. This one also powers the visual editor on Wikipedia. But this is no handy client-site lib to include in your app, but a full-blown parsing and transformation server suite. A production version of Parsoid on the Wikimedia cluster can be accessed at http://parsoid-lb.eqiad.wikimedia.org/.
Other JavaScript Libraries, which are translating from WikiText to HTML only (ordered by popularity), are:
Wiky.js - doesn't support full WikiText syntax. (by tanin47, not to be confused with Wiki.js from Requarks - a different project completely)
wtf_wikipedia - isn't directly translating to HTML but JSON, which results in much more powerful possiblities (e.g. info-boxes as key-value pairs). This is the most up-to-date library and "its a combination of instaview, txtwiki, and uses the inter-language data from Parsoid javascript parser."
instaview - no updates in the last 2 years.
Also checkout the current and full list of alternative MediaWiki parsers.

Categories

Resources