Files
express/docs/guide.html

1808 lines
63 KiB
HTML

<html>
<head>
<title>Express - node web framework</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<style>
#tagline {
margin-left: 75px;
margin-bottom: 30px;
color: rgba(255,255,255,0.7); }
html {
background: #1c1c1c url(images/bg.tile.jpg); }
body {
margin: 0;
padding-bottom: 30px;
font: 14px/1.4 "Helvetica Neue", "Lucida Grande", "Arial";
font-size: 14px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
background: url(images/bg.jpg) 50% 0 no-repeat;
color: #8b8b8b; }
* {
outline: none; }
em {
color: white; }
a img {
border: none !important; }
a {
font-weight: bold;
text-decoration: none;
color: white;
-webkit-transition-property: opacity, -webkit-transform, color, background-color, padding, -webkit-box-shadow;
-webkit-transition-duration: 0.15s;
-webkit-transition-timing-function: ease-out; }
a:hover {
opacity: 0.8; }
h1, h2, h3, h4 {
margin: 45px 0 0 0;
color: white;
text-shadow: 1px 2px 2px rgba(0,0,0,0.6); }
h3 {
font-size: 18px; }
h4 {
margin-left: 10px;
font-size: 14px;
}
pre {
margin: 20px 10px;
padding: 25px 20px;
background: rgba(0,0,0,0.5);
border: 1px solid #323232;
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
-webkit-border-radius: 5px;
-moz-border-radius: 5px; }
code {
font-family: "Helvetica Neue", "Lucida Grande", "Arial"; }
ul {
margin: 15px 0;
padding: 0 0 0 35px; }
ul li {
margin: 0;
padding: 2px 0;
list-style: square; }
ul li ul {
margin: 0;
padding-left: 12px;
}
.man-name, #Express { display:none; }
.sect {
margin-left: 40px; }
img {
margin-left: 20px;
margin-bottom: 15px;
}
#logo {
display: block;
margin-left: 30%;
margin-bottom: 30px;
width: 194px;
height: 51px;
background: url(images/logo.png) 0 0 no-repeat;
text-indent: -99999px; }
#logo:hover {
opacity: 0.7; }
#logo:active {
opacity: 0.3; }
#ribbon {
position: fixed;
top: 0;
right: 0;
z-index: 2; }
#wrapper {
width: 100%;
min-height: 800px;
background: url(images/top.png) 0 0 repeat-x; }
#container {
margin: 0 auto;
padding-top: 80px;
width: 550px; }
#toc {
position: fixed;
top: 0;
left: 0;
margin: 0 0 0 15px;
padding: 15px;
height: 100%;
background: rgba(0,0,0,0.2);
overflow: auto;
border-right: 1px solid rgba(255,255,255,0.05);
}
#toc li {
padding: 0;
list-style: none;
}
#toc li a {
font-size: 11px;
}
#menu {
margin-left: 75px;
padding: 0;
padding-bottom: 30px; }
#menu li {
display: inline;
list-style: none; }
#menu li a {
display: block;
float: left;
margin: 0 2px;
padding: 3px 15px;
background: rgba(0,0,0,0.2);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
-webkit-transition-property: opacity, -webkit-transform, color, background-color, -webkit-box-shadow;
-webkit-transition-duration: 0.15s;
-webkit-transition-timing-function: ease-out; }
#menu li a:hover,
#menu li a.active {
background: rgba(0,0,0,0.5); }
#menu li a:active {
background: rgba(0,0,0,0.1);
-webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.4);
-moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.4); }
</style>
<script>
$(function(){
$('.section').hide();
$('.toggle, a.section-title').toggle(function(){
$(this).siblings('ul').fadeIn(300);
return false;
}, function(){
$(this).siblings('ul').fadeOut(300);
return false;
});
});
</script>
</head>
<body>
<a href='http://github.com/visionmedia/express'>
<img alt='Fork me on GitHub' id='ribbon' src='http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png' />
</a>
<div id="wrapper">
<div id="container"><ul id="toc">
</ul><ul id="toc">
<li><a href="#installation">Installation</a></li>
<li><a href="#creating-a server">Creating A Server</a></li>
<li><a href="#creating-an https server">Creating An HTTPS Server</a></li>
<li><a href="#configuration">Configuration</a></li>
<li><a href="#settings">Settings</a></li>
<li><a href="#routing">Routing</a></li>
<li><a href="#passing-route control">Passing Route Control</a></li>
<li><a href="#middleware">Middleware</a></li>
<li><a href="#route-middleware">Route Middleware</a></li>
<li><a href="#http-methods">HTTP Methods</a></li>
<li><a href="#error-handling">Error Handling</a></li>
<li><a href="#route-param pre-conditions">Route Param Pre-conditions</a></li>
<li><a href="#view-rendering">View Rendering</a></li>
<li><a href="#view-partials">View Partials</a></li>
<li><a href="#view-lookup">View Lookup</a></li>
<li><a href="#template-engines">Template Engines</a></li>
<li><a href="#session-support">Session Support</a></li>
<li><a href="#migration-guide">Migration Guide</a></li>
<li><a href="#" class="toggle">+</a> <a class="section-title" href="#">Request</a><ul class="section" id="section-Request">
<li><a href="#req.header()">header()</a></li>
<li><a href="#req.accepts()">accepts()</a></li>
<li><a href="#req.is()">is()</a></li>
<li><a href="#req.param()">param()</a></li>
<li><a href="#req.get()">get()</a></li>
<li><a href="#req.flash()">flash()</a></li>
<li><a href="#req.isxmlhttprequest">isXMLHttpRequest</a></li>
</ul></li>
<li><a href="#" class="toggle">+</a> <a class="section-title" href="#">Response</a><ul class="section" id="section-Response">
<li><a href="#res.header()">header()</a></li>
<li><a href="#res.charset">charset</a></li>
<li><a href="#res.contenttype()">contentType()</a></li>
<li><a href="#res.attachment()">attachment()</a></li>
<li><a href="#res.sendfile()">sendfile()</a></li>
<li><a href="#res.download()">download()</a></li>
<li><a href="#res.send()">send()</a></li>
<li><a href="#res.redirect()">redirect()</a></li>
<li><a href="#res.cookie()">cookie()</a></li>
<li><a href="#res.clearcookie()">clearCookie()</a></li>
<li><a href="#res.render()">render()</a></li>
<li><a href="#res.partial()">partial()</a></li>
<li><a href="#res.local()">local()</a></li>
<li><a href="#res.locals()">locals()</a></li>
</ul></li>
<li><a href="#" class="toggle">+</a> <a class="section-title" href="#">Server</a><ul class="section" id="section-Server">
<li><a href="#app.set()">set()</a></li>
<li><a href="#app.enable()">enable()</a></li>
<li><a href="#app.enabled()">enabled()</a></li>
<li><a href="#app.disable()">disable()</a></li>
<li><a href="#app.disabled()">disabled()</a></li>
<li><a href="#app.configure()">configure()</a></li>
<li><a href="#app.redirect()">redirect()</a></li>
<li><a href="#app.error()">error()</a></li>
<li><a href="#app.helpers()">helpers()</a></li>
<li><a href="#app.dynamichelpers()">dynamicHelpers()</a></li>
<li><a href="#app.lookup">lookup</a></li>
<li><a href="#app.match">match</a></li>
<li><a href="#app.mounted()">mounted()</a></li>
<li><a href="#app.register()">register()</a></li>
<li><a href="#app.listen()">listen()</a></li>
</ul></li>
</ul>
<a href='http://github.com/visionmedia/express' id='logo'>Express</a>
<p id="tagline">
High performance, high class web development for
<a href="http://nodejs.org">Node.js</a>
</p>
<ul id="menu">
<li><a href="index.html">Home</a></li>
<li><a href="guide.html">Guide</a></li>
<li><a href="screencasts.html">Screencasts</a></li>
<li><a href="applications.html">Applications</a></li>
</ul>
<h3 id="installation">Installation</h3>
<pre><code>$ npm install express
</code></pre>
<p>or to access the <code>express(1)</code> executable install globally:</p>
<pre><code>$ npm install -g express
</code></pre>
<h2>Quick Start</h2>
<p> The quickest way to get started with express is to utilize the executable <code>express(1)</code> to generate an application as shown below:</p>
<p> Create the app:</p>
<pre><code>$ npm install -g express
$ express /tmp/foo &amp;&amp; cd /tmp/foo
</code></pre>
<p> Install dependencies:</p>
<pre><code>$ npm install -d
</code></pre>
<p> Start the server:</p>
<pre><code>$ node app.js
</code></pre>
<h3 id="creating-a server">Creating A Server</h3>
<p> To create an instance of the <em>express.HTTPServer</em>, simply invoke the <em>createServer()</em> method. With our instance <em>app</em> we can then define routes based on the HTTP verbs, in this example <em>app.get()</em>.</p>
<pre><code>var app = require('express').createServer();
app.get('/', function(req, res){
res.send('hello world');
});
app.listen(3000);
</code></pre>
<h3 id="creating-an https server">Creating An HTTPS Server</h3>
<p> To initialize a <em>express.HTTPSServer</em> we do the same as above, however we
pass an options object, accepting <em>key</em>, <em>cert</em> and the others mentioned in node&rsquo;s <a href="http://nodejs.org/docs/v0.3.7/api/https.html#https.createServer">https documentation</a>.</p>
<pre><code> var app = require('express').createServer({ key: ... });
</code></pre>
<h3 id="configuration">Configuration</h3>
<p>Express supports arbitrary environments, such as <em>production</em> and <em>development</em>. Developers
can use the <em>configure()</em> method to setup needs required by the current environment. When
<em>configure()</em> is called without an environment name it will be run in <em>every</em> environment
prior to the environment specific callback.</p>
<p>In the example below we only <em>dumpExceptions</em>, and respond with exception stack traces
in <em>development</em> mode, however for both environments we utilize <em>methodOverride</em> and <em>bodyParser</em>.
Note the use of <em>app.router</em>, which can (optionally) be used to mount the application routes,
otherwise the first call to <em>app.get()</em>, <em>app.post()</em>, etc will mount the routes.</p>
<pre><code>app.configure(function(){
app.use(express.methodOverride());
app.use(express.bodyParser());
app.use(app.router);
});
app.configure('development', function(){
app.use(express.static(__dirname + '/public'));
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
var oneYear = 31557600000;
app.use(express.static(__dirname + '/public', { maxAge: oneYear }));
app.use(express.errorHandler());
});
</code></pre>
<p>For internal and arbitrary settings Express provides the <em>set(key[, val])</em>, <em>enable(key)</em>, <em>disable(key)</em> methods:</p>
<pre><code> app.configure(function(){
app.set('views', __dirname + '/views');
app.set('views');
// =&gt; "/absolute/path/to/views"
app.enable('some feature');
// same as app.set('some feature', true);
app.disable('some feature');
// same as app.set('some feature', false);
app.enabled('some feature')
// =&gt; false
});
</code></pre>
<p>To alter the environment we can set the <em>NODE_ENV</em> environment variable, for example:</p>
<pre><code>$ NODE_ENV=production node app.js
</code></pre>
<p>This is <em>very</em> important, as many caching mechanisms are <em>only enabled</em> when in production.</p>
<h3 id="settings">Settings</h3>
<p>Express supports the following settings out of the box:</p>
<ul>
<li><em>home</em> Application base path used for <em>res.redirect()</em> and transparently handling mounted apps.</li>
<li><em>views</em> Root views directory defaulting to <strong>CWD/views</strong></li>
<li><em>view engine</em> Default view engine name for views rendered without extensions</li>
<li><em>view options</em> An object specifying global view options</li>
<li><em>view cache</em> Enable view caching (enabled in production)</li>
<li><em>case sensitive routes</em> Enable case-sensitive routing</li>
</ul>
<h3 id="routing">Routing</h3>
<p>Express utilizes the HTTP verbs to provide a meaningful, expressive routing API.
For example we may want to render a user&rsquo;s account for the path <em>/user/12</em>, this
can be done by defining the route below. The values associated to the named placeholders
are available as <code>req.params</code>.</p>
<pre><code>app.get('/user/:id', function(req, res){
res.send('user ' + req.params.id);
});
</code></pre>
<p>A route is simple a string which is compiled to a <em>RegExp</em> internally. For example
when <em>/user/:id</em> is compiled, a simplified version of the regexp may look similar to:</p>
<pre><code>\/user\/([^\/]+)\/?
</code></pre>
<p>Regular expression literals may also be passed for complex uses. Since capture
groups with literal <em>RegExp</em>&rsquo;s are anonymous we can access them directly <code>req.params</code>. So our first capture group would be <em>req.params[0]</em> and the second would follow as <em>req.params[1]</em>.</p>
<pre><code>app.get(/^\/users?(?:\/(\d+)(?:\.\.(\d+))?)?/, function(req, res){
res.send(req.params);
});
</code></pre>
<p>Curl requests against the previously defined route:</p>
<pre><code> $ curl http://dev:3000/user
[null,null]
$ curl http://dev:3000/users
[null,null]
$ curl http://dev:3000/users/1
["1",null]
$ curl http://dev:3000/users/1..15
["1","15"]
</code></pre>
<p>Below are some route examples, and the associated paths that they
may consume:</p>
<pre><code> "/user/:id"
/user/12
"/users/:id?"
/users/5
/users
"/files/*"
/files/jquery.js
/files/javascripts/jquery.js
"/file/*.*"
/files/jquery.js
/files/javascripts/jquery.js
"/user/:id/:operation?"
/user/1
/user/1/edit
"/products.:format"
/products.json
/products.xml
"/products.:format?"
/products.json
/products.xml
/products
"/user/:id.:format?"
/user/12
/user/12.json
</code></pre>
<p>For example we can <strong>POST</strong> some json, and echo the json back using the <em>bodyParser</em> middleware which will parse json request bodies (as well as others), and place the result in <em>req.body</em>:</p>
<pre><code>var express = require('express')
, app = express.createServer();
app.use(express.bodyParser());
app.post('/', function(req, res){
res.send(req.body);
});
app.listen(3000);
</code></pre>
<p>Typically we may use a &ldquo;dumb&rdquo; placeholder such as &ldquo;/user/:id&rdquo; which has no restrictions, however say for example we are limiting a user id to digits, we may use <em>&lsquo;/user/:id([0-9]+)&rsquo;</em> which will <em>not</em> match unless the placeholder value contains only digits.</p>
<h3 id="passing-route control">Passing Route Control</h3>
<p>We may pass control to the next <em>matching</em> route, by calling the <em>third</em> argument,
the <em>next()</em> function. When a match cannot be made, control is passed back to Connect,
and middleware continue to be invoked in the order that they are added via <em>use()</em>. The same is true for several routes which have the same path defined, they will simply be executed in order until one does <em>not</em> call <em>next()</em> and decides to respond.</p>
<pre><code>app.get('/users/:id?', function(req, res, next){
var id = req.params.id;
if (id) {
// do something
} else {
next();
}
});
app.get('/users', function(req, res){
// do something else
});
</code></pre>
<p>The <em>app.all()</em> method is useful for applying the same logic for all HTTP verbs in a single call. Below we use this to load a user from our fake database, and assign it to <em>req.user</em>.</p>
<pre><code>var express = require('express')
, app = express.createServer();
var users = [{ name: 'tj' }];
app.all('/user/:id/:op?', function(req, res, next){
req.user = users[req.params.id];
if (req.user) {
next();
} else {
next(new Error('cannot find user ' + req.params.id));
}
});
app.get('/user/:id', function(req, res){
res.send('viewing ' + req.user.name);
});
app.get('/user/:id/edit', function(req, res){
res.send('editing ' + req.user.name);
});
app.put('/user/:id', function(req, res){
res.send('updating ' + req.user.name);
});
app.get('*', function(req, res){
res.send('what???', 404);
});
app.listen(3000);
</code></pre>
<h3 id="middleware">Middleware</h3>
<p>Middleware via <a href="http://github.com/senchalabs/connect">Connect</a> can be
passed to <em>express.createServer()</em> as you would with a regular Connect server. For example:</p>
<pre><code> var express = require('express');
var app = express.createServer(
express.logger()
, express.bodyParser()
);
</code></pre>
<p>Alternatively we can <em>use()</em> them which is useful when adding middleware within <em>configure()</em> blocks, in a progressive manner.</p>
<pre><code>app.use(express.logger({ format: ':method :url' }));
</code></pre>
<p>Typically with connect middleware you would <em>require(&lsquo;connect&rsquo;)</em> like so:</p>
<pre><code>var connect = require('connect');
app.use(connect.logger());
app.use(connect.bodyParser());
</code></pre>
<p>This is somewhat annoying, so express re-exports these middleware properties, however they are <em>identical</em>:</p>
<pre><code>app.use(express.logger());
app.use(express.bodyParser());
</code></pre>
<p>Middleware ordering is important, when Connect receives a request the <em>first</em> middleware we pass to <em>createServer()</em> or <em>use()</em> is executed with three parameters, <em>request</em>, <em>response</em>, and a callback function usually named <em>next</em>. When <em>next()</em> is invoked the second middleware will then have it&rsquo;s turn and so on. This is important to note because many middleware depend on each other, for example <em>methodOverride()</em> checks <em>req.body.</em>method<em> for the HTTP method override, however </em>bodyParser()<em> parses the request body and populates </em>req.body<em>. Another example of this is cookie parsing and session support, we must first </em>use()<em> </em>cookieParser()<em> followed by </em>session()_.</p>
<p>Many Express applications may contain the line <em>app.use(app.router)</em>, while this may appear strange, it&rsquo;s simply the middleware function that contains all defined routes, and performs route lookup based on the current request url and HTTP method. Express allows you to position this middleware, though by default it will be added to the bottom. By positioning the router, we can alter middleware precedence, for example we may want to add error reporting as the <em>last</em> middleware so that any exception passed to <em>next()</em> will be handled by it, or perhaps we want static file serving to have low precedence, allowing our routes to intercept requests to a static file to count downloads etc. This may look a little like below</p>
<pre><code>app.use(express.logger(...));
app.use(express.bodyParser(...));
app.use(express.cookieParser(...));
app.use(express.session(...));
app.use(app.router);
app.use(express.static(...));
app.use(express.errorHandler(...));
</code></pre>
<p>First we add <em>logger()</em> so that it may wrap node&rsquo;s <em>req.end()</em> method, providing us with response-time data. Next the request&rsquo;s body will be parsed (if any), followed by cookie parsing and session support, meaning <em>req.session</em> will be defined by the time we hit our routes in <em>app.router</em>. If a request such as <em>GET /javascripts/jquery.js</em> is handled by our routes, and we do not call <em>next()</em> then the <em>static()</em> middleware will never see this request, however if were to define a route as shown below, we can record stats, refuse downloads, consume download credits etc.</p>
<pre><code>var downloads = {};
app.use(app.router);
app.use(express.static(__dirname + '/public'));
app.get('/*', function(req, res, next){
var file = req.params[0];
downloads[file] = downloads[file] || 0;
downloads[file]++;
next();
});
</code></pre>
<h3 id="route-middleware">Route Middleware</h3>
<p>Routes may utilize route-specific middleware by passing one or more additional callbacks (or arrays) to the method. This feature is extremely useful for restricting access, loading data used by the route etc.</p>
<p>Typically async data retrieval might look similar to below, where we take the <em>:id</em> parameter, and attempt loading a user.</p>
<pre><code>app.get('/user/:id', function(req, res, next){
loadUser(req.params.id, function(err, user){
if (err) return next(err);
res.send('Viewing user ' + user.name);
});
});
</code></pre>
<p>To keep things DRY and to increase readability we can apply this logic within a middleware. As you can see below, abstracting this logic into middleware allows us to reuse it, and clean up our route at the same time.</p>
<pre><code>function loadUser(req, res, next) {
// You would fetch your user from the db
var user = users[req.params.id];
if (user) {
req.user = user;
next();
} else {
next(new Error('Failed to load user ' + req.params.id));
}
}
app.get('/user/:id', loadUser, function(req, res){
res.send('Viewing user ' + req.user.name);
});
</code></pre>
<p>Multiple route middleware can be applied, and will be executed sequentially to apply further logic such as restricting access to a user account. In the example below only the authenticated user may edit his/her account.</p>
<pre><code>function andRestrictToSelf(req, res, next) {
req.authenticatedUser.id == req.user.id
? next()
: next(new Error('Unauthorized'));
}
app.get('/user/:id/edit', loadUser, andRestrictToSelf, function(req, res){
res.send('Editing user ' + req.user.name);
});
</code></pre>
<p>Keeping in mind that middleware are simply functions, we can define function that <em>returns</em> the middleware in order to create a more expressive and flexible solution as shown below.</p>
<pre><code>function andRestrictTo(role) {
return function(req, res, next) {
req.authenticatedUser.role == role
? next()
: next(new Error('Unauthorized'));
}
}
app.del('/user/:id', loadUser, andRestrictTo('admin'), function(req, res){
res.send('Deleted user ' + req.user.name);
});
</code></pre>
<p>Commonly used &ldquo;stacks&rdquo; of middleware can be passed as an array (<em>applied recursively</em>), which can be mixed and matched to any degree.</p>
<pre><code>var a = [middleware1, middleware2]
, b = [middleware3, middleware4]
, all = [a, b];
app.get('/foo', a, function(){});
app.get('/bar', a, function(){});
app.get('/', a, middleware3, middleware4, function(){});
app.get('/', a, b, function(){});
app.get('/', all, function(){});
</code></pre>
<p>For this example in full, view the <a href="http://github.com/visionmedia/express/blob/master/examples/route-middleware/app.js">route middleware example</a> in the repository.</p>
<p>There are times when we may want to &ldquo;skip&rdquo; passed remaining route middleware, but continue matching subsequent routes. To do this we invoke <code>next()</code> with the string &ldquo;route&rdquo; <code>next('route')</code>. If no remaining routes match the request url then Express will respond with 404 Not Found.</p>
<h3 id="http-methods">HTTP Methods</h3>
<p>We have seen <em>app.get()</em> a few times, however Express also exposes other familiar HTTP verbs in the same manner, such as <em>app.post()</em>, <em>app.del()</em>, etc.</p>
<p> A common example for <em>POST</em> usage, is when &ldquo;submitting&rdquo; a form. Below we simply set our form method to &ldquo;post&rdquo; in our html, and control will be given to the route we have defined below it.</p>
<pre><code> &lt;form method="post" action="/"&gt;
&lt;input type="text" name="user[name]" /&gt;
&lt;input type="text" name="user[email]" /&gt;
&lt;input type="submit" value="Submit" /&gt;
&lt;/form&gt;
</code></pre>
<p>By default Express does not know what to do with this request body, so we should add the <em>bodyParser</em> middleware, which will parse <em>application/x-www-form-urlencoded</em> and <em>application/json</em> request bodies and place the variables in <em>req.body</em>. We can do this by &ldquo;using&rdquo; the middleware as shown below:</p>
<pre><code>app.use(express.bodyParser());
</code></pre>
<p>Our route below will now have access to the <em>req.body.user</em> object which will contain the <em>name</em> and <em>email</em> properties when defined.</p>
<pre><code>app.post('/', function(req, res){
console.log(req.body.user);
res.redirect('back');
});
</code></pre>
<p>When using methods such as <em>PUT</em> with a form, we can utilize a hidden input named <em>_method</em>, which can be used to alter the HTTP method. To do so we first need the <em>methodOverride</em> middleware, which should be placed below <em>bodyParser</em> so that it can utilize it&rsquo;s <em>req.body</em> containing the form values.</p>
<pre><code>app.use(express.bodyParser());
app.use(express.methodOverride());
</code></pre>
<p>The reason that these are not always defaults, is simply because these are not required for Express to be fully functional. Depending on the needs of your application, you may not need these at all, your methods such as <em>PUT</em> and <em>DELETE</em> can still be accessed by clients which can use them directly, although <em>methodOverride</em> provides a great solution for forms. Below shows what the usage of <em>PUT</em> might look like:</p>
<pre><code>&lt;form method="post" action="/"&gt;
&lt;input type="hidden" name="_method" value="put" /&gt;
&lt;input type="text" name="user[name]" /&gt;
&lt;input type="text" name="user[email]" /&gt;
&lt;input type="submit" value="Submit" /&gt;
&lt;/form&gt;
app.put('/', function(){
console.log(req.body.user);
res.redirect('back');
});
</code></pre>
<h3 id="error-handling">Error Handling</h3>
<p>Express provides the <em>app.error()</em> method which receives exceptions thrown within a route,
or passed to <em>next(err)</em>. Below is an example which serves different pages based on our
ad-hoc <em>NotFound</em> exception:</p>
<pre><code>function NotFound(msg){
this.name = 'NotFound';
Error.call(this, msg);
Error.captureStackTrace(this, arguments.callee);
}
NotFound.prototype.__proto__ = Error.prototype;
app.get('/404', function(req, res){
throw new NotFound;
});
app.get('/500', function(req, res){
throw new Error('keyboard cat!');
});
</code></pre>
<p>We can call <em>app.error()</em> several times as shown below.
Here we check for an instanceof <em>NotFound</em> and show the
404 page, or we pass on to the next error handler.</p>
<p>Note that these handlers can be defined anywhere, as they
will be placed below the route handlers on <em>listen()</em>. This
allows for definition within <em>configure()</em> blocks so we can
handle exceptions in different ways based on the environment.</p>
<pre><code>app.error(function(err, req, res, next){
if (err instanceof NotFound) {
res.render('404.jade');
} else {
next(err);
}
});
</code></pre>
<p>Here we assume all errors as 500 for the simplicity of
this demo, however you can choose whatever you like. For example when node performs filesystem syscalls, you may receive an error object with the <em>error.code</em> of <em>ENOENT</em>, meaning &ldquo;no such file or directory&rdquo;, we can utilize this in our error handling and display a page specific to this if desired.</p>
<pre><code>app.error(function(err, req, res){
res.render('500.jade', {
error: err
});
});
</code></pre>
<p>Our apps could also utilize the Connect <em>errorHandler</em> middleware
to report on exceptions. For example if we wish to output exceptions
in &ldquo;development&rdquo; mode to <em>stderr</em> we can use:</p>
<pre><code>app.use(express.errorHandler({ dumpExceptions: true }));
</code></pre>
<p>Also during development we may want fancy html pages to show exceptions
that are passed or thrown, so we can set <em>showStack</em> to true:</p>
<pre><code>app.use(express.errorHandler({ showStack: true, dumpExceptions: true }));
</code></pre>
<p>The <em>errorHandler</em> middleware also responds with <em>json</em> if <em>Accept: application/json</em>
is present, which is useful for developing apps that rely heavily on client-side JavaScript.</p>
<h3 id="route-param pre-conditions">Route Param Pre-conditions</h3>
<p>Route param pre-conditions can drastically improve the readability of your application, through implicit loading of data, and validation of request urls. For example if you are constantly fetching common data for several routes, such as loading a user for <em>/user/:id</em>, we might typically do something like below:</p>
<pre><code>app.get('/user/:userId', function(req, res, next){
User.get(req.params.userId, function(err, user){
if (err) return next(err);
res.send('user ' + user.name);
});
});
</code></pre>
<p>With preconditions our params can be mapped to callbacks which may perform validation, coercion, or even loading data from a database. Below we invoke <em>app.param()</em> with the parameter name we wish to map to some middleware, as you can see we receive the <em>id</em> argument which contains the placeholder value. Using this we load the user and perform error handling as usual, and simple call <em>next()</em> to pass control to the next precondition or route handler.</p>
<pre><code>app.param('userId', function(req, res, next, id){
User.get(id, function(err, user){
if (err) return next(err);
if (!user) return next(new Error('failed to find user'));
req.user = user;
next();
});
});
</code></pre>
<p>Doing so, as mentioned drastically improves our route readability, and allows us to easily share this logic throughout our application:</p>
<pre><code>app.get('/user/:userId', function(req, res){
res.send('user ' + req.user.name);
});
</code></pre>
<h3 id="view-rendering">View Rendering</h3>
<p>View filenames take the form &ldquo;&lt;name&gt;.&lt;engine&gt;&rdquo;, where &lt;engine&gt; is the name
of the module that will be required. For example the view <em>layout.ejs</em> will
tell the view system to <em>require(&lsquo;ejs&rsquo;)</em>, the module being loaded must export the method <em>exports.compile(str, options)</em>, and return a <em>Function</em> to comply with Express. To alter this behaviour
<em>app.register()</em> can be used to map engines to file extensions, so that for example &ldquo;foo.html&rdquo; can be rendered by ejs.</p>
<p>Below is an example using <a href="http://github.com/visionmedia/jade">Jade</a> to render <em>index.html</em>,
and since we do not use <em>layout: false</em> the rendered contents of <em>index.jade</em> will be passed as
the <em>body</em> local variable in <em>layout.jade</em>.</p>
<pre><code>app.get('/', function(req, res){
res.render('index.jade', { title: 'My Site' });
});
</code></pre>
<p>The new <em>view engine</em> setting allows us to specify our default template engine,
so for example when using jade we could set:</p>
<pre><code>app.set('view engine', 'jade');
</code></pre>
<p>Allowing us to render with:</p>
<pre><code>res.render('index');
</code></pre>
<p>vs:</p>
<pre><code>res.render('index.jade');
</code></pre>
<p>When <em>view engine</em> is set, extensions are entirely optional, however we can still
mix and match template engines:</p>
<pre><code>res.render('another-page.ejs');
</code></pre>
<p>Express also provides the <em>view options</em> setting, which is applied each time a view is rendered, so for example if you rarely use layouts you may set:</p>
<pre><code>app.set('view options', {
layout: false
});
</code></pre>
<p>Which can then be overridden within the <em>res.render()</em> call if need be:</p>
<pre><code>res.render('myview.ejs', { layout: true });
</code></pre>
<p>When an alternate layout is required, we may also specify a path. For example if we have <em>view engine</em> set to <em>jade</em> and a file named <em>./views/mylayout.jade</em> we can simply pass:</p>
<pre><code>res.render('page', { layout: 'mylayout' });
</code></pre>
<p>Otherwise we must specify the extension:</p>
<pre><code>res.render('page', { layout: 'mylayout.jade' });
</code></pre>
<p>These paths may also be absolute:</p>
<pre><code>res.render('page', { layout: __dirname + '/../../mylayout.jade' });
</code></pre>
<p>A good example of this is specifying custom <em>ejs</em> opening and closing tags:</p>
<pre><code>app.set('view options', {
open: '{{',
close: '}}'
});
</code></pre>
<h3 id="view-partials">View Partials</h3>
<p>The Express view system has built-in support for partials and collections, which are &ldquo;mini&rdquo; views representing a document fragment. For example rather than iterating
in a view to display comments, we could use partial collection:</p>
<pre><code>partial('comment', { collection: comments });
</code></pre>
<p>If no other options or local variables are desired, we can omit the object and simply pass our array, which is equivalent to above:</p>
<pre><code>partial('comment', comments);
</code></pre>
<p>When using the partial collection support a few &ldquo;magic&rdquo; locals are provided
for free:</p>
<ul>
<li><em>firstInCollection</em> true if this is the first object</li>
<li><em>indexInCollection</em> index of the object in the collection</li>
<li><em>lastInCollection</em> true if this is the last object</li>
<li><em>collectionLength</em> length of the collection</li>
</ul>
<p>Local variables passed (or generated) take precedence, however locals passed to the parent view are available in the child view as well. So for example if we were to render a blog post with <em>partial(&lsquo;blog/post&rsquo;, post)</em> it would generate the <em>post</em> local, but the view calling this function had the local <em>user</em>, it would be available to the <em>blog/post</em> view as well.</p>
<p>For documentation on altering the object name view <a href="http://expressjs.com/guide.html#res-partial-view-options-">res.partial()</a>.</p>
<p><strong>NOTE:</strong> be careful about when you use partial collections, as rendering an array with a length of 100 means we have to render 100 views. For simple collections you may inline the iteration instead of using partial collection support to decrease overhead.</p>
<h3 id="view-lookup">View Lookup</h3>
<p>View lookup is performed relative to the parent view, for example if we had a page view named <em>views/user/list.jade</em>, and within that view we did <em>partial(&lsquo;edit&rsquo;)</em> it would attempt to load <em>views/user/edit.jade</em>, whereas <em>partial(&lsquo;../messages&rsquo;)</em> would load <em>views/messages.jade</em>.</p>
<p>The view system also allows for index templates, allowing you to have a directory of the same name. For example within a route we may have <em>res.render(&lsquo;users&rsquo;)</em> either <em>views/users.jade</em>, or <em>views/users/index.jade</em>.</p>
<p>When utilizing index views as shown above, we may reference <em>views/users/index.jade</em> from a view in the same directory by <em>partial(&lsquo;users&rsquo;)</em>, and the view system will try <em>../users/index</em>, preventing us from needing to call <em>partial(&lsquo;index&rsquo;)</em>.</p>
<h3 id="template-engines">Template Engines</h3>
<p>Below are a few template engines commonly used with Express:</p>
<ul>
<li><a href="http://github.com/visionmedia/haml.js">Haml</a> haml implementation</li>
<li><a href="http://jade-lang.com">Jade</a> haml.js successor</li>
<li><a href="http://github.com/visionmedia/ejs">EJS</a> Embedded JavaScript</li>
<li><a href="http://github.com/mauricemach/coffeekup">CoffeeKup</a> CoffeeScript based templating</li>
<li><a href="https://github.com/kof/node-jqtpl">jQuery Templates</a> for node</li>
</ul>
<h3 id="session-support">Session Support</h3>
<p>Sessions support can be added by using Connect&rsquo;s <em>session</em> middleware. To do so we also need the <em>cookieParser</em> middleware place above it, which will parse and populate cookie data to <em>req.cookies</em>.</p>
<pre><code>app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));
</code></pre>
<p>By default the <em>session</em> middleware uses the memory store bundled with Connect, however many implementations exist. For example <a href="http://github.com/visionmedia/connect-redis">connect-redis</a> supplies a <a href="http://code.google.com/p/redis/">Redis</a> session store and can be used as shown below:</p>
<pre><code>var RedisStore = require('connect-redis')(express);
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat", store: new RedisStore }));
</code></pre>
<p>Now the <em>req.session</em> and <em>req.sessionStore</em> properties will be accessible to all routes and subsequent middleware. Properties on <em>req.session</em> are automatically saved on a response, so for example if we wish to shopping cart data:</p>
<pre><code>var RedisStore = require('connect-redis')(express);
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat", store: new RedisStore }));
app.post('/add-to-cart', function(req, res){
// Perhaps we posted several items with a form
// (use the bodyParser() middleware for this)
var items = req.body.items;
req.session.items = items;
res.redirect('back');
});
app.get('/add-to-cart', function(req, res){
// When redirected back to GET /add-to-cart
// we could check req.session.items &amp;&amp; req.session.items.length
// to print out a message
if (req.session.items &amp;&amp; req.session.items.length) {
req.flash('info', 'You have %s items in your cart', req.session.items.length);
}
res.render('shopping-cart');
});
</code></pre>
<p>The <em>req.session</em> object also has methods such as <em>Session#touch()</em>, <em>Session#destroy()</em>, <em>Session#regenerate()</em> among others to maintain and manipulate sessions. For more information view the <a href="http://senchalabs.github.com/connect/middleware-session.html">Connect Session</a> documentation.</p>
<h3 id="migration-guide">Migration Guide</h3>
<p> Express 1.x developers may reference the <a href="migrate.html">Migration Guide</a> to get up to speed on how to upgrade your application to work with Express 2.x, Connect 1.x, and Node 0.4.x.</p>
<h3 id="req.header()">req.header(key[, defaultValue])</h3>
<p>Get the case-insensitive request header <em>key</em>, with optional <em>defaultValue</em>:</p>
<pre><code>req.header('Host');
req.header('host');
req.header('Accept', '*/*');
</code></pre>
<p>The <em>Referrer</em> and <em>Referer</em> header fields are special-cased, either will work:</p>
<pre><code>// sent Referrer: http://google.com
req.header('Referer');
// =&gt; "http://google.com"
req.header('Referrer');
// =&gt; "http://google.com"
</code></pre>
<h3 id="req.accepts()">req.accepts(type)</h3>
<p>Check if the <em>Accept</em> header is present, and includes the given <em>type</em>.</p>
<p>When the <em>Accept</em> header is not present <em>true</em> is returned. Otherwise
the given <em>type</em> is matched by an exact match, and then subtypes. You
may pass the subtype such as &ldquo;html&rdquo; which is then converted internally
to &ldquo;text/html&rdquo; using the mime lookup table.</p>
<pre><code>// Accept: text/html
req.accepts('html');
// =&gt; true
// Accept: text/*; application/json
req.accepts('html');
req.accepts('text/html');
req.accepts('text/plain');
req.accepts('application/json');
// =&gt; true
req.accepts('image/png');
req.accepts('png');
// =&gt; false
</code></pre>
<h3 id="req.is()">req.is(type)</h3>
<p>Check if the incoming request contains the <em>Content-Type</em>
header field, and it contains the give mime <em>type</em>.</p>
<pre><code> // With Content-Type: text/html; charset=utf-8
req.is('html');
req.is('text/html');
// =&gt; true
// When Content-Type is application/json
req.is('json');
req.is('application/json');
// =&gt; true
req.is('html');
// =&gt; false
</code></pre>
<p>Ad-hoc callbacks can also be registered with Express, to perform
assertions again the request, for example if we need an expressive
way to check if our incoming request is an image, we can register <em>&ldquo;an image&rdquo;</em>
callback:</p>
<pre><code> app.is('an image', function(req){
return 0 == req.headers['content-type'].indexOf('image');
});
</code></pre>
<p>Now within our route callbacks, we can use to to assert content types
such as <em>&ldquo;image/jpeg&rdquo;</em>, <em>&ldquo;image/png&rdquo;</em>, etc.</p>
<pre><code> app.post('/image/upload', function(req, res, next){
if (req.is('an image')) {
// do something
} else {
next();
}
});
</code></pre>
<p>Keep in mind this method is <em>not</em> limited to checking <em>Content-Type</em>, you
can perform any request assertion you wish.</p>
<p>Wildcard matches can also be made, simplifying our example above for <em>&ldquo;an image&rdquo;</em>, by asserting the <em>subtype</em> only:</p>
<pre><code>req.is('image/*');
</code></pre>
<p>We may also assert the <em>type</em> as shown below, which would return true for <em>&ldquo;application/json&rdquo;</em>, and <em>&ldquo;text/json&rdquo;</em>.</p>
<pre><code>req.is('*/json');
</code></pre>
<h3 id="req.param()">req.param(name[, default])</h3>
<p>Return the value of param <em>name</em> when present or <em>default</em>.</p>
<ul>
<li>Checks route params (<em>req.params</em>), ex: /user/:id</li>
<li>Checks query string params (<em>req.query</em>), ex: ?id=12</li>
<li>Checks urlencoded body params (<em>req.body</em>), ex: id=12</li>
</ul>
<p>To utilize urlencoded request bodies, <em>req.body</em>
should be an object. This can be done by using
the _express.bodyParser middleware.</p>
<h3 id="req.get()">req.get(field, param)</h3>
<p> Get <em>field</em>&rsquo;s <em>param</em> value, defaulting to &lsquo;&rsquo; when the <em>param</em>
or <em>field</em> is not present.</p>
<pre><code> req.get('content-disposition', 'filename');
// =&gt; "something.png"
req.get('Content-Type', 'boundary');
// =&gt; "--foo-bar-baz"
</code></pre>
<h3 id="req.flash()">req.flash(type[, msg])</h3>
<p>Queue flash <em>msg</em> of the given <em>type</em>.</p>
<pre><code>req.flash('info', 'email sent');
req.flash('error', 'email delivery failed');
req.flash('info', 'email re-sent');
// =&gt; 2
req.flash('info');
// =&gt; ['email sent', 'email re-sent']
req.flash('info');
// =&gt; []
req.flash();
// =&gt; { error: ['email delivery failed'], info: [] }
</code></pre>
<p>Flash notification message may also utilize formatters, by default only the %s string formatter is available:</p>
<pre><code>req.flash('info', 'email delivery to _%s_ from _%s_ failed.', toUser, fromUser);
</code></pre>
<h3 id="req.isxmlhttprequest">req.isXMLHttpRequest</h3>
<p>Also aliased as <em>req.xhr</em>, this getter checks the <em>X-Requested-With</em> header
to see if it was issued by an <em>XMLHttpRequest</em>:</p>
<pre><code>req.xhr
req.isXMLHttpRequest
</code></pre>
<h3 id="res.header()">res.header(key[, val])</h3>
<p>Get or set the response header <em>key</em>.</p>
<pre><code>res.header('Content-Length');
// =&gt; undefined
res.header('Content-Length', 123);
// =&gt; 123
res.header('Content-Length');
// =&gt; 123
</code></pre>
<h3 id="res.charset">res.charset</h3>
<p>Sets the charset for subsequent <code>Content-Type</code> header fields. For example <code>res.send()</code> and <code>res.render()</code> default to &ldquo;utf8&rdquo;, so we may explicitly set the charset before rendering a template:</p>
<pre><code>res.charset = 'ISO-8859-1';
res.render('users');
</code></pre>
<p>or before responding with <code>res.send()</code>:</p>
<pre><code>res.charset = 'ISO-8859-1';
res.send(str);
</code></pre>
<p>or with node&rsquo;s <code>res.end()</code>:</p>
<pre><code>res.charset = 'ISO-8859-1';
res.header('Content-Type', 'text/plain');
res.end(str);
</code></pre>
<h3 id="res.contenttype()">res.contentType(type)</h3>
<p>Sets the <em>Content-Type</em> response header to the given <em>type</em>.</p>
<pre><code> var filename = 'path/to/image.png';
res.contentType(filename);
// Content-Type is now "image/png"
</code></pre>
<p>A literal <em>Content-Type</em> works as well:</p>
<pre><code> res.contentType('application/json');
</code></pre>
<p>Or simply the extension without leading <code>.</code>:</p>
<pre><code> res.contentType('json');
</code></pre>
<h3 id="res.attachment()">res.attachment([filename])</h3>
<p>Sets the <em>Content-Disposition</em> response header to &ldquo;attachment&rdquo;, with optional <em>filename</em>.</p>
<pre><code> res.attachment('path/to/my/image.png');
</code></pre>
<h3 id="res.sendfile()">res.sendfile(path[, options[, callback]])</h3>
<p>Used by <code>res.download()</code> to transfer an arbitrary file.</p>
<pre><code>res.sendfile('path/to/my.file');
</code></pre>
<p>This method accepts an optional callback which is called when
an error occurs, or when the transfer is complete. By default failures call <code>next(err)</code>, however when a callback is supplied you must do this explicitly, or act on the error.</p>
<pre><code>res.sendfile(path, function(err){
if (err) {
next(err);
} else {
console.log('transferred %s', path);
}
});
</code></pre>
<p>Options may also be passed to the internal <em>fs.createReadStream()</em> call, for example altering the <em>bufferSize</em>:</p>
<pre><code>res.sendfile(path, { bufferSize: 1024 }, function(err){
// handle
});
</code></pre>
<h3 id="res.download()">res.download(file[, filename[, callback[, callback2]]])</h3>
<p>Transfer the given <em>file</em> as an attachment with optional alternative <em>filename</em>.</p>
<pre><code>res.download('path/to/image.png');
res.download('path/to/image.png', 'foo.png');
</code></pre>
<p>This is equivalent to:</p>
<pre><code>res.attachment(file);
res.sendfile(file);
</code></pre>
<p>An optional callback may be supplied as either the second or third argument, which is passed to <em>res.sendfile()</em>. Within this callback you may still respond, as the header has not been sent.</p>
<pre><code>res.download(path, 'expenses.doc', function(err){
// handle
});
</code></pre>
<p>An optional second callback, <em>callback2</em> may be given to allow you to act on connection related errors, however you should not attempt to respond.</p>
<pre><code>res.download(path, function(err){
// error or finished
}, function(err){
// connection related error
});
</code></pre>
<h3 id="res.send()">res.send(body|status[, headers|status[, status]])</h3>
<p>The <em>res.send()</em> method is a high level response utility allowing you to pass
objects to respond with json, strings for html, Buffer instances, or numbers representing the status code. The following are all valid uses:</p>
<pre><code> res.send(); // 204
res.send(new Buffer('wahoo'));
res.send({ some: 'json' });
res.send('&lt;p&gt;some html&lt;/p&gt;');
res.send('Sorry, cant find that', 404);
res.send('text', { 'Content-Type': 'text/plain' }, 201);
res.send(404);
</code></pre>
<p>By default the <em>Content-Type</em> response header is set, however if explicitly
assigned through <code>res.send()</code> or previously with <code>res.header()</code> or <code>res.contentType()</code>
it will not be set again.</p>
<p>Note that this method <em>end()</em>s the response, so you will want to use node&rsquo;s <em>res.write()</em> for multiple writes or streaming.</p>
<h3 id="res.redirect()">res.redirect(url[, status])</h3>
<p>Redirect to the given <em>url</em> with a default response <em>status</em> of 302.</p>
<pre><code>res.redirect('/', 301);
res.redirect('/account');
res.redirect('http://google.com');
res.redirect('home');
res.redirect('back');
</code></pre>
<p>Express supports &ldquo;redirect mapping&rdquo;, which by default provides <em>home</em>, and <em>back</em>.
The <em>back</em> map checks the <em>Referrer</em> and <em>Referer</em> headers, while <em>home</em> utilizes
the &ldquo;home&rdquo; setting and defaults to &ldquo;/&rdquo;.</p>
<h3 id="res.cookie()">res.cookie(name, val[, options])</h3>
<p>Sets the given cookie <em>name</em> to <em>val</em>, with options <em>httpOnly</em>, <em>secure</em>, <em>expires</em> etc.</p>
<pre><code>// "Remember me" for 15 minutes
res.cookie('rememberme', 'yes', { expires: new Date(Date.now() + 900000), httpOnly: true });
</code></pre>
<p>The <em>maxAge</em> property may be used to set <em>expires</em> relative to <em>Date.now()</em> in milliseconds, so our example above can now become:</p>
<pre><code>res.cookie('rememberme', 'yes', { maxAge: 900000 });
</code></pre>
<p>To parse incoming <em>Cookie</em> headers, use the <em>cookieParser</em> middleware, which provides the <em>req.cookies</em> object:</p>
<pre><code>app.use(express.cookieParser());
app.get('/', function(req, res){
// use req.cookies.rememberme
});
</code></pre>
<h3 id="res.clearcookie()">res.clearCookie(name[, options])</h3>
<p>Clear cookie <em>name</em> by setting &ldquo;expires&rdquo; far in the past.</p>
<pre><code>res.clearCookie('rememberme');
</code></pre>
<h3 id="res.render()">res.render(view[, options[, fn]])</h3>
<p>Render <em>view</em> with the given <em>options</em> and optional callback <em>fn</em>.
When a callback function is given a response will <em>not</em> be made
automatically, however otherwise a response of <em>200</em> and <em>text/html</em> is given.</p>
<p>The <em>options</em> passed are the local variables as well, for example if we want to expose &ldquo;user&rdquo; to the view, and prevent a local we do so within the same object:</p>
<pre><code>var user = { name: 'tj' };
res.render('index', { layout: false, user: user });
</code></pre>
<h3 id="res.partial()">res.partial(view[, options])</h3>
<p>Render <em>view</em> partial with the given <em>options</em>. This method is always available
to the view as a local variable.</p>
<ul>
<li><em>object</em> the object named by <em>as</em> or derived from the view name</li>
<li><p><em>as</em> Variable name for each <em>collection</em> or <em>object</em> value, defaults to the view name.</p>
<ul>
<li>as: &lsquo;something&rsquo; will add the <em>something</em> local variable</li>
<li>as: this will use the collection value as the template context</li>
<li>as: global will merge the collection value&rsquo;s properties with <em>locals</em></li>
</ul>
</li>
<li><p><em>collection</em> Array of objects, the name is derived from the view name itself.
For example <em>video.html</em> will have a object <em>video</em> available to it.</p></li>
</ul>
<p>The following are equivalent, and the name of collection value when passed
to the partial will be <em>movie</em> as derived from the name.</p>
<pre><code>partial('theatre/movie.jade', { collection: movies });
partial('theatre/movie.jade', movies);
partial('movie.jade', { collection: movies });
partial('movie.jade', movies);
partial('movie', movies);
// In view: movie.director
</code></pre>
<p>To change the local from <em>movie</em> to <em>video</em> we can use the &ldquo;as&rdquo; option:</p>
<pre><code>partial('movie', { collection: movies, as: 'video' });
// In view: video.director
</code></pre>
<p>Also we can make our movie the value of <em>this</em> within our view so that instead
of <em>movie.director</em> we could use <em>this.director</em>.</p>
<pre><code>partial('movie', { collection: movies, as: this });
// In view: this.director
</code></pre>
<p>Another alternative is to &ldquo;expand&rdquo; the properties of the collection item into
pseudo globals (local variables) by using <em>as: global</em>, which again is syntactic sugar:</p>
<pre><code>partial('movie', { collection: movies, as: global });
// In view: director
</code></pre>
<p>This same logic applies to a single partial object usage:</p>
<pre><code>partial('movie', { object: movie, as: this });
// In view: this.director
partial('movie', { object: movie, as: global });
// In view: director
partial('movie', { object: movie, as: 'video' });
// In view: video.director
partial('movie', { object: movie });
// In view: movie.director
</code></pre>
<p>When a non-collection (does <em>not</em> have <em>.length</em>) is passed as the second argument, it is assumed to be the <em>object</em>, after which the object&rsquo;s local variable name is derived from the view name:</p>
<pre><code>var movie = new Movie('Nightmare Before Christmas', 'Tim Burton')
partial('movie', movie)
// =&gt; In view: movie.director
</code></pre>
<p>The exception of this, is when a &ldquo;plain&rdquo; object, aka &ldquo;{}&rdquo; or &ldquo;new Object&rdquo; is passed, which is considered an object with local variable. For example some may expect a &ldquo;movie&rdquo; local with the following, however since it is a plain object &ldquo;director&rdquo; and &ldquo;title&rdquo; are simply locals:</p>
<pre><code>var movie = { title: 'Nightmare Before Christmas', director: 'Tim Burton' };
partial('movie', movie)
</code></pre>
<p>For cases like this where passing a plain object is desired, simply assign it to a key, or use the <code>object</code> key which will use the filename-derived variable name. The examples below are equivalent:</p>
<pre><code> partial('movie', { locals: { movie: movie }})
partial('movie', { movie: movie })
partial('movie', { object: movie })
</code></pre>
<p>This exact API can be utilized from within a route, to respond with a fragment via Ajax or WebSockets, for example we can render a collection of users directly from a route:</p>
<pre><code>app.get('/users', function(req, res){
if (req.xhr) {
// respond with the each user in the collection
// passed to the "user" view
res.partial('user', users);
} else {
// respond with layout, and users page
// which internally does partial('user', users)
// along with other UI
res.render('users', { users: users });
}
});
</code></pre>
<h3 id="res.local()">res.local(name[, val])</h3>
<p>Get or set the given local variable <em>name</em>. The locals built up for a response are applied to those given to the view rendering methods such as <code>res.render()</code>.</p>
<pre><code> app.all('/movie/:id', function(req, res, next){
Movie.get(req.params.id, function(err, movie){
// Assigns res.locals.movie = movie
res.local('movie', movie);
});
});
app.get('/movie/:id', function(req, res){
// movie is already a local, however we
// can pass more if we wish
res.render('movie', { displayReviews: true });
});
</code></pre>
<h3 id="res.locals()">res.locals(obj)</h3>
<p> Assign several locals with the given <em>obj</em>. The following are equivalent:</p>
<pre><code> res.local('foo', bar);
res.local('bar', baz);
res.locals({ foo: bar, bar, baz });
</code></pre>
<h3 id="app.set()">app.set(name[, val])</h3>
<p>Apply an application level setting <em>name</em> to <em>val</em>, or
get the value of <em>name</em> when <em>val</em> is not present:</p>
<pre><code>app.set('views', __dirname + '/views');
app.set('views');
// =&gt; ...path...
</code></pre>
<p>Alternatively you may simply access the settings via <em>app.settings</em>:</p>
<pre><code>app.settings.views
// =&gt; ...path...
</code></pre>
<h3 id="app.enable()">app.enable(name)</h3>
<p>Enable the given setting <em>name</em>:</p>
<pre><code>app.enable('some arbitrary setting');
app.set('some arbitrary setting');
// =&gt; true
app.enabled('some arbitrary setting');
// =&gt; true
</code></pre>
<h3 id="app.enabled()">app.enabled(name)</h3>
<p>Check if setting <em>name</em> is enabled:</p>
<pre><code>app.enabled('view cache');
// =&gt; false
app.enable('view cache');
app.enabled('view cache');
// =&gt; true
</code></pre>
<h3 id="app.disable()">app.disable(name)</h3>
<p>Disable the given setting <em>name</em>:</p>
<pre><code>app.disable('some setting');
app.set('some setting');
// =&gt; false
app.disabled('some setting');
// =&gt; false
</code></pre>
<h3 id="app.disabled()">app.disabled(name)</h3>
<p>Check if setting <em>name</em> is disabled:</p>
<pre><code>app.enable('view cache');
app.disabled('view cache');
// =&gt; false
app.disable('view cache');
app.disabled('view cache');
// =&gt; true
</code></pre>
<h3 id="app.configure()">app.configure(env|function[, function])</h3>
<p>Define a callback function for the given <em>env</em> (or all environments) with callback <em>function</em>:</p>
<pre><code>app.configure(function(){
// executed for each env
});
app.configure('development', function(){
// executed for 'development' only
});
</code></pre>
<h3 id="app.redirect()">app.redirect(name, val)</h3>
<p>For use with <em>res.redirect()</em> we can map redirects at the application level as shown below:</p>
<pre><code>app.redirect('google', 'http://google.com');
</code></pre>
<p>Now in a route we may call:</p>
<p> res.redirect(&lsquo;google&rsquo;);</p>
<p>We may also map dynamic redirects:</p>
<pre><code>app.redirect('comments', function(req, res){
return '/post/' + req.params.id + '/comments';
});
</code></pre>
<p>So now we may do the following, and the redirect will dynamically adjust to
the context of the request. If we called this route with <em>GET /post/12</em> our
redirect <em>Location</em> would be <em>/post/12/comments</em>.</p>
<pre><code>app.get('/post/:id', function(req, res){
res.redirect('comments');
});
</code></pre>
<p>When mounted, <em>res.redirect()</em> will respect the mount-point. For example if a blog app is mounted at <em>/blog</em>, the following will redirect to <em>/blog/posts</em>:</p>
<pre><code>res.redirect('/posts');
</code></pre>
<h3 id="app.error()">app.error(function)</h3>
<p>Adds an error handler <em>function</em> which will receive the exception as the first parameter as shown below.
Note that we may set several error handlers by making several calls to this method, however the handler
should call <em>next(err)</em> if it does not wish to deal with the exception:</p>
<pre><code>app.error(function(err, req, res, next){
res.send(err.message, 500);
});
</code></pre>
<h3 id="app.helpers()">app.helpers(obj)</h3>
<p>Registers static view helpers.</p>
<pre><code>app.helpers({
name: function(first, last){ return first + ', ' + last }
, firstName: 'tj'
, lastName: 'holowaychuk'
});
</code></pre>
<p>Our view could now utilize the <em>firstName</em> and <em>lastName</em> variables,
as well as the <em>name()</em> function exposed.</p>
<pre><code>&lt;%= name(firstName, lastName) %&gt;
</code></pre>
<p>Express also provides a few locals by default:</p>
<pre><code>- `settings` the app's settings object
- `filename` the view's filename
- `layout(path)` specify the layout from within a view
</code></pre>
<p>This method is aliased as <em>app.locals()</em>.</p>
<h3 id="app.dynamichelpers()">app.dynamicHelpers(obj)</h3>
<p>Registers dynamic view helpers. Dynamic view helpers
are simply functions which accept <em>req</em>, <em>res</em>, and are
evaluated against the <em>Server</em> instance before a view is rendered. The <em>return value</em> of this function
becomes the local variable it is associated with.</p>
<pre><code>app.dynamicHelpers({
session: function(req, res){
return req.session;
}
});
</code></pre>
<p>All views would now have <em>session</em> available so that session data can be accessed via <em>session.name</em> etc:</p>
<pre><code>&lt;%= session.name %&gt;
</code></pre>
<h3 id="app.lookup">app.lookup</h3>
<p> The <em>app.lookup</em> http methods returns an array of callback functions
associated with the given <em>path</em>.</p>
<p> Suppose we define the following routes:</p>
<pre><code> app.get('/user/:id', function(){});
app.put('/user/:id', function(){});
app.get('/user/:id/:op?', function(){});
</code></pre>
<p> We can utilize this lookup functionality to check which routes
have been defined, which can be extremely useful for higher level
frameworks built on Express.</p>
<pre><code> app.lookup.get('/user/:id');
// =&gt; [Function]
app.lookup.get('/user/:id/:op?');
// =&gt; [Function]
app.lookup.put('/user/:id');
// =&gt; [Function]
app.lookup.all('/user/:id');
// =&gt; [Function, Function]
app.lookup.all('/hey');
// =&gt; []
</code></pre>
<p> To alias <em>app.lookup.VERB()</em>, we can simply invoke <em>app.VERB()</em>
without a callback, as a shortcut, for example the following are
equivalent:</p>
<pre><code> app.lookup.get('/user');
app.get('/user');
</code></pre>
<p> Each function returned has the following properties:</p>
<pre><code> var fn = app.get('/user/:id/:op?')[0];
fn.regexp
// =&gt; /^\/user\/(?:([^\/]+?))(?:\/([^\/]+?))?\/?$/i
fn.keys
// =&gt; ['id', 'op']
fn.path
// =&gt; '/user/:id/:op?'
fn.method
// =&gt; 'GET'
</code></pre>
<h3 id="app.match">app.match</h3>
<p> The <em>app.match</em> http methods return an array of callback functions
which match the given <em>url</em>, which may include a query string etc. This
is useful when you want reflect on which routes have the opportunity to
respond.</p>
<p> Suppose we define the following routes:</p>
<pre><code> app.get('/user/:id', function(){});
app.put('/user/:id', function(){});
app.get('/user/:id/:op?', function(){});
</code></pre>
<p> Our match against <strong>GET</strong> will return two functions, since the <em>:op</em>
in our second route is optional.</p>
<pre><code> app.match.get('/user/1');
// =&gt; [Function, Function]
</code></pre>
<p> This second call returns only the callback for <em>/user/:id/:op?</em>.</p>
<pre><code> app.match.get('/user/23/edit');
// =&gt; [Function]
</code></pre>
<p> We can also use <em>all()</em> to disregard the http method:</p>
<pre><code> app.match.all('/user/20');
// =&gt; [Function, Function, Function]
</code></pre>
<p> Each function matched has the following properties:</p>
<pre><code> var fn = app.match.get('/user/23/edit')[0];
fn.keys
// =&gt; ['id', 'op']
fn.params
// =&gt; { id: '23', op: 'edit' }
fn.method
// =&gt; 'GET'
</code></pre>
<h3 id="app.mounted()">app.mounted(fn)</h3>
<p>Assign a callback <em>fn</em> which is called when this <em>Server</em> is passed to <em>Server#use()</em>.</p>
<pre><code>var app = express.createServer(),
blog = express.createServer();
blog.mounted(function(parent){
// parent is app
// "this" is blog
});
app.use(blog);
</code></pre>
<h3 id="app.register()">app.register(ext, exports)</h3>
<p>Register the given template engine <em>exports</em>
as <em>ext</em>. For example we may wish to map &ldquo;.html&rdquo;
files to jade:</p>
<pre><code> app.register('.html', require('jade'));
</code></pre>
<p>This is also useful for libraries that may not
match extensions correctly. For example my haml.js
library is installed from npm as &ldquo;hamljs&rdquo; so instead
of layout.hamljs, we can register the engine as &ldquo;.haml&rdquo;:</p>
<pre><code> app.register('.haml', require('haml-js'));
</code></pre>
<p>For engines that do not comply with the Express
specification, we can also wrap their api this way. Below
we map <em>.md</em> to render markdown files, rendering the html once
since it will not change on subsequent calls, and support local substitution
in the form of &ldquo;{name}&rdquo;.</p>
<pre><code> app.register('.md', {
compile: function(str, options){
var html = md.toHTML(str);
return function(locals){
return html.replace(/\{([^}]+)\}/g, function(_, name){
return locals[name];
});
};
}
});
</code></pre>
<h3 id="app.listen()">app.listen([port[, host]])</h3>
<p>Bind the app server to the given <em>port</em>, which defaults to 3000. When <em>host</em> is omitted all
connections will be accepted via <em>INADDR_ANY</em>.</p>
<pre><code>app.listen();
app.listen(3000);
app.listen(3000, 'n.n.n.n');
</code></pre>
<p>The <em>port</em> argument may also be a string representing the path to a unix domain socket:</p>
<pre><code>app.listen('/tmp/express.sock');
</code></pre>
<p>Then try it out:</p>
<pre><code>$ telnet /tmp/express.sock
GET / HTTP/1.1
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 11
Hello World
</code></pre>
</div>
</div>
</body>
</html>