Partial不使用Express 4和JUST

时间:2014-05-17 17:37:29

标签: node.js express

我从EJS迁移到JUST,因为EJS从partials移动到包含不接受传递数据的包含。

我需要这个,因为我正在尝试为ul列表实现递归模板。 基本上,如果列表对象具有子项并且在嵌入式ul上对相关li进行处理,则它会调用自身。这意味着在每次调用时,我必须传递特定列表项的数据。当遇到没有子节点的列表项时,循环结束。否则,如果我不能在每次迭代中传递相关数据,那么它将是一个无限循环的调用。

我有JUST模板工作,但只要它试图找到一个部分文件就会抛出错误。

Error: ENOENT, open 'list'

我的应用代码:

var path = require('path');
    var express         = require('express'),
        session         = require('express-session'),
        mysql           = require('mysql'),
        cookieParser    = require('cookie-parser'),
        engines         = require('consolidate'), // needed to force 'just' to match the signature
        // JUST            = require('just'),
        ejs             = require('ejs'),
        bodyParser      = require('body-parser'),
        _               = require("underscore");
    var app = express();

    // Database setup
    var db = mysql.createConnection({
            host     : 'localhost',
            user     : 'root',
            password : '1234'
        });
    if (db) {db.query('USE cleckner');}

    // assign the just engine to .html files
    app.engine('html', engines.just);
    // app.engine('html', ejs.renderFile);

    // set .html as the default extension
    app.set('view engine', 'html');
    app.set('views', __dirname + '/app/views');
    app.set('partial', __dirname + '/app/views');
    app.set('port', process.env.PORT || 3000);
    app.set('db', db);
    app.set('_', _);

    app.use(bodyParser());
    app.use(cookieParser());
    // app.use(_());
    app.use(session({secret:'cleckner'}));
    // app.use(favicon('/assets/img/logo.jpg'));
    app.use(express.static(__dirname + 'app/views'));
    app.use('/assets', express.static(__dirname + '/public/assets'));



    var routers = require('./app/routers/router.js').set(app);

    // development only
    if ('development' === app.get('env')) {
      // app.use(errorHandler());
    }

    app.listen(app.get('port'));
    console.log('Listening on port '+app.get('port'));

test.html模板

<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= title %><</title>

    <!-- If you are using CSS version, only link these 2 files, you may add app.css to use for your overrides if you like. -->
    <link rel="stylesheet" href="/assets/css/vendor.css">
    <link rel="stylesheet" href="/assets/css/app.css">

    <script src="/assets/js/modernizr.js"></script>

    <!--[if lt IE 9]>
        <script src="/assets/js/ie.js"></script>
    <![endif]-->
</head>
<body>
    <header><%= title %></header>
    <%@ partials/list %>
</body>
</html>

部分 - list.html

    <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
    </ul>

我的路由器正在运行此功能:

var renderTestPage = function(req, res, options) {
    var subs = [{val:1}, {val:2}, {val:3}];
    var options = {subs:subs, title:'JUST Test'}
    res.render('test.html', options);
};

正如我之前所说,标题正确显示,表示模板正在加载和运行。但我不能让我的部分工作。

1 个答案:

答案 0 :(得分:0)

我所做的包括对ejs / express的布局支持是:

/*
   Usage:
     Set a global/default layout with:
        app.set('view layout', 'foo');
     Set a layout per-render (overrides global layout) with:
        res.render('foo', { layout: 'bar' });
     Or disable a layout if a global layout is set with:
        res.render('foo', { layout: false });
     If no layout is provided using either of the above methods,
     then the view will be rendered as-is like normal.

     Inside your layout, the variable `body` holds the rendered partial/child view.

   Installation:
     Call `mpResponse();` before doing `require('express');` in your application.
*/

function mpResponse() {
  var expressResponse = require('express/lib/response'),
      expressResRender = expressResponse.render;
  expressResponse.render = function(view, options, fn) {
    options = options || {};
    var self = this,
        req = this.req,
        app = req.app,
        layout,
        cb;

    // support callback function as second arg
    if (typeof options === 'function')
      fn = options, options = {};

    // merge res.locals
    options._locals = self.locals;

    // default callback to respond
    fn = fn || function(err, str) {
      if (err) return req.next(err);
      self.send(str);
    };

    if (typeof options.layout === 'string')
      layout = options.layout;
    else if (options.layout !== false
             && typeof app.get('view layout') === 'string')
      layout = app.get('view layout');

    if (layout) {
      cb = function(err, str) {
        if (err) return req.next(err);
        options.body = str;
        expressResRender.call(self, layout, options, fn);
      };
    } else
      cb = fn;

    // render
    app.render(view, options, cb);
  };
}

然后对于布局中的变量,我会有一个中间件,根据路由设置类似res.locals.title = 'Foo';的东西。然后,您可以像res.render()一样向res.render('mypartial', { bar: 'baz' });发送任何其他数据。