expressのpartialの使い方

ぐぐってもparitalの使い方があんまりでてこないのでメモメモ

  • 環境
    • v0.4.2
    • express@2.0.0

コード

  • app.js
app.get('/', function(req, res){
  var entries = Entry.find(); //擬似コードです
  res.render('index', {
    title: 'blog',
    entries: entries
  }
});

ここから2つの書き方があります。

  1. partialの方で良きに計らう
  2. partialの方はあくまで断片
1のケース
  • view/index.jade
h1= title
div!= partial('entry', entries)
  • view/entry.jade
section.entry
  h2= entry.title
  div= entry.body
2のケース
  • view/index.jade
h1= title
div
  - entries.forEach(function(entry){
    section.entry!= partial('entry', {object: entry}) // .lengthが無いとダメポと言われる
    • コメント欄での指摘を受けて修正しました (2011/03/22 2:22)
  • view/entry.jade
h2= entry.title
div= entry.body

とまあこんなふうに使います

極私的なexpressの使い方

expressは使いやすいのですがappにroutingを足していくと長くなってきて読みにくくなったり、基本的な渡すlocalsが一緒だったりとするので、こんなふうに使っています

  • ディレクトリ構成に下記を追加
    • locals
      • jp.js, en.js (これはアプリに合わせて)
    • controllers
      • index.js, entry.js(これはアプリに合わせて)
    • config.js
  • app.js
var express = require('express'),
    app = module.exports = express.createServer(),
    config = app.config = require('./config.js'),
    locals = app.locals = require('./locals').jp,
    logfh = require('fs').createWriteStream('./logs/access.log', {flags: 'w', encoding: 'utf8', mode: '0644'}),
    log4js = require('log4js'),
    sysLogger = app.sysLogger;
log4js.addAppender(log4js.fileAppender('./logs/system.log'), 'sysLogger');
sysLogger = log4js.getLogger('sysLogger');

// Configuration
app.configure(function(){
  app.set('port', 8080); // 基本的には8080ポートで
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.logger({format: ':method :date :status :url :response-time :remote-addr :referrer', stream: logfh}));
  app.use(express.cookieParser());
  app.use(express.session({secret: 'CareerUp', store: new RedisStore}));
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.set('port', 80);
  app.use(express.errorHandler());
});

// Routes
require('./controllers');

// Only listen on $ node app.js
if (!module.parent) {
  app.listen(app.settings.port);
  console.log("Express server listening on port %d", app.address().port);
}
  • controller/index.js
var app = module.exports = module.parent.exports,
    fs = require('fs'),
    path = require('path'),
    files = fs.readdirSync(__dirname),
    locals = app.locals,
    utils = require('connect').utils,
    merge = utils.merge;

for(var i in files){
  if(files[i] !== path.basename(__filename) && // 自身(index.js)を無視
     files[i].indexOf('.') !== 0 && // 隠しファイルやviのswapファイル無視
     files[i].indexOf('~') !== (files[i].length - 1)){ // emacsの一時ファイル無視
    require(__dirname + '/' + files[i]);
  }
}

// "/"だけはこのファイルで設定する
app.get('/', function(req, res){
  res.render('index', merge( // 個別の要素を足し合わせる
    {
      entries: [{title: 1},{title:2},{title:3}]
    },
    locals));
});
  • locals/index.js
module.exports = exports = {
  jp: require('./jp.js'),
  en: require'./en.js')
}
  • locals/jp.js
module.exports = exports = {
  title: 'title',
  error: undefined,
  login: 'ログイン',
  logout: 'ログアウト',
  edit: '編集',
  navi: {
    next: '次へ',
    prev: '前へ'
  }
};