Comment puis-je passer le contenu d'un modèle à une mise en page Express?
-
25-09-2019 - |
Question
J'ai un serveur express de base:
// 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'}
});
});
Avec une mise en page de jade de base:
// views/layout.jade:
!!! 5
html(lang='en')
head
title= pageTitle
body
h1= pageTitle
aside(id="sidebar")= sidebarContent
#content
#{body}
Et une page simple:
# views/welcome.jade:
// How do I pass pageTitle and sidebarContent out to the layout from here?
p
Welcome to my fine site!
(Dans Rails, cela pourrait être quelque chose comme content_for
ou une simple variable d'instance.)
La solution
En utilisant la pointe ci-dessus à propos dynamicHelpers, et la magie de la fermeture, j'ai trouvé une solution assez élégante qui fonctionne sans impliquer l'objet de la demande. L'astuce consiste à envelopper la variable de titre dans une fermeture qui fournit une fonction get () et set () autour d'elle, et de faire cet emballage objet le résultat de l'assistant dynamique page_title.
Créer un property.js:
exports.create = function () {
var value = null;
return {
get: function () {
return value;
},
set: function (new_value) {
value = new_value;
}
};
}
Donc, appeler create () retourne un objet avec un get () et set () méthode sur, que et ECRIRE la variable de fermeture.
Ensuite, dans le code de configuration de votre application:
var property = require("./property.js");
app.dynamicHelpers ({
page_title: function () {
return property.create ();
}
});
Étant donné que la valeur d'aide dynamique est le résultat de l'appel de sa fonction, dans votre vue et modèle, la variable page_title sera l'objet d'emballage avec les fonctions get () et set ().
À votre avis, vous pouvez dire:
- page_title.set ("my specific page title");
Et dans votre mise en page:
title= page_title.get()
Pour simplifier un peu plus loin, en ajoutant ceci à property.js:
exports.creator = function () {
return function () {
return exports.create();
};
}
vous permet de simplifier les aides dynamiques bloc de déclaration à ceci:
var property = require("./property.js");
app.dynamicHelpers ({
page_title: property.creator()
});
Autres conseils
Express ne dispose pas d'une idée préconçue de « blocs » ou tout ce qu'ils appellent que dans des rails, mais vous pouvez utiliser une combinaison d'aides () et dynamicHelpers () pour obtenir quelque chose de similaire http://expressjs.com/guide.html#app-helpers-obj-
Les sections locales transmises sont disponibles à la fois la mise en page et la page vue que
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');
...
facile peazy.
Vous pouvez le faire en utilisant ce petit extrait.
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') });
Voir:
<% prop.set('foo', 'bar') %>
Mise en page:
<%= prop.get('foo') %>
Passez dans la population locale: {some: 'Locals', pageTitle: 'Welcome!'}
Pour Express 3 modèle agnostique, fonctionne bien avec 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()