Wie gehe ich Inhalte aus einer Vorlage zu einem Layout in Express?
-
25-09-2019 - |
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.)
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.
Erstellenein 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()