问题
i need two defaultlayout for my project nodejs (point of sale), the first: for the authentication page and the registration of a new user (cashier) (with his own CSS code), the second for the dashboard (pos interface as well as the product addition page ...) (with its own CSS code too).
the structure of my code should be:
views/
layouts/
mainDashboard.hbs
mainLogin.hbs
dashboard.hbs
addProduct.hbs
login.hbs
register.hbs
My code in server.js (make juste one DefaultLayout):
const express = require("express");
const exphbs = require("express-handlebars");
const app = new express();
// view enginge
app.engine(
"handlebars",
exphbs({
defaultLayout: "mainlogin" ,
})
);
app.set("view engine", "handlebars");
Now i want to make two different layout with different CSS Code, I find this post but I do not understand the solution (I specify that I am a beginner in node.js and that site is my first project So I need more detail please)
回答1:
To explain what is happening in the post you need to know some basic things:
1) res.render is a express function which is used to render views(like .hbs, .ejs etc etc). Typically how you use render function is like this:
res.render('index.hbs')
Which returns some html and writes it to browser.
2) app.use
is used to add middlewares(which is nothing but functions with 3 params) to the middleware chain.
app.use(middleware1);
app.use(middleware2);
For the above example every http request will go through middleware1 THEN middleware2 THEN the handler like app.get
or app.post
.
So basically a middleware is created to overwrite the res.render
function
Now, to use the code shown there,
Make two folders inside views for two themes. For example,
views/
theme1/
index.hbs
theme2/
index.hbs
In the index.js
file it should be normal express code then add the middlwares:
const express = require("express");
const app = express();
...
...
...
app.use(function(req, res, next) {
// cache original render
var _render = res.render;
res.render = function(view, options, done) {
// custom logic to determine which theme to render
var theme = getThemeFromRequest(req);
// ends up rendering /themes/theme1/index.hbs
_render.call(this, 'themes/' + theme + '/' + view, options, done);
};
next();
});
function getThemeFromRequest(req) {
// in your case you probably would get this from req.hostname or something
// but this example will render the file from theme2 if you add ?theme=2 to the url
if(req.query && req.query.theme) {
return 'theme' + req.query.theme;
}
// default to theme1
return 'theme1';
}
app.listen(8080, ()=>console.log("Started"));
Now let's say you make a route:
app.get('/', (req, res) =>{
res.render('index.hbs');
});
Now go to, http://localhost:8080/
it will render the theme1/index.hbs
if you do http://localhost:8080/?theme=theme2
it will render the theme2/index.hbs
.
Hope you understood the explanation.
来源:https://stackoverflow.com/questions/59246280/express-and-handlebars-implementing-multiple-defaultlayouts