How to combine templates from different HTML files

Since individual Knockout templates are stored in script tags, I thought I could set the src attribute of the tag and load the HTML from a separate file. It just didn’t work out naively, so

  • There's some trick to associate templates with the src tag that I need to use
  • There is another way to load templates from different files.

(The other two options are 3, it is expected that all programmers of this project will modify the same giant file that will be loaded by the browser at startup, and 4, do not use Knockoutjs for anything more than a toy project - I consider it equivalent.)

+8
source share
2 answers

The browser will not respond to src for anything that has a type other than one of the various javascript types, and with those that it tries to execute the result as a script.

Several variants:

+11
source share

Each template in my project is its own html file. I use the naming convention (* .ko.html) to identify them. My build chain is as follows:

Step 1: Lint and minify * .ko.html files This is easy to remove comments (except for <!-- ko --> ones) and remove extra spaces for a more compact payload.

Step 2: Stringify and concat minified html to js file. Js looks something like

 var templates={ 'name1':'some stringified html', 'name2':'some more' }; 

I was considering concatenating into an html file with <script type="text/plain"> delimiters, but chose js because in this way it can be loaded using a simple <script> instead of ajax get + inject.

Step 3: Fix your own template engine to extract templates from my js object.

 var engine = new ko.nativeTemplateEngine(); engine._makeTemplateSource = engine.makeTemplateSource; engine.makeTemplateSource = function (template, doc) { if (typeof (template) === 'string' && templates[template]) { return { text: function () { return templates[template]; } }; } return engine._makeTemplateSource(template, doc); }; ko.setTemplateEngine(engine); 

My implementation uses gruntjs to complete these build steps. (grunt-contrib-htmlmin, grunt-contrib-concat)

for htmlmin:

 { removeComments: true, collapseWhitespace: true, ignoreCustomComments: [/^\s*ko /, /^\s*\/ko /] } 

parameters for concat

 { stripBanners: true, banner: "(function(t){", footer: "})(window.templates || (window.templates={}));", process: function (src, file) { return 't[\'' + file.replace(/^.*\//, '').replace('.ko.html', '') + '\']=' + JSON.stringify(src) + ';'; } } 

For some, it’s interesting why someone wants to do this: The source template files are standard separate html files that can be edited in any html editor and source controlled as such. Editing html inside <script> tags is not fun. As a bonus, source files may include comments that will be deleted. Templates can be reused on any page by including the script tag: they do not need to be embedded in each page. The resulting package is a static file that browsers can easily cache, but templates embedded in a dynamically generated page cannot. Almost the same reasons for linking javascript files.

+1
source share

All Articles