web-dev-qa-db-ja.com

Express.jsビュー「グローバル」

私はExpress.js(Node.js上)を使用しており、「locals」パラメーターを介してカスタムデータを含むビューをレンダリングできることを知っています。 (res.render("template", { locals: { foo: "bar" } });

「グローバル」にする方法はありますか? (つまり、すべてのビューからアクセスできるデータ)

私が見た view optionsですが、再帰的ではないため、テンプレートでローカルを使用すると、設定したローカルが置き換えられます。

これは私の使用例です。CSS/ JSファイルをページごとに追加できるようにしたいと思います。これは私のメインレイアウトの一部です。問題は、すべてのレンダリングでこれらの配列を明示的に設定しないと、未定義のエラーが発生するため、テンプレートで常にtypeof css !== "undefined" ダンス。さらに、各フォームに明示的に追加したくない他の選択ボックスオプションリストがあります。

44
Dominic Barnes

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オブジェクトになりました。そのため、すべてのプロパティを1つずつ設定する必要があります。

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'
}
57
tigerFinch

動的ビューヘルパーを使用して、ビューに「グローバル」変数を設定する方法があります。

Express.jsガイドから:

app.dynamicHelpers(obj)

動的ビューヘルパーを登録します。動的ビューヘルパーは、req、resを受け入れる単純な関数であり、ビューがレンダリングされる前にサーバーインスタンスに対して評価されます。この関数の戻り値は、関連付けられているローカル変数になります。

app.dynamicHelpers({session:function(req、res){return req.session;}});

すべてのビューでセッションが利用可能になり、セッションデータにsession.nameなどを介してアクセスできるようになります。

これらの使用方法の実際の例は、ここにあります: https://github.com/alessioalex/Nodetuts/tree/master/express_samples (node app.js to start the app)

10
alessioalex

作者が述べたように、ビューオプションを使用する実際の例:

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変数を1か所更新するだけで、アセットがVarnishや他の場所にキャッシュされないようにすることができます。

7
mikl

私はソースコードを調べてみましたが、実際には、これがExpressのどのバージョンでも不可能であることがわかりました。 (これまでのところ、GitHubでのみ利用可能)

4
Dominic Barnes

これを行う最も簡単な方法は、ビューのローカルのデフォルトセットを表す変数を作成することです。次に、オブジェクトを受け取り、それをローカルにマージして、マージされたオブジェクトを返す関数を作成します。

私もコンテナオブジェクト内のすべてのローカルを渡しますつまり{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)
});
1

これは埋もれた応答ですが、ようやく動作しました。

1)これはモジュールの例ですconnect-flash

2)server.js/app.jsにミドルウェアを追加して、reqlocalsに追加します。これにより、テンプレートは必要なときにいつでも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)通常どおりルートを設定します(これはコーヒースクリプトですが、特別なものはありません)

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

4)メッセージが必要なときにrequest.flash()を呼び出します。それらは呼び出しごとに消費されるので、console.logしないでください。

!!!
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
0
Michael Cole

エクスプレス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"
  }
0
Drozerah