Skip to content

Client Side Plating

mwawrusch edited this page Nov 18, 2011 · 21 revisions

WORK IN PROGRESS

This page attempts to give useful tips on how to use Plates in a client side environment when developing single page apps.

How can I get my templates into the browser?

There are several options, each one with pros and cons.

Include the plates' html in the script

When does it make sense?

This is a great solution for scripts that are driven by functionality and less layout. Think about a small label indicator using twitters bootstrap or something similar. There is really not much in terms of value that could be derived from storing this anywhere but within the javascript itself.

Downsides

This tends to get messy as soon as you have more complex html, especially if the html makes use of YOUR css versus a pre-built css library like bootstrap, where changes of class names won't happen.

Sample

//NOTE: Trying hard to convince github to render this correctly
var html, data,bound;
data = {...};
html = "<span class=\\"label\\">Label</span>";
bound = Plates.bind(html,data);

(code)

Include individual plates' html as part of the dom, but hidden

You can always include your scripts as html, setting it's visibility to hidden in your css. This is a good solution that will work for a lot of scenarios. Designers will love it because they can WYSIWIG the elements, and it is visually pleasing.

Downsides

There is one major downside and that is the possible interference with third party plugins, for example jQuery plugins or even your own code. You want this to be a template, not live code. One way of dealing with this is to take the templates out of the dom and store them in a caching object of yours. This has to be done before you instantiate any jQuery plugins.

Sample

<style>
  .templates { display: none }
</style>

(css)

<div class="templates">
  <div id="template1">...</div>
  <span id="template2">...</span>
</div>

(html)

// NOTE: Should not be text() but outerText(), need to look that up.
// demonstrate removal from dom and local caching eventually
var html, data,bound;
data = {...};
html = $("#template1").text();
bound = Plates.bind(html,data);

(code)

Include individual plates' html embedded in a script tag

An approach somewhat similar to the previous one is to make use of the script tag and set the mime type to "text/x-plates-tmpl" (It could actually be anything text/* like, but we settled on that convention). This stores the html as a text string that can be referenced in your html through the usual dom manipulation functions. The example below shows a jQuery version.

Downsides

  • You do have a sea of script tags, it does not look so good in your html.
  • The html is not validated in the browser, as it is text. Some people use languages like haml or jade to create the templates which ensure correct html output.
  • You do not have WYSIWIG.

Sample

<script id="template1" type="text/x-plates-tmpl">
 <div>...</div>
</script>
<script id="template2" type="text/x-plates-tmpl">
 <span>...</span>
</script>

(html)

var html, data,bound;
data = {...};
html = $("#template1").text();
bound = Plates.bind(html,data);

(code)

Include a combined plates' html as part of the dom, but hidden

This approach is for design heavy single page apps that need full WYSIWIG during the design phase. To achieve that we bascally create one template that contains the whole page, with all states, and embeds it"s sub templates directly. During load a small script needs to split the template into individual templates for processing.

Sample

<style>
  .templates { display: none }
</style>

(css)

<div class="templates">
  <div id="template1" class='template'>
    <ul id="someList">
      <li id="template2" class='template'>... Some list item style here ...</li>
      <li id="template3" class='template'>... A different template for the list item ... </li>

    </ul>
  </div>
</div>

(html)

var html, data,bound, templates = {};

// Magic code that splits the above html into individual templates goes here.

data = {...};
html = templates["template1"];
bound = Plates.bind(html,data);

(code)