{"id":237,"date":"2013-07-24T13:02:47","date_gmt":"2013-07-24T02:02:47","guid":{"rendered":"https:\/\/mindbleach.com\/words\/?p=237"},"modified":"2013-08-09T15:30:02","modified_gmt":"2013-08-09T04:30:02","slug":"javascript-templates-using-src","status":"publish","type":"post","link":"https:\/\/mindbleach.com\/words\/2013\/07\/24\/javascript-templates-using-src\/","title":{"rendered":"Javascript Templates Using &#8216;src&#8217;"},"content":{"rendered":"<h1>Background<\/h1>\n<p><a title=\"Javascript Micro Templating\" href=\"http:\/\/ejohn.org\/blog\/javascript-micro-templating\/\" target=\"_blank\">John Resig<\/a> was the first to document a technique for storing templates in &lt;script&gt; tags;<\/p>\n<pre class=\"brush: html; gutter: true\">&lt;script type=&quot;text\/html&quot; id=&quot;item_template&quot;&gt;\r\n   &lt;li&gt;&lt;b&gt;{{ name }}&lt;\/b&gt; - {{ description }}&lt;\/li&gt;\r\n&lt;\/script&gt;<\/pre>\n<p>This works well for several reasons;<\/p>\n<ol>\n<li>Using the unknown type &#8220;text\/html&#8221; means that the browser ignores it.<\/li>\n<li>Giving the tag an id allows us to easily grab its contents;<\/li>\n<\/ol>\n<pre class=\"brush: javascript; gutter: true\">\/\/Build a new item, and add it to the list\r\n\/\/Using JQuery, Underscore.js\r\nvar contents = _.template(\r\n  $(&quot;#item_template&quot;).html(),\r\n  {name: &quot;Foo&quot;, description:&quot;Sir Foo the Second&quot;}\r\n);\r\n$list.append( $(contents) );<\/pre>\n<p>Today there are many libraries available for retrieving and building templates in this way, such as <a href=\"https:\/\/github.com\/janl\/mustache.js\/\" target=\"_blank\">Mustache.js<\/a> and <a href=\"http:\/\/icanhazjs.com\/\" target=\"_blank\">ICanHaz.js<\/a>, and more that integrate support.<\/p>\n<h1>Problem<\/h1>\n<p>One of the only problems with this technique, is that the scripts must be declared inline.<\/p>\n<pre class=\"brush: html; gutter: true\">&lt;!-- Works! --&gt;\r\n&lt;script type=&quot;text\/html&quot; id=&quot;item_template&quot;&gt;\r\n   &lt;li&gt;&lt;b&gt;{{ name }}&lt;\/b&gt; - {{ description }}&lt;\/li&gt;\r\n&lt;\/script&gt;\r\n\r\n&lt;!-- Doesn&#039;t work. --&gt;\r\n&lt;script type=&quot;text\/html&quot; id=&quot;item_template2&quot; \r\n                  src=&quot;templates\/item2.html&quot;&gt;&lt;\/script&gt;<\/pre>\n<p>If the browser doesn&#8217;t understand the type, it won&#8217;t load the source. Whatever the reason, the template text is never added to the DOM.<\/p>\n<p>Inlining template contents is detrimental to readability, maintainability, and traceability.<\/p>\n<p>Some libraries offer asynchronous methods for loading templates. (require.js among them) Some have issues with complexity and performance.<\/p>\n<p>It feels natural to define and <strong>compile <\/strong>the template functions at class definition time. Other solutions may add unnecessary layers of indirection.<\/p>\n<h1>Solution<\/h1>\n<p>I&#8217;ll preface this by saying <em>&#8220;Okay, maybe this won&#8217;t work for you&#8221;<\/em>, but so far it&#8217;s working well, transparently, and fast. And when you go to production, a decent deployment optimisation process will inline the templates anyway.<\/p>\n<p>What if the src attributes <strong>were <\/strong>read properly?<\/p>\n<pre class=\"brush: html; gutter: true\">&lt;script type=&quot;text\/html&quot; id=&quot;template_widgets&quot;\r\n                    src=&quot;templates\/widgets.html&quot;&gt;&lt;\/script&gt;\r\n&lt;script type=&quot;text\/html&quot; id=&quot;template_widgets_item \r\n                    src=&quot;templates\/widgets_item.html&quot;&gt;&lt;\/script&gt;\r\n...\r\n...\r\n&lt;script type=&quot;text\/javascript&quot;&gt;\r\n  \/\/Synchronously load the templates\r\n  var $templates = $(&#039;script[type=&quot;text\/html&quot;]&#039;);\r\n  $templates.each(function() { \r\n    \/\/Only get non-inline templates\r\n    \/\/No need to change code for production.\r\n    if ($(this).attr(&quot;src&quot;)) { \r\n      $.ajax(\r\n        $(this).attr(&quot;src&quot;), \r\n        {\r\n          async:false, \r\n          context:this, \r\n          success:function(data) { $(this).html(data); }\r\n        }\r\n      );\r\n    }\r\n  });\r\n  \/\/From this point onwards (in the same script, in the \r\n  \/\/following scripts) all the &quot;text\/html&quot; script tags \r\n  \/\/will be loaded as if they were inline.\r\n&lt;\/script&gt;<\/pre>\n<p>Just insert this code <strong>after<\/strong> all your template tags, and <strong>before<\/strong> you build your template functions, and you&#8217;ll be able to treat them as if they were inline all along.<\/p>\n<p>Easy.* \ud83d\ude42<\/p>\n<p>*There are some downsides to loading template serially and synchronously. I&#8217;ve written a follow-up article <a title=\"More Javascript Templates Using \u2018src\u2019\" href=\"https:\/\/mindbleach.com\/words\/more-javascript-templates-using-src\/\">that discusses a technically better solution<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Background John Resig was the first to document a technique for storing templates in &lt;script&gt; tags; &lt;script type=&quot;text\/html&quot; id=&quot;item_template&quot;&gt; &lt;li&gt;&lt;b&gt;{{ name }}&lt;\/b&gt; &#8211; {{ description }}&lt;\/li&gt; &lt;\/script&gt; This works well for several reasons; Using the unknown type &#8220;text\/html&#8221; means that &hellip; <a href=\"https:\/\/mindbleach.com\/words\/2013\/07\/24\/javascript-templates-using-src\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,11],"tags":[17,22,20,21,19,18,23],"class_list":["post-237","post","type-post","status-publish","format-standard","hentry","category-javascript-programming","category-programming","tag-javascript","tag-mustache","tag-remote","tag-resource","tag-tag","tag-template","tag-underscore"],"_links":{"self":[{"href":"https:\/\/mindbleach.com\/words\/wp-json\/wp\/v2\/posts\/237"}],"collection":[{"href":"https:\/\/mindbleach.com\/words\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mindbleach.com\/words\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mindbleach.com\/words\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mindbleach.com\/words\/wp-json\/wp\/v2\/comments?post=237"}],"version-history":[{"count":10,"href":"https:\/\/mindbleach.com\/words\/wp-json\/wp\/v2\/posts\/237\/revisions"}],"predecessor-version":[{"id":261,"href":"https:\/\/mindbleach.com\/words\/wp-json\/wp\/v2\/posts\/237\/revisions\/261"}],"wp:attachment":[{"href":"https:\/\/mindbleach.com\/words\/wp-json\/wp\/v2\/media?parent=237"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mindbleach.com\/words\/wp-json\/wp\/v2\/categories?post=237"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mindbleach.com\/words\/wp-json\/wp\/v2\/tags?post=237"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}