public

Compile Ember Handlebars Templates in .net mvc (2 options: first using postbuild, second using a bundle transform)

  • Download Gist
HandlebarsBundleTransform.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
using System.IO;
using System.Text;
using System.Web;
using System.Web.Optimization;
using Jurassic;
 
namespace Fewt.Web
{
public class EmberHandlebarsBundleTransform : IBundleTransform
{
ScriptEngine _scriptEngine;
 
public EmberHandlebarsBundleTransform()
{
_scriptEngine = new ScriptEngine();
 
_scriptEngine.ExecuteFile(Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/"), "Scripts/handlebars-1.0.0.beta.6.js"));
_scriptEngine.ExecuteFile(Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/"), "Scripts/headless-ember.js"));
_scriptEngine.ExecuteFile(Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/"), "Scripts/ember.js"));
}
 
public void Process(BundleContext context, BundleResponse response)
{
var sb = new StringBuilder();
 
sb.AppendLine("(function() {\n");
 
foreach (var assetFile in response.Files)
{
var template = File.ReadAllText(assetFile.FullName);
var compiled = _scriptEngine.CallGlobalFunction<string>("precompileEmberHandlebars", template);
var templateName = Path.GetFileNameWithoutExtension(Path.GetDirectoryName(assetFile.FullName)) + "-" + Path.GetFileNameWithoutExtension(assetFile.FullName);
sb.AppendLine("Ember.TEMPLATES[\'" + templateName.ToLower() + "\'] = Handlebars.template(" + compiled + ");\n");
}
 
sb.AppendLine("})();");
 
response.Content = sb.ToString();
response.ContentType = "text/javascript";
response.Cacheability = HttpCacheability.Public;
}
}
}
ember-precompile.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
var fs = require('fs');
var vm = require('vm');
var path = require('path');
 
var handlebars = fs.readFileSync('../Scripts/handlebars-1.0.0.beta.6.js', 'utf8');
var headlessEmber = fs.readFileSync('../Scripts/headless-ember.js', 'utf8');
var emberJs = fs.readFileSync('../Scripts/ember-1.0.pre.js', 'utf8');
 
var templatesDir = '../templates';
var outputFile = '../Scripts/templates.js';
 
var walk = function (dir, done) {
var results = [];
fs.readdir(dir, function (err, list) {
if (err) return done(err);
var i = 0;
(function next() {
var file = list[i++];
if (!file) return done(null, results);
file = dir + '/' + file;
fs.stat(file, function (err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function (err, res) {
results = results.concat(res);
next();
});
} else {
results.push(file);
next();
}
});
})();
});
};
 
 
if (fs.existsSync(outputFile)) {
fs.unlinkSync(outputFile); //delete the file
}
fs.appendFileSync(outputFile, '(function() {\n');
 
console.log('Compiling .handlebars templates');
 
walk(templatesDir, function (err, files) {
if (err) throw err;
for (i = 0; i < files.length; i++) {
if (/\.hbs|\.handlebars/.test(files[i])) {
// Create a context with the file.
var context = vm.createContext({
template: fs.readFileSync(files[i], 'utf8')
});
 
// Load ember, headless-ly.
vm.runInContext(handlebars, context, 'handlebars.js');
vm.runInContext(headlessEmber, context, 'headless-ember.js');
vm.runInContext(emberJs, context, 'ember.js');
 
// Compile the file inside the context.
vm.runInContext('tJs = precompileEmberHandlebars(template);', context);
 
// Generate code for our new js file.
var templateName = path.basename(path.dirname(files[i])) + "-" + path.basename(files[i]).replace(/\.hbs|\.handlebars/, '');
console.log(templateName);
var namedTemplateJs = 'Ember.TEMPLATES["' + templateName + '"] = ' +
'Ember.Handlebars.template(' + context.tJs + ');';
 
fs.appendFileSync(outputFile, namedTemplateJs);
}
}
fs.appendFileSync(outputFile, '})();');
console.log('Done!');
});

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.