Frage

Ich habe einen grundlegenden Express-Server:

// server.js:
var Express = require('express');
app = Express.createServer();
app.configure(function(){
  app.set('views', Path.join(__dirname, 'views'));
  app.set('view engine', 'jade');
  app.set('view options');
});
app.get('/', function (request, response) {
  response.render('welcome', {
    locals: {some: 'Locals'}
  });
});

Mit einem grundlegenden Jade Layout:

// views/layout.jade:
!!! 5
html(lang='en')
  head
    title= pageTitle
  body
    h1= pageTitle
    aside(id="sidebar")= sidebarContent
    #content
      #{body}

Und eine einfache Seite:

# views/welcome.jade:
// How do I pass pageTitle and sidebarContent out to the layout from here?
p
  Welcome to my fine site!

(In Rails, das so etwas wie content_for sein könnte oder eine einfache Instanzvariable.)

War es hilfreich?

Lösung

Mit der Spitze über etwa dynamicHelpers, und die Magie der Verschlüsse, fand ich eine ziemlich elegante Lösung, die funktioniert, ohne das Request-Objekt beinhaltet. Der Trick ist, den Seitentitel Variable in einem Verschluss zu wickeln, die eine get () und set () Funktion um sie bietet, und macht, dass Wrapper-Objekt das Ergebnis der page_title dynamischen Helfer.

Erstellen

ein property.js:

exports.create = function () {
    var value = null;
    return {
        get: function () {
           return value;
        },
        set: function (new_value) {
           value = new_value;
        }
    };
}

erstellen So Aufruf () gibt ein Objekt mit einem get () und set () Methode darauf, dass get und die Schließung Variable gesetzt.

Dann in Ihrem App Setup-Code:

    var property = require("./property.js");
    app.dynamicHelpers ({
        page_title: function () {
         return property.create ();
        }
    });

Da der Wert des dynamischen Helfers ist das Ergebnis der Funktion des Aufrufs aus Ihrer Sicht und Vorlage, die page_title Variable wird das Wrapper-Objekt mit dem get () sein und set () Funktionen.

Ihrer Ansicht nach kann man dann sagen:

- page_title.set ("my specific page title");

Und in Ihrem Layout:

title= page_title.get()

diese ein bisschen weiter zu vereinfachen, und fügte hinzu, dies zu property.js:

exports.creator = function () {
    return function () {
        return exports.create();
    };
}

Hier können Sie den dynamischen Helfer Deklarationsblock auf diese Vereinfachung:

        var property = require("./property.js");
        app.dynamicHelpers ({
            page_title: property.creator()
        });

Andere Tipps

Express hat kein Vorurteil von „Blöcken“ oder was auch immer sie nennen, dass in in Schienen, aber Sie eine Kombination von Helfern verwenden können () und dynamicHelpers () zu erreichen, etwas Ähnliches http://expressjs.com/guide.html#app-helpers-obj-

Die Einheimischen geleitet bothavailable das Layout und die Seitenansicht obwohl

layout.jade

# the following function is a safe getter/setter for locals
- function pagevar(key, value) { var undef; return (value===undef) ? locals[key] || null : locals[key] = value; }
block config
  #intended as a non-rendered block so that locals can be overridden.
  # put your defaults here... - use append in the child view
!!!
html
  head
    title=pagevar('title')
    meta(name='description',content=pagevar('description'))
...

page.jade

append config
  - locals.title = 'override';
  - locals.description = 'override 2';
  - pagevars('somekey', 'some value');
...

Einfache peazy.

Sie können das tun, indem Sie diesen kleinen Ausschnitt verwendet wird.

prop.js:

var hash = {};
module.exports = function() {
    return {
        set: function(key, val) { hash[key] = val },
        get: function(key) { return hash[key] }
    };
};

server.js:

app.dynamicHelpers({ prop: require(__dirname + '/views/helpers/prop') });

Ausblick:

<% prop.set('foo', 'bar') %>

Layout:

<%= prop.get('foo') %>

Direkt in Einheimischen: {some: 'Locals', pageTitle: 'Welcome!'}

Für Express 3 template Agnostiker, funktioniert gut mit express-partials

app.use (req, res, next)->
  req.locals = {} unless req.locals

  res.locals.content_for = (k, v = null)->
    if !v
      req.locals[k]
    else
      req.locals[k] = v

  next()
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top