Skip to content

Instantly share code, notes, and snippets.

@tbranyen
Last active December 24, 2015 15:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tbranyen/6821045 to your computer and use it in GitHub Desktop.
Save tbranyen/6821045 to your computer and use it in GitHub Desktop.
LoDash Template Loader
/* Lo-Dash Template Loader v0.1.0
* Copyright 2013, Tim Branyen (@tbranyen).
* lodash-loader.js may be freely distributed under the MIT license.
*
* Configure in your RequireJS configuration:
*
* // You can name the plugin prefix whatever you like.
* paths: {
* "lo": "path/to/amd_template"
* },
*
* // Options below are the defaults.
* _templateSettings: {
* ext: ".html",
* root: "/"
* }
*
* And then you can use simply:
*
* // Omit the extension and root path.
* require(["lo!path/to/template"], function(template) {
* var contents = template({
* // Some data.
* });
* });
*
* This template loader plugin works in both RequireJS and R.js bundled with Almond.
*
* Should support Dojo as well. (Untested).
*
*/
(function(global) {
"use strict";
// Cache used to map configuration options between load and write.
var buildMap = {};
// Alias the correct `nodeRequire` method.
var nodeRequire = requirejs.nodeRequire;
// If in Node, get access to the filesystem.
if (nodeRequire) {
fs = nodeRequire("fs");
}
// Define the plugin using the CommonJS syntax.
define(function(require, exports) {
var _ = require("lodash");
exports.version = "0.1.0";
// Invoked by the AMD builder, passed the path to resolve, the require
// function, done callback, and the configuration options.
exports.load = function(name, req, load, config) {
// Dojo provides access to the config object through the req function.
if (!config) {
config = require.rawConfig;
}
// Always keep a copy of the original name.
var originalName = name;
// Default settings point to the project root and using html files.
var settings = _.defaults(config._templateSettings, {
ext: ".html",
root: "/"
});
// Builds must happen with Node.
if (config.isBuild) {
name = settings.root + name + settings.ext;
// Remove a leading forward slash during builds.
if (name[0] === "/") {
name = name.slice(1);
}
// Read in the file synchronously, as RequireJS expects, and return the
// contents. Process as a Lo-Dash template.
buildMap[originalName] = _.template(String(fs.readFileSync(name)));
return load();
}
// Create a basic XHR.
var xhr = new XMLHttpRequest();
// Wait for it to load.
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
// Process as a Lo-Dash template and cache.
buildMap[name] = _.template(xhr.responseText);
// Return the compiled template.
load(buildMap[name]);
}
};
// Ensure the root always end in a trailing slash.
if (settings.root[settings.root.length-1] !== "/") {
settings.root = settings.root + "/";
}
// Initiate the fetch.
xhr.open("GET", settings.root + name + settings.ext, true);
xhr.send(null);
};
// Also invoked by the AMD builder, this writes out a compatible define
// call that will work with loaders such as almond.js that cannot read
// the configuration data.
exports.write = function(pluginName, moduleName, write) {
var template = String(buildMap[moduleName]);
// This will return the template.
var retTemplate = [
"function() {",
"return ", template, ";",
"}"
].join("");
// Write out the actual definition
write([
"define('", pluginName, "!", moduleName, "', ", "[], ",
retTemplate,
");\n"
].join(""));
};
});
})(typeof global === "object" ? global : this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment