mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-17 03:01:08 +01:00
init
This commit is contained in:
2
public/language/TODO
Normal file
2
public/language/TODO
Normal 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.
|
||||||
3
public/language/en/global.json
Normal file
3
public/language/en/global.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"home": "Home"
|
||||||
|
}
|
||||||
8
public/language/en/login.json
Normal file
8
public/language/en/login.json
Normal 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
12
public/src/language.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
(function (module) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})('undefined' === typeof module ? {
|
||||||
|
module: {
|
||||||
|
exports: {}
|
||||||
|
}
|
||||||
|
} : module);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
(function(module) {
|
(function (module) {
|
||||||
|
|
||||||
var config = {},
|
var config = {},
|
||||||
templates,
|
templates,
|
||||||
@@ -12,11 +12,11 @@
|
|||||||
fs = require('fs');
|
fs = require('fs');
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
templates.force_refresh = function(tpl) {
|
templates.force_refresh = function (tpl) {
|
||||||
return !!config.force_refresh[tpl];
|
return !!config.force_refresh[tpl];
|
||||||
}
|
}
|
||||||
|
|
||||||
templates.get_custom_map = function(tpl) {
|
templates.get_custom_map = function (tpl) {
|
||||||
if (config['custom_mapping'] && tpl) {
|
if (config['custom_mapping'] && tpl) {
|
||||||
for (var pattern in config['custom_mapping']) {
|
for (var pattern in config['custom_mapping']) {
|
||||||
if (tpl.match(pattern)) {
|
if (tpl.match(pattern)) {
|
||||||
@@ -28,11 +28,11 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
templates.is_available = function(tpl) {
|
templates.is_available = function (tpl) {
|
||||||
return jQuery.inArray(tpl, available_templates) !== -1;
|
return jQuery.inArray(tpl, available_templates) !== -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
templates.ready = function(callback) {
|
templates.ready = function (callback) {
|
||||||
if (callback == null) {
|
if (callback == null) {
|
||||||
if (this.ready_callback) {
|
if (this.ready_callback) {
|
||||||
this.ready_callback();
|
this.ready_callback();
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
templates.prepare = function(raw_tpl, data) {
|
templates.prepare = function (raw_tpl, data) {
|
||||||
var template = {};
|
var template = {};
|
||||||
template.html = raw_tpl;
|
template.html = raw_tpl;
|
||||||
template.parse = parse;
|
template.parse = parse;
|
||||||
@@ -62,10 +62,10 @@
|
|||||||
var loaded = templatesToLoad.length;
|
var loaded = templatesToLoad.length;
|
||||||
|
|
||||||
for (var t in templatesToLoad) {
|
for (var t in templatesToLoad) {
|
||||||
(function(file) {
|
(function (file) {
|
||||||
fs.readFile(__dirname + '/../templates/' + file + '.tpl', function(err, html) {
|
fs.readFile(__dirname + '/../templates/' + file + '.tpl', function (err, html) {
|
||||||
var template = function() {
|
var template = function () {
|
||||||
this.toString = function() {
|
this.toString = function () {
|
||||||
return this.html;
|
return this.html;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadClient() {
|
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];
|
config = config_data[0];
|
||||||
available_templates = templates_data[0];
|
available_templates = templates_data[0];
|
||||||
templates.ready();
|
templates.ready();
|
||||||
@@ -96,11 +96,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
templates.init = function(templates_to_load) {
|
templates.init = function (templates_to_load) {
|
||||||
loadTemplates(templates_to_load || []);
|
loadTemplates(templates_to_load || []);
|
||||||
}
|
}
|
||||||
|
|
||||||
templates.getTemplateNameFromUrl = function(url) {
|
templates.getTemplateNameFromUrl = function (url) {
|
||||||
var parts = url.split('?')[0].split('/');
|
var parts = url.split('?')[0].split('/');
|
||||||
|
|
||||||
for (var i = 0; i < parts.length; ++i) {
|
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,
|
var location = document.location || window.location,
|
||||||
rootUrl = location.protocol + '//' + (location.hostname || location.host) + (location.port ? ':' + location.port : '');
|
rootUrl = location.protocol + '//' + (location.hostname || location.host) + (location.port ? ':' + location.port : '');
|
||||||
|
|
||||||
@@ -129,13 +129,13 @@
|
|||||||
var template_data = null;
|
var template_data = null;
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(function () {
|
||||||
var timestamp = new Date().getTime(); //debug
|
var timestamp = new Date().getTime(); //debug
|
||||||
|
|
||||||
if (!templates[tpl_url]) {
|
if (!templates[tpl_url]) {
|
||||||
jQuery.get(RELATIVE_PATH + '/templates/' + tpl_url + '.tpl?v=' + timestamp, function(html) {
|
jQuery.get(RELATIVE_PATH + '/templates/' + tpl_url + '.tpl?v=' + timestamp, function (html) {
|
||||||
var template = function() {
|
var template = function () {
|
||||||
this.toString = function() {
|
this.toString = function () {
|
||||||
return this.html;
|
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) {
|
if (!data) {
|
||||||
ajaxify.go('404');
|
ajaxify.go('404');
|
||||||
@@ -165,7 +165,7 @@
|
|||||||
|
|
||||||
template_data = data;
|
template_data = data;
|
||||||
parse_template();
|
parse_template();
|
||||||
}).fail(function(data) {
|
}).fail(function (data) {
|
||||||
template_data = {};
|
template_data = {};
|
||||||
parse_template();
|
parse_template();
|
||||||
});
|
});
|
||||||
@@ -180,9 +180,12 @@
|
|||||||
else
|
else
|
||||||
template_data['relative_path'] = RELATIVE_PATH;
|
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;
|
var value = null;
|
||||||
|
|
||||||
switch (element.getAttribute('template-type')) {
|
switch (element.getAttribute('template-type')) {
|
||||||
@@ -208,20 +211,20 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
templates.flush = function() {
|
templates.flush = function () {
|
||||||
parsed_variables = {};
|
parsed_variables = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
templates.get = function(key) {
|
templates.get = function (key) {
|
||||||
return parsed_variables[key];
|
return parsed_variables[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
templates.set = function(key, value) {
|
templates.set = function (key, value) {
|
||||||
parsed_variables[key] = value;
|
parsed_variables[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//modified from https://github.com/psychobunny/dcp.templates
|
//modified from https://github.com/psychobunny/dcp.templates
|
||||||
var parse = function(data) {
|
var parse = function (data) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
function replace(key, value, template) {
|
function replace(key, value, template) {
|
||||||
|
|||||||
75
public/src/translator.js
Normal file
75
public/src/translator.js
Normal 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);
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="{relative_path}/src/templates.js"></script>
|
<script src="{relative_path}/src/templates.js"></script>
|
||||||
<script src="{relative_path}/src/ajaxify.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/jquery.form.js"></script>
|
||||||
<script src="{relative_path}/src/utils.js"></script>
|
<script src="{relative_path}/src/utils.js"></script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li itemscope="itemscope" itemtype="http://data-vocabulary.org/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>
|
||||||
<li class="active" itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb">
|
<li class="active" itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb">
|
||||||
<span itemprop="title">Login</span>
|
<span itemprop="title">[[login:login]]</span>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
@@ -13,18 +13,18 @@
|
|||||||
<div class="well well-lg">
|
<div class="well well-lg">
|
||||||
<div class="alert alert-danger" id="login-error-notify" style="display:none">
|
<div class="alert alert-danger" id="login-error-notify" style="display:none">
|
||||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||||
<strong>Failed Login Attempt</strong> <p></p>
|
<strong>[[login:failed_login_attempt]]</strong> <p></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form class="form-horizontal" role="form">
|
<form class="form-horizontal" role="form">
|
||||||
<div class="form-group">
|
<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">
|
<div class="col-lg-10">
|
||||||
<input class="form-control" type="text" placeholder="Enter Username" name="username" id="username" />
|
<input class="form-control" type="text" placeholder="Enter Username" name="username" id="username" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<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">
|
<div class="col-lg-10">
|
||||||
<input class="form-control" type="password" placeholder="Enter Password" name="password" id="password" />
|
<input class="form-control" type="password" placeholder="Enter Password" name="password" id="password" />
|
||||||
</div>
|
</div>
|
||||||
@@ -33,14 +33,14 @@
|
|||||||
<div class="col-lg-offset-2 col-lg-10">
|
<div class="col-lg-offset-2 col-lg-10">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox"> Remember me
|
<input type="checkbox"> [[login:remember_me]]
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-lg-offset-2 col-lg-10">
|
<div class="col-lg-offset-2 col-lg-10">
|
||||||
<button class="btn btn-primary" id="login" type="submit">Login</button> <a href="/reset">Forgot Password?</a>
|
<button class="btn btn-primary" id="login" type="submit">[[login:login]]</button> <a href="/reset">[[login:forgot_password]]</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" name="_csrf" value="{token}" id="csrf-token" />
|
<input type="hidden" name="_csrf" value="{token}" id="csrf-token" />
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
<div class="col-md-6 {alternate_logins:display}">
|
<div class="col-md-6 {alternate_logins:display}">
|
||||||
<div class="well well-lg">
|
<div class="well well-lg">
|
||||||
<h4>Alternative Logins</h4>
|
<h4>[[login:alternative_logins]]</h4>
|
||||||
<ul class="alt-logins">
|
<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/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>
|
<li data-url="/auth/google" class="google {google:display}"><i class="icon-google-plus-sign icon-3x"></i></li>
|
||||||
|
|||||||
Reference in New Issue
Block a user