Skip to content

Instantly share code, notes, and snippets.

@jbgutierrez
Last active May 25, 2021 06:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbgutierrez/5611410 to your computer and use it in GitHub Desktop.
Save jbgutierrez/5611410 to your computer and use it in GitHub Desktop.
Java + EJS + I18n
├── pom.xml
└── src
├── main
│   ├── java
│   │   └── EJSRenderer.java
│   └── javascript
│   └── EJSRenderer.js
└── test
└── java
├── EJSRendererTest.java
└── EJSRendererTest.plain
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.apache.commons.lang.StringEscapeUtils;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.ByteArrayOutputStream;
/**
* Evals EJS Templates written in Javascript within a Java context
*/
public class EJSRenderer
{
/* https://github.com/bestiejs/json3 */
static final String JSON = "(function(){function T(t){var n,i,o,u='{\"A\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}',a=t==\"json\";if(a||t==\"json-stringify\"||t==\"json-parse\"){if(t==\"json-stringify\"||a){if(n=typeof s.stringify==\"function\"&&b){(o=function(){return 1}).toJSON=o;try{n=s.stringify(0)===\"0\"&&s.stringify(new Number)===\"0\"&&s.stringify(new String)=='\"\"'&&s.stringify(e)===r&&s.stringify(r)===r&&s.stringify()===r&&s.stringify(o)===\"1\"&&s.stringify([o])==\"[1]\"&&s.stringify([r])==\"[null]\"&&s.stringify(null)==\"null\"&&s.stringify([r,e,null])==\"[null,null,null]\"&&s.stringify({A:[o,true,false,null,\"\\0\\b\\n\\f\\r\t\"]})==u&&s.stringify(null,o)===\"1\"&&s.stringify([1,2],null,1)==\"[\\n 1,\\n 2\\n]\"&&s.stringify(new Date(-864e13))=='\"-271821-04-20T00:00:00.000Z\"'&&s.stringify(new Date(864e13))=='\"+275760-09-13T00:00:00.000Z\"'&&s.stringify(new Date(-621987552e5))=='\"-000001-01-01T00:00:00.000Z\"'&&s.stringify(new Date(-1))=='\"1969-12-31T23:59:59.999Z\"'}catch(f){n=false}}if(!a){return n}}if(t==\"json-parse\"||a){if(typeof s.parse==\"function\"){try{if(s.parse(\"0\")===0&&!s.parse(false)){o=s.parse(u);if(i=o.A.length==5&&o.A[0]==1){try{i=!s.parse('\"\t\"')}catch(f){}if(i){try{i=s.parse(\"01\")!=1}catch(f){}}}}}catch(f){i=false}}if(!a){return i}}return n&&i}}var e={}.toString,t,n,r;var i=typeof define===\"function\"&&define.amd,s=!i&&typeof exports==\"object\"&&exports;if(s||i){if(typeof JSON==\"object\"&&JSON){if(i){s=JSON}else{s.stringify=JSON.stringify;s.parse=JSON.parse}}else if(i){s=this.JSON={}}}else{s=this.JSON||(this.JSON={})}var o,u,a,f;var l,c,h,p,d,v,m,g,y;var b=new Date(-0xc782b5b800cec),w,E,S;try{b=b.getUTCFullYear()==-109252&&b.getUTCMonth()===0&&b.getUTCDate()==1&&b.getUTCHours()==10&&b.getUTCMinutes()==37&&b.getUTCSeconds()==6&&b.getUTCMilliseconds()==708}catch(x){}if(!T(\"json\")){if(!b){w=Math.floor;E=[0,31,59,90,120,151,181,212,243,273,304,334];S=function(e,t){return E[t]+365*(e-1970)+w((e-1969+(t=+(t>1)))/4)-w((e-1901+t)/100)+w((e-1601+t)/400)}}if(!(t={}.hasOwnProperty)){t=function(n){var r={},i;if((r.__proto__=null,r.__proto__={toString:1},r).toString!=e){t=function(e){var t=this.__proto__,n=e in(this.__proto__=null,this);this.__proto__=t;return n}}else{i=r.constructor;t=function(e){var t=(this.constructor||i).prototype;return e in this&&!(e in t&&this[e]===t[e])}}r=null;return t.call(this,n)}}n=function(n,r){var i=0,s,o,u,a;(s=function(){this.valueOf=0}).prototype.valueOf=0;o=new s;for(u in o){if(t.call(o,u)){i++}}s=o=null;if(!i){o=[\"valueOf\",\"toString\",\"toLocaleString\",\"propertyIsEnumerable\",\"isPrototypeOf\",\"hasOwnProperty\",\"constructor\"];a=function(n,r){var i=e.call(n)==\"[object Function]\",s,u;for(s in n){if(!(i&&s==\"prototype\")&&t.call(n,s)){r(s)}}for(u=o.length;s=o[--u];t.call(n,s)&&r(s));}}else if(i==2){a=function(n,r){var i={},s=e.call(n)==\"[object Function]\",o;for(o in n){if(!(s&&o==\"prototype\")&&!t.call(i,o)&&(i[o]=1)&&t.call(n,o)){r(o)}}}}else{a=function(n,r){var i=e.call(n)==\"[object Function]\",s,o;for(s in n){if(!(i&&s==\"prototype\")&&t.call(n,s)&&!(o=s===\"constructor\")){r(s)}}if(o||t.call(n,s=\"constructor\")){r(s)}}}return a(n,r)};if(!T(\"json-stringify\")){o={\"\\\\\":\"\\\\\\\\\",'\"':'\\\\\"',\"\\b\":\"\\\\b\",\"\\f\":\"\\\\f\",\"\\n\":\"\\\\n\",\"\\r\":\"\\\\r\",\"\t\":\"\\\\t\"};u=function(e,t){return(\"000000\"+(t||0)).slice(-e)};a=function(e){var t='\"',n=0,r;for(;r=e.charAt(n);n++){t+='\\\\\"\\b\\f\\n\\r\t'.indexOf(r)>-1?o[r]:o[r]=r<\" \"?\"\\\\u00\"+u(2,r.charCodeAt(0).toString(16)):r}return t+'\"'};f=function(i,s,o,l,c,h,p){var d=s[i],v,m,g,y,b,E,x,T,N,C,k,L,A,O,M,_;if(typeof d==\"object\"&&d){v=e.call(d);if(v==\"[object Date]\"&&!t.call(d,\"toJSON\")){if(d>-1/0&&d<1/0){if(S){y=w(d/864e5);for(m=w(y/365.2425)+1970-1;S(m+1,0)<=y;m++);for(g=w((y-S(m,0))/30.42);S(m,g+1)<=y;g++);y=1+y-S(m,g);b=(d%864e5+864e5)%864e5;E=w(b/36e5)%24;x=w(b/6e4)%60;T=w(b/1e3)%60;N=b%1e3}else{m=d.getUTCFullYear();g=d.getUTCMonth();y=d.getUTCDate();E=d.getUTCHours();x=d.getUTCMinutes();T=d.getUTCSeconds();N=d.getUTCMilliseconds()}d=(m<=0||m>=1e4?(m<0?\"-\":\"+\")+u(6,m<0?-m:m):u(4,m))+\"-\"+u(2,g+1)+\"-\"+u(2,y)+\"T\"+u(2,E)+\":\"+u(2,x)+\":\"+u(2,T)+\".\"+u(3,N)+\"Z\"}else{d=null}}else if(typeof d.toJSON==\"function\"&&(v!=\"[object Number]\"&&v!=\"[object String]\"&&v!=\"[object Array]\"||t.call(d,\"toJSON\"))){d=d.toJSON(i)}}if(o){d=o.call(s,i,d)}if(d===null){return\"null\"}v=e.call(d);if(v==\"[object Boolean]\"){return\"\"+d}else if(v==\"[object Number]\"){return d>-1/0&&d<1/0?\"\"+d:\"null\"}else if(v==\"[object String]\"){return a(d)}if(typeof d==\"object\"){for(A=p.length;A--;){if(p[A]===d){throw TypeError()}}p.push(d);C=[];O=h;h+=c;if(v==\"[object Array]\"){for(L=0,A=d.length;L<A;M||(M=true),L++){k=f(L,d,o,l,c,h,p);C.push(k===r?\"null\":k)}_=M?c?\"[\\n\"+h+C.join(\",\\n\"+h)+\"\\n\"+O+\"]\":\"[\"+C.join(\",\")+\"]\":\"[]\"}else{n(l||d,function(e){var t=f(e,d,o,l,c,h,p);if(t!==r){C.push(a(e)+\":\"+(c?\" \":\"\")+t)}M||(M=true)});_=M?c?\"{\\n\"+h+C.join(\",\\n\"+h)+\"\\n\"+O+\"}\":\"{\"+C.join(\",\")+\"}\":\"{}\"}p.pop();return _}};s.stringify=function(t,n,r){var i,s,o,u,a,l;if(typeof n==\"function\"||typeof n==\"object\"&&n){if(e.call(n)==\"[object Function]\"){s=n}else if(e.call(n)==\"[object Array]\"){o={};for(u=0,a=n.length;u<a;l=n[u++],(e.call(l)==\"[object String]\"||e.call(l)==\"[object Number]\")&&(o[l]=1));}}if(r){if(e.call(r)==\"[object Number]\"){if((r-=r%1)>0){for(i=\"\",r>10&&(r=10);i.length<r;i+=\" \");}}else if(e.call(r)==\"[object String]\"){i=r.length<=10?r:r.slice(0,10)}}return f(\"\",(l={},l[\"\"]=t,l),s,o,i,\"\",[])}}if(!T(\"json-parse\")){l=String.fromCharCode;c={\"\\\\\":\"\\\\\",'\"':'\"',\"/\":\"/\",b:\"\\b\",t:\"\t\",n:\"\\n\",f:\"\\f\",r:\"\\r\"};h=function(){g=y=null;throw SyntaxError()};p=function(){var e=y,t=e.length,n,r,i,s,o;while(g<t){n=e.charAt(g);if(\"\t\\r\\n \".indexOf(n)>-1){g++}else if(\"{}[]:,\".indexOf(n)>-1){g++;return n}else if(n=='\"'){for(r=\"@\",g++;g<t;){n=e.charAt(g);if(n<\" \"){h()}else if(n==\"\\\\\"){n=e.charAt(++g);if('\\\\\"/btnfr'.indexOf(n)>-1){r+=c[n];g++}else if(n==\"u\"){i=++g;for(s=g+4;g<s;g++){n=e.charAt(g);if(!(n>=\"0\"&&n<=\"9\"||n>=\"a\"&&n<=\"f\"||n>=\"A\"&&n<=\"F\")){h()}}r+=l(\"0x\"+e.slice(i,g))}else{h()}}else{if(n=='\"'){break}r+=n;g++}}if(e.charAt(g)=='\"'){g++;return r}h()}else{i=g;if(n==\"-\"){o=true;n=e.charAt(++g)}if(n>=\"0\"&&n<=\"9\"){if(n==\"0\"&&(n=e.charAt(g+1),n>=\"0\"&&n<=\"9\")){h()}o=false;for(;g<t&&(n=e.charAt(g),n>=\"0\"&&n<=\"9\");g++);if(e.charAt(g)==\".\"){s=++g;for(;s<t&&(n=e.charAt(s),n>=\"0\"&&n<=\"9\");s++);if(s==g){h()}g=s}n=e.charAt(g);if(n==\"e\"||n==\"E\"){n=e.charAt(++g);if(n==\"+\"||n==\"-\"){g++}for(s=g;s<t&&(n=e.charAt(s),n>=\"0\"&&n<=\"9\");s++);if(s==g){h()}g=s}return+e.slice(i,g)}if(o){h()}if(e.slice(g,g+4)==\"true\"){g+=4;return true}else if(e.slice(g,g+5)==\"false\"){g+=5;return false}else if(e.slice(g,g+4)==\"null\"){g+=4;return null}h()}}return\"$\"};d=function(e){var t,n,r;if(e==\"$\"){h()}if(typeof e==\"string\"){if(e.charAt(0)==\"@\"){return e.slice(1)}if(e==\"[\"){t=[];for(;;n||(n=true)){e=p();if(e==\"]\"){break}if(n){if(e==\",\"){e=p();if(e==\"]\"){h()}}else{h()}}if(e==\",\"){h()}t.push(d(e))}return t}else if(e==\"{\"){t={};for(;;n||(n=true)){e=p();if(e==\"}\"){break}if(n){if(e==\",\"){e=p();if(e==\"}\"){h()}}else{h()}}if(e==\",\"||typeof e!=\"string\"||e.charAt(0)!=\"@\"||p()!=\":\"){h()}t[e.slice(1)]=d(p())}return t}h()}return e};m=function(e,t,n){var i=v(e,t,n);if(i===r){delete e[t]}else{e[t]=i}};v=function(t,r,i){var s=t[r],o;if(typeof s==\"object\"&&s){if(e.call(s)==\"[object Array]\"){for(o=s.length;o--;){m(s,o,i)}}else{n(s,function(e){m(s,e,i)})}}return i.call(t,r,s)};s.parse=function(t,n){var r,i;g=0;y=t;r=d(p());if(p()!=\"$\"){h()}g=y=null;return n&&e.call(n)==\"[object Function]\"?v((i={},i[\"\"]=r,i),\"\",n):r}}}if(i){define(function(){return s})}}).call(this)";
/* https://github.com/visionmedia/ejs */
static final String EJS = "ejs=function(){function require(p){if(\"fs\"==p)return{};var path=require.resolve(p),mod=require.modules[path];if(!mod)throw new Error('failed to require \"'+p+'\"');return mod.exports||(mod.exports={},mod.call(mod.exports,mod,mod.exports,require.relative(path))),mod.exports}return require.modules={},require.resolve=function(path){var orig=path,reg=path+\".js\",index=path+\"/index.js\";return require.modules[reg]&&reg||require.modules[index]&&index||orig},require.register=function(path,fn){require.modules[path]=fn},require.relative=function(parent){return function(p){if(\".\"!=p.substr(0,1))return require(p);var path=parent.split(\"/\"),segs=p.split(\"/\");path.pop();for(var i=0;i<segs.length;i++){var seg=segs[i];\"..\"==seg?path.pop():\".\"!=seg&&path.push(seg)}return require(path.join(\"/\"))}},require.register(\"ejs.js\",function(module,exports,require){var utils=require(\"./utils\"),fs=require(\"fs\");exports.version=\"0.7.2\";var filters=exports.filters=require(\"./filters\"),cache={};exports.clearCache=function(){cache={}};function filtered(js){return js.substr(1).split(\"|\").reduce(function(js,filter){var parts=filter.split(\":\"),name=parts.shift(),args=parts.shift()||\"\";return args&&(args=\", \"+args),\"filters.\"+name+\"(\"+js+args+\")\"})}function rethrow(err,str,filename,lineno){var lines=str.split(\"\\n\"),start=Math.max(lineno-3,0),end=Math.min(lines.length,lineno+3),context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?\" >> \":\" \")+curr+\"| \"+line}).join(\"\\n\");throw err.path=filename,err.message=(filename||\"ejs\")+\":\"+lineno+\"\\n\"+context+\"\\n\\n\"+err.message,err}var parse=exports.parse=function(str,options){var options=options||{},open=options.open||exports.open||\"<%\",close=options.close||exports.close||\"%>\",buf=[\"var buf = [];\",\"\\nwith (locals) {\",\"\\n buf.push('\"],lineno=1,consumeEOL=!1;for(var i=0,len=str.length;i<len;++i)if(str.slice(i,open.length+i)==open){i+=open.length;var prefix,postfix,line=\"__stack.lineno=\"+lineno;switch(str.substr(i,1)){case\"=\":prefix=\"', escape((\"+line+\", \",postfix=\")), '\",++i;break;case\"-\":prefix=\"', (\"+line+\", \",postfix=\"), '\",++i;break;default:prefix=\"');\"+line+\";\",postfix=\"; buf.push('\"}var end=str.indexOf(close,i),js=str.substring(i,end),start=i,n=0;\"-\"==js[js.length-1]&&(js=js.substring(0,js.length-2),consumeEOL=!0);while(~(n=js.indexOf(\"\\n\",n)))n++,lineno++;js.substr(0,1)==\":\"&&(js=filtered(js)),buf.push(prefix,js,postfix),i+=end-start+close.length-1}else str.substr(i,1)==\"\\\\\"?buf.push(\"\\\\\\\\\"):str.substr(i,1)==\"'\"?buf.push(\"\\\\'\"):str.substr(i,1)==\"\\r\"?buf.push(\" \"):str.substr(i,1)==\"\\n\"?consumeEOL?consumeEOL=!1:(buf.push(\"\\\\n\"),lineno++):buf.push(str.substr(i,1));return buf.push(\"');\\n}\\nreturn buf.join('');\"),buf.join(\"\")},compile=exports.compile=function(str,options){options=options||{};var input=JSON.stringify(str),filename=options.filename?JSON.stringify(options.filename):\"undefined\";str=[\"var __stack = { lineno: 1, input: \"+input+\", filename: \"+filename+\" };\",rethrow.toString(),\"try {\",exports.parse(str,options),\"} catch (err) {\",\" rethrow(err, __stack.input, __stack.filename, __stack.lineno);\",\"}\"].join(\"\\n\"),options.debug&&console.log(str);var fn=new Function(\"locals, filters, escape\",str);return function(locals){return fn.call(this,locals,filters,utils.escape)}};exports.render=function(str,options){var fn,options=options||{};if(options.cache){if(!options.filename)throw new Error('\"cache\" option requires \"filename\".');fn=cache[options.filename]||(cache[options.filename]=compile(str,options))}else fn=compile(str,options);return options.__proto__=options.locals,fn.call(options.scope,options)},exports.renderFile=function(path,options,fn){var key=path+\":string\";\"function\"==typeof options&&(fn=options,options={}),options.filename=path;try{var str=options.cache?cache[key]||(cache[key]=fs.readFileSync(path,\"utf8\")):fs.readFileSync(path,\"utf8\");fn(null,exports.render(str,options))}catch(err){fn(err)}},exports.__express=exports.renderFile,require.extensions?require.extensions[\".ejs\"]=function(module,filename){source=require(\"fs\").readFileSync(filename,\"utf-8\"),module._compile(compile(source,{}),filename)}:require.registerExtension&&require.registerExtension(\".ejs\",function(src){return compile(src,{})})}),require.register(\"filters.js\",function(module,exports,require){exports.first=function(obj){return obj[0]},exports.last=function(obj){return obj[obj.length-1]},exports.capitalize=function(str){return str=String(str),str[0].toUpperCase()+str.substr(1,str.length)},exports.downcase=function(str){return String(str).toLowerCase()},exports.upcase=function(str){return String(str).toUpperCase()},exports.sort=function(obj){return Object.create(obj).sort()},exports.sort_by=function(obj,prop){return Object.create(obj).sort(function(a,b){return a=a[prop],b=b[prop],a>b?1:a<b?-1:0})},exports.size=exports.length=function(obj){return obj.length},exports.plus=function(a,b){return Number(a)+Number(b)},exports.minus=function(a,b){return Number(a)-Number(b)},exports.times=function(a,b){return Number(a)*Number(b)},exports.divided_by=function(a,b){return Number(a)/Number(b)},exports.join=function(obj,str){return obj.join(str||\", \")},exports.truncate=function(str,len){return str=String(str),str.substr(0,len)},exports.truncate_words=function(str,n){var str=String(str),words=str.split(/ +/);return words.slice(0,n).join(\" \")},exports.replace=function(str,pattern,substitution){return String(str).replace(pattern,substitution||\"\")},exports.prepend=function(obj,val){return Array.isArray(obj)?[val].concat(obj):val+obj},exports.append=function(obj,val){return Array.isArray(obj)?obj.concat(val):obj+val},exports.map=function(arr,prop){return arr.map(function(obj){return obj[prop]})},exports.reverse=function(obj){return Array.isArray(obj)?obj.reverse():String(obj).split(\"\").reverse().join(\"\")},exports.get=function(obj,prop){return obj[prop]},exports.json=function(obj){return JSON.stringify(obj)}}),require.register(\"utils.js\",function(module,exports,require){exports.escape=function(html){return String(html).replace(/&(?!\\w+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\")}}),require(\"ejs\")}();";
/* Source: src/javascript/EJSRenderer.js */
static final String EJSHelpers = "function addHelpers(e){var t=e.language,n=e.territory,r=t+\"_\"+n;var i={};e.dict=function(e){i=e};var s=function(e,t){return(i[e]||{})[t]};e.t=function(e){return s(r,e)||s(n,e)||s(t,e)||s(\"en\",e)||\"**\"+e+\"**\"};var o=[].slice;e.at=function(){var e=o.call(arguments,0),i=e.length,s,u;for(s=0;s<i;s++){u=e[s];if(u===t||u===n||u===r){return true}}return false}}";
public static String executeEJS(String template, Object ctx) {
String result;
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine jsCtx = scriptEngineManager.getEngineByName("JavaScript");
try {
// Build java json context
ByteArrayOutputStream os = new ByteArrayOutputStream();
(new ObjectMapper()).writeValue(os, ctx);
String javaContext = new String(os.toByteArray(),"UTF-8");
// Build the script
String script = String.format("%s;%s;%s;%s;%s;%s",
JSON,
EJS,
EJSHelpers,
"var locals = " + javaContext,
"addHelpers(locals)",
"ejs.render('" + StringEscapeUtils.escapeJavaScript(template) + "', locals)"
);
// Execute the script
Object obj = jsCtx.eval(script);
result = (String) obj;
}
catch(Exception e) {
result = "<!-- " + e.getMessage() + " -->";
e.printStackTrace();
}
return result;
}
}
function addHelpers(exports) {
var language = exports.language,
territory = exports.territory,
locale = language + "_" + territory;
var dict = {};
exports.dict = function(_dict) {
dict = _dict;
};
var lookup = function(locale, key) {
return (dict[locale] || {} )[key];
};
exports.t = function(key){
return lookup(locale, key) ||
lookup(territory, key) ||
lookup(language, key) ||
lookup('en', key) ||
"**" + key + "**";
};
var __slice = [].slice;
exports.at = function(/*locales*/){
var locales = __slice.call(arguments, 0),
length = locales.length,
i, current;
for(i = 0; i < length; i++) {
current = locales[i];
if (current === language || current === territory || current === locale) {
return true;
}
}
return false;
};
}
import org.junit.Assert;
import org.junit.Test;
import java.io.File;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class EJSRendererTest {
String template;
@Test
public void testExecuteEJS() throws Exception {
String tests = new Scanner(new File("src/test/java/EJSRendererTest.plain")).useDelimiter("\\A").next();
Pattern pattern = Pattern.compile("# ([\\w_]+) - (.+)([^#]+)");
Matcher matcher = pattern.matcher(tests);
while(matcher.find()){
String localeOrAction = matcher.group(1),
message = matcher.group(2),
text = matcher.group(3);
if (localeOrAction.equals("SETUP")) {
System.out.println(localeOrAction + ": " + message);
template = text;
} else {
System.out.println(localeOrAction + ": testing " + message);
AssertExecution(localeOrAction, text);
}
}
}
public void AssertExecution(final String locale, String expected) {
String result = EJSRenderer.executeEJS(template, new Object() {
private String[] tokens = locale.split("_");
public String getLanguage() { return tokens[0]; }
public String getTerritory() { return tokens[1]; }
});
Assert.assertEquals(expected.replaceAll("\\n", ""), result.replaceAll("\\n", "") );
}
}
# SETUP - Example 1: Rendering HTML
<%
dict({
en: { h1: 'I love music' },
es: { h1: 'Me gusta la música' },
fr: { h1: 'J\'aime la musique' },
JP: { h1: '私は音楽を愛する' },
fr_CA: { h1: 'I♡ ♫' }
});
%>
<h1><%- t('h1') %></h1>
<% if (at('JP')) { %>
<p>* 邦楽</p>
<% } %>
# fr_FR - French in France
<h1>J'aime la musique</h1>
# fr_CH - French in Switzerland
<h1>J'aime la musique</h1>
# fr_CA - French in Canada
<h1>I♡ ♫</h1>
# en_ES - English (anywhere)
<h1>I love music</h1>
# es_ES - Spanish (anywhere)
<h1>Me gusta la música</h1>
# de_CH - English fallback (anywhere)
<h1>I love music</h1>
# en_JP - English in Japan (should show japanese)
<h1>私は音楽を愛する</h1>
<p>* 邦楽</p>
# ja_JP - Japanese in Japan + message
<h1>私は音楽を愛する</h1>
<p>* 邦楽</p>
# SETUP - Example 2: Rendering JSON
<%
dict({
en: { message: 'I love music' },
es: { message: 'Me gusta la música' },
fr: { message: 'J\'aime la musique' },
JP: { message: '私は音楽を愛する' },
fr_CA: { message: 'I♡ ♫' }
});
messages = {
message: t('message')
}
if (at('JP')) {
messages.messageAlternative = '* 邦楽';
}
%>
<%- JSON.stringify(messages) %>
# fr_FR - French in France
{"message":"J'aime la musique"}
# fr_CH - French in Switzerland
{"message":"J'aime la musique"}
# fr_CA - French in Canada
{"message":"I♡ ♫"}
# en_ES - English (anywhere)
{"message":"I love music"}
# es_ES - Spanish (anywhere)
{"message":"Me gusta la música"}
# de_CH - English fallback (anywhere)
{"message":"I love music"}
# en_JP - English in Japan (should show japanese)
{"message":"私は音楽を愛する","messageAlternative":"* 邦楽"}
# ja_JP - Japanese in Japan + message
{"message":"私は音楽を愛する","messageAlternative":"* 邦楽"}
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.acme</groupId>
<artifactId>rhinosample</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>rhinosample</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.8.5</version>
</dependency>
</dependencies>
</project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment