Example #1
0
  fs.readFile(fileName, "utf8", function(err, buffer) {
    // Pass up any errors.
    if (err) {
      return next(err);
    }

    // Send back the compiled template.
    var template = combyne(String(buffer));

    // Find all extend.
    var extend = visitCombyne(template.tree.nodes, function(node) {
      return node.type === "ExtendExpression";
    }).map(function(node) { return node.value; });

    // Find all partials.
    var partials = visitCombyne(template.tree.nodes, function(node) {
      return node.type === "PartialExpression" && noParse !== node.value;
    }).map(function(node) { return node.value; });

    // Find all filters.
    var filters = visitCombyne(template.tree.nodes, function(node) {
      return node.filters && node.filters.length;
    }).map(function(node) {
      return node.filters.map(function(filter) {
        return filter.value;
      }).join(" ");
    });

    // Flatten the array.
    if (filters.length) {
      filters = filters.join(" ").split(" ");
    }

    // Map all extend to functions.
    extend = extend.map(function(render) {
      return function(callback) {
        var name = render.template;
        var renderPath = path.join(dirname, name + ext);

        // The last argument of this call is the noparse option that specifies
        // the virtual partial should not be loaded.
        processTemplate.call(route, renderPath, data, function(err, render) {
          if (err) { return callback(err); }

          template.registerPartial(name, render);
          callback(err, template);
        }, render.partial);
      };
    });

    // Map all partials to functions.
    partials = partials.map(function(name) {
      return function(callback) {
        // Ignore those that have already been defined globally.
        if (name in settings._partials) {
          return callback();
        }

        var partialPath = path.join(dirname, name + ext);

        processTemplate.call(route, partialPath, data, function(err, partial) {
          if (err) { return callback(err); }

          template.registerPartial(name, partial);
          settings._partials[name] = partial;
          callback(err, template);
        });
      };
    });

    // Map all filters to functions.
    filters = filters.map(function(name) {
      // Filters cannot be so easily inferred location-wise, so assume they are
      // preconfigured or exist in a filters directory.
      return function(callback) {
        var filtersDir = settings.filtersDir || "filters";
        var filtersPath = path.join(dirname, filtersDir, name + ".js");

        // Ignore those that have already been defined globally.
        if (name in settings._filters) {
          return callback();
        }

        try {
          var filter = require(filtersPath);

          // Register the exported function.
          settings._filters[name] = filter;
        }
        catch (ex) {
          return callback(ex);
        }

        callback(null, filter);
      };
    });

    // Find all files and map the partials.
    async.parallel(partials.concat(extend, filters), function(err) {
      if (err) { return next(err); }

      // Register all the global partials.
      Object.keys(settings._partials).forEach(function(name) {
        var partial = settings._partials[name];
        template.registerPartial(name, partial);
      });

      // Register all the global filters.
      Object.keys(settings._filters).forEach(function(name) {
        var filter = settings._filters[name];
        template.registerFilter(name, filter);
      });

      // Render the template.
      next(err, template);
    });
  });
