# Express High performance web framework for node. |
## index | lib/express/index.js
Re-export connect auto-loaders. This prevents the need to `require('connect')` in order to access core middleware, so for example `express.logger()` instead of `require('connect').logger()`. |
    var exports = module.exports = require('connect').middleware;
Framework version. |
    exports.version = '1.0.0';
Module dependencies. |
    var Server = exports.Server = require('./server');
Shortcut for `new Server(...)`. ## param: Function ... return: Server api: public |
    exports.createServer = function(){
      return new Server(Array.prototype.slice.call(arguments));
    };
View extensions. |
    require('./view');
Response extensions. |
    require('./response');
Request extensions. |
    require('./request');
## request | lib/express/request.js
Module dependencies. |
    var http = require('http')
      , utils = require('./utils')
      , mime = require('connect/utils').mime;
Default flash formatters. type: Object |
    var flashFormatters = exports.flashFormatters = {
      s: function(val){
        return String(val);
      }
    };
Return request header or optional default. ## Examples
    req.header('Content-Type');
    // => "text/plain"

    req.header('content-type');
    // => "text/plain"

    req.header('Accept');
    // => undefined

    req.header('Accept', 'text/html');
    // => "text/html"
## param: String name param: String defaultValue return: String api: public |
    http.IncomingMessage.prototype.header = function(name, defaultValue){
      return this.headers[name.toLowerCase()] || defaultValue;
    };
Check if the Accept header is present, and includes the given `type`. When the Accept header is not present `true` is returned. Otherwise the given `type` is matched by an exact match, and then subtypes. You may pass the subtype such as "html" which is then converted internally to "text/html" using the mime lookup table. ## Examples
    // Accept: text/html
    req.accepts('html');
    // => true

    // Accept: text/*; application/json
    req.accepts('html');
    req.accepts('text/html');
    req.accepts('text/plain');
    req.accepts('application/json');
    // => true

    req.accepts('image/png');
    req.accepts('png');
    // => false
