Improve this doc

Client-Side Templates

Client-side templates generate HTML in the browser, allowing SocketStream to send raw, layoutless data over the websocket. This not only dramatically reduces bandwidth, but also gives you flexibility to render the data into HTML in any number of ways.

Why use client-side templates?

If your app is really simple, you might be happy manually building your HTML using jQuery functions:

// client/code/main/index.js
var people = [
  { name: 'Alice', major: 'Astronomy'},
  { name: 'Bob', major: 'Biology' }
];

$(document).ready(function() {
  var i;

  for (i = 0; i < people.length; i++) {
    $('#people').append("<li>" + people[i].name + " the student studies <strong>" +
      people[i].major + "</strong></li>"
    );
  }
});

However, not only does this solution scale poorly for larger templates, but mixing together display logic and HTML is bad practice. Enter client-side templates.

Template Engines

SocketStream supports two types of client-side template engines out-of-the-box:

ember

Outputs inline templates in the correct format for Ember.js.

angular

Outputs inline templates in the correct format for Angular.js.

default

Simply wraps each template in a DIV tag with an ID prefix of 'tmpl-'. Suitable for use with many template engines, including jQuery Templates (as used by SocketStream 0.2).

To use a built-in template engine, pass the name as a string:

ss.client.templateEngine.use('ember');

As built-in template engines are only simple wrappers, most of the time you'll want to use one of the several template languages supported via optional modules on npm:

To use an external optional template engine, pass the module as so:

ss.client.templateEngine.use(require('ss-hogan'));

If you can't find a module for your favorite templating library it's easy to create your own.

Mix and match different template engines

All client-side templates live in the client/templates folder; however you don't have to serve every template with the same engine.

SocketStream allows you to mix and match different templates, perfect for trying out something like Ember.js without having to convert all your exiting templates over at once.

You may limit the scope of a template engine by passing the name of a directory as the second argument.

// serve all templates with ss-hogan
ss.client.templateEngine.use(require('ss-hogan'));
// apart from any in the /client/ember directory
ss.client.templateEngine.use('ember', './ember');

The new style of SocketStream is to use relative paths from the client directory. The default destinations for templates still work as shown below. However it is a good habit to specify the directory with the new notation style. If you want to have templates outside the client, you can access the project directory with the ../ prefix.

// serve all templates with ss-hogan
ss.client.templateEngine.use(require('ss-hogan'));
// apart from any in the /client/templates/em directory
ss.client.templateEngine.use('ember', '/em');

Example

Here we're using the Hogan templating library, using the ss-hogan module bundled by default when you create a new project.

In this folder, let's create a file called person.html:

<!-- client/templates/person.html -->
<li>{{ name }} the student studies <strong>{{ major }}</strong></li>

NOTE: If you prefer, you may use a formatter to construct your HTML templates. For example, to use Jade, use .jade instead of .html for your template's file extension.

If you refresh the page and view the HTML source code you'll see a new <script> tag containing the compiled template.

The person.html file in the templates folder is now accessible via ss.tmpl['person']. If the file was in a subdirectory model/person.html, then it would be accessible via ss.tmpl['model-person'].

Now that we have a template, let's put it to good use by refactoring our code:

// in your client-side code
var people = [
  { name: 'Alice', major: 'Astronomy'},
  { name: 'Bob', major: 'Biology' }
];

$(document).ready(function() {
  var i;

  for (i = 0; i < people.length; i++) {
    $('#people').append(ss.tmpl['person'].render(people[i]));
  }
});

Serving different templates to different clients

By default all templates will be sent to all single-page clients you define with:

ss.client.define()

However, by organizing your templates into directories, you can specify which templates will be sent to each client as so:

// app.js
ss.client.define('iphone', {
  view: 'app.jade',
  css:  ['libs', 'app.styl'],
  code: ['libs', 'app'],
  tmpl: ['main', 'mobile']  // will only send templates in the 'main' and 'mobile' directories
});