mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-01-30 01:08:32 -05:00
JS string formatting parameter substitution.
This changes the string usage pattern from:
r.strings.stringname to r.strings('stringname', parameters).
This commit is contained in:
@@ -196,7 +196,7 @@ class DataSource(Source):
|
||||
|
||||
class StringsSource(DataSource):
|
||||
"""A virtual source consisting of localized strings from r2.lib.strings."""
|
||||
def __init__(self, lang=None, keys=None, wrap="r.strings = {content}"):
|
||||
def __init__(self, lang=None, keys=None, wrap="r.strings.set({content})"):
|
||||
DataSource.__init__(self, wrap=wrap)
|
||||
self.lang = lang
|
||||
self.keys = keys
|
||||
@@ -208,6 +208,15 @@ class StringsSource(DataSource):
|
||||
return obj.string_dict
|
||||
raise TypeError
|
||||
|
||||
invalid_formatting_specifier_re = re.compile(r"(?<!%)%\w|(?<!%)%\(\w+\)[^s]")
|
||||
def _check_formatting_specifiers(self, key, string):
|
||||
if not isinstance(string, str):
|
||||
return
|
||||
|
||||
if self.invalid_formatting_specifier_re.search(string):
|
||||
raise ValueError("Invalid string formatting specifier:"
|
||||
" strings[%r]" % key)
|
||||
|
||||
def get_content(self):
|
||||
from pylons.i18n import get_lang
|
||||
from r2.lib import strings, translation
|
||||
@@ -220,6 +229,7 @@ class StringsSource(DataSource):
|
||||
if self.keys is not None:
|
||||
for key in self.keys:
|
||||
data[key] = strings.strings[key]
|
||||
self._check_formatting_specifiers(key, data[key])
|
||||
else:
|
||||
data = dict(strings.strings)
|
||||
|
||||
@@ -232,7 +242,7 @@ class StringsSource(DataSource):
|
||||
class LocalizedModule(Module):
|
||||
"""A module that is localized with r2.lib.strings.
|
||||
|
||||
References to `r.strings.<string>` are parsed out of the module source.
|
||||
References to `r.strings(<string>)` are parsed out of the module source.
|
||||
A StringsSource is created and included which contains localized versions
|
||||
of the strings referenced in the module.
|
||||
"""
|
||||
@@ -246,7 +256,8 @@ class LocalizedModule(Module):
|
||||
Module.build(self, closure)
|
||||
|
||||
reddit_source = open(self.path).read()
|
||||
string_keys = re.findall("r\.strings\.([\w$_]+)", reddit_source)
|
||||
string_keys = re.findall("r\.strings\(['\"]([\w$_]+)['\"]", reddit_source)
|
||||
string_keys.append("permissions")
|
||||
|
||||
print >> sys.stderr, "Creating language-specific files:"
|
||||
for lang, unused in iter_langs():
|
||||
@@ -318,6 +329,7 @@ module["reddit"] = LocalizedModule("reddit.js",
|
||||
"jquery.reddit.js",
|
||||
"base.js",
|
||||
"utils.js",
|
||||
"strings.js",
|
||||
"ui.js",
|
||||
"login.js",
|
||||
"analytics.js",
|
||||
|
||||
@@ -175,8 +175,8 @@ Note: there are a couple of places outside of your subreddit where someone can c
|
||||
go = _("go"),
|
||||
view_subreddit_traffic = _("view subreddit traffic"),
|
||||
|
||||
an_error_occurred = _("an error occurred"),
|
||||
an_error_occurred_friendly = _("an error occurred. please try again later!"),
|
||||
an_error_occurred = _("an error occurred (status: %(status)s)"),
|
||||
an_error_occurred_friendly = _("an error occurred. please try again later! (status: %(status)s)"),
|
||||
rate_limit = _("please wait a few seconds and try again."),
|
||||
subscribed_multi = _("multireddit of your subscriptions"),
|
||||
mod_multi = _("multireddit of subreddits you moderate"),
|
||||
|
||||
@@ -43,7 +43,7 @@ r.gold = {
|
||||
|
||||
var form = $('.gold-form.cloneable:first').clone(),
|
||||
authorName = $link.thing().find('.entry .author:first').text(),
|
||||
message = r.strings.gold_summary_comment_gift.replace('%(recipient)s', authorName),
|
||||
message = r.strings('gold_summary_comment_gift', {recipient: authorName}),
|
||||
passthroughs = form.find('.passthrough'),
|
||||
cbBaseUrl = form.find('[name="cbbaseurl"]').val()
|
||||
|
||||
@@ -147,21 +147,21 @@ r.gold = {
|
||||
Stripe.setPublishableKey(publicKey)
|
||||
|
||||
if (!cardName) {
|
||||
status.text(r.strings.missing_credit_name)
|
||||
status.text(r.strings('missing_credit_name'))
|
||||
} else if (!(Stripe.validateCardNumber(cardNumber))) {
|
||||
status.text(r.strings.bad_credit_number)
|
||||
status.text(r.strings('bad_credit_number'))
|
||||
} else if (!Stripe.validateExpiry(expiryMonth, expiryYear)) {
|
||||
status.text(r.strings.bad_credit_expiry)
|
||||
status.text(r.strings('bad_credit_expiry'))
|
||||
} else if (!Stripe.validateCVC(cardCvc)) {
|
||||
status.text(r.strings.bad_credit_cvc)
|
||||
status.text(r.strings('bad_credit_cvc'))
|
||||
} else if (!cardAddress1) {
|
||||
status.text(r.strings.missing_credit_address)
|
||||
status.text(r.strings('missing_credit_address'))
|
||||
} else if (!cardCity) {
|
||||
status.text(r.strings.missing_credit_city)
|
||||
status.text(r.strings('missing_credit_city'))
|
||||
} else if (!cardState) {
|
||||
status.text(r.strings.missing_credit_state)
|
||||
status.text(r.strings('missing_credit_state'))
|
||||
} else if (!cardZip) {
|
||||
status.text(r.strings.missing_credit_zip)
|
||||
status.text(r.strings('missing_credit_zip'))
|
||||
} else {
|
||||
|
||||
var workingTimer = setTimeout(function () {
|
||||
|
||||
@@ -77,7 +77,7 @@ r.ui.InterestBar.prototype = {
|
||||
.removeClass('working')
|
||||
.addClass('error')
|
||||
.find('.error-caption')
|
||||
.text(r.strings.an_error_occurred_friendly + ' (' + xhr.status + ')')
|
||||
.text(r.strings('an_error_occurred_friendly', {status: xhr.status}))
|
||||
|
||||
this.hideResults()
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ r.ui.LoginForm.prototype = $.extend(new r.ui.Form(), {
|
||||
if (xhr.status == 0 && r.config.currentOrigin != r.config.https_endpoint) {
|
||||
$('<p>').append(
|
||||
$('<a>')
|
||||
.text(r.strings.login_fallback_msg)
|
||||
.text(r.strings('login_fallback_msg'))
|
||||
.attr('href', r.config.https_endpoint + '/login')
|
||||
).appendTo(this.$el.find('.status'))
|
||||
}
|
||||
|
||||
@@ -101,9 +101,9 @@ function form_error(form) {
|
||||
return function(req) {
|
||||
var msg
|
||||
if (req == 'ratelimit') {
|
||||
msg = r.strings.rate_limit
|
||||
msg = r.strings('rate_limit')
|
||||
} else {
|
||||
msg = 'an error occurred while posting (status: ' + req.status + ')'
|
||||
msg = r.strings('an_error_occurred', {status: req.status})
|
||||
}
|
||||
$(form).find('.status').text(msg)
|
||||
}
|
||||
|
||||
14
r2/r2/public/static/js/strings.js
Normal file
14
r2/r2/public/static/js/strings.js
Normal file
@@ -0,0 +1,14 @@
|
||||
r.strings = function(name, params) {
|
||||
var string = r.strings.index[name]
|
||||
if (params) {
|
||||
return r.utils.pyStrFormat(string, params)
|
||||
} else {
|
||||
return string
|
||||
}
|
||||
}
|
||||
|
||||
r.strings.index = {}
|
||||
r.strings.set = function(strings) {
|
||||
_.extend(r.strings.index, strings)
|
||||
this.permissions = this.index.permissions
|
||||
}
|
||||
@@ -8,9 +8,9 @@ r.traffic = {
|
||||
addSubredditSelector: function () {
|
||||
$('<form>').append(
|
||||
$('<fieldset>').append(
|
||||
$('<legend>').text(r.strings.view_subreddit_traffic),
|
||||
$('<legend>').text(r.strings('view_subreddit_traffic')),
|
||||
$('<input type="text" id="srname">'),
|
||||
$('<input type="submit">').attr('value', r.strings.go)
|
||||
$('<input type="submit">').attr('value', r.strings('go'))
|
||||
)
|
||||
).submit(r.traffic._onSubredditSelected)
|
||||
.prependTo('.traffic-tables-side')
|
||||
|
||||
@@ -141,7 +141,7 @@ r.ui.Form.prototype = $.extend(new r.ui.Base(), {
|
||||
},
|
||||
|
||||
_handleNetError: function(result, err, xhr) {
|
||||
this.showStatus(r.strings.an_error_occurred + ' (' + xhr.status + ')', true)
|
||||
this.showStatus(r.strings('an_error_occurred', {status: xhr.status}), true)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -36,5 +36,15 @@ r.utils = {
|
||||
params[value.name] = value.value
|
||||
})
|
||||
return params
|
||||
},
|
||||
|
||||
_pyStrFormatRe: /%\((\w+)\)s/,
|
||||
pyStrFormat: function(format, params) {
|
||||
return format.replace(this._pyStrFormatRe, function(match, fieldName) {
|
||||
if (!(fieldName in params)) {
|
||||
throw 'missing format parameter'
|
||||
}
|
||||
return params[fieldName]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user