Simple translation for your javascripts, yummy with your favorite templates engine like EJS.

Related tags

Validation jsperanto
Overview

jsperanto

Simple translation for your javascripts, yummy with your favorite templates engine like EJS.

  • Pluralization, interpolation & "nested lookup" support for your translations
  • Uses XHR to get a JSON dictionary (or load it your own way & format)
  • JSLint-ed, QUnit-ed
  • similar to Rails's i18n but sans backend needed
  • No global pollution (hides under jQuery.jsperanto)
  • Works with : IE6+, Firefox 3+, Safari 3+, Chrome, Opera 9+
  • AMD, CommonJS modules supported

Depends on jQuery 1.4+ (uses $.ajax, $.each, $.extend)

Usage example

"JSON" $.t('can_speak',{count:1}); //-> "I can only speak one language" $.t('can_speak',{count:3}); //-> "I can speak 3 languages" $.t('can_speak_plural',{count:'any'}); //-> "I can speak any languages" $.t('project.size.source',{value:4,unit:"kb"}); //-> "jsperanto is 4 kb" $.t('project.size.min',{value:1727,unit:"bytes"}) //-> "jsperanto is 1727 bytes when minified" $.t('project.size.gzip',{value:833,unit:"bytes"}) //-> "jsperanto is 833 bytes when minified and gzipped" }); //given this dictionary { "project" : { "name" : "jsperanto", "store" : "JSON", "size" : { "source" : "$t(project.name) is __value__ __unit__", "min" : "$t(project.size.source) when minified", "gzip" : "$t(project.size.min) and gzipped" } }, "can_speak" : "I can only speak one language", "can_speak_plural" : "I can speak __count__ languages" }">
$.jsperanto.init(function(t){
    t('project.name'); //-> "jsperanto"
    $.t('project.store'); //-> "JSON"
    
    $.t('can_speak',{count:1}); //-> "I can only speak one language"
    $.t('can_speak',{count:3}); //-> "I can speak 3 languages"
    $.t('can_speak_plural',{count:'any'}); //-> "I can speak any languages"
  
    $.t('project.size.source',{value:4,unit:"kb"}); //-> "jsperanto is 4 kb"
    $.t('project.size.min',{value:1727,unit:"bytes"}) //-> "jsperanto is 1727 bytes when minified"
    $.t('project.size.gzip',{value:833,unit:"bytes"}) //-> "jsperanto is 833 bytes when minified and gzipped"
});

//given this dictionary
{
  "project" : {
     "name" : "jsperanto",
     "store" : "JSON",
     "size" : {
        "source" : "$t(project.name) is __value__ __unit__",
        "min" : "$t(project.size.source) when minified",
        "gzip" : "$t(project.size.min) and gzipped"
     }
  },
  "can_speak" : "I can only speak one language",
  "can_speak_plural" : "I can speak __count__ languages"
}

API

$.jsperanto.init(function(t),options)

initialize jsperanto by loading the dictionary, calling back when ready

function(t) : is called once jsperanto is ready, passing the translate method ($.jsperanto.translate)

options extends these defaults

1 || typeof(count) == "string" ) ? o.pluralSuffix : ""; }; o.maxRecursion = 50; //used while applying reuse of strings to avoid infinite loop o.reusePrefix = "$t("; //nested lookup prefix o.reuseSuffix = ")"; //nested lookup suffix o.fallbackLang = 'en-US'; // see Language fallback section o.dicoPath = 'locales'; // see Dictionary section o.keyseparator = "."; // keys passed to $.jsperanto.translate use this separator o.setDollarT = true; // $.t aliases $.jsperanto.translate, nice shortcut o.dictionary = false; // to supply the dictionary instead of loading it using $.ajax. A (big) javascript object containing your namespaced translations o.lang = false; //specify a language to use i.e en-US">
o.interpolationPrefix = '__'; 
o.interpolationSuffix = '__';
o.pluralSuffix = "_plural";
o.getSuffixMethod = function(count){ return ( count > 1 || typeof(count) == "string" )  ? o.pluralSuffix : ""; };
o.maxRecursion = 50; //used while applying reuse of strings to avoid infinite loop
o.reusePrefix = "$t("; //nested lookup prefix
o.reuseSuffix = ")"; //nested lookup suffix
o.fallbackLang = 'en-US'; // see Language fallback section
o.dicoPath = 'locales'; // see Dictionary section
o.keyseparator = "."; // keys passed to $.jsperanto.translate use this separator
o.setDollarT = true; // $.t aliases $.jsperanto.translate, nice shortcut
o.dictionary = false; // to supply the dictionary instead of loading it using $.ajax. A (big) javascript object containing your namespaced translations
o.lang = false; //specify a language to use i.e en-US

Use init to switch language too :

$.jsperanto.init(someMethod,{lang:"fr"})

$.jsperanto.translate(key,options)

looks up the key in the dictionary applying plural, interpolation & nested lookup.

key to lookup in the dictionary, for example "register.error.email"

