diff --git a/README.markdown b/README.markdown index e31065c..a1b0747 100644 --- a/README.markdown +++ b/README.markdown @@ -1,3 +1,71 @@ +# jq-localize.js + +## jqMobi plugin enabling localization for mobile devices. + +## Usage: +Add to any html element you want to localize following attribute: + +localize-data="localize[json.value]" + +## Example: +given a json file named: + + main_language-fr.json + +in your base directory named + + localize/ + +with following content: + { + "maintext":{ + "hello": "Bonjour" + } + } + +add following line between script tag to your html header: + + /* + * Search in directory "localize" + * the file starting with "main_language" + * if the browser language is english, skip + $("[localize-data*=localize]").localize("localize/main_language", {skipLanguage: /^en/, loadBase: false}); + +any tag containing: + + localize-data="localize[maintext.hello]" + +like: + +

Hello

+ +will have it's text changed to "Bonjour" if the browser language is discovered to + + "fr" + +## In use with Intel XDK & appMobi +jqMobi is using asynchronous Ajax method to load any file. Thus loading the json file before +AppMobi.device is being instantiated, will result in an empty value and no localization will be possible. + +Possible solution + + /* This code is used for appMobi native apps */ + var onDeviceReady = function() { + AppMobi.device.setRotateOrientation("portrait"); + AppMobi.device.setAutoRotate(false); + webRoot = AppMobi.webRoot + "/"; + + // Now the device should be ready + $("[localize-data*=localize]").localize("localize/main_language", {skipLanguage: /^en/, loadBase: false}); + + }; + document.addEventListener("appMobi.device.ready", onDeviceReady, false); + + + + +
+ # jquery.localize.js ## a jQuery plugin that makes it easy to i18n your static web site. diff --git a/src/jq-localize b/src/jq-localize new file mode 100644 index 0000000..56bc3f0 --- /dev/null +++ b/src/jq-localize @@ -0,0 +1,167 @@ +# Copyright (c) MobComp GmbH (http://www.mobcomp.ch), 2013. +# Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. +# Written by Thomas Baumann (tbaumann@mobcomp.ch) for use on mc-time web app. +# http://github.com/thomasbau/jquery-localize/src/jq-localize +# Based off of Keith Wood's Localisation jQuery plugin. +# http://keith-wood.name/localisation.html +# and Jim Garvin (http://github.com/coderifous) + + +(function() { + var $, normaliseLang; + $ = jq; + normaliseLang = function(lang) { + lang = lang.replace(/_/, '-').toLowerCase(); + if (lang.length > 3) { + lang = lang.substring(0, 3) + lang.substring(3).toUpperCase(); + } + return lang; + }; + $.defaultLanguage = normaliseLang(navigator.language || navigator.userLanguage); + + $.localize = function(pkg, options) { + var defaultCallback, + fileExtension, + intermediateLangData, + jsonCall, + lang, + loadLanguage, + notifyDelegateLanguageLoaded, + regexify, + valueForKey, + wrappedSet; + + if (options === null) { + options = {}; + } + + wrappedSet = this; + intermediateLangData = {}; + fileExtension = options.fileExtension || "json"; + + loadLanguage = function(pkg, lang, level) { + var file; + if (level === null) { + level = 1; + } + switch (level) { + case 1: + intermediateLangData = {}; + if (options.loadBase) { + file = pkg + ("." + fileExtension); + return jsonCall(file, pkg, lang, level); + } else { + return loadLanguage(pkg, lang, 2); + } + break; + case 2: + if (lang.length >= 2) { + file = "" + pkg + "-" + (lang.substring(0, 2)) + "." + fileExtension; + return jsonCall(file, pkg, lang, level); + } + break; + case 3: + if (lang.length >= 5) { + file = "" + pkg + "-" + (lang.substring(0, 5)) + "." + fileExtension; + return jsonCall(file, pkg, lang, level); + } + } + }; + + jsonCall = function(file, pkg, lang, level) { + var ajaxOptions, successFunc; + if (typeof options.pathPrefix !== 'undefined') { + file = "" + options.pathPrefix + "/" + file; + } + successFunc = function(d) { + notifyDelegateLanguageLoaded($.parseJSON(d)); + return loadLanguage(pkg, lang, level + 1); + }; + + ajaxOptions = { + url: file, + crossDomain: true, + type: "GET", + success: successFunc + }; + $.ajax(ajaxOptions); + }; + + + defaultCallback = function(data) { + $.localize.data[pkg] = data; + return wrappedSet.each(function() { + var elem, key, value; + elem = $(this); + key = elem.attr("localize-data").match(/localize\[(.*?)\]/)[1]; + value = valueForKey(key, data); + + var type = elem[0].nodeName; + if (type === 'INPUT') { + if (elem.attr("placeholder")) { + return elem.attr("placeholder", value); + } else { + return elem.val(value); + } + } else if (elem.is('img')) { + value = valueForKey("" + key + ".alt", data); + if (value != null) { + elem.attr("alt", value); + } + value = valueForKey("" + key + ".src", data); + if (value != null) { + return elem.attr("src", value); + } + } else { + return elem.html(value); + } + }); + }; + + notifyDelegateLanguageLoaded = function(data) { + if (options.callback != null) { + return options.callback(data, defaultCallback); + } else { + return defaultCallback(data); + } + }; + + valueForKey = function(key, data) { + var keys, value, _i, _len; + keys = key.split(/\./); + value = data; + for (_i = 0, _len = keys.length; _i < _len; _i++) { + key = keys[_i]; + value = value != null ? value[key] : null; + } + return value; + }; + + regexify = function(string_or_regex_or_array) { + var thing; + if (typeof string_or_regex_or_array === "string") { + return "^" + string_or_regex_or_array + "$"; + } else if (string_or_regex_or_array.length != null) { + return ((function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = string_or_regex_or_array.length; _i < _len; _i++) { + thing = string_or_regex_or_array[_i]; + _results.push(regexify(thing)); + } + return _results; + })()).join("|"); + } else { + return string_or_regex_or_array; + } + }; + lang = normaliseLang(options.language ? options.language : $.defaultLanguage); + if (!(options.skipLanguage && lang.match(regexify(options.skipLanguage)))) { + loadLanguage(pkg, lang, 1); + } + return wrappedSet; + }; + + $.fn.localize = $.localize; + $.localize.data = {}; +}).call(this);