src/js/mustache.js
author hamidouk
Tue, 11 Oct 2011 17:13:08 +0200
branchpopcorn-port
changeset 61 dc7b5ed7b02b
parent 39 4b8c52e11a13
permissions -rw-r--r--
DataLoader, first draft.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
39
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
     1
/*
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
     2
  mustache.js — Logic-less templates in JavaScript
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
     3
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
     4
  See http://mustache.github.com/ for more info.
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
     5
*/
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
     6
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
     7
var Mustache = function() {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
     8
  var Renderer = function() {};
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
     9
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    10
  Renderer.prototype = {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    11
    otag: "{{",
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    12
    ctag: "}}",
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    13
    pragmas: {},
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    14
    buffer: [],
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    15
    pragmas_implemented: {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    16
      "IMPLICIT-ITERATOR": true
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    17
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    18
    context: {},
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    19
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    20
    render: function(template, context, partials, in_recursion) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    21
      // reset buffer & set context
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    22
      if(!in_recursion) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    23
        this.context = context;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    24
        this.buffer = []; // TODO: make this non-lazy
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    25
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    26
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    27
      // fail fast
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    28
      if(!this.includes("", template)) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    29
        if(in_recursion) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    30
          return template;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    31
        } else {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    32
          this.send(template);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    33
          return;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    34
        }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    35
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    36
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    37
      template = this.render_pragmas(template);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    38
      var html = this.render_section(template, context, partials);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    39
      if(in_recursion) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    40
        return this.render_tags(html, context, partials, in_recursion);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    41
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    42
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    43
      this.render_tags(html, context, partials, in_recursion);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    44
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    45
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    46
    /*
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    47
      Sends parsed lines
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    48
    */
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    49
    send: function(line) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    50
      if(line !== "") {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    51
        this.buffer.push(line);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    52
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    53
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    54
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    55
    /*
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    56
      Looks for %PRAGMAS
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    57
    */
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    58
    render_pragmas: function(template) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    59
      // no pragmas
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    60
      if(!this.includes("%", template)) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    61
        return template;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    62
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    63
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    64
      var that = this;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    65
      var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    66
            this.ctag, "g");
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    67
      return template.replace(regex, function(match, pragma, options) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    68
        if(!that.pragmas_implemented[pragma]) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    69
          throw({message: 
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    70
            "This implementation of mustache doesn't understand the '" +
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    71
            pragma + "' pragma"});
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    72
        }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    73
        that.pragmas[pragma] = {};
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    74
        if(options) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    75
          var opts = options.split("=");
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    76
          that.pragmas[pragma][opts[0]] = opts[1];
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    77
        }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    78
        return "";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    79
        // ignore unknown pragmas silently
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    80
      });
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    81
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    82
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    83
    /*
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    84
      Tries to find a partial in the curent scope and render it
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    85
    */
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    86
    render_partial: function(name, context, partials) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    87
      name = this.trim(name);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    88
      if(!partials || partials[name] === undefined) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    89
        throw({message: "unknown_partial '" + name + "'"});
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    90
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    91
      if(typeof(context[name]) != "object") {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    92
        return this.render(partials[name], context, partials, true);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    93
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    94
      return this.render(partials[name], context[name], partials, true);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    95
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    96
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    97
    /*
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    98
      Renders inverted (^) and normal (#) sections
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
    99
    */
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   100
    render_section: function(template, context, partials) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   101
      if(!this.includes("#", template) && !this.includes("^", template)) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   102
        return template;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   103
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   104
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   105
      var that = this;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   106
      // CSW - Added "+?" so it finds the tighest bound, not the widest
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   107
      var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   108
              "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   109
              "\\s*", "mg");
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   110
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   111
      // for each {{#foo}}{{/foo}} section do...
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   112
      return template.replace(regex, function(match, type, name, content) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   113
        var value = that.find(name, context);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   114
        if(type == "^") { // inverted section
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   115
          if(!value || that.is_array(value) && value.length === 0) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   116
            // false or empty list, render it
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   117
            return that.render(content, context, partials, true);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   118
          } else {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   119
            return "";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   120
          }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   121
        } else if(type == "#") { // normal section
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   122
          if(that.is_array(value)) { // Enumerable, Let's loop!
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   123
            return that.map(value, function(row) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   124
              return that.render(content, that.create_context(row),
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   125
                partials, true);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   126
            }).join("");
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   127
          } else if(that.is_object(value)) { // Object, Use it as subcontext!
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   128
            return that.render(content, that.create_context(value),
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   129
              partials, true);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   130
          } else if(typeof value === "function") {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   131
            // higher order section
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   132
            return value.call(context, content, function(text) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   133
              return that.render(text, context, partials, true);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   134
            });
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   135
          } else if(value) { // boolean section
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   136
            return that.render(content, context, partials, true);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   137
          } else {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   138
            return "";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   139
          }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   140
        }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   141
      });
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   142
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   143
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   144
    /*
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   145
      Replace {{foo}} and friends with values from our view
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   146
    */
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   147
    render_tags: function(template, context, partials, in_recursion) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   148
      // tit for tat
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   149
      var that = this;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   150
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   151
      var new_regex = function() {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   152
        return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   153
          that.ctag + "+", "g");
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   154
      };
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   155
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   156
      var regex = new_regex();
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   157
      var tag_replace_callback = function(match, operator, name) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   158
        switch(operator) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   159
        case "!": // ignore comments
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   160
          return "";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   161
        case "=": // set new delimiters, rebuild the replace regexp
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   162
          that.set_delimiters(name);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   163
          regex = new_regex();
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   164
          return "";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   165
        case ">": // render partial
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   166
          return that.render_partial(name, context, partials);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   167
        case "{": // the triple mustache is unescaped
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   168
          return that.find(name, context);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   169
        default: // escape the value
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   170
          return that.escape(that.find(name, context));
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   171
        }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   172
      };
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   173
      var lines = template.split("\n");
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   174
      for(var i = 0; i < lines.length; i++) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   175
        lines[i] = lines[i].replace(regex, tag_replace_callback, this);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   176
        if(!in_recursion) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   177
          this.send(lines[i]);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   178
        }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   179
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   180
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   181
      if(in_recursion) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   182
        return lines.join("\n");
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   183
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   184
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   185
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   186
    set_delimiters: function(delimiters) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   187
      var dels = delimiters.split(" ");
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   188
      this.otag = this.escape_regex(dels[0]);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   189
      this.ctag = this.escape_regex(dels[1]);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   190
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   191
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   192
    escape_regex: function(text) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   193
      // thank you Simon Willison
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   194
      if(!arguments.callee.sRE) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   195
        var specials = [
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   196
          '/', '.', '*', '+', '?', '|',
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   197
          '(', ')', '[', ']', '{', '}', '\\'
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   198
        ];
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   199
        arguments.callee.sRE = new RegExp(
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   200
          '(\\' + specials.join('|\\') + ')', 'g'
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   201
        );
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   202
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   203
      return text.replace(arguments.callee.sRE, '\\$1');
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   204
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   205
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   206
    /*
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   207
      find `name` in current `context`. That is find me a value
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   208
      from the view object
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   209
    */
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   210
    find: function(name, context) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   211
      name = this.trim(name);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   212
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   213
      // Checks whether a value is thruthy or false or 0
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   214
      function is_kinda_truthy(bool) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   215
        return bool === false || bool === 0 || bool;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   216
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   217
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   218
      var value;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   219
      if(is_kinda_truthy(context[name])) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   220
        value = context[name];
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   221
      } else if(is_kinda_truthy(this.context[name])) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   222
        value = this.context[name];
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   223
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   224
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   225
      if(typeof value === "function") {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   226
        return value.apply(context);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   227
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   228
      if(value !== undefined) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   229
        return value;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   230
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   231
      // silently ignore unkown variables
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   232
      return "";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   233
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   234
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   235
    // Utility methods
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   236
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   237
    /* includes tag */
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   238
    includes: function(needle, haystack) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   239
      return haystack.indexOf(this.otag + needle) != -1;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   240
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   241
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   242
    /*
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   243
      Does away with nasty characters
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   244
    */
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   245
    escape: function(s) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   246
      s = String(s === null ? "" : s);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   247
      return s.replace(/&(?!\w+;)|["'<>\\]/g, function(s) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   248
        switch(s) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   249
        case "&": return "&amp;";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   250
        case "\\": return "\\\\";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   251
        case '"': return '&quot;';
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   252
        case "'": return '&#39;';
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   253
        case "<": return "&lt;";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   254
        case ">": return "&gt;";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   255
        default: return s;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   256
        }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   257
      });
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   258
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   259
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   260
    // by @langalex, support for arrays of strings
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   261
    create_context: function(_context) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   262
      if(this.is_object(_context)) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   263
        return _context;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   264
      } else {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   265
        var iterator = ".";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   266
        if(this.pragmas["IMPLICIT-ITERATOR"]) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   267
          iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   268
        }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   269
        var ctx = {};
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   270
        ctx[iterator] = _context;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   271
        return ctx;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   272
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   273
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   274
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   275
    is_object: function(a) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   276
      return a && typeof a == "object";
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   277
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   278
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   279
    is_array: function(a) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   280
      return Object.prototype.toString.call(a) === '[object Array]';
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   281
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   282
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   283
    /*
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   284
      Gets rid of leading and trailing whitespace
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   285
    */
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   286
    trim: function(s) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   287
      return s.replace(/^\s*|\s*$/g, "");
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   288
    },
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   289
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   290
    /*
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   291
      Why, why, why? Because IE. Cry, cry cry.
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   292
    */
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   293
    map: function(array, fn) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   294
      if (typeof array.map == "function") {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   295
        return array.map(fn);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   296
      } else {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   297
        var r = [];
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   298
        var l = array.length;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   299
        for(var i = 0; i < l; i++) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   300
          r.push(fn(array[i]));
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   301
        }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   302
        return r;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   303
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   304
    }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   305
  };
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   306
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   307
  return({
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   308
    name: "mustache.js",
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   309
    version: "0.3.1-dev",
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   310
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   311
    /*
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   312
      Turns a template and view into HTML
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   313
    */
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   314
    to_html: function(template, view, partials, send_fun) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   315
      var renderer = new Renderer();
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   316
      if(send_fun) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   317
        renderer.send = send_fun;
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   318
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   319
      renderer.render(template, view, partials);
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   320
      if(!send_fun) {
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   321
        return renderer.buffer.join("\n");
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   322
      }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   323
    }
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   324
  });
4b8c52e11a13 a small templating engine.
hamidouk
parents:
diff changeset
   325
}();