mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 12:42:16 +08:00
Added Site Setting to change locale.
This commit is contained in:
parent
e37c7f1e1d
commit
628927a79f
2
Gemfile
2
Gemfile
|
@ -21,7 +21,7 @@ gem 'fastimage'
|
|||
gem 'fog', require: false
|
||||
gem 'has_ip_address'
|
||||
gem 'hiredis'
|
||||
gem 'i18n-js'
|
||||
|
||||
# note: for image_optim to correctly work you need
|
||||
# sudo apt-get install -y advancecomp gifsicle jpegoptim libjpeg-progs optipng pngcrush
|
||||
gem 'image_optim'
|
||||
|
|
|
@ -203,8 +203,6 @@ GEM
|
|||
hiredis (0.4.5)
|
||||
httpauth (0.2.0)
|
||||
i18n (0.6.1)
|
||||
i18n-js (2.1.2)
|
||||
i18n
|
||||
image_optim (0.7.2)
|
||||
fspath (~> 2.0.3)
|
||||
image_size (~> 1.1)
|
||||
|
@ -479,7 +477,6 @@ DEPENDENCIES
|
|||
guard-spork
|
||||
has_ip_address
|
||||
hiredis
|
||||
i18n-js
|
||||
image_optim
|
||||
jasminerice
|
||||
jquery-rails
|
||||
|
|
|
@ -20,11 +20,6 @@
|
|||
|
||||
// The rest of the externals
|
||||
//= require_tree ./external
|
||||
//= require i18n
|
||||
|
||||
// The following needs to go right after including i18n, because other scripts
|
||||
// below require correctly set locale already
|
||||
//= require init_locale
|
||||
|
||||
//= require ./discourse/helpers/i18n_helpers
|
||||
//= require ./discourse
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
I18n.locale = window.currentLocale;
|
|
@ -1,2 +1,3 @@
|
|||
//= depend_on 'client.en.yml'
|
||||
<%= JsLocaleHelper.output_locale(:en); %>
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:en) %>
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
//= depend_on 'client.fr.yml'
|
||||
<%= JsLocaleHelper.output_locale(:fr); %>
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:fr) %>
|
||||
|
|
531
app/assets/javascripts/locales/i18n.js
Normal file
531
app/assets/javascripts/locales/i18n.js
Normal file
|
@ -0,0 +1,531 @@
|
|||
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
|
||||
if (!Array.prototype.indexOf) {
|
||||
Array.prototype.indexOf = function(searchElement /*, fromIndex */) {
|
||||
"use strict";
|
||||
|
||||
if (this === void 0 || this === null) {
|
||||
throw new TypeError();
|
||||
}
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
|
||||
if (len === 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var n = 0;
|
||||
if (arguments.length > 0) {
|
||||
n = Number(arguments[1]);
|
||||
if (n !== n) { // shortcut for verifying if it's NaN
|
||||
n = 0;
|
||||
} else if (n !== 0 && n !== (Infinity) && n !== -(Infinity)) {
|
||||
n = (n > 0 || -1) * Math.floor(Math.abs(n));
|
||||
}
|
||||
}
|
||||
|
||||
if (n >= len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var k = n >= 0
|
||||
? n
|
||||
: Math.max(len - Math.abs(n), 0);
|
||||
|
||||
for (; k < len; k++) {
|
||||
if (k in t && t[k] === searchElement) {
|
||||
return k;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
// Instantiate the object
|
||||
var I18n = I18n || {};
|
||||
|
||||
// Set default locale to english
|
||||
I18n.defaultLocale = "en";
|
||||
|
||||
// Set default handling of translation fallbacks to false
|
||||
I18n.fallbacks = false;
|
||||
|
||||
// Set default separator
|
||||
I18n.defaultSeparator = ".";
|
||||
|
||||
// Set current locale to null
|
||||
I18n.locale = null;
|
||||
|
||||
// Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`.
|
||||
I18n.PLACEHOLDER = /(?:\{\{|%\{)(.*?)(?:\}\}?)/gm;
|
||||
|
||||
I18n.fallbackRules = {
|
||||
};
|
||||
|
||||
I18n.pluralizationRules = {
|
||||
en: function (n) {
|
||||
return n == 0 ? ["zero", "none", "other"] : n == 1 ? "one" : "other";
|
||||
}
|
||||
};
|
||||
|
||||
I18n.getFallbacks = function(locale) {
|
||||
if (locale === I18n.defaultLocale) {
|
||||
return [];
|
||||
} else if (!I18n.fallbackRules[locale]) {
|
||||
var rules = []
|
||||
, components = locale.split("-");
|
||||
|
||||
for (var l = 1; l < components.length; l++) {
|
||||
rules.push(components.slice(0, l).join("-"));
|
||||
}
|
||||
|
||||
rules.push(I18n.defaultLocale);
|
||||
|
||||
I18n.fallbackRules[locale] = rules;
|
||||
}
|
||||
|
||||
return I18n.fallbackRules[locale];
|
||||
}
|
||||
|
||||
I18n.isValidNode = function(obj, node, undefined) {
|
||||
return obj[node] !== null && obj[node] !== undefined;
|
||||
};
|
||||
|
||||
I18n.lookup = function(scope, options) {
|
||||
var options = options || {}
|
||||
, lookupInitialScope = scope
|
||||
, translations = this.prepareOptions(I18n.translations)
|
||||
, locale = options.locale || I18n.currentLocale()
|
||||
, messages = translations[locale] || {}
|
||||
, options = this.prepareOptions(options)
|
||||
, currentScope
|
||||
;
|
||||
|
||||
if (typeof(scope) == "object") {
|
||||
scope = scope.join(this.defaultSeparator);
|
||||
}
|
||||
|
||||
if (options.scope) {
|
||||
scope = options.scope.toString() + this.defaultSeparator + scope;
|
||||
}
|
||||
|
||||
scope = scope.split(this.defaultSeparator);
|
||||
|
||||
while (messages && scope.length > 0) {
|
||||
currentScope = scope.shift();
|
||||
messages = messages[currentScope];
|
||||
}
|
||||
|
||||
if (!messages) {
|
||||
if (I18n.fallbacks) {
|
||||
var fallbacks = this.getFallbacks(locale);
|
||||
for (var fallback = 0; fallback < fallbacks.length; fallbacks++) {
|
||||
messages = I18n.lookup(lookupInitialScope, this.prepareOptions({locale: fallbacks[fallback]}, options));
|
||||
if (messages) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!messages && this.isValidNode(options, "defaultValue")) {
|
||||
messages = options.defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return messages;
|
||||
};
|
||||
|
||||
// Merge serveral hash options, checking if value is set before
|
||||
// overwriting any value. The precedence is from left to right.
|
||||
//
|
||||
// I18n.prepareOptions({name: "John Doe"}, {name: "Mary Doe", role: "user"});
|
||||
// #=> {name: "John Doe", role: "user"}
|
||||
//
|
||||
I18n.prepareOptions = function() {
|
||||
var options = {}
|
||||
, opts
|
||||
, count = arguments.length
|
||||
;
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
opts = arguments[i];
|
||||
|
||||
if (!opts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var key in opts) {
|
||||
if (!this.isValidNode(options, key)) {
|
||||
options[key] = opts[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
I18n.interpolate = function(message, options) {
|
||||
options = this.prepareOptions(options);
|
||||
var matches = message.match(this.PLACEHOLDER)
|
||||
, placeholder
|
||||
, value
|
||||
, name
|
||||
;
|
||||
|
||||
if (!matches) {
|
||||
return message;
|
||||
}
|
||||
|
||||
for (var i = 0; placeholder = matches[i]; i++) {
|
||||
name = placeholder.replace(this.PLACEHOLDER, "$1");
|
||||
|
||||
value = options[name];
|
||||
|
||||
if (!this.isValidNode(options, name)) {
|
||||
value = "[missing " + placeholder + " value]";
|
||||
}
|
||||
|
||||
regex = new RegExp(placeholder.replace(/\{/gm, "\\{").replace(/\}/gm, "\\}"));
|
||||
message = message.replace(regex, value);
|
||||
}
|
||||
|
||||
return message;
|
||||
};
|
||||
|
||||
I18n.translate = function(scope, options) {
|
||||
options = this.prepareOptions(options);
|
||||
var translation = this.lookup(scope, options);
|
||||
|
||||
try {
|
||||
if (typeof(translation) == "object") {
|
||||
if (typeof(options.count) == "number") {
|
||||
return this.pluralize(options.count, scope, options);
|
||||
} else {
|
||||
return translation;
|
||||
}
|
||||
} else {
|
||||
return this.interpolate(translation, options);
|
||||
}
|
||||
} catch(err) {
|
||||
return this.missingTranslation(scope);
|
||||
}
|
||||
};
|
||||
|
||||
I18n.localize = function(scope, value) {
|
||||
switch (scope) {
|
||||
case "currency":
|
||||
return this.toCurrency(value);
|
||||
case "number":
|
||||
scope = this.lookup("number.format");
|
||||
return this.toNumber(value, scope);
|
||||
case "percentage":
|
||||
return this.toPercentage(value);
|
||||
default:
|
||||
if (scope.match(/^(date|time)/)) {
|
||||
return this.toTime(scope, value);
|
||||
} else {
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
I18n.parseDate = function(date) {
|
||||
var matches, convertedDate;
|
||||
|
||||
// we have a date, so just return it.
|
||||
if (typeof(date) == "object") {
|
||||
return date;
|
||||
};
|
||||
|
||||
// it matches the following formats:
|
||||
// yyyy-mm-dd
|
||||
// yyyy-mm-dd[ T]hh:mm::ss
|
||||
// yyyy-mm-dd[ T]hh:mm::ss
|
||||
// yyyy-mm-dd[ T]hh:mm::ssZ
|
||||
// yyyy-mm-dd[ T]hh:mm::ss+0000
|
||||
//
|
||||
matches = date.toString().match(/(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2}):(\d{2}))?(Z|\+0000)?/);
|
||||
|
||||
if (matches) {
|
||||
for (var i = 1; i <= 6; i++) {
|
||||
matches[i] = parseInt(matches[i], 10) || 0;
|
||||
}
|
||||
|
||||
// month starts on 0
|
||||
matches[2] -= 1;
|
||||
|
||||
if (matches[7]) {
|
||||
convertedDate = new Date(Date.UTC(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6]));
|
||||
} else {
|
||||
convertedDate = new Date(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6]);
|
||||
}
|
||||
} else if (typeof(date) == "number") {
|
||||
// UNIX timestamp
|
||||
convertedDate = new Date();
|
||||
convertedDate.setTime(date);
|
||||
} else if (date.match(/\d+ \d+:\d+:\d+ [+-]\d+ \d+/)) {
|
||||
// a valid javascript format with timezone info
|
||||
convertedDate = new Date();
|
||||
convertedDate.setTime(Date.parse(date))
|
||||
} else {
|
||||
// an arbitrary javascript string
|
||||
convertedDate = new Date();
|
||||
convertedDate.setTime(Date.parse(date));
|
||||
}
|
||||
|
||||
return convertedDate;
|
||||
};
|
||||
|
||||
I18n.toTime = function(scope, d) {
|
||||
var date = this.parseDate(d)
|
||||
, format = this.lookup(scope)
|
||||
;
|
||||
|
||||
if (date.toString().match(/invalid/i)) {
|
||||
return date.toString();
|
||||
}
|
||||
|
||||
if (!format) {
|
||||
return date.toString();
|
||||
}
|
||||
|
||||
return this.strftime(date, format);
|
||||
};
|
||||
|
||||
I18n.strftime = function(date, format) {
|
||||
var options = this.lookup("date");
|
||||
|
||||
if (!options) {
|
||||
return date.toString();
|
||||
}
|
||||
|
||||
options.meridian = options.meridian || ["AM", "PM"];
|
||||
|
||||
var weekDay = date.getDay()
|
||||
, day = date.getDate()
|
||||
, year = date.getFullYear()
|
||||
, month = date.getMonth() + 1
|
||||
, hour = date.getHours()
|
||||
, hour12 = hour
|
||||
, meridian = hour > 11 ? 1 : 0
|
||||
, secs = date.getSeconds()
|
||||
, mins = date.getMinutes()
|
||||
, offset = date.getTimezoneOffset()
|
||||
, absOffsetHours = Math.floor(Math.abs(offset / 60))
|
||||
, absOffsetMinutes = Math.abs(offset) - (absOffsetHours * 60)
|
||||
, timezoneoffset = (offset > 0 ? "-" : "+") + (absOffsetHours.toString().length < 2 ? "0" + absOffsetHours : absOffsetHours) + (absOffsetMinutes.toString().length < 2 ? "0" + absOffsetMinutes : absOffsetMinutes)
|
||||
;
|
||||
|
||||
if (hour12 > 12) {
|
||||
hour12 = hour12 - 12;
|
||||
} else if (hour12 === 0) {
|
||||
hour12 = 12;
|
||||
}
|
||||
|
||||
var padding = function(n) {
|
||||
var s = "0" + n.toString();
|
||||
return s.substr(s.length - 2);
|
||||
};
|
||||
|
||||
var f = format;
|
||||
f = f.replace("%a", options.abbr_day_names[weekDay]);
|
||||
f = f.replace("%A", options.day_names[weekDay]);
|
||||
f = f.replace("%b", options.abbr_month_names[month]);
|
||||
f = f.replace("%B", options.month_names[month]);
|
||||
f = f.replace("%d", padding(day));
|
||||
f = f.replace("%e", day);
|
||||
f = f.replace("%-d", day);
|
||||
f = f.replace("%H", padding(hour));
|
||||
f = f.replace("%-H", hour);
|
||||
f = f.replace("%I", padding(hour12));
|
||||
f = f.replace("%-I", hour12);
|
||||
f = f.replace("%m", padding(month));
|
||||
f = f.replace("%-m", month);
|
||||
f = f.replace("%M", padding(mins));
|
||||
f = f.replace("%-M", mins);
|
||||
f = f.replace("%p", options.meridian[meridian]);
|
||||
f = f.replace("%S", padding(secs));
|
||||
f = f.replace("%-S", secs);
|
||||
f = f.replace("%w", weekDay);
|
||||
f = f.replace("%y", padding(year));
|
||||
f = f.replace("%-y", padding(year).replace(/^0+/, ""));
|
||||
f = f.replace("%Y", year);
|
||||
f = f.replace("%z", timezoneoffset);
|
||||
|
||||
return f;
|
||||
};
|
||||
|
||||
I18n.toNumber = function(number, options) {
|
||||
options = this.prepareOptions(
|
||||
options,
|
||||
this.lookup("number.format"),
|
||||
{precision: 3, separator: ".", delimiter: ",", strip_insignificant_zeros: false}
|
||||
);
|
||||
|
||||
var negative = number < 0
|
||||
, string = Math.abs(number).toFixed(options.precision).toString()
|
||||
, parts = string.split(".")
|
||||
, precision
|
||||
, buffer = []
|
||||
, formattedNumber
|
||||
;
|
||||
|
||||
number = parts[0];
|
||||
precision = parts[1];
|
||||
|
||||
while (number.length > 0) {
|
||||
buffer.unshift(number.substr(Math.max(0, number.length - 3), 3));
|
||||
number = number.substr(0, number.length -3);
|
||||
}
|
||||
|
||||
formattedNumber = buffer.join(options.delimiter);
|
||||
|
||||
if (options.precision > 0) {
|
||||
formattedNumber += options.separator + parts[1];
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
formattedNumber = "-" + formattedNumber;
|
||||
}
|
||||
|
||||
if (options.strip_insignificant_zeros) {
|
||||
var regex = {
|
||||
separator: new RegExp(options.separator.replace(/\./, "\\.") + "$")
|
||||
, zeros: /0+$/
|
||||
};
|
||||
|
||||
formattedNumber = formattedNumber
|
||||
.replace(regex.zeros, "")
|
||||
.replace(regex.separator, "")
|
||||
;
|
||||
}
|
||||
|
||||
return formattedNumber;
|
||||
};
|
||||
|
||||
I18n.toCurrency = function(number, options) {
|
||||
options = this.prepareOptions(
|
||||
options,
|
||||
this.lookup("number.currency.format"),
|
||||
this.lookup("number.format"),
|
||||
{unit: "$", precision: 2, format: "%u%n", delimiter: ",", separator: "."}
|
||||
);
|
||||
|
||||
number = this.toNumber(number, options);
|
||||
number = options.format
|
||||
.replace("%u", options.unit)
|
||||
.replace("%n", number)
|
||||
;
|
||||
|
||||
return number;
|
||||
};
|
||||
|
||||
I18n.toHumanSize = function(number, options) {
|
||||
var kb = 1024
|
||||
, size = number
|
||||
, iterations = 0
|
||||
, unit
|
||||
, precision
|
||||
;
|
||||
|
||||
while (size >= kb && iterations < 4) {
|
||||
size = size / kb;
|
||||
iterations += 1;
|
||||
}
|
||||
|
||||
if (iterations === 0) {
|
||||
unit = this.t("number.human.storage_units.units.byte", {count: size});
|
||||
precision = 0;
|
||||
} else {
|
||||
unit = this.t("number.human.storage_units.units." + [null, "kb", "mb", "gb", "tb"][iterations]);
|
||||
precision = (size - Math.floor(size) === 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
options = this.prepareOptions(
|
||||
options,
|
||||
{precision: precision, format: "%n%u", delimiter: ""}
|
||||
);
|
||||
|
||||
number = this.toNumber(size, options);
|
||||
number = options.format
|
||||
.replace("%u", unit)
|
||||
.replace("%n", number)
|
||||
;
|
||||
|
||||
return number;
|
||||
};
|
||||
|
||||
I18n.toPercentage = function(number, options) {
|
||||
options = this.prepareOptions(
|
||||
options,
|
||||
this.lookup("number.percentage.format"),
|
||||
this.lookup("number.format"),
|
||||
{precision: 3, separator: ".", delimiter: ""}
|
||||
);
|
||||
|
||||
number = this.toNumber(number, options);
|
||||
return number + "%";
|
||||
};
|
||||
|
||||
I18n.pluralizer = function(locale) {
|
||||
pluralizer = this.pluralizationRules[locale];
|
||||
if (pluralizer !== undefined) return pluralizer;
|
||||
return this.pluralizationRules["en"];
|
||||
};
|
||||
|
||||
I18n.findAndTranslateValidNode = function(keys, translation) {
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
if (this.isValidNode(translation, key)) return translation[key];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
I18n.pluralize = function(count, scope, options) {
|
||||
var translation;
|
||||
|
||||
try {
|
||||
translation = this.lookup(scope, options);
|
||||
} catch (error) {}
|
||||
|
||||
if (!translation) {
|
||||
return this.missingTranslation(scope);
|
||||
}
|
||||
|
||||
var message;
|
||||
options = this.prepareOptions(options);
|
||||
options.count = count.toString();
|
||||
|
||||
pluralizer = this.pluralizer(this.currentLocale());
|
||||
key = pluralizer(Math.abs(count));
|
||||
keys = ((typeof key == "object") && (key instanceof Array)) ? key : [key];
|
||||
|
||||
message = this.findAndTranslateValidNode(keys, translation);
|
||||
if (message == null) message = this.missingTranslation(scope, keys[0]);
|
||||
|
||||
return this.interpolate(message, options);
|
||||
};
|
||||
|
||||
I18n.missingTranslation = function() {
|
||||
var message = '[missing "' + this.currentLocale()
|
||||
, count = arguments.length
|
||||
;
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
message += "." + arguments[i];
|
||||
}
|
||||
|
||||
message += '" translation]';
|
||||
|
||||
return message;
|
||||
};
|
||||
|
||||
I18n.currentLocale = function() {
|
||||
return (I18n.locale || I18n.defaultLocale);
|
||||
};
|
||||
|
||||
// shortcuts
|
||||
I18n.t = I18n.translate;
|
||||
I18n.l = I18n.localize;
|
||||
I18n.p = I18n.pluralize;
|
|
@ -1,2 +1,3 @@
|
|||
//= depend_on 'client.nl.yml'
|
||||
<%= JsLocaleHelper.output_locale(:nl); %>
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:nl) %>
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
//= depend_on 'client.pseudo.yml'
|
||||
<%= JsLocaleHelper.output_locale(:pseudo); %>
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:pseudo) %>
|
||||
|
|
3
app/assets/javascripts/locales/sv.js.erb
Normal file
3
app/assets/javascripts/locales/sv.js.erb
Normal file
|
@ -0,0 +1,3 @@
|
|||
//= depend_on 'client.sv.yml'
|
||||
//= require locales/i18n
|
||||
<%= JsLocaleHelper.output_locale(:sv) %>
|
|
@ -21,6 +21,7 @@ class ApplicationController < ActionController::Base
|
|||
before_filter :store_incoming_links
|
||||
before_filter :preload_json
|
||||
before_filter :check_xhr
|
||||
before_filter :set_locale
|
||||
|
||||
rescue_from Exception do |exception|
|
||||
unless [ ActiveRecord::RecordNotFound, ActionController::RoutingError,
|
||||
|
@ -77,6 +78,11 @@ class ApplicationController < ActionController::Base
|
|||
render file: 'public/403', formats: [:html], layout: false, status: 403
|
||||
end
|
||||
|
||||
|
||||
def set_locale
|
||||
I18n.locale = SiteSetting.default_locale
|
||||
end
|
||||
|
||||
def store_preloaded(key, json)
|
||||
@preloaded ||= {}
|
||||
# I dislike that there is a gsub as opposed to a gsub!
|
||||
|
|
|
@ -2,20 +2,22 @@ module JsLocaleHelper
|
|||
|
||||
def self.output_locale(locale)
|
||||
|
||||
SimplesIdeias::I18n.assert_usable_configuration!
|
||||
locale_str = locale.to_s
|
||||
|
||||
s = "var I18n = I18n || {};"
|
||||
segment = "app/assets/javascripts/i18n/#{locale}.js"
|
||||
s += "I18n.translations = " + SimplesIdeias::I18n.translation_segments[segment].to_json + ";"
|
||||
translations = YAML::load(File.open("#{Rails.root}/config/locales/client.#{locale_str}.yml"))
|
||||
|
||||
segment = "app/assets/javascripts/i18n/admin.#{locale}.js"
|
||||
admin = SimplesIdeias::I18n.translation_segments[segment]
|
||||
admin[locale][:js] = admin[locale].delete(:admin_js)
|
||||
# We used to split the admin versus the client side, but it's much simpler to just
|
||||
# include both for now due to the small size of the admin section.
|
||||
#
|
||||
# For now, let's leave it split out in the translation file in case we want to split
|
||||
# it again later, so we'll merge the JSON ourselves.
|
||||
admin_contents = translations[locale_str].delete('admin_js')
|
||||
|
||||
s += "jQuery.extend(true, I18n.translations, " + admin.to_json + ");"
|
||||
|
||||
s
|
||||
translations[locale_str]['js'].merge!(admin_contents) if admin_contents.present?
|
||||
|
||||
result = "I18n.translations = #{translations.to_json};\n"
|
||||
result << "I18n.locale = '#{locale_str}'\n"
|
||||
result
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -149,6 +149,9 @@ class SiteSetting < ActiveRecord::Base
|
|||
|
||||
setting(:title_fancy_entities, true)
|
||||
|
||||
# The default locale for the site
|
||||
setting(:default_locale, 'en')
|
||||
|
||||
client_setting(:educate_until_posts, 2)
|
||||
|
||||
def self.call_discourse_hub?
|
||||
|
|
|
@ -16,10 +16,6 @@
|
|||
|
||||
<%# load the selected locale before any other scripts %>
|
||||
<%= javascript_include_tag "locales/#{I18n.locale}" %>
|
||||
<%# store the locale into a variable, because the scripts need it, see init_locale.js %>
|
||||
<script>
|
||||
window.currentLocale = "<%= I18n.locale %>";
|
||||
</script>
|
||||
|
||||
<%- if mini_profiler_enabled? %>
|
||||
<%- Rack::MiniProfiler.step "application" do %>
|
||||
|
|
|
@ -34,6 +34,11 @@ module Discourse
|
|||
'jquery.js', 'defer/html-sanitizer-bundle.js'
|
||||
]
|
||||
|
||||
# Precompile all available locales
|
||||
Dir.glob("app/assets/javascripts/locales/*.js.erb").each do |file|
|
||||
config.assets.precompile << file.match(/([a-z]+\.js)\.erb$/)[1]
|
||||
end
|
||||
|
||||
# Activate observers that should always be running.
|
||||
config.active_record.observers = [
|
||||
:user_email_observer,
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
# Split context in several files.
|
||||
# By default only one file with all translations is exported and
|
||||
# no configuration is required. Your settings for asset pipeline
|
||||
# are automatically recognized.
|
||||
#
|
||||
# If you want to split translations into several files or specify
|
||||
# locale contexts that will be exported, just use this file to do
|
||||
# so.
|
||||
#
|
||||
# If you're going to use the Rails 3.1 asset pipeline, change
|
||||
# the following configuration to something like this:
|
||||
#
|
||||
# translations:
|
||||
# - file: "app/assets/javascripts/i18n/translations.js"
|
||||
#
|
||||
# If you're running an old version, you can use something
|
||||
# like this:
|
||||
#
|
||||
# translations:
|
||||
# - file: "public/javascripts/translations.js"
|
||||
# only: "*"
|
||||
#
|
||||
|
||||
translations:
|
||||
- file: 'app/assets/javascripts/i18n/en.js'
|
||||
only: 'en.js.*'
|
||||
- file: 'app/assets/javascripts/i18n/admin.en.js'
|
||||
only: 'en.admin_js.*'
|
||||
|
||||
- file: 'app/assets/javascripts/i18n/pseudo.js'
|
||||
only: 'pseudo.js.*'
|
||||
- file: 'app/assets/javascripts/i18n/admin.pseudo.js'
|
||||
only: 'pseudo.admin_js.*'
|
||||
|
||||
- file: 'app/assets/javascripts/i18n/fr.js'
|
||||
only: 'fr.js.*'
|
||||
- file: 'app/assets/javascripts/i18n/admin.fr.js'
|
||||
only: 'fr.admin_js.*'
|
|
@ -15,6 +15,7 @@ exclude_paths:
|
|||
- app/assets/javascripts/external/*
|
||||
- app/assets/javascripts/external_production/*
|
||||
- app/assets/javascripts/defer/*
|
||||
- app/assets/javascripts/locales/i18n.js
|
||||
|
||||
|
||||
# ------------ jshint options ------------
|
||||
|
|
|
@ -241,6 +241,10 @@ pseudo:
|
|||
title: ! '[[ Łóǧ Íɳ ŵíťĥ Ýáĥóó ]]'
|
||||
message: ! '[[ Áůťĥéɳťíčáťíɳǧ ŵíťĥ Ýáĥóó (ɱáǩé šůřé ƿóƿ ůƿ ƀłóčǩéřš ářé ɳóť
|
||||
éɳáƀłéď) ]]'
|
||||
github:
|
||||
title: ! '[[ Łóǧ Íɳ ŵíťĥ Ǧíťĥůƀ ]]'
|
||||
message: ! '[[ Áůťĥéɳťíčáťíɳǧ ŵíťĥ Ǧíťĥůƀ (ɱáǩé šůřé ƿóƿ ůƿ ƀłóčǩéřš ářé ɳóť
|
||||
éɳáƀłéď) ]]'
|
||||
composer:
|
||||
saving_draft_tip: ! '[[ šáνíɳǧ ]]'
|
||||
saved_draft_tip: ! '[[ šáνéď ]]'
|
||||
|
@ -353,7 +357,9 @@ pseudo:
|
|||
unread_posts: ! '[[ ýóů ĥáνé {{unread}} ůɳřéáď ółď ƿóšťš íɳ ťĥíš ťóƿíč ]]'
|
||||
new_posts: ! '[[ ťĥéřé ářé {{new_posts}} ɳéŵ ƿóšťš íɳ ťĥíš ťóƿíč šíɳčé ýóů łášť
|
||||
řéáď íť ]]'
|
||||
likes: ! '[[ ťĥéřé ářé {{likes}} łíǩéš íɳ ťĥíš ťóƿíč ]]'
|
||||
likes:
|
||||
one: ! '[[ ťĥéřé íš 1 łíǩé íɳ ťĥíš ťóƿíč ]]'
|
||||
other: ! '[[ ťĥéřé ářé {{count}} łíǩéš íɳ ťĥíš ťóƿíč ]]'
|
||||
back_to_list: ! '[[ Ɓáčǩ ťó Ťóƿíč Łíšť ]]'
|
||||
options: ! '[[ Ťóƿíč Óƿťíóɳš ]]'
|
||||
show_links: ! '[[ šĥóŵ łíɳǩš ŵíťĥíɳ ťĥíš ťóƿíč ]]'
|
||||
|
|
|
@ -237,6 +237,7 @@ en:
|
|||
yaxis: "Visits"
|
||||
|
||||
site_settings:
|
||||
default_locale: "The default language of this Discourse instance (ISO 639-1 Code)"
|
||||
min_post_length: "Minimum post length in characters"
|
||||
max_post_length: "Maximum post length in characters"
|
||||
min_topic_title_length: "Minimum topic title length in characters"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
pseudo:
|
||||
title: ! '[[ Ďíščóůřšé ]]'
|
||||
topics: ! '[[ Ťóƿíčš ]]'
|
||||
via: ! '[[ %{username} νíá %{site_name} ]]'
|
||||
is_reserved: ! '[[ íš řéšéřνéď ]]'
|
||||
too_many_mentions: ! '[[ ĥáš ťóó ɱáɳý ůšéřš ɱéɳťíóɳéď ]]'
|
||||
too_many_images: ! '[[ ĥáš ťóó ɱáɳý íɱáǧéš ]]'
|
||||
|
@ -225,7 +226,14 @@ pseudo:
|
|||
action: ! '[[ Řé-Šůƀščříƀé ]]'
|
||||
title: ! '[[ Řé-Šůƀščříƀéď! ]]'
|
||||
description: ! '[[ Ýóů ĥáνé ƀééɳ řé-šůƀščříƀéď. ]]'
|
||||
reports:
|
||||
visits:
|
||||
title: ! '[[ Ůšéřš Ѷíšíťš ƀý Ďáý ]]'
|
||||
xaxis: ! '[[ Ďáý ]]'
|
||||
yaxis: ! '[[ Ѷíšíťš ]]'
|
||||
site_settings:
|
||||
default_locale: ! '[[ Ťĥé ďéƒáůłť łáɳǧůáǧé óƒ ťĥíš Ďíščóůřšé íɳšťáɳčé (ÍŠÓ 639-1
|
||||
Čóďé) ]]'
|
||||
min_post_length: ! '[[ Ϻíɳíɱůɱ ƿóšť łéɳǧťĥ íɳ čĥářáčťéřš ]]'
|
||||
max_post_length: ! '[[ Ϻáхíɱůɱ ƿóšť łéɳǧťĥ íɳ čĥářáčťéřš ]]'
|
||||
min_topic_title_length: ! '[[ Ϻíɳíɱůɱ ťóƿíč ťíťłé łéɳǧťĥ íɳ čĥářáčťéřš ]]'
|
||||
|
@ -239,7 +247,13 @@ pseudo:
|
|||
ɳíčǩɳáɱé řéǧíšťřý áť ďíščóůřšé.óřǧ ]]'
|
||||
educate_until_posts: ! '[[ Šĥóŵ ƿóƿ-ůƿ čóɱƿóšéř éďůčáťíóɳ ƿáɳéł ůɳťíł ťĥé ůšéř
|
||||
ĥáš ɱáďé ťĥíš ɱáɳý ƿóšťš ]]'
|
||||
title: ! '[[ Ťíťłé óƒ ťĥíš ŵéƀšíťé ]]'
|
||||
title: ! '[[ Ťíťłé óƒ ťĥíš šíťé, ŵíłł ƀé ůšéď íɳ ťĥé ťíťłé ťáǧ áɳď éłšéŵĥéřé ]]'
|
||||
company_full_name: ! '[[ Ťĥé ƒůłł ɳáɱé óƒ ťĥé čóɱƿáɳý ťĥáť řůɳš ťĥíš šíťé, ůšéď
|
||||
íɳ łéǧáł ďóčůɱéɳťš łíǩé ťĥé /ťóš ]]'
|
||||
company_short_name: ! '[[ Ťĥé šĥóřť ɳáɱé óƒ ťĥé čóɱƿáɳý ťĥáť řůɳš ťĥíš šíťé, ůšéď
|
||||
íɳ łéǧáł ďóčůɱéɳťš łíǩé ťĥé /ťóš ]]'
|
||||
company_domain: ! '[[ Ťĥé ďóɱáíɳ ɳáɱé óŵɳéď ƀý ťĥé čóɱƿáɳý ťĥáť řůɳš ťĥíš šíťé,
|
||||
ůšéď íɳ łéǧáł ďóčůɱéɳťš łíǩé ťĥé /ťóš ]]'
|
||||
restrict_access: ! '[[ Řéšťříčť ƒóřůɱ áččéšš ůɳłéšš á ƿáššŵóřď íš éɳťéřéď ]]'
|
||||
access_password: ! '[[ Ŵĥéɳ řéšťříčťéď áččéšš íš éɳáƀłéď, ťĥíš ƿáššŵóřď ɱůšť ƀé
|
||||
éɳťéřéď ]]'
|
||||
|
@ -328,23 +342,35 @@ pseudo:
|
|||
řóƀóťš.ťхť) ]]'
|
||||
email_domains_blacklist: ! '[[ Á ƿíƿé-ďéłíɱíťéď łíšť óƒ éɱáíł ďóɱáíɳš ťĥáť ářé
|
||||
ɳóť áłłóŵéď. Éхáɱƿłé: ɱáíłíɳáťóř.čóɱ|ťřášĥɱáíł.ɳéť ]]'
|
||||
version_checks: ! '[[ Рíɳǧ Ďíščóůřšé Ĥůƀ ƒóř νéřšíóɳ ůƿďáťéš áɳď řéƿóřť ťĥéɱ óɳ
|
||||
ťĥé áďɱíɳ ďášĥƀóářď. ]]'
|
||||
port: ! '[[ ̓ ýóů''ď łíǩé ťó šƿéčíƒý á ƿóřť íɳ ťĥé ŮŘŁ. Ůšéƒůł íɳ ďéνéłóƿɱéɳť
|
||||
ɱóďé. Łéáνé ƀłáɳǩ ƒóř ɳóɳé ]]'
|
||||
force_hostname: ! '[[ ̓ ýóů''ď łíǩé ťó šƿéčíƒý á ĥóšťɳáɱé íɳ ťĥé ŮŘŁ. Ůšéƒůł
|
||||
íɳ ďéνéłóƿɱéɳť ɱóďé. Łéáνé ƀłáɳǩ ƒóř ɳóɳé ]]'
|
||||
version_checks: ! '[[ Рíɳǧ ťĥé Ďíščóůřšé Ĥůƀ ƒóř νéřšíóɳ ůƿďáťéš áɳď šĥóŵ νéřšíóɳ
|
||||
ɱéššáǧéš óɳ ťĥé /áďɱíɳ ďášĥƀóářď ]]'
|
||||
port: ! '[[ Ůšé ťĥíš ĤŤŤР ƿóřť řáťĥéř ťĥáɳ ťĥé ďéƒáůłť óƒ ƿóřť 80. Łéáνé ƀłáɳǩ
|
||||
ƒóř ɳóɳé, ɱáíɳłý ůšéƒůł ƒóř ďéνéłóƿɱéɳť ]]'
|
||||
force_hostname: ! '[[ Šƿéčíƒý á ĥóšťɳáɱé íɳ ťĥé ŮŘŁ. Łéáνé ƀłáɳǩ ƒóř ɳóɳé, ɱáíɳłý
|
||||
ůšéƒůł ƒóř ďéνéłóƿɱéɳť ]]'
|
||||
invite_expiry_days: ! '[[ Ĥóŵ łóɳǧ ůšéř íɳνíťáťíóɳ ǩéýš ářé νáłíď, íɳ ďáýš ]]'
|
||||
enable_google_logins: ! '[[ Éɳáƀłé Ǧóóǧłé áůťĥéɳťíčáťíóɳ ]]'
|
||||
enable_yahoo_logins: ! '[[ Éɳáƀłé Ýáĥóó áůťĥéɳťíčáťíóɳ ]]'
|
||||
enable_twitter_logins: ! '[[ Éɳáƀłé Ťŵíťťéř áůťĥéɳťíčáťíóɳ, řéƣůířéš ťŵíťťéř_čóɳšůɱéř_ǩéý
|
||||
áɳď ťŵíťťéř_čóɳšůɱéř_šéčřéť ]]'
|
||||
twitter_consumer_key: ! '[[ Čóɳšůɱéř ǩéý ƒóř Ťŵíťťéř áůťĥéɳťíčáťíóɳ, řéǧíšťéřéď
|
||||
áť ĥťťƿ://ďéν.ťŵíťťéř.čóɱ ]]'
|
||||
twitter_consumer_secret: ! '[[ Čóɳšůɱéř šéčřéť ƒóř Ťŵíťťéř áůťĥéɳťíčáťíóɳ, řéǧíšťéřéď
|
||||
áť ĥťťƿ://ďéν.ťŵíťťéř.čóɱ ]]'
|
||||
enable_facebook_logins: ! '[[ Éɳáƀłé Ƒáčéƀóóǩ áůťĥéɳťíčáťíóɳ, řéƣůířéš ƒáčéƀóóǩ_áƿƿ_íď
|
||||
áɳď ƒáčéƀóóǩ_áƿƿ_šéčřéť ]]'
|
||||
facebook_app_id: ! '[[ Áƿƿ íď ƒóř Ƒáčéƀóóǩ áůťĥéɳťíčáťíóɳ, řéǧíšťéřéď áť ĥťťƿš://ďéνéłóƿéřš.ƒáčéƀóóǩ.čóɱ/áƿƿš
|
||||
]]'
|
||||
facebook_app_secret: ! '[[ Áƿƿ šéčřéť ƒóř Ƒáčéƀóóǩ áůťĥéɳťíčáťíóɳ, řéǧíšťéřéď
|
||||
áť ĥťťƿš://ďéνéłóƿéřš.ƒáčéƀóóǩ.čóɱ/áƿƿš ]]'
|
||||
enable_github_logins: ! '[[ Éɳáƀłé Ǧíťĥůƀ áůťĥéɳťíčáťíóɳ, řéƣůířéš ǧíťĥůƀ_čłíéɳť_íď
|
||||
áɳď ǧíťĥůƀ_čłíéɳť_šéčřéť ]]'
|
||||
github_client_id: ! '[[ Čłíéɳť íď ƒóř Ǧíťĥůƀ áůťĥéɳťíčáťíóɳ, řéǧíšťéřéď áť ĥťťƿš://ǧíťĥůƀ.čóɱ/šéťťíɳǧš/áƿƿłíčáťíóɳš
|
||||
]]'
|
||||
github_client_secret: ! '[[ Čłíéɳť šéčřéť ƒóř Ǧíťĥůƀ áůťĥéɳťíčáťíóɳ, řéǧíšťéřéď
|
||||
áť ĥťťƿš://ǧíťĥůƀ.čóɱ/šéťťíɳǧš/áƿƿłíčáťíóɳš ]]'
|
||||
allow_import: ! '[[ Áłłóŵ íɱƿóřť, ŵĥíčĥ čáɳ řéƿłáčé ÁŁŁ šíťé ďáťá; łéáνé ƒáłšé
|
||||
ůɳłéšš ýóů ƿłáɳ ťó ďó íɱƿóřťš ]]'
|
||||
ůɳłéšš ýóů ƿłáɳ ťó ďó ďáťá íɱƿóřťš ]]'
|
||||
active_user_rate_limit_secs: ! '[[ Ĥóŵ ƒřéƣůéɳťłý ŵé ůƿďáťé ťĥé ''łášť_šééɳ_áť''
|
||||
ƒíéłď, íɳ šéčóɳďš ]]'
|
||||
previous_visit_timeout_hours: ! '[[ Ĥóŵ łóɳǧ á νíšíť łášťš ƀéƒóřé ŵé čóɳšíďéř
|
||||
|
@ -357,21 +383,20 @@ pseudo:
|
|||
ýóů čáɳ čřéáťé áɳóťĥéř ťóƿíč ]]'
|
||||
rate_limit_create_post: ! '[[ Ĥóŵ ɱáɳý šéčóɳďš, áƒťéř čřéáťíɳǧ á ƿóšť, ƀéƒóřé
|
||||
ýóů čáɳ čřéáťé áɳóťĥéř ƿóšť ]]'
|
||||
max_likes_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ łíǩéš á ůšéř čáɳ ƿéřƒóřɱ íɳ á ďáý ]]'
|
||||
max_flags_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ ƒłáǧš á ůšéř čáɳ ƿéřƒóřɱ íɳ á ďáý ]]'
|
||||
max_bookmarks_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ ƀóóǩɱářǩš á ůšéř čáɳ čřéáťé íɳ
|
||||
á ďáý ]]'
|
||||
max_edits_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ éďíťš á ůšéř čáɳ ƿéřƒóřɱ íɳ á ďáý ]]'
|
||||
max_favorites_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ ťóƿíčš ťĥáť čáɳ ƀé ƒáνóříťéď íɳ
|
||||
á ďáý ]]'
|
||||
max_topics_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ ťóƿíčš á ůšéř čáɳ čřéáťé íɳ á ďáý
|
||||
]]'
|
||||
max_private_messages_per_day: ! '[[ Ťĥé ɱáхíɱůɱ áɱóůɳť óƒ ƿříνáťé ɱéššáǧéš ýóů
|
||||
čáɳ šéɳď íɳ á ďáý ]]'
|
||||
suggested_topics: ! '[[ Ťĥé ɳůɱƀéř óƒ šůǧǧéšťéď ťóƿíčš áť ťĥé ƀóťťóɱ óƒ á ťóƿíč
|
||||
]]'
|
||||
max_likes_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ łíǩéš ƿéř ůšéř ƿéř ďáý ]]'
|
||||
max_flags_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ ƒłáǧš ƿéř ůšéř ƿéř ďáý ]]'
|
||||
max_bookmarks_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ ƀóóǩɱářǩš ƿéř ůšéř ƿéř ďáý ]]'
|
||||
max_edits_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ éďíťš ƿéř ůšéř ƿéř ďáý ]]'
|
||||
max_favorites_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ ťóƿíčš ťĥáť čáɳ ƀé ƒáνóříťéď ƿéř
|
||||
ůšéř ƿéř ďáý ]]'
|
||||
max_topics_per_day: ! '[[ Ϻáхíɱůɱ ɳůɱƀéř óƒ ťóƿíčš á ůšéř čáɳ čřéáťé ƿéř ďáý ]]'
|
||||
max_private_messages_per_day: ! '[[ Ťĥé ɱáхíɱůɱ áɱóůɳť óƒ ƿříνáťé ɱéššáǧéš ůšéřš
|
||||
čáɳ čřéáťé ƿéř ďáý ]]'
|
||||
suggested_topics: ! '[[ Ťĥé ɳůɱƀéř óƒ šůǧǧéšťéď ťóƿíčš šĥóŵɳ áť ťĥé ƀóťťóɱ óƒ
|
||||
á ťóƿíč ]]'
|
||||
enable_s3_uploads: ! '[[ Рłáčé ůƿłóáďš óɳ Áɱážóɳ Š3 ]]'
|
||||
s3_upload_bucket: ! '[[ Ťĥé Áɱážóɳ Š3 ƀůčǩéť ƒíłéš ŵíłł ƀé ůƿłóáďéď íɳťó ]]'
|
||||
s3_upload_bucket: ! '[[ Ťĥé Áɱážóɳ Š3 ƀůčǩéť ɳáɱé ťĥáť ƒíłéš ŵíłł ƀé ůƿłóáďéď
|
||||
íɳťó ]]'
|
||||
default_invitee_trust_level: ! '[[ Ďéƒáůłť ťřůšť łéνéł (0-5) ƒóř íɳνíťéď ůšéřš
|
||||
]]'
|
||||
default_trust_level: ! '[[ Ďéƒáůłť ťřůšť łéνéł (0-5) ƒóř ůšéřš ]]'
|
||||
|
@ -389,8 +414,10 @@ pseudo:
|
|||
šéčóɳďš ]]'
|
||||
max_word_length: ! '[[ Ťĥé ɱáхíɱůɱ áłłóŵéď ŵóřď łéɳǧťĥ, íɳ čĥářáčťéřš, íɳ á ťóƿíč
|
||||
ťíťłé ]]'
|
||||
title_min_entropy: ! '[[ Ťĥé ɱíɳíɱůɱ áłłóŵéď éɳťřóƿý ƒóř á ťóƿíč ťíťłé ]]'
|
||||
body_min_entropy: ! '[[ Ťĥé ɱíɳíɱůɱ áłłóŵéď éɳťřóƿý ƒóř ƿóšť ƀóďý ]]'
|
||||
title_min_entropy: ! '[[ Ťĥé ɱíɳíɱůɱ áłłóŵéď éɳťřóƿý (ůɳíƣůé čĥářáčťéřš) řéƣůířéď
|
||||
ƒóř á ťóƿíč ťíťłé ]]'
|
||||
body_min_entropy: ! '[[ Ťĥé ɱíɳíɱůɱ áłłóŵéď éɳťřóƿý (ůɳíƣůé čĥářáčťéřš) řéƣůířéď
|
||||
ƒóř á ƿóšť ƀóďý ]]'
|
||||
new_user_period_days: ! '[[ Ĥóŵ łóɳǧ á ůšéř íš ĥíǧĥłíǧĥťéď áš ƀéíɳǧ ɳéŵ, íɳ ďáýš
|
||||
]]'
|
||||
title_fancy_entities: ! '[[ Čóɳνéřť ƒáɳčý ĤŤϺŁ éɳťíťíéš íɳ ťóƿíč ťíťłéš ]]'
|
||||
|
@ -629,6 +656,11 @@ pseudo:
|
|||
]]'
|
||||
text_body_template: ! "[[ %{username} ɱéɳťíóɳéď ýóů íɳ '%{topic_title}' óɳ %{site_name}:\n\n---\n%{message}\n\n---\nРłéášé
|
||||
νíšíť ťĥíš łíɳǩ ťó řéšƿóɳď: %{base_url}%{url}\n ]]"
|
||||
user_posted:
|
||||
subject_template: ! '[[ [%{site_name}] %{username} ƿóšťéď íɳ ''%{topic_title}''
|
||||
]]'
|
||||
text_body_template: ! "[[ %{username} ƿóšťéď íɳ '%{topic_title}' óɳ %{site_name}:\n\n---\n%{message}\n\n---\nРłéášé
|
||||
νíšíť ťĥíš łíɳǩ ťó řéšƿóɳď: %{base_url}%{url}\n ]]"
|
||||
digest:
|
||||
why: ! '[[ Ĥéřé''š á ƀříéƒ šůɱɱářý óƒ ŵĥáť ĥáƿƿéɳéď óɳ %{site_link} šíɳčé ŵé
|
||||
łášť šáŵ ýóů óɳ %{last_seen_at}. ]]'
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
// The rest of the externals
|
||||
//= require_tree ../../app/assets/javascripts/external
|
||||
//= require i18n
|
||||
|
||||
//= require ../../app/assets/javascripts/discourse/helpers/i18n_helpers
|
||||
//= require ../../app/assets/javascripts/discourse
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
[
|
||||
{
|
||||
"path": "app",
|
||||
"folder_exclude_patterns": ["external", "external_production", "images", "imported", "fonts", "defer"]
|
||||
"folder_exclude_patterns": ["external", "external_production", "images", "imported", "fonts", "defer"],
|
||||
"file_exclude_patterns": ["i18n.js"]
|
||||
},
|
||||
{ "path": "config" },
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user