diff --git a/r2/r2/lib/js.py b/r2/r2/lib/js.py index 75797f188..f327c484f 100755 --- a/r2/r2/lib/js.py +++ b/r2/r2/lib/js.py @@ -196,6 +196,25 @@ class DataSource(Source): return [] +class TemplateFileSource(DataSource, FileSource): + """A JavaScript template file on disk.""" + def __init__(self, name, wrap="r.templates.set({content})"): + DataSource.__init__(self, wrap) + FileSource.__init__(self, name) + self.name = name + + def get_content(self): + from r2.lib.static import locate_static_file + name, style = os.path.splitext(self.name) + path = locate_static_file(os.path.join('static/js', self.name)) + with open(path) as f: + return [{ + "name": name, + "style": style.lstrip('.'), + "template": f.read() + }] + + class StringsSource(DataSource): """A virtual source consisting of localized strings from r2.lib.strings.""" def __init__(self, lang=None, keys=None, wrap="r.strings.set({content})"): @@ -345,6 +364,7 @@ module["reddit"] = LocalizedModule("reddit.js", "lib/jquery.cookie.js", "lib/jquery.url.js", "lib/backbone-0.9.10.js", + "templates.js", "utils.js", "ui.js", "login.js", diff --git a/r2/r2/public/static/js/templates.js b/r2/r2/public/static/js/templates.js new file mode 100644 index 000000000..338185fc0 --- /dev/null +++ b/r2/r2/public/static/js/templates.js @@ -0,0 +1,59 @@ +r.templating = {} + +r.templating.TemplateSet = function() { + this.index = {} +} +r.templating.TemplateSet.prototype = { + _templateSettings: { + variable: 'thing' + }, + + _key: function(name, style) { + return name + '.' + style + }, + + _create: function(templateData) { + return _.template(templateData, null, this._templateSettings) + }, + + set: function(templates) { + _.each(templates, function(tplInfo) { + var key = this._key(tplInfo.name, tplInfo.style) + this.index[key] = tplInfo.template + }, this) + }, + + _defaultStyle: function(nameAndStyle) { + // `nameAndStyle` can be an array of [name, style] or simply a name, + // defaulting the style to r.config.renderstyle. + if (!_.isArray(nameAndStyle)) { + nameAndStyle = [nameAndStyle, r.config.renderstyle] + } + return nameAndStyle + }, + + get: function(nameAndStyle) { + nameAndStyle = this._defaultStyle(nameAndStyle) + var key = this._key(nameAndStyle[0], nameAndStyle[1]) + + if (!this.index[key]) { + throw '"' + nameAndStyle[0] + '.' + nameAndStyle[1] + '"' + ' template not found.' + } + + template = this.index[key] + if (!_.isFunction(template)) { + template = this.index[key] = this._create(template) + } + return template + }, + + make: function(nameAndStyle, data, parentEl) { + html = this.get(nameAndStyle)(data) + if (parentEl) { + $(parentEl).append(html) + } + return html + } +} + +r.templates = new r.templating.TemplateSet()