Express.js查看“全局”

时间:2011-01-17 23:00:29

标签: javascript node.js express

我正在使用Express.js(在Node.js上),我知道您可以通过“locals”参数使用自定义数据渲染视图。 (res.render("template", { locals: { foo: "bar" } });

有没有办法拥有“全局”? (即每个视图都可以访问的数据)

我看到view options,但这不是递归的,所以如果我在模板中使用任何本地语,它将替换我设置的本地语。

这是我的用例:我想这样做,以便可以在每页的基础上添加CSS / JS文件,这是我的主要布局的一部分。问题是,如果我没有在每个渲染上显式设置这些数组,我会得到一个未定义的错误,所以在我的模板中我总是要做typeof css !== "undefined"舞。此外,我还有其他选择框选项列表,我不想明确添加到我的每个表单。

7 个答案:

答案 0 :(得分:57)

值得注意的是,自Express 3发布以来可能遇到过这个问题的人,“dynamicHelpers”方法不再存在。

相反,您可以使用app.locals函数,该函数充当您可以存储值或函数的对象,然后使它们可用于视图。例如: -

// In your app.js etc.
app.locals.title = "My App";
app.locals({
    version: 3,
    somefunction: function() {
        return "function result";
    }
});

// Then in your templates (shown here using a jade template)

=title
=version
=somefunction()  

// Will output

My App
3
function result

如果您需要访问请求对象以从中提取信息,您可以编写一个简单的中间件函数并使用app.settings变量。

例如,如果您使用connect-flash向用户提供消息,则可能会执行以下操作:

app.use(function(req, res, next) {
    app.set('error', req.flash('error'));
    next();
});

您可以在模板中使用= settings.error访问错误消息。

这里讨论了这些主题,虽然稍作简要说明:http://expressjs.com/api.html#app.locals

更新:Express 4

app.locals现在是一个简单的JavaScript对象,因此必须逐个设置每个属性。

app.locals.version = 3;
app.locals.somefunction = function() {
    return "function result";
}

res.locals提供完全相同的功能,但它应该用于特定于请求的数据而不是应用程序范围的数据。用户对象或设置是常见用例。

res.locals.user = req.isAuthenticated() ? req.user : null;
res.locals.userSettings = {
    backgroundColor: 'fff'
}

答案 1 :(得分:10)

使用动态视图帮助程序可以为视图创建“全局”变量。

从Express.js指南:

  

app.dynamicHelpers(OBJ)

     

注册动态视图助手。   动态视图助手很简单   接受req,res和的函数   针对服务器进行评估   在呈现视图之前的实例。   此函数的返回值   成为它的局部变量   与。相关联。

     

app.dynamicHelpers({session:   function(req,res){       返回req.session; }});

     

所有视图现在都有会话   可用,以便会话数据可以   通过session.name等访问:

     

你可以在这里找到一个关于如何使用它们的真实例子:https://github.com/alessioalex/Nodetuts/tree/master/express_samples(节点app.js来启动应用程序)

答案 2 :(得分:7)

作者提到的使用视图选项的真实示例:

var app = express.createServer();

app.configure(function() {
  app.set('views', path.join(__dirname, '..', 'views'));
  app.set('view engine', 'jade');
  app.set('view options', {
    assetVersion: 1
  });

然后在我的layout.jade(在我的情况下为应用程序的基本模板):

link(rel='stylesheet', href='/static/css/' + assetVersion + '/style.css')
script(src='/static/js/' + assetVersion + '/script.js')

通过这个小技巧,我只需要在一个地方更新assetVersion变量,以确保我的资产不会在Varnish或其他地方缓存。

答案 3 :(得分:4)

我查看了源代码,我实际上发现现在可以在从不版本的Express中使用。 (到目前为止,只能通过GitHub获得)

答案 4 :(得分:1)

实现此目的的最简单方法是创建一个表示视图的默认本地化集的变量。然后创建一个接受对象的函数,将其与locals合并,并返回合并的对象。

我还在容器对象中传递我的所有本地人,即{locals:{g:{prop:val}}}所以在我的观看中,我可以推荐g.prop,当它不是null时设置,而不是抛出未定义的错误。

function default_page_vars(custom_vars){
    var vars = {
        footer: true,
        host: req.headers.host.split(':')[0],
        config: this.config
    };

    if(custom_vars){
        for(var k in custom_vars){
            vars[k] = custom_vars[k];
        }
    }
    return {
        g:vars
    };
}

//within your handler
response.render(view, {
    locals: default_page_vars(other_locals)
});

答案 5 :(得分:0)

这是一个埋藏的回应,但我终于让它发挥作用了。

1)这是模块 connect-flash

的示例

2)在server.js / app.js中添加一个中间件,将req添加到locals。这允许模板在需要时调用request.flash()。如果没有这个,flash()会在每次请求/重定向上消耗掉目的。

var app = module.exports = express()
  , flash=require('connect-flash');
app.configure(function(){
  ...
  app.use(express.session({ secret: "shhh" }));

  // Start Router
  app.use(flash());
  app.use(function(req, res, next) {
    res.locals.request = req;
    next();
  });

  app.use(app.router);
});

3)正常设置你的路线(这是coffeescript,但没什么特别的)

app.get '/home', (req, res) ->
  req.flash "info", "this"
  res.render "#{__dirname}/views/index"

4)在需要消息时调用request.flash()。它们在每次调用时被消耗掉,因此不要调度它们或者它们将会消失: - )

!!!
html
  head
    title= config.appTitle
    include partials/_styles

  body
    include partials/_scripts

    #header
      a(href="/logout") Logout CURRENTUSER
      h2= config.appTitle

    #messages
      - var flash = request.flash()
      each flashType in ['info','warn','error']
        if flash[flashType]
          p.flash(class=flashType)
            = flash[flashType]


    block content
      h1 content here

答案 6 :(得分:0)

Express 4

  

您可以在应用程序内呈现的模板中访问局部变量。

因此,如果您想在模板中使用任何本地语言=>假设您已将模板引擎npm安装到节点/表达应用程序。

首先,您需要在app.js文件中使用自定义变量设置express locals objects,如果需要多个值(本文中的情况),可以使用一个对象

 /**
  *  Set locals object
  */

 app.locals.layoutData = { 
  site: {
      title: 'MyWebSiteTitle',
  },   
  metaTag: {
      charset: 'UTF-8',
      description: 'MyDescription',
      keywords: 'keyword-1,keyword-2,...',
      author: 'MyName',
      viewport: 'width=device-width, initial-scale=1.0'
  }
 };

然后,访问模板文件layout.pug中的值(例如,对于PUG模板引擎)

doctype html
html
  head
    //title
    title #{locals.layoutData.site.title}
    //Describe metadata
    meta(charset=layoutData.metaTag.charset)
    meta(name='description', content=locals.layoutData.metaTag.description)
    meta(name='keywords', content=locals.layoutData.metaTag.keywords)
    meta(name='author', content=locals.layoutData.metaTag.author)
    meta(name='viewport', content=locals.layoutData.metaTag.viewport)
  body
      block content
      br
      hr
      footer
        p All rights reserved © 2018 |  #{locals.layoutData.site.title}

经过

测试
  "dependencies": {
    "express": "^4.16.3",
    "pug": "^2.0.3"
  }