HTML templating library for JS
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

index.js 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. var regStr = "{{(.+)}}";
  2. var localRegex = new RegExp(regStr);
  3. var globalRegex = new RegExp(regStr, "g");
  4. function hasMultipleStatements(str) {
  5. return (str.indexOf(";") !== -1)
  6. }
  7. function Func(args) {
  8. return Function.apply(this, args);
  9. }
  10. Func.prototype = Function.prototype;
  11. function Templish(str, vals) {
  12. str = str.replace(/\s+/g, " ").replace(/}}/g, "}}\n");
  13. this.string = str;
  14. this.vals = vals;
  15. this.subs = [];
  16. var matches = str.match(globalRegex);
  17. if (!matches)
  18. return;
  19. matches.forEach(function(m) {
  20. var str = m.match(localRegex)[1];
  21. //Add user defined arguments
  22. var args = [];
  23. vals.forEach(function(v) {
  24. args.push(v);
  25. });
  26. //We also need a callback function, for async things
  27. args.push("cb");
  28. //We want to automatically return if there's only one statement
  29. if (hasMultipleStatements(str))
  30. args.push(str);
  31. else
  32. args.push("return ("+str+")");
  33. this.subs.push({
  34. func: new Func(args),
  35. match: m+"\n"
  36. });
  37. }.bind(this));
  38. }
  39. Templish.prototype.exec = function(vals, cb) {
  40. var str = this.string;
  41. //Prepare generic arguments
  42. var args = [];
  43. for (var i in vals) {
  44. var index = this.vals.indexOf(i);
  45. if (index === -1)
  46. throw new Error("Error: argument "+i+" doesn't exist");
  47. args[index] = vals[i];
  48. }
  49. var numArgs = args.length;
  50. //Keep track of how many callbacks we're waiting for
  51. var cbsRemaining = this.subs.length;
  52. //Replace
  53. this.subs.forEach(function(sub, i) {
  54. //Create a callback function for each substitute
  55. args[numArgs] = function(err, res) {
  56. if (err)
  57. throw err;
  58. str = str.replace(sub.match, res);
  59. //If this is the last callback to be executed,
  60. //call back with the resulting string
  61. if (cbsRemaining <= 0)
  62. cb(null, str);
  63. cbsRemaining -= 1;
  64. }
  65. var ret = sub.func.apply(null, args);
  66. //If the substitute's function returns anything, we use that directly,
  67. //but if it doesn't, we wait for a callback
  68. if (ret !== undefined) {
  69. str = str.replace(sub.match, ret);
  70. if (cbsRemaining <= 0)
  71. cb(str);
  72. cbsRemaining -= 1;
  73. }
  74. });
  75. //If there's no asynchronous functions to wait for,
  76. //just call back immediately
  77. if (cbsRemaining === 0)
  78. return cb(null, str);
  79. }
  80. module.exports = Templish;