This commit is contained in:
psychobunny
2013-09-20 14:35:32 -04:00
parent db4dc03abc
commit b5274a0d91
8 changed files with 151 additions and 47 deletions

2
public/language/TODO Normal file
View File

@@ -0,0 +1,2 @@
For now, language packs will be stored here. Eventually, will be moved to server side to allow for npm installability.
When that happens, server code will generate compressed JSON language files in this folder.

View File

@@ -0,0 +1,3 @@
{
"home": "Home"
}

View File

@@ -0,0 +1,8 @@
{
"login": "Login",
"username": "Username",
"password": "Password",
"remember_me": "Remember Me?",
"forgot_password": "Forgot Password?",
"alternative_logins": "Alternative Logins"
}

12
public/src/language.js Normal file
View File

@@ -0,0 +1,12 @@
(function (module) {
})('undefined' === typeof module ? {
module: {
exports: {}
}
} : module);

View File

@@ -1,4 +1,4 @@
(function(module) {
(function (module) {
var config = {},
templates,
@@ -12,11 +12,11 @@
fs = require('fs');
} catch (e) {}
templates.force_refresh = function(tpl) {
templates.force_refresh = function (tpl) {
return !!config.force_refresh[tpl];
}
templates.get_custom_map = function(tpl) {
templates.get_custom_map = function (tpl) {
if (config['custom_mapping'] && tpl) {
for (var pattern in config['custom_mapping']) {
if (tpl.match(pattern)) {
@@ -28,11 +28,11 @@
return false;
}
templates.is_available = function(tpl) {
templates.is_available = function (tpl) {
return jQuery.inArray(tpl, available_templates) !== -1;
};
templates.ready = function(callback) {
templates.ready = function (callback) {
if (callback == null) {
if (this.ready_callback) {
this.ready_callback();
@@ -48,7 +48,7 @@
}
};
templates.prepare = function(raw_tpl, data) {
templates.prepare = function (raw_tpl, data) {
var template = {};
template.html = raw_tpl;
template.parse = parse;
@@ -62,10 +62,10 @@
var loaded = templatesToLoad.length;
for (var t in templatesToLoad) {
(function(file) {
fs.readFile(__dirname + '/../templates/' + file + '.tpl', function(err, html) {
var template = function() {
this.toString = function() {
(function (file) {
fs.readFile(__dirname + '/../templates/' + file + '.tpl', function (err, html) {
var template = function () {
this.toString = function () {
return this.html;
};
}
@@ -84,7 +84,7 @@
}
function loadClient() {
jQuery.when(jQuery.getJSON(RELATIVE_PATH + '/templates/config.json'), jQuery.getJSON(RELATIVE_PATH + '/api/get_templates_listing')).done(function(config_data, templates_data) {
jQuery.when(jQuery.getJSON(RELATIVE_PATH + '/templates/config.json'), jQuery.getJSON(RELATIVE_PATH + '/api/get_templates_listing')).done(function (config_data, templates_data) {
config = config_data[0];
available_templates = templates_data[0];
templates.ready();
@@ -96,11 +96,11 @@
}
templates.init = function(templates_to_load) {
templates.init = function (templates_to_load) {
loadTemplates(templates_to_load || []);
}
templates.getTemplateNameFromUrl = function(url) {
templates.getTemplateNameFromUrl = function (url) {
var parts = url.split('?')[0].split('/');
for (var i = 0; i < parts.length; ++i) {
@@ -112,7 +112,7 @@
}
templates.load_template = function(callback, url, template) {
templates.load_template = function (callback, url, template) {
var location = document.location || window.location,
rootUrl = location.protocol + '//' + (location.hostname || location.host) + (location.port ? ':' + location.port : '');
@@ -129,13 +129,13 @@
var template_data = null;
(function() {
(function () {
var timestamp = new Date().getTime(); //debug
if (!templates[tpl_url]) {
jQuery.get(RELATIVE_PATH + '/templates/' + tpl_url + '.tpl?v=' + timestamp, function(html) {
var template = function() {
this.toString = function() {
jQuery.get(RELATIVE_PATH + '/templates/' + tpl_url + '.tpl?v=' + timestamp, function (html) {
var template = function () {
this.toString = function () {
return this.html;
};
}
@@ -154,9 +154,9 @@
}());
(function() {
(function () {
jQuery.get(API_URL + api_url, function(data) {
jQuery.get(API_URL + api_url, function (data) {
if (!data) {
ajaxify.go('404');
@@ -165,7 +165,7 @@
template_data = data;
parse_template();
}).fail(function(data) {
}).fail(function (data) {
template_data = {};
parse_template();
});
@@ -180,22 +180,25 @@
else
template_data['relative_path'] = RELATIVE_PATH;
document.getElementById('content').innerHTML = templates[tpl_url].parse(template_data);
jQuery('#content [template-variable]').each(function(index, element) {
translator.translate(templates[tpl_url].parse(template_data), function (translatedTemplate) {
document.getElementById('content').innerHTML = translatedTemplate;
});
jQuery('#content [template-variable]').each(function (index, element) {
var value = null;
switch (element.getAttribute('template-type')) {
case 'boolean':
value = (element.value === 'true' || element.value === '1') ? true : false;
break;
case 'int': // Intentional fall-through
case 'integer':
value = parseInt(element.value);
break;
default:
value = element.value;
break;
case 'boolean':
value = (element.value === 'true' || element.value === '1') ? true : false;
break;
case 'int': // Intentional fall-through
case 'integer':
value = parseInt(element.value);
break;
default:
value = element.value;
break;
}
templates.set(element.getAttribute('template-variable'), value);
@@ -208,20 +211,20 @@
}
templates.flush = function() {
templates.flush = function () {
parsed_variables = {};
}
templates.get = function(key) {
templates.get = function (key) {
return parsed_variables[key];
}
templates.set = function(key, value) {
templates.set = function (key, value) {
parsed_variables[key] = value;
}
//modified from https://github.com/psychobunny/dcp.templates
var parse = function(data) {
var parse = function (data) {
var self = this;
function replace(key, value, template) {

75
public/src/translator.js Normal file
View File

@@ -0,0 +1,75 @@
(function (module) {
"use strict";
/*global RELATIVE_PATH*/
var translator = {},
loaded = {};
module.exports = translator;
translator.load = function (file, callback) {
if (loaded[file]) {
callback(loaded[file]);
} else {
var timestamp = new Date().getTime(); //debug
jQuery.getJSON(RELATIVE_PATH + '/language/en/' + file + '.json?v=' + timestamp, function (language) {
loaded[file] = language;
callback(language);
});
}
};
translator.translate = function (data, callback) {
var keys = data.match(/\[\[.*?\]\]/g),
loading = 0;
for (var key in keys) {
if (keys.hasOwnProperty(key)) {
var parsedKey = keys[key].replace('[[', '').replace(']]', '').split(':'),
languageFile = parsedKey[0];
parsedKey = parsedKey[1];
if (loaded[languageFile]) {
data = data.replace(keys[key], loaded[file][parsedKey]);
} else {
loading++;
(function (languageKey, parsedKey) {
translator.load(languageFile, function (languageData) {
data = data.replace(languageKey, languageData[parsedKey]);
loading--;
checkComplete();
});
}(keys[key], parsedKey));
}
}
checkComplete();
}
function checkComplete() {
if (loading === 0) {
callback(data);
}
}
};
if ('undefined' !== typeof window) {
window.translator = module.exports;
}
})('undefined' === typeof module ? {
module: {
exports: {}
}
} : module);

View File

@@ -24,6 +24,7 @@
</script>
<script src="{relative_path}/src/templates.js"></script>
<script src="{relative_path}/src/ajaxify.js"></script>
<script src="{relative_path}/src/translator.js"></script>
<script src="{relative_path}/src/jquery.form.js"></script>
<script src="{relative_path}/src/utils.js"></script>

View File

@@ -1,9 +1,9 @@
<ol class="breadcrumb">
<li itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb">
<a href="/" itemprop="url"><span itemprop="title">Home</span></a>
<a href="/" itemprop="url"><span itemprop="title">[[global:home]]</span></a>
</li>
<li class="active" itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb">
<span itemprop="title">Login</span>
<span itemprop="title">[[login:login]]</span>
</li>
</ol>
@@ -13,18 +13,18 @@
<div class="well well-lg">
<div class="alert alert-danger" id="login-error-notify" style="display:none">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<strong>Failed Login Attempt</strong> <p></p>
<strong>[[login:failed_login_attempt]]</strong> <p></p>
</div>
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="username" class="col-lg-2 control-label">Username</label>
<label for="username" class="col-lg-2 control-label">[[login:username]]</label>
<div class="col-lg-10">
<input class="form-control" type="text" placeholder="Enter Username" name="username" id="username" />
</div>
</div>
<div class="form-group">
<label for="password" class="col-lg-2 control-label">Password</label>
<label for="password" class="col-lg-2 control-label">[[login:password]]</label>
<div class="col-lg-10">
<input class="form-control" type="password" placeholder="Enter Password" name="password" id="password" />
</div>
@@ -33,14 +33,14 @@
<div class="col-lg-offset-2 col-lg-10">
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
<input type="checkbox"> [[login:remember_me]]
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button class="btn btn-primary" id="login" type="submit">Login</button> &nbsp; <a href="/reset">Forgot Password?</a>
<button class="btn btn-primary" id="login" type="submit">[[login:login]]</button> &nbsp; <a href="/reset">[[login:forgot_password]]</a>
</div>
</div>
<input type="hidden" name="_csrf" value="{token}" id="csrf-token" />
@@ -51,7 +51,7 @@
<div class="col-md-6 {alternate_logins:display}">
<div class="well well-lg">
<h4>Alternative Logins</h4>
<h4>[[login:alternative_logins]]</h4>
<ul class="alt-logins">
<li data-url="/auth/twitter" class="twitter {twitter:display}"><i class="icon-twitter-sign icon-3x"></i></li>
<li data-url="/auth/google" class="google {google:display}"><i class="icon-google-plus-sign icon-3x"></i></li>