## param: String type return: Boolean api: public |
    http.IncomingMessage.prototype.accepts = function(type){
      var accept = this.header('Accept');
      if (!accept || accept === '*
') { return true; } else if (type) { // Allow "html" vs "text/html" etc if (type.indexOf('/') < 0) { type = mime.types['.' + type]; } // Check if we have a direct match if (accept.indexOf(type) >= 0) { return true; // Check if we have type/ } else { type = type.split('/')[0] + '/'; return accept.indexOf(type) >= 0; } } else { return false; } }; /** Return the value of param `name` when present. Checks route placeholders, ex: /user/:id Checks query string params, ex: ?id=12 Checks urlencoded body params, ex: id=12 To utilize urlencoded request bodies, `req.body` should be an object. This can be done by using the `connect.bodyDecoder` middleware. ## param: String name return: String api: public |
    http.IncomingMessage.prototype.param = function(name){
      // Route params like /user/:id
      if (this.params[name] !== undefined) {
        return this.params[name];
      }
      // Query string params
      if (this.query[name] !== undefined) {
        return this.query[name];
      }
      // Request body params via connect.bodyDecoder
      if (this.body &amp;&amp; this.body[name] !== undefined) {
        return this.body[name];
      }
    };
Queue flash `msg` of the given `type`. ## Examples
     req.flash('info', 'email sent');
     req.flash('error', 'email delivery failed');
     req.flash('info', 'email re-sent');
     // => 2

     req.flash('info');
     // => ['email sent', 'email re-sent']

     req.flash('info');
     // => []

     req.flash();
     // => { error: ['email delivery failed'], info: [] }
## Formatting Flash notifications also support arbitrary formatting support. For example you may pass variable arguments to `req.flash()` and use the %s specifier to be replaced by the associated argument:
    req.flash('info', 'email has been sent to %s.', userName);
To add custom formatters use the `exports.flashFormatters` object. ## param: String type param: String msg return: Array | Object | Number api: public |
    http.IncomingMessage.prototype.flash = function(type, msg){
      var msgs = this.session.flash = this.session.flash || {};
      if (type &amp;&amp; msg) {
        var i = 2
          , args = arguments
          , formatters = this.app.flashFormatters || {};
        formatters.__proto__ = flashFormatters;
        msg = utils.miniMarkdown(utils.htmlEscape(msg));
        msg = msg.replace(/%([a-zA-Z])/g, function(_, format){
          var formatter = formatters[format];
          if (formatter) return formatter(args[i++]);
        });
        return (msgs[type] = msgs[type] || []).push(msg);
      } else if (type) {
        var arr = msgs[type];
        delete msgs[type];
        return arr || [];
      } else {
        this.session.flash = {};
        return msgs;
      }
    };
Check if the incoming request contains the "Content-Type" header field, and it contains the give mime `type`. ## Examples
     // With Content-Type: text/html; charset=utf-8
     req.is('html');
     req.is('text/html');
     // => true

     // When Content-Type is application/json
     req.is('json');
     req.is('application/json');
     // => true

     req.is('html');
     // => false
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 "an image" callback:
      app.is('an image', function(req){
        return 0 == req.headers['content-type'].indexOf('image');
      });
Now within our route callbacks, we can use to to assert content types such as "image/jpeg", "image/png", etc.
     app.post('/image/upload', function(req, res, next){
       if (req.is('an image')) {
         // do something
       } else {
         next();
       }
     });
## param: String type return: Boolean api: public |
    http.IncomingMessage.prototype.is = function(type){
      var fn = this.app.is(type);
      if (fn) return fn(this);
      var contentType = this.headers['content-type'];
      if (!contentType) return;
      if (!~type.indexOf('/')) type = mime.type('.' + type);
      // TODO: remove when connect no longer appends charset...
      if (~type.indexOf(';')) type = type.split(';')[0];
      if (~type.indexOf('*')) {
        type = type.split('/')
        contentType = contentType.split('/');
        if ('*' == type[0] &amp;&amp; type[1] == contentType[1]) return true;
        if ('*' == type[1] &amp;&amp; type[0] == contentType[0]) return true;
      }
      return ~contentType.indexOf(type);
    };

    // Callback for isXMLHttpRequest / xhr

    function isxhr() {
      return this.header('X-Requested-With', '').toLowerCase() === 'xmlhttprequest';
    }
Check if the request was an XMLHttpRequest. ## return: Boolean api: public |
    http.IncomingMessage.prototype.__defineGetter__('isXMLHttpRequest', isxhr);
    http.IncomingMessage.prototype.__defineGetter__('xhr', isxhr);
## response | lib/express/response.js
Module dependencies. |
    var fs = require('fs')
      , http = require('http')
      , path = require('path')
      , pump = require('sys').pump
      , utils = require('connect/utils')
      , mime = require('connect/utils').mime
      , parseRange = require('./utils').parseRange;
Header fields supporting multiple values. type: Array |
    var multiple = ['Set-Cookie'];
Send a response with the given `body` and optional `headers` and `status` code. ## Examples
    res.send();
    res.send(new Buffer('wahoo'));
    res.send({ some: 'json' });
    res.send('<p>some html</p>');
    res.send('Sorry, cant find that', 404);
    res.send('text', { 'Content-Type': 'text/plain' }, 201);
    res.send(404);
## param: String | Object | Number | Buffer body or status param: Object | Number headers or status param: Number status return: ServerResponse api: public |
    http.ServerResponse.prototype.send = function(body, headers, status){
      // Allow status as second arg
      if (typeof headers === 'number') {
        status = headers,
        headers = null;
      }

      // Defaults
      status = status || 200;

      // Allow 0 args as 204
      if (!arguments.length) {
        body = status = 204;
      }

      // Determine content type
      switch (typeof body) {
        case 'number':
          if (!this.headers['Content-Type']) {
            this.contentType('.txt');
          }
          body = http.STATUS_CODES[status = body];
          break;
        case 'string':
          if (!this.headers['Content-Type']) {
            this.contentType('.html');
          }
          break;
        case 'object':
          if (body instanceof Buffer) {
            if (!this.headers['Content-Type']) {
              this.contentType('.bin');
            }
          } else {
            if (!this.headers['Content-Type']) {
              this.contentType('.json');
            }
            body = JSON.stringify(body);
            if (this.req.query.callback &amp;&amp; this.app.settings['jsonp callback']) {
              this.header('Content-Type', 'text/javascript');
              body = this.req.query.callback + '(' + body + ');';
            }
          }
          break;
      }

      // Populate Content-Length
      if (!this.headers['Content-Length']) {
        this.header('Content-Length', body instanceof Buffer
          ? body.length
          : Buffer.byteLength(body));
      }

      // Merge headers passed
      if (headers) {
        var fields = Object.keys(headers);
        for (var i = 0, len = fields.length; i &lt; len; ++i) {
          var field = fields[i];
          this.header(field, headers[field]);
        }
      }

      // Strip irrelevant headers
      if (204 === status) {
        delete this.headers['Content-Type'];
        delete this.headers['Content-Length'];
      }

      // Respond
      this.writeHead(status, this.headers);
      this.end('HEAD' == this.req.method ? undefined : body);
    };
Transfer the file at the given `path`. Automatically sets the Content-Type response header via `res.contentType()`. The given callback `fn` is invoked when an error occurs, passing it as the first argument, or when the file is transferred, passing the path as the second argument. When the filesize is >= "stream threshold" (defaulting to 32k), the file will be streamed using an `fs.ReadStream` and `sys.pump()`. ## param: String path param: Function fn api: public |
    http.ServerResponse.prototype.sendfile = function(path, fn){
      var self = this
        , streamThreshold = this.app.set('stream threshold') || 32 * 1024
        , ranges = self.req.headers.range;

      if (~path.indexOf('..')) this.send(403);

      function error(err) {
        delete self.headers['Content-Disposition'];
        if (fn) {
          fn(err, path);
        } else {
          self.req.next(err);
        }
      }

      fs.stat(path, function(err, stat){
        if (err) return error(err);
        if (stat.size &gt;= streamThreshold) {
          var status = 200;
          if (ranges) ranges = parseRange(stat.size, ranges);
          if (ranges) {
            var stream = fs.createReadStream(path, ranges[0])
              , start = ranges[0].start
              , end = ranges[0].end;
            status = 206;
            self.header('Content-Range', 'bytes '
              + start
              + '-'
              + end
              + '/'
              + stat.size);
          } else {
            var stream = fs.createReadStream(path);
          }
          self.contentType(path);
          self.header('Accept-Ranges', 'bytes');
          self.writeHead(status, self.headers);
          pump(stream, self, function(err){
            fn &amp;&amp; fn(err, path, true);
          });
        } else {
          fs.readFile(path, function(err, buf){
            if (err) return error(err);
            self.contentType(path);
            self.send(buf);
            fn &amp;&amp; fn(null, path);
          });
        }
      });
    };
Set Content-Type response header passed through `mime.type()`. ## Examples
    var filename = 'path/to/image.png';
    res.contentType(filename);
    // res.headers['Content-Type'] is now "image/png"
## param: String type return: String the resolved mime type api: public |
    http.ServerResponse.prototype.contentType = function(type){
      return this.header('Content-Type', mime.type(type));
    };
Set Content-Disposition header to attachment with optional `filename`. ## param: String filename return: ServerResponse api: public |
    http.ServerResponse.prototype.attachment = function(filename){
      this.header('Content-Disposition', filename
        ? 'attachment; filename="' + path.basename(filename) + '"'
        : 'attachment');
      return this;
    };
Transfer the file at the given `path`, with optional `filename` as an attachment. Once transferred, or if an error occurs `fn` is called with the error and path. ## param: String path param: String filename param: Function fn return: Type api: public |
    http.ServerResponse.prototype.download = function(path, filename, fn){
      this.attachment(filename || path).sendfile(path, fn);
    };
Set or get response header `name` with optional `val`. Headers that may be set multiple times (as indicated by the `multiple` array) can be called with a value several times, for example: res.header('Set-Cookie', '...'); res.header('Set-Cookie', '...'); ## param: String name param: String val return: String api: public |
    http.ServerResponse.prototype.header = function(name, val){
      if (val === undefined) {
        return this.headers[name];
      } else {
        if (this.headers[name] &amp;&amp; ~multiple.indexOf(name)) {
          return this.headers[name] += '\r\n' + name + ': ' + val;
        } else {
          return this.headers[name] = val;
        }
      }
    };
Clear cookie `name`. ## param: String name api: public |
    http.ServerResponse.prototype.clearCookie = function(name){
      this.cookie(name, '', { expires: new Date(1) });
    };
Set cookie `name` to `val`. ## Examples // "Remember Me" for 15 minutes res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true }); ## param: String name param: String val param: Options options api: public |
    http.ServerResponse.prototype.cookie = function(name, val, options){
      var cookie = utils.serializeCookie(name, val, options);
      this.header('Set-Cookie', cookie);
    };
Redirect to the given `url` with optional response `status` defauling to 302. The given `url` can also be the name of a mapped url, for example by default express supports "back" which redirects to the Referrer or Referer headers or the application's "home" setting. Express also supports "home" out of the box, which can be set via `app.set('home', '/blog');`, and defaults to '/'. ## Redirect Mapping To extend the redirect mapping capabilities that Express provides, we may use the `app.redirect()` method:
    app.redirect('google', 'http://google.com');
Now in a route we may call:
    res.redirect('google');
We may also map dynamic redirects:
     app.redirect('comments', function(req, res){
         return '/post/' + req.params.id + '/comments';
     });
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 GET /post/12 our redirect Location would be /post/12/comments.
     app.get('/post/:id', function(req, res){
         res.redirect('comments');
     });
## param: String url param: Number code api: public |
    http.ServerResponse.prototype.redirect = function(url, status){
      var basePath = this.app.set('home') || '/'
        , status = status || 302
        , body;

      // Setup redirect map
      var map = {
        back: this.req.headers.referrer || this.req.headers.referer || basePath,
        home: basePath
      };

      // Support custom redirect map
      map.__proto__ = this.app.redirects;

      // Attempt mapped redirect
      var mapped = typeof map[url] === 'function'
        ? map[url](this.req, this)
        : map[url];

      // Perform redirect
      url = mapped || url;

      // Support text/{plain,html} by default
      if (this.req.accepts('html')) {
        body = '<p>' + http.STATUS_CODES[status] + '. Redirecting to <a href="' + url + '">' + url + '</a></p>';
        this.header('Content-Type', 'text/html');
      } else {
        body = http.STATUS_CODES[status] + '. Redirecting to ' + url;
        this.header('Content-Type', 'text/plain');
      }

      // Respond
      this.send(body, { Location: url }, status);
    };
## server | lib/express/server.js
Module dependencies. |
    var url = require('url')
      , view = require('./view')
      , connect = require('connect')
      , utils = connect.utils
      , queryString = require('querystring')
      , router = require('connect/middleware/router');
Initialize a new `Server` with optional `middleware`. ## param: Array middleware api: public |
    var Server = exports = module.exports = function Server(middleware){
      var self = this;
      this.config = {};
      this.settings = {};
      this.redirects = {};
      this.isCallbacks = {};
      this.viewHelpers = {};
      this.dynamicViewHelpers = {};
      this.errorHandlers = [];
      connect.Server.call(this, middleware || []);

      // Default "home" to /
      this.set('home', '/');

      // DEPRECATED: remove in 1.0
      if (process.env.EXPRESS_ENV) {
        process.env.NODE_ENV = process.env.EXPRESS_ENV;
        console.warn('\x1b[33mWarning\x1b[0m: EXPRESS_ENV is deprecated, use NODE_ENV.');
      }

      // TODO: remove when Connect removes "Server" ...
      this.showVersion = false;

      // Set "env" to NODE_ENV, defaulting to "development"
      this.set('env', process.env.NODE_ENV || 'development');

      // Expose objects to each other
      this.use(function(req, res, next){
        req.query = {};
        res.headers = { 'X-Powered-By': 'Express' };
        req.app = res.app = self;
        req.res = res;
        res.req = req;
        req.next = next;
        // Assign req.params.get
        if (req.url.indexOf('?') &gt; 0) {
          var query = url.parse(req.url).query;
          req.query = exports.parseQueryString(query);
        }
        next();
      });

      // Use router, expose as app.get(), etc
      var fn = router(function(app){ self.routes = app; });
      this.__defineGetter__('router', function(){
        this.__usedRouter = true;
        return fn;
      });
    };
Inherit from `connect.Server`. |
    Server.prototype.__proto__ = connect.Server.prototype;
Support swappable querystring parsers. |
    exports.parseQueryString = queryString.parse;
Proxy in order to register error handlers. |
    Server.prototype.listen = function(){
      this.registerErrorHandlers();
      connect.Server.prototype.listen.apply(this, arguments);
    };
Proxy in order to register error handlers. |
    Server.prototype.listenFD = function(){
      this.registerErrorHandlers();
      connect.Server.prototype.listenFD.apply(this, arguments);
    };
Register error handlers. This is automatically called from within `Server#listen()` and `Server#listenFD()`. ## return: Server for chaining api: public |
    Server.prototype.registerErrorHandlers = function(){
      this.errorHandlers.forEach(function(fn){
        this.use(function(err, req, res, next){
          fn.apply(this, arguments);
        });
      }, this);
      return this;
    };
Proxy `connect.Server#use()` to apply settings to mounted applications. ## param: String | Function | Server route param: Function | Server middleware return: Server for chaining api: public |
    Server.prototype.use = function(route, middleware){
      if (typeof route !== 'string') {
        middleware = route, route = '/';
      }

      connect.Server.prototype.use.call(this, route, middleware);

      // Mounted an app
      if (middleware instanceof Server) {
        // Home is /:route/:home
        var app = middleware
          , home = app.set('home');
        if (home === '/') home = '';
        app.set('home', (app.route || '') + home);
        app.parent = this;
        // Mounted hook
        if (app.__mounted) app.__mounted.call(app, this);
      }

      return this;
    };
Assign a callback `fn` which is called when this `Server` is passed to `Server#use()`. ## Examples var app = express.createServer(), blog = express.createServer(); blog.mounted(function(parent){ // parent is app // "this" is blog }); app.use(blog); ## param: Function fn return: Server for chaining api: public |
    Server.prototype.mounted = function(fn){
      this.__mounted = fn;
      return this;
    };
## See view.register. ## return: Server for chaining api: public |
    Server.prototype.register = function(){
      view.register.apply(this, arguments);
      return this;
    };
Register the given view helpers `obj`. This method can be called several times to apply additional helpers. ## param: Object obj return: Server for chaining api: public |
    Server.prototype.helpers = function(obj){
      utils.merge(this.viewHelpers, obj);
      return this;
    };
Register the given dynamic view helpers `obj`. This method can be called several times to apply additional helpers. ## param: Object obj return: Server for chaining api: public |
    Server.prototype.dynamicHelpers = function(obj){
      utils.merge(this.dynamicViewHelpers, obj);
      return this;
    };
Assign a custom exception handler callback `fn`. These handlers are always last in the middleware stack. ## param: Function fn return: Server for chaining api: public |
    Server.prototype.error = function(fn){
      this.errorHandlers.push(fn);
      return this;
    };
Register the given callback `fn` for the given `type`. ## param: String type param: Function fn return: Server for chaining api: public |
    Server.prototype.is = function(type, fn){
      if (!fn) return this.isCallbacks[type];
      this.isCallbacks[type] = fn;
      return this;
    };
Assign `setting` to `val`, or return `setting`'s value. Mounted servers inherit their parent server's settings. ## param: String setting param: String val return: Server | Mixed for chaining, or the setting value api: public |
    Server.prototype.set = function(setting, val){
      if (val === undefined) {
        if (this.settings.hasOwnProperty(setting)) {
          return this.settings[setting];
        } else if (this.parent) {
          return this.parent.set(setting);
        }
      } else {
        this.settings[setting] = val;
        return this;
      }
    };
Enable `setting`. ## param: String setting return: Server for chaining api: public |
    Server.prototype.enable = function(setting){
      return this.set(setting, true);
    };
Disable `setting`. ## param: String setting return: Server for chaining api: public |
    Server.prototype.disable = function(setting){
      return this.set(setting, false);
    };
Redirect `key` to `url`. ## param: String key param: String url return: Server for chaining api: public |
    Server.prototype.redirect = function(key, url){
      this.redirects[key] = url;
      return this;
    };
Configure callback for the given `env`. ## param: String env param: Function fn return: Server for chaining api: public |
    Server.prototype.configure = function(env, fn){
      if (typeof env === 'function') {
        fn = env, env = 'all';
      }
      if (env === 'all' || this.set('env') === env) {
        fn.call(this);
      }
      return this;
    };

    // Generate routing methods

    (function(method){
      Server.prototype[method] = function(path, fn){
        var self = this;

        // Ensure router is mounted
        if (!this.__usedRouter) {
          this.use(this.router);
        }

        // Route specific middleware support
        if (arguments.length &gt; 2) {
          var args = Array.prototype.slice.call(arguments, 1);
          fn = args.pop();
          (function stack(middleware){
            middleware.forEach(function(fn){
              if (Array.isArray(fn)) {
                stack(fn);
              } else {
                self[method](path, fn);
              }
            });
          })(args);
        }

        // Generate the route
        this.routes[method](path, fn);
        return this;
      };
      return arguments.callee;
    })('get')('post')('put')('delete')('all');

    // Alias delete as "del"

    Server.prototype.del = Server.prototype.delete;
## utils | lib/express/utils.js
Parse mini markdown implementation. The following conversions are supported, primarily for the "flash" middleware: foo or foo become <em>foo</em> foo or foo become <strong>foo</strong> A becomes <a href="B">A</a> ## param: String str return: String api: private |
    exports.miniMarkdown = function(str){
      return String(str)
        .replace(/(__|\*\*)(.*?)\1/g, '<strong>$2</strong>')
        .replace(/(_|\*)(.*?)\1/g, '<em>$2</em>')
        .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
    };
Escape special characters in the given string of html. ## param: String html return: String api: private |
    exports.htmlEscape = function(html) {
      return String(html)
        .replace(/&/g, '&')
        .replace(/"/g, '"')
        .replace(/</g, '<')
        .replace(/>/g, '>');
    };
Parse "Range" header `str` relative to the given file `size`. ## param: Number size param: String str return: Array api: private |
    exports.parseRange = function(size, str){
      var valid = true;
      var arr = str.substr(6).split(',').map(function(range){
        var range = range.split('-')
          , start = parseInt(range[0], 10)
          , end = parseInt(range[1], 10);

        // -500
        if (isNaN(start)) {
          start = size - end;
          end = size - 1;
        // 500-
        } else if (isNaN(end)) {
          end = size - 1;
        }

        // Invalid
        if (isNaN(start) || isNaN(end) || start &gt; end) valid = false;

        return { start: start, end: end };
      });
      return valid ? arr : undefined;
    };
## view | lib/express/view.js
Module dependencies. |
    var extname = require('path').extname
      , utils = require('connect').utils
      , http = require('http')
      , fs = require('fs')
      , mime = utils.mime;
Cache supported template engine exports to increase performance by lowering the number of calls to `require()`. type: Object |
    var cache = {};
Cache view contents to prevent I/O hits. type: Object |
    var viewCache = {};
Cache view path derived names. type: Object |
    var viewNameCache = {};
Synchronously cache view at the given `path`. ## param: String path return: String api: private |
    function cacheViewSync(path) {
      return viewCache[path] = fs.readFileSync(path, 'utf8');
    }
Return view root path for the given `app`. ## param: express.Server app return: String api: private |
    function viewRoot(app) {
      return app.set('views') || process.cwd() + '/views';
    }
Return object name deduced from the given `view` path. ## Examples "movie/director" -> director "movie.director" -> director "forum/thread/post" -> post "forum/thread.post" -> post ## param: String view return: String api: private |
    function objectName(view) {
      return view.split('/').slice(-1)[0].split('.')[0];
    }
Register the given template engine `exports` as `ext`. For example we may wish to map ".html" files to jade: app.register('.html', require('jade')); This is also useful for libraries that may not match extensions correctly. For example my haml.js library is installed from npm as "hamljs" so instead of layout.hamljs, we can register the engine as ".haml": app.register('.haml', require('haml-js')); For engines that do not comply with the Express specification, we can also wrap their api this way. app.register('.foo', { render: function(str, options) { // perhaps their api is // return foo.toHTML(str, options); } }); ## param: String ext param: Object obj api: public |
    exports.register = function(ext, exports) {
      cache[ext] = exports;
    };
Render `view` partial with the given `options`. ## Options `object` Single object with name derived from the view (unless `as` is present) `as` Variable name for each `collection` value, defaults to the view name. as: 'something' will add the `something` local variable as: this will use the collection value as the template context as: global will merge the collection value's properties with `locals` `collection` Array of objects, the name is derived from the view name itself. For example video.html will have a object video available to it. ## param: String view param: Object | Array options, collection, or object return: String api: public |
    http.ServerResponse.prototype.partial = function(view, options, ext, locals){
      locals = locals || {};

      // Inherit parent view extension when not present
      if (ext &amp;&amp; view.indexOf('.') &lt; 0) {
        view += ext;
      }

      // Allow collection to be passed as second param
      if (options) {
        if ('length' in options) {
          options = { collection: options };
        } else if (!options.collection &amp;&amp; !options.locals &amp;&amp; !options.object) {
          options = { object: options };
        }
      } else {
        options = {};
      }

      // Inherit locals from parent
      options.locals = options.locals
        ? utils.merge(locals, options.locals)
        : locals;

      // Partials dont need layouts
      options.partial = true;
      options.layout = false;

      // Deduce name from view path
      var name = options.as
        || viewNameCache[view]
        || (viewNameCache[view] = objectName(view));

      // Collection support
      var collection = options.collection;
      if (collection) {
        var len = collection.length
          , buf = '';
        delete options.collection;
        options.locals.collectionLength = len;
        for (var i = 0; i &lt; len; ++i) {
          var val = collection[i];
          options.locals.firstInCollection = i === 0;
          options.locals.indexInCollection = i;
          options.locals.lastInCollection = i === len - 1;
          options.object = val;
          buf += this.partial(view, options);
        }
        return buf;
      } else {
        if (options.object) {
          if ('string' == typeof name) {
            options.locals[name] = options.object;
          } else if (name === global) {
            utils.merge(options.locals, options.object);
          } else {
            options.scope = options.object;
          }
        }
        return this.render(view, options);
      }
    };
Render `view` with the given `options` and optional callback `fn`. When a callback function is given a response will not be made automatically, however otherwise a response of 200 and text/html is given. ## Options Most engines accept one or more of the following options, both haml and jade accept all: `scope` Template evaluation context (the value of `this`) `locals` Object containing local variables `debug` Output debugging information `status` Response status code, defaults to 200 `headers` Response headers object ## param: String view param: Object | Function options or callback function param: Function fn api: public |
    http.ServerResponse.prototype.render = function(view, options, fn){
      // Support callback function as second arg
      if (typeof options === 'function') {
        fn = options, options = {};
      }

      var options = options || {}
        , app = this.app
        , viewOptions = app.settings['view options']
        , defaultEngine = app.settings['view engine'];

      // Mixin "view options"
      if (viewOptions) options.__proto__ = viewOptions;

      // Support "view engine" setting
      if (view.indexOf('.') &lt; 0 &amp;&amp; defaultEngine) {
        view += '.' + defaultEngine;
      }

      // Defaults
      var self = this
        , helpers = this.app.viewHelpers
        , dynamicHelpers = this.app.dynamicViewHelpers
        , root = viewRoot(this.app)
        , ext = extname(view)
        , partial = options.partial
        , layout = options.layout === undefined ? true : options.layout
        , layout = layout === true
          ? 'layout' + ext
          : layout;

      // Allow layout name without extension
      if (typeof layout === 'string' &amp;&amp; layout.indexOf('.') &lt; 0) {
        layout += ext;
      }

      // Default execution scope to the response
      options.scope = options.scope || this.req;

      // Auto-cache in production
      if ('production' == app.settings.env) {
        options.cache = true;
      }

      // Partials support
      if (options.partial) {
        root = app.settings.partials || root + '/partials';
      }

      // View path
      var path = view[0] === '/'
        ? view
        : root + '/' + view;

      // Pass filename to the engine and view
      var locals = options.locals = options.locals || {};
      options.locals.__filename = options.filename = path;

      // Dynamic helper support
      if (false !== options.dynamicHelpers) {
        // cache
        if (!this.__dynamicHelpers) {
          this.__dynamicHelpers = {};
          var keys = Object.keys(dynamicHelpers);
          for (var i = 0, len = keys.length; i &lt; len; ++i) {
            var key = keys[i]
              , val = dynamicHelpers[key];
            if (typeof val === 'function') {
              this.__dynamicHelpers[key] = val.call(
                    this.app
                  , this.req
                  , this);
            }
          }
        }

        // apply
        helpers.__proto__ = this.__dynamicHelpers;
      }

      // Merge view helpers
      options.locals.__proto__ = helpers;

      // Always expose partial() as a local
      options.locals.partial = function(view, options){
        return self.partial.call(self, view, options, ext, locals);
      };

      function error(err) {
        if (fn) {
          fn(err);
        } else {
          self.req.next(err);
        }
      }

      // Cache contents
      try {
        var str = (options.cache ? viewCache[path] : null) || cacheViewSync(path);
      } catch (err) {
        return error(err);
      }

      // Cache template engine exports
      var engine = cache[ext] || (cache[ext] = require(ext.substr(1)));

      // Attempt render
      try {
        var str = engine.render(str, options);
      } catch (err) {
        return error(err);
      }

      // Layout support
      if (layout) {
        options.layout = false;
        options.locals.body = str;
        options.isLayout = true;
        self.render(layout, options, fn);
      } else if (partial) {
        return str;
      } else if (fn) {
        fn(null, str);
      } else {
        this.send(str, options.headers, options.status);
      }
    };