|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- /*
- Shamless port of http://github.com/defunkt/mustache
- by Jan Lehnardt <jan@apache.org>
-
- Thanks @defunkt for the awesome code
- TBD: MIT, see LICENSE
-
- ChangeLog:
- - 04.10.2009: Ininitial port at http://devhouseberlin.de/
-
- */
-
- var Mustache = {
- name: "mustache.js",
- version: "0.1",
- debug: true,
- stack: " ",
- context: {},
- to_html: function(template, view) {
- return this.render(template, view);
- },
-
- render: function(template, view) {
- this.stack = this.stack + " ";
- // fail fast
- if(template.indexOf("{{") == -1) {
- return template;
- }
- this.context = context = this.merge((this.context || {}), view);
- var html = this.render_section(template);
- // restore context, recursion might have messed it up
- this.context = context;
- return this.render_tags(html);
- },
-
- render_partial: function(name) {
- var evil_name = eval(name)
- switch(typeof evil_name) {
- case "string":
- return this.to_html(evil_name, "");
- case "object":
- var tpl = name + "_template";
- return this.to_html(eval(tpl), evil_name);
- default:
- throw("Unknown partial type.");
- }
- },
-
- merge: function(a, b) {
- for(var name in b) {
- if(b.hasOwnProperty(name)) {
- a[name] = b[name];
- }
- }
- return a;
- },
-
- render_section: function(template) {
- if(template.indexOf("{{#") == -1) {
- return template;
- }
- var that = this;
- return template.replace(/\{\{\#(.+)\}\}\s*([\s\S]+)\{\{\/\1\}\}\s*/mg,
- function(match, name, content) {
- var value = that.find(name);
- if(that.is_array(value)) {
- return value.map(function(row) {
- return that.render(content, row);
- }).join('');
- } else if(value) {
- return that.render(content);
- } else {
- return "";
- }
- }
- );
- },
-
- is_array: function(a) {
- return (a &&
- typeof a === 'object' &&
- a.constructor === Array);
- },
-
- render_tags: function(template) {
- // values
- var that = this;
- return template.replace(/\{\{(!|<|\{)?([^\/#]+?)\1?\}\}+/mg,
- function (match, operator, name) {
- switch(operator) {
- case "!": // ignore comments
- return match;
- case "<": // render partial
- return that.render_partial(name);
- case '{': // the triple mustache is unescaped
- return that.find(name);
- default: // escape the value
- return that.escape(that.find(name));
- }
- }, this);
- },
-
- escape: function(s) {
- return s.toString().replace(/[&"<>\\]/g, function(s) {
- switch(s) {
- case "&": return "&";
- case "\\": return "\\\\";;
- case '"': return '\"';;
- case "<": return "<";
- case ">": return ">";
- default: return s;
- }
- });
- },
-
- find: function(name) {
- name = this.trim(name);
- // print(this.stack + "find(" + name + ")");
- var context = this.context;
- if(typeof context[name] === "function") {
- return context[name].apply(context);
- }
- if(context[name] !== undefined) {
- return context[name];
- }
- throw("Can't find " + name + " in " + context);
- },
-
- trim: function(s) {
- return s.replace(/^\s*|\s*$/g, '');
- },
- };
-
- var view_partial = {
- greeting: function() {
- return "Welcome";
- },
-
- farewell: function() {
- return "Fair enough, right?";
- }
- };
-
- var simple = {
- name: "Chris",
- value: 10000,
- taxed_value: function() {
- return this.value - (this.value * 0.4);
- },
- in_ca: true
- };
-
- var simple_template = "Hello {{name}}\n" +
- "You have just won ${{value}}!\n" +
- "{{#in_ca}}\n" +
- "Well, ${{ taxed_value }}, after taxes.\n" +
- "{{/in_ca}}\n";
-
- var template = "<h1>{{greeting}}<\/h1>\n{{<simple}}\n<h3>{{farewell}}<\/h3>";
- var result = Mustache.to_html(template, view_partial);
- print(result);
|