docs/partials/tutorials/defining_multiple_clients.html
<a href="https://github.com/socketstream/socketstream/edit/master/src/docs/tutorials/en/defining_multiple_clients.ngdoc" class="improve-docs"><i class="icon-edit"> </i>Improve this doc</a><h1><code ng:non-bindable=""></code>
<div><span class="hint"></span>
</div>
</h1>
<div><div class="defining-multiple-clients-page"><h2 id="defining-multiple-single-page-clients">Defining Multiple Single-Page Clients</h2>
<p>SocketStream is exclusively a single-page framework; however we make it easy to define multiple single-page clients to be sent to different devices (e.g. desktop browsers and iPhones), or to be served on different URLs (useful for providing an /admin interface).</p>
<p>New clients are defined with the <code>ss.client.define()</code> function in your <code>app.js</code> file. You may define as many as you like, just be sure to give each one a unique name (passed to the first argument).</p>
<h4 id="defining-multiple-single-page-clients_default-settings">Default settings</h4>
<p>A single-page client consist of one HTML view and multiple CSS, client-side code and template files.</p>
<p>When you create a new SocketStream project we define a client called <code>main</code> for you with the following options:</p>
<pre class="prettyprint linenums">
// in app.js
ss.client.define('main', {
view: 'app.html',
css: ['libs/reset.css', 'app.styl'],
code: ['libs/jquery.min.js', 'app'],
tmpl: '*'
});
</pre>
<p>For each type of asset you may provide one or more file names or directory names. When passing directory names, the contents of the directory (including any sub-directories) will be served alphanumerically.</p>
<p>Let's look more closely at each type of asset:</p>
<h6 id="defining-multiple-single-page-clients_default-settings_view">view</h6>
<p>A view is the initial HTML sent to the browser which provides layout and structure for your app. View files are stored in <code>/client/views</code>. Due to the nature of a single-page application, you may only specify one view for each client you define.</p>
<h6 id="defining-multiple-single-page-clients_default-settings_css">css</h6>
<p>CSS files live in <code>/client/css</code>. This option allows you to specify as many files or directories as you wish. As order is important when serving CSS, you'll need to make sure any CSS libraries (e.g. <code>reset.css</code>) are sent before your application stylesheets.</p>
<p>Note: If you're using Stylus (highly recommended!), you'll only need to specify the first <code>.styl</code> file here as any additional files can be imported using the <code>@import</code> command. If you're using plain CSS, you'll need to list each <code>.css</code> file individually or pass the name of a directory instead.</p>
<h6 id="defining-multiple-single-page-clients_default-settings_code">code</h6>
<p>Client-side code lives in <code>/client/code</code>. This option allows you to specify as many files or directories as you wish to be sent to the client upon initial connection.</p>
<p>Important: Modules are always mounted to the root (/) namespace, even if you specify nested directories. Hence if you specify <code>code: ['iphone/new_release']</code>, and have a module in here called <code>calendar.js</code> you will require this module as <code>require('/calendar')</code> in your app, not <code>require('/iphone/new_release/calendar')</code>. </p>
<p>Not all code has to be sent upon initial connection - you may prefer to <a href="#/tutorials/loading_assets_on_demand">load modules on demand</a>.</p>
<h6 id="defining-multiple-single-page-clients_default-settings_tmpl">tmpl</h6>
<p>Client-side Templates live in <code>/client/templates</code>. This option allows you to specify multiple files or directories of templates to be sent to the client upon initial connection. Note the <code>*</code> means send everything.</p>
<h4 id="defining-multiple-single-page-clients_defining-a-new-client">Defining a new client</h4>
<p>For this example let's imagine we want to define a new single-page client to be sent to an iPhone:</p>
<pre class="prettyprint linenums">
ss.client.define('iphone', {
view: 'iphone.jade',
css : ['libs/reset.css', 'iphone.styl'],
code: ['libs/jquery.min.js', 'app'],
tmpl: 'iphone'
});
</pre>
<p>Here we're not only specifying a different view (<code>/client/views/iphone.jade</code>) but we're also choosing to send different CSS and client-side templates, though in this example we've not changed the client-side code we're sending.</p>
<h4 id="defining-multiple-single-page-clients_serving-different-clients">Serving different clients</h4>
<p>Once you've defined a single-page client you can choose to serve it on a particular URL:</p>
<pre class="prettyprint linenums">
// short format
ss.http.route('/').serveClient('main');
// long format
ss.http.route('/iphone', function(req, res) {
res.serveClient('iphone');
});
</pre>
<p>or depending upon the browser's UserAgent:</p>
<pre class="prettyprint linenums">
ss.http.route('/', function(req, res) {
if (req.headers['user-agent'].match(/iPhone/))
res.serveClient('iphone');
else
res.serveClient('main');
});
</pre>
<h4 id="defining-multiple-single-page-clients_sharing-common-code">Sharing common code</h4>
<p>Typically you'll want to divide all your assets into three sections: Those to be served to desktop clients, those for to be served to mobile clients, and those to be shared by both.</p>
<p>Hence a typical desktop/iPhone config may look something like this:</p>
<pre class="prettyprint linenums">
ss.client.define('desktop', {
view: 'desktop.jade',
css: ['common/libs', 'desktop/libs', 'desktop.styl'],
code: ['common/libs', 'desktop/libs', 'common/app', 'desktop/app'],
tmpl: ['common', 'desktop']
});
ss.client.define('iphone', {
view: 'iphone.jade',
css: ['common/libs', 'iphone/libs', 'iphone.styl'],
code: ['common/libs', 'iphone/libs', 'common/app', 'iphone/app'],
tmpl: ['common', 'iphone']
});
</pre>
<p>As you can see, SocketStream gives you the flexibility and power to mix and match client-side assets for any possible combination of devices or pages without having to duplicate code.</p>
</div></div>