Skip to content

Instantly share code, notes, and snippets.

@mrsheepuk
Last active August 29, 2015 14:08
Show Gist options
  • Save mrsheepuk/0caa9584d5b80ec59ebf to your computer and use it in GitHub Desktop.
Save mrsheepuk/0caa9584d5b80ec59ebf to your computer and use it in GitHub Desktop.
Using PhantomJS to pre-compile handlebars templates without node
/*
* PhantomJS Runner Handlebars Pre-compiler
*
* PhantomJS binaries: http://phantomjs.org/download.html
* Requires: PhantomJS 1.6+ (1.7+ recommended)
* Requires: handlebars.js, jquery.js
*
* Run with:
* phantomjs hbcompiler.js
* [url-or-path-of-your-uncompiled-templates]
* [class-name-of-template-script-tags-to-extract]
* [class-name-of-partials-script-tags-to-extract]
* [optional base name to add the templates to, defaults to Templates]
*
* e.g.
* phantomjs hbcompiler.js http://localhost/templates/filewithtemplatesin.html hbTemplate hbPartial MyTemplates
*
* In the source html file, wrap each template in a script tag with a class of hbTemplate or hbPartial,
* and give it an ID:
* <script type="text/x-handlebars-template" class="hbTemplate" id="MyFabulousTemplate">
* <p>This template is FABULOUS - hello {{username}}!!!</p>
* </script>
*
* Outputs the compiled templates on stdout - pipe it to a .js file and include in your web page, then
* to use the compiled templates:
*
* var template = Handlebars.template(MyTemplates.pcTemplates["MyFabulousTemplate"]);
* // Then for e.g. execute the template and put the resulting output in the element with
* // ID "target":
* $("#target").html(template({ username: "CheeseMonger" }));
*
* And to register the supplied partials:
*
* for (var key in MyTemplates.pcPartials) {
* // Skip weirdyobjectprops.
* if (!MyTemplates.pcPartials.hasOwnProperty(key)) continue;
* // Add this pre-compiled partial.
* Handlebars.partials[key] = Handlebars.template(MyTemplates.pcPartials[key]);
* }
*
*/
/*global phantom:false, require:false, console:false, window:false */
(function() {
'use strict';
var src, srcClass, partialClass, targetObj, page,
args = require('system').args,
HANDLEBARS = "js/lib/handlebars-v2.0.0.js",
JQUERY = "js/lib/jquery-1.11.1.min.js";
// arg[0]: scriptName, args[1...]: arguments
if (args.length < 4 || args.length > 5) {
console.error('Usage:\n phantomjs hbcompiler.js [url-or-path-of-your-uncompiled-templates] [class-name-of-script-tags-for-templates] [class-name-of-script-tags-for-partials]');
phantom.exit(1);
}
src = args[1];
srcClass = args[2];
partialClass = args[3];
targetObj = "Template";
if (args.length === 5) targetObj = args[4];
page = require('webpage').create();
// Route `console.log()` calls from within the Page context to the main Phantom context (i.e. current `this`)
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.onInitialized = function() {
};
page.onCallback = function(message) {
};
page.open(src, function(status) {
if (status !== 'success') {
console.error('Unable to access network: ' + status);
phantom.exit(1);
} else {
page.injectJs(HANDLEBARS);
page.injectJs(JQUERY);
var output = page.evaluate(function(classToSelect, partClassToSelect, targetObj) {
var out = [];
$("." + classToSelect).each(function(ind,elem) {
out.push(targetObj + ".pcTemplates['" + $(this).attr("id") + "'] = " + Handlebars.precompile($(this).html()) + ";");
});
$("." + partClassToSelect).each(function(ind,elem) {
out.push(targetObj + ".pcPartials['" + $(this).attr("id") + "'] = " + Handlebars.precompile($(this).html()) + ";");
});
return out;
}, srcClass, partialClass, targetObj);
console.log("// *** DO NOT EDIT *** Pre-compiled from: " + src + "\n");
console.log("if ("+targetObj+" === undefined) var "+targetObj+" = {};");
console.log("if ("+targetObj+".pcTemplates === undefined) "+targetObj+".pcTemplates = {};");
console.log("if ("+targetObj+".pcPartials === undefined) "+targetObj+".pcPartials = {};");
for (var x = 0; x < output.length; x++) {
console.log(output[x]);
}
phantom.exit(0);
}
});
})();
@mrsheepuk
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment