MVC How to bundle html templates of type "text/html"?

3.1k Views Asked by At

I have a series of template files (*.html) that are used by some JS components. Instead of having those JS components write the templates to the DOM when loaded, I wanted to bundle them together like scripts and have them downloaded separately by the client. This way should be faster (clientside), allow for caching (less round trips), and be more readable (template doesn't have to be stored in a JS string which breaks highlighting/intellisense).

How can this be accomplished?

1

There are 1 best solutions below

0
On

I. Use BundleTransformer [http://bundletransformer.codeplex.com/] and Mustache templates [https://mustache.github.io/] or Handlebars [http://handlebarsjs.com/]

II. [Angular example but you can inspire a lot]

I'm not saying this is the best approach for your case, but i cannot left it like a comment.

Here is an example where the OP stores his bundle in $templateCache. Angular has a templateCache object, which stores all the templates it has loaded so far. It also lets you pre-load templates into the template cache.

Create a BundleTransform class, as he did:

public class PartialsTransform : IBundleTransform
    {
        private readonly string _moduleName;
        public PartialsTransform(string moduleName)
        {
            _moduleName = moduleName;
        }

        public void Process(BundleContext context, BundleResponse response)
        {
            var strBundleResponse = new StringBuilder();
            // Javascript module for Angular that uses templateCache 
            strBundleResponse.AppendFormat(
                @"angular.module('{0}').run(['$templateCache',function(t){{",
                _moduleName);

            foreach (var file in response.Files)
            {
                // Get the partial page, remove line feeds and escape quotes
                var content = File.ReadAllText(file.FullName)
                    .Replace("\r\n", "").Replace("'", "\\'");
                // Create insert statement with template
                strBundleResponse.AppendFormat(
                    @"t.put('partials/{0}','{1}');", file.Name, content);
            }
            strBundleResponse.Append(@"}]);");

            response.Files = new FileInfo[] {};
            response.Content = strBundleResponse.ToString();
            response.ContentType = "text/javascript";
        }
    }

But you can store the templates where you want [i don't know where you want to store them].

Then create a Bundle.

public class PartialsBundle : Bundle
    {
        public PartialsBundle(string moduleName, string virtualPath)
            : base(virtualPath, new[] { new PartialsTransform(moduleName) })
        {
        }
    }

And you can use it like a ScriptBundle or StyleBundle.

bundles.Add(new PartialsBundle("testSPA", "~/bundles/partials").Include(
        "~/Partials/nav-bar.html",
        "~/Partials/home-page.html",
        "~/Partials/investment-filter.html",
        "~/Partials/investments-component.html",
        "~/Partials/sector-component.html",
        "~/Partials/transactions-component.html"));

And render like this: @Scripts.Render("~/bundles/partials")

In production transforming in this:

<script src="/bundles/partials?v=dq0i_tF8ogDVZ0X69xyBCdV2O2Qr3nCu0iVsatAzhq41"></script>

This guy is using the $templateCache object forcing Angular not to dynamically download template when are needed.

Further reading here: http://blog.scottlogic.com/2014/08/18/asp-angular-optimisation.html