Micro templating

JavaScript micro-templating, similar to John Resig's implementation.

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greatest.deepsurf.us/scripts/15246/95830/Micro%20templating.js

  1. // ==UserScript==
  2. // @name Micro templating
  3. // @description JavaScript micro-templating, similar to John Resig's implementation.
  4. // @version 0.1
  5. // ==/UserScript==
  6. /*!
  7. Underscore.js templates as a standalone implementation.
  8. JavaScript micro-templating, similar to John Resig's implementation.
  9. Underscore templates documentation: http://documentcloud.github.com/underscore/#template
  10. Modifyed by Martin Lundgren
  11. */
  12. (function () {
  13.  
  14. 'use strict';
  15.  
  16. // By default, Underscore uses ERB-style template delimiters, change the
  17. // following template settings to use alternative delimiters.
  18. var settings = {
  19. evaluate: /<%([\s\S]+?)%>/g,
  20. interpolate: /<%=([\s\S]+?)%>/g,
  21. escape: /<%-([\s\S]+?)%>/g
  22. };
  23.  
  24. // When customizing `templateSettings`, if you don't want to define an
  25. // interpolation, evaluation or escaping regex, we need one that is
  26. // guaranteed not to match.
  27. var noMatch = /.^/;
  28.  
  29. // Certain characters need to be escaped so that they can be put into a
  30. // string literal.
  31. var escapes = {
  32. '\\': '\\',
  33. "'": "'",
  34. 'r': '\r',
  35. 'n': '\n',
  36. 't': '\t',
  37. 'u2028': '\u2028',
  38. 'u2029': '\u2029'
  39. };
  40.  
  41. for (var p in escapes) {
  42. escapes[escapes[p]] = p;
  43. }
  44.  
  45. var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
  46. var unescaper = /\\(\\|'|r|n|t|u2028|u2029)/g;
  47.  
  48. var tmpl = function (text, data, objectName) {
  49. settings.variable = objectName;
  50.  
  51. // Compile the template source, taking care to escape characters that
  52. // cannot be included in a string literal and then unescape them in code
  53. // blocks.
  54. var source = "__p+='" + text
  55. .replace(escaper, function (match) {
  56. return '\\' + escapes[match];
  57. })
  58. .replace(settings.escape || noMatch, function (match, code) {
  59. return "'+\n_.escape(" + unescape(code) + ")+\n'";
  60. })
  61. .replace(settings.interpolate || noMatch, function (match, code) {
  62. return "'+\n(" + unescape(code) + ")+\n'";
  63. })
  64. .replace(settings.evaluate || noMatch, function (match, code) {
  65. return "';\n" + unescape(code) + "\n;__p+='";
  66. }) + "';\n";
  67.  
  68. // If a variable is not specified, place data values in local scope.
  69. if (!settings.variable) {
  70. source = 'with(obj||{}){\n' + source + '}\n';
  71. }
  72.  
  73. source = "var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n" + source + "return __p;\n";
  74.  
  75. var render = new Function(settings.variable || 'obj', source);
  76.  
  77. if (data) {
  78. return render(data);
  79. }
  80.  
  81. var template = function (data) {
  82. return render.call(this, data);
  83. };
  84.  
  85. // Provide the compiled function source as a convenience for build time
  86. // precompilation.
  87. template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
  88.  
  89. return template;
  90. };
  91.  
  92. window._tmpl = tmpl;
  93.  
  94. }());