options each prop name are are used for interpolation

options.count special prop that indicates to retrieve the plural version (key_plural) if its greater than 1. Also used for interpolation

options.defaultValue specify default value if the key can't be resolved (the key itself will be sent back if no defaultValue is provided)

aliases : $.jsperanto.t , $.t if init option setDollarT is left to true.

Dictionary loading

Using defaults, jsperanto uses a basic browser language detection

(navigator.language) ? navigator.language : navigator.userLanguage

to determine what dictionary file to load. You can also instruct jsperanto to load a specific language (via init option lang).

Once the language is determined, jsperanto will use $.ajax to load the dictionary using locales/somelang.json as url. For example locales/fr-CA.json is used for a french canadian browser. If the json file can't be retrieved, it will try to get the fallback language, which is 'en-US' by default. (you can change this using init option fallbacklang). If no dictionary file can be retrieved at all, jsperanto translate method will simply return the provided key.

You can bypass this loading mechanism completely by providing a dictionary object to init (options.dictionary)

Switching language

Simply use init again and specify a language (or dictionary) to use.

$.jsperanto.init(someMethod,{lang:"fr"})

Custom suffixes

At init time you can specify a method which will calculate the suffix to use if count is present. the argument passed to this method is the count and can be a string or number. Anything other than a string returned will be disregarded.