Example #2
0
var processTemplate = function(templateSource, settings, callback) {
  var root = settings.root;
  var template = combyne(templateSource);
  var extension = settings.extension || '.html';

  // Find all extend.
  var extend = visitCombyne(template.tree.nodes, function(node) {
    return node.type === 'ExtendExpression';
  }).map(function(node) { return node.value; });

  // Find all partials.
  var partials = visitCombyne(template.tree.nodes, function(node) {
    return node.type === 'PartialExpression' && !extendsCache[node.value];
  }).map(function(node) { return node.value; });

  // Find all filters.
  var filters = visitCombyne(template.tree.nodes, function(node) {
    return node.filters && node.filters.length;
  }).map(function(node) {
    return node.filters.map(function(filter) {
      return filter.value;
    }).join(' ');
  });

  // Flatten the array.
  if (filters.length) {
    filters = filters.join(' ').split(' ');
  }

  // Filters cannot be so easily inferred location-wise, so assume they are
  // preconfigured or exist in a filters directory.
  var filtersDir = settings.filtersDir || 'filters';

  filters.forEach(function(filterName) {
    // Register the exported function.
    template._filters[filterName] = path.join(root, filtersDir, filterName);
  });

  // Map all partials to functions.
  partials.forEach(function(name) {
    template._partials[name] = path.resolve(path.join(root, name + extension));
  });

  // Map all extend to functions.
  extend.forEach(function(render) {
    var name = render.template;
    var superTemplate = path.resolve(path.join(root, name + extension));

    // Pre-cache this template.
    extendsCache[render.partial] = true;

    // Set the partial to the super template.
    template._partials[name] = superTemplate;
  });

  // Augment the template source to include dependencies.
  var lines = template.source.split('\n');

  partials = Object.keys(template._partials).map(function(name) {
    return '"' + name + '": require("' + template._partials[name] + '")';
  });

  filters = Object.keys(template._filters).map(function(name) {
    return '"' + name + '": require("' + template._filters[name] + '")';
  });

  // This replaces the partials and filters inline.
  lines[1] = '_partials: {' + partials.join(',') + '},';
  lines[2] = '_filters: {' + filters.join(',') + '},';

  // Flatten the template to remove unnecessary `\n` whitespace.
  template.source = lines.join('\n');

  if (this.push) {
    this.push('module.exports = ' + template.source);
  }

  callback.call(this, template);
};
Example #3
0
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4) {
        var template = combyne(xhr.responseText);

        // Find all extend.
        var extend = recurse(template.tree.nodes, function(node) {
          return node.type === 'ExtendExpression';
        }).map(function(node) { return node.value; });

        // Find all partials.
        var partials = recurse(template.tree.nodes, function(node) {
          return node.type === 'PartialExpression' && !extendsCache[node.value];
        }).map(function(node) { return node.value; });

        // Find all filters.
        var filters = recurse(template.tree.nodes, function(node) {
          return node.filters && node.filters.length;
        }).map(function(node) {
          return node.filters.map(function(filter) {
            return filter.value;
          }).join(' ');
        });

        // Flatten the array.
        if (filters.length) {
          filters = filters.join(' ').split(' ');
        }

        // Map all filters to functions.
        filters = filters.map(function(filterName) {
          // Filters cannot be so easily inferred location-wise, so assume they are
          // preconfigured or exist in a filters directory.
          var filtersDir = settings.filtersDir || 'filters';
          var filtersPath = root + filtersDir + '/' + filterName;

          return new Promise(function(resolve) {
            require([filtersPath + '.js'], function(filter) {
              // Register the exported function.
              template.registerFilter(filterName, filter);
              resolve(filter);
            });
          });
        });

        // Process as a Lo-Dash template and cache.
        buildMap[name] = template;

        // Wait for all filters, then partials, and finally extends to load and
        // then pass back control.
        Promise.all(filters).then(function(filters) {
          // Map all partials to functions.
          partials = partials.map(function(name) {
            return new Promise(function(resolve, reject) {
              // The last argument of this call is the noparse option that
              // specifies the virtual partial should not be loaded.
              require([root + name + '.html'], function(render) {
                template.registerPartial(name, render);
                resolve(render);
              });
            });
          });

          return Promise.all(partials);
        }).then(function() {
          // Map all extend to functions.
          var list = extend.map(function(render) {
            return new Promise(function(resolve, reject) {
              var name = render.template;

              // Pre-cache this template.
              extendsCache[render.partial] = true;

              // The last argument of this call is the noparse option that
              // specifies the virtual partial should not be loaded.
              require([root + name + '.html'], function(tmpl) {
                tmpl.registerPartial(render.partial, template);
                template.registerPartial(name, tmpl);
                resolve(tmpl);
              });
            });
          });

          return Promise.all(list);
        }).then(function() {
          // Return the compiled template.
          load(template);
        });
      }
    };