Created
November 8, 2012 14:40
-
-
Save garth/4039168 to your computer and use it in GitHub Desktop.
Pre-compile emberjs handlebars templates with ASP.NET MVC Bundles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// use NuGet to add BundleTransformer to your project | |
// add ember.js and handlebars.js to the /Scripts folder | |
// in bundle config add something like this | |
bundles.Add(new ScriptBundle("~/bundles/templates").IncludeDirectory( | |
"~/templates", "*.handlebars")); | |
// or like this | |
bundles.Add(new ScriptBundle("~/bundles/teamplates").Include( | |
"~/templates/application.handlebars", | |
"~/templates/header.handlebars", | |
"~/templates/footer.handlebars"))); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class HandlebarsAssetHandler : AssetHandlerBase { | |
public override string ContentType { | |
get { return BundleTransformer.Core.Constants.ContentType.Js; } | |
} | |
/// <summary>Constructs instance of TypeScript asset handler</summary> | |
public HandlebarsAssetHandler() | |
: this(HttpContext.Current.Cache, | |
BundleTransformerContext.Current.GetFileSystemWrapper(), | |
BundleTransformerContext.Current.GetCoreConfiguration().AssetHandler, | |
BundleTransformerContext.Current.GetApplicationInfo()) { } | |
/// <summary>Constructs instance of Handlebars asset handler</summary> | |
/// <param name="cache">Server cache</param> | |
/// <param name="fileSystemWrapper">File system wrapper</param> | |
/// <param name="assetHandlerConfig">Configuration settings of HTTP-handler that responsible | |
/// for text output of processed asset</param> | |
/// <param name="applicationInfo">Information about web application</param> | |
public HandlebarsAssetHandler(Cache cache, IFileSystemWrapper fileSystemWrapper, | |
AssetHandlerSettings assetHandlerConfig, IHttpApplicationInfo applicationInfo) | |
: base(cache, fileSystemWrapper, assetHandlerConfig, applicationInfo) { } | |
/// <summary>Translates handlebars templates to JS-code</summary> | |
/// <param name="asset">Handlebars template</param> | |
/// <returns>Asset with translated code</returns> | |
protected override IAsset ProcessAsset(IAsset asset) { | |
ITranslator handlebarsTranslator = BundleTransformerContext.Current.GetJsTranslatorInstance("HandlebarsTranslator"); | |
handlebarsTranslator.IsDebugMode = _applicationInfo.IsDebugMode; | |
return handlebarsTranslator.Translate(asset); | |
} | |
} | |
public class HandlebarsTranslator : TranslatorWithNativeMinificationBase { | |
private readonly MsieJsEngine jsEngine = new MsieJsEngine(); | |
public HandlebarsTranslator() { | |
//setup a dummy browser environment with jquery | |
jsEngine.Execute(@" | |
var window = this | |
//dummy jQuery | |
var $ = jQuery = function () { return jQuery } | |
jQuery.ready = function () { return jQuery } | |
jQuery.inArray = function () { return jQuery } | |
jQuery.jquery = '1.8.2' | |
jQuery.event = { fixHooks: {} } | |
//dummy DOM element | |
var element = { | |
firstChild: function () { return element }, | |
innerHTML: function () { return element } | |
} | |
// DOM | |
var document = { | |
createRange: false, | |
createElement: function () { return element } | |
} | |
// Console | |
var console = { | |
log: function () {} | |
} | |
"); | |
//load handlebars and ember | |
var server = new AspServerPathResolver(); | |
jsEngine.ExecuteFile(server.GetFullPath("~/Scripts/handlebars.js")); | |
jsEngine.ExecuteFile(server.GetFullPath("~/Scripts/ember.js")); | |
} | |
public override IAsset Translate(IAsset asset) { | |
// inject the template | |
jsEngine.SetVariableValue("template", asset.Content); | |
// compile | |
string templateJs = jsEngine.Evaluate<string>("Ember.Handlebars.precompile(template).toString()"); | |
// add the template to the collection | |
var templateName = Path.GetFileNameWithoutExtension(asset.Path); | |
asset.Content = "Ember.TEMPLATES['" + templateName + "'] = Ember.Handlebars.template(" + templateJs + ");"; | |
return asset; | |
} | |
public override IList<IAsset> Translate(IList<IAsset> assets) { | |
foreach (IAsset asset in assets) { | |
Translate(asset); | |
} | |
return assets; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Add relevant bits to your web config and fix namespaces/assembly names --> | |
<?xml version="1.0" encoding="utf-8"?> | |
<configuration> | |
<system.web> | |
<httpHandlers> | |
<add path="*.handlebars" verb="GET" type="yournamespace.HandlebarsAssetHandler, yourassembly" /> | |
</httpHandlers> | |
</system.web> | |
<system.webServer> | |
<handlers> | |
<add name="HandlebarsAssetHandler" path="*.handlebars" verb="GET" type="yournamespace.HandlebarsAssetHandler, yourassembly" resourceType="File" preCondition="" /> | |
</handlers> | |
</system.webServer> | |
<bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd"> | |
<core> | |
<js> | |
<translators> | |
<add name="HandlebarsTranslator" type="yournamespace.HandlebarsTranslator, yourassembly" enabled="true" /> | |
</translators> | |
</js> | |
</core> | |
</bundleTransformer> | |
</configuration> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This example turns out to be buggy for production use, but can be used as a starting point.