$.jsperanto.init(someMethod, {
  lang:"en-us",
  getSuffixMethod : function(count){
     if ( count == 0 ) {
        return "_zero";
     }
     if ( count != 1 ) {
        return "_plural";
     }
  }
)

Licence

MIT License

Copyright (c) 2010 Jean-Philippe Joyal, http://leastusedfeature.wordpress.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Inspiration & similar projects

Rails i18n

Babilu

l10n.js

javascript_i18n

Thanks

Many thanks to Radialpoint for letting me open source this work

Comments
  • Added AMD and CommonJS modules support

    Added AMD and CommonJS modules support

    Hi,

    I hope this helps you too,

    I added AMD and CommonJS support following umd/jqueryPluginCommonjs.js wrapper

    you could check any other wrapper on https://github.com/umdjs/umd

    opened by fernandogmar 2
  • Server side use?

    Server side use?

    Bonjour Jean-Philippe!

    Great work on this lib. I'm debating on a JS localisation library for nodeJs/backbone. JsPeranto would be my first pick for its simplicity, but I'd like to use dictionary on the server as well for email templating. Any experience on using the lib on the client + server?

    PS: Your JSON format is fully supported on https://webtranslateit.com, it seem to be quick and simple translating tool, it may be worth mentioning it to other users (as it's solve the entire translation workflow for lazy devs like me).

    Cheers!

    félix

    opened by iplanwebsites 2
  • Hey

    Hey

    _plural did not work in english with 0 items being singular.

    I removed _plural and added _aboveOne, _exactlyOne, _belowOne. I also updated the test cases and markdown.

    opened by chris-rudmin 2
  • Replace all token instead of first occurence

    Replace all token instead of first occurence

    This patch allow $.t('__FOO__ and __FOO__', {FOO: 'foo'}) to translate to foo and foo instead of foo and __FOO__.

    I replaced the replace call to a simple split/join which act as a replaceAll. I didn't use a global regex so we don't have to escape special character and split/join has better performance.

    opened by isra17 1
  • Adds jQuery promise support

    Adds jQuery promise support

    The init function now returns a promise, so that it can also be used in a $.when() for example.

    $.when($.get('/something'), $.jsperanto.init()).done(function(){
        // do sth...
    });
    

    Also, since the callback is not needed in this case, it allows to omit the callback as first parameter in the init function.

    This change uses $.isPlainObject() which has been introduced in jQuery 1.4, so the library would no longer support jQuery 1.3.2 as it's claimed in the Readme.

    opened by janmonschke 1
  • More readable rewrite

    More readable rewrite

    Hi,

    I did a quick rewrite of your code (which is great, thanks !) in order to get a cleaner JavaScript to fit well with UglifyJS.

    Tell me if you want to talk about it.

    opened by sebastien-p 0
  • underscore Support

    underscore Support

    I have made the lib node/underscore compatible. This is done with little easy but the applyReplacement function has to be change because of the callbacks param order in each. see bottom

    this should not brake anything, besides for people that are using jquery and underscore they would have to switch to _ such as _.jsperanto.init

    Add to the factory function

    if (typeof _ !== 'undefined') {
        // Underscore.
        factory(_);
    } else if (typeof exports === 'object') {
    

    removed the call to check if function and did it inline

    options = (options == Object(options))? options : callback;
    

    applyReplacement

    function applyReplacement(string,replacementHash){
        if ($.ajax === undefined) {
            $.each(replacementHash, function (value, key) {
                string = string.split([o.interpolationPrefix, key, o.interpolationSuffix].join('')).join(value);
            });
        } else {
            $.each(replacementHash, function (key, value) {
                string = string.split([o.interpolationPrefix, key, o.interpolationSuffix].join('')).join(value);
            });
        }
        return string;
    }
    
    opened by adrianj98 0
  • load fallback dictionary to provide default strings

    load fallback dictionary to provide default strings

    I wanted to provide a way to use strings from the fallback dictionary/lang when they weren't found in the primary dictionary. The order I chose to use was dictionary, fallback dictionary, default value. Perhaps is would be better to use the default value if provided first? Also, maybe add a setting to trigger this behavior to begin with?

    opened by brian123zx 0
Owner
Jean-Philippe Joyal
Jean-Philippe Joyal
Jquery.iocurve - jQuery plugin like Tone Curve on Photoshop or GIMP

jquery.iocurve jQuery plugin like Tone Curve on Photoshop or GIMP. See Official page for more information. Quick start Create HTML and open in your br

null 5 Jul 28, 2022
🎉🎉🎉like vcsode, string/texts can be replaced in file(s).

tiny-replace-files Like vscode, simple utility to quickly replace text in one or more files. ?? Getting Started install # npm npm install --save tiny

兔子先生 16 Nov 22, 2022
What does the Cosmos Hub validator set looks like without ICF delegations?

This is a Next.js project bootstrapped with create-next-app. Getting Started First, run the development server: npm run dev # or yarn dev Open http://

Made in Block 2 Sep 2, 2022
Dead simple Object schema validation

Yup Yup is a JavaScript schema builder for value parsing and validation. Define a schema, transform a value to match, validate the shape of an existin

Jason Quense 19.2k Jan 2, 2023
A simple and composable way to validate data in JavaScript (and TypeScript).

A simple and composable way to validate data in JavaScript (and TypeScript). Usage • Why? • Principles • Demo • Examples • Documentation Superstruct m

Ian Storm Taylor 6.3k Jan 9, 2023
Simple and basic javascript form validations

JavaScript-Form-Validations Simple and basic javascript form validations Table of Validations: S. No. Type of validation Link 1 Non-empty text field h

MAINAK CHAUDHURI 23 Dec 17, 2022
A simple credit cards validation library in JavaScript

creditcard.js A simple credit cards validation library in JavaScript. Project website: https://contaazul.github.io/creditcard.js Install creditcard.js

ContaAzul 323 Jan 7, 2023
Simple validator for Steuerliche Identifikationsnummer (German personal tax number) according to the official docs (see readme).

simple-de-taxid-validator Important Code of this validator is taken (with small changes like optimization or removing not needed elements) from THIS R

Wojciech 3 Feb 24, 2022
A simple environment variables validator for Node.js and web browsers

A simple environment variables validator for Node.js and web browsers

Mathieu Acthernoene 25 Jul 20, 2022
Simple password validator made with Javascript 💛

Password Validator Simple password validator made with Javascript ?? Branch history base-code: a complex logic to password validator. In next branches

Lais Frigério 8 Jul 25, 2022
Simple, smart and pleasant validation solution.

nice-validator Simple, smart and pleasant validation solution. Download the latest release or install package via npm or bower $ npm install nice-vali

Jony 608 Nov 18, 2022
A simple library to validate Mexican CURPs (Personal ID)

Validate CURP A simple and lightweight library to validate Mexican CURPs (Personal ID). Install NodeJS Use NPM: $ npm install --save validate-curp Or

Manuel de la Torre 15 Nov 24, 2022
Validate your forms, frontend, without writing a single line of javascript

Parsley JavaScript form validation, without actually writing a single line of JavaScript! Version 2.9.2 Doc See index.html and doc/ Requirements jQuer

Guillaume Potier 9k Dec 27, 2022
The best @jquery plugin to validate form fields. Designed to use with Bootstrap + Zurb Foundation + Pure + SemanticUI + UIKit + Your own frameworks.

FormValidation - Download http://formvalidation.io - The best jQuery plugin to validate form fields, designed to use with: Bootstrap Foundation Pure S

FormValidation 2.8k Mar 29, 2021
[DISCONTINUED] jQuery plugin that makes it easy to validate user input while keeping your HTML markup clean from javascript code.

jQuery Form Validator [DISCONTINUED] Validation framework that let's you configure, rather than code, your validation logic. I started writing this pl

Victor Jonsson 976 Dec 30, 2022
Validate properties and well known annotations in your Backstage catalog-info.yaml files.

Backstage entity validator This package can be used as a GitHub action or a standalone node.js module GitHub action Inputs path Optional Path to the c

Roadie 39 Dec 26, 2022
DiscordEmailVerifier - Quickly verify emails on your tokens for completely free using mail.tm's api.

DiscordEmailVerifier Quickly verify emails on your tokens for completely free using mail.tm's api. /* ❗ No, this code doesn't verify the email for you

eric 3 Jun 7, 2022
Copypaster Has your project structure gotten so complex that to add a new feature you need to copy

Copypaster Has your project structure gotten so complex that to add a new feature you need to copy, paste and rename tens or hundreds of files each ti

null 2 Nov 4, 2022