Express 和 Handlebars:实现多个主题
Express and Handlebars: Implementing multiple themes
我和团队的任务是为我们的项目实施多个主题(请记住,我们现在有一个单一主题的项目)。
主题我的意思不仅仅是CSS,我指的是不同的标记文件,某些事物的某些特征等等(如果你不喜欢这个词 'theme' 在这个上下文中不要使用它,我希望你明白这个想法:有些东西需要在代码库中重用,有些东西需要特定于主题)。总的来说,我们在以可维护的方式构建它并实现大部分方面没有问题,但我们不知道如何制作多个 express-handlebars 配置,我们可以根据这些配置进行切换某些因素。
现在我们有一个非常标准的 express-handlebars 项目结构,如下所示:
views/
index
layouts/
main.hbs
content.hbs
whatever.hbs
我们想要的是这样的:
views/
themes
theme1
layouts/
main.hbs
index.hbs
content.hbs
theme2
layouts/
main.hbs
index
我们使用非常标准的方式在我们的应用程序启动文件中初始化 express-handlebars,如下所示:
var handlebars = exphbs.create({
defaultLayout: 'main',
extname: '.hbs',
helpers: require('./server/hbsHelpers')
});
app.engine('.hbs', handlebars.engine);
app.set('view engine', '.hbs');
app.set('views', __dirname + '/views');
我正在考虑初始化几个 exphbs 对象并在运行时(请求时)切换它们,但这不会起作用,因为 app.set
将是一个应用程序-广泛的设置(长话短说,我们用一个应用程序托管多个网站,无法在应用程序级别进行任何更改,只能在明确请求级别进行更改)。
期望的行为是这样的:
res.render(‘/theme1/file.hbs’);
貌似不配置直接渲染没问题,但是我们还需要指定handlebars需要从特定的特定主题中抓取特定主题的布局和局部来源
或
res.render(‘file.hbs’, { theme: ‘theme1’ });
我们正在使用这种变体的快速车把 – https://github.com/ericf/express-handlebars
(也许你可以建议一个替代方案,允许我上面描述的我们可以互换而不破坏很多东西 - 我们的代码库非常庞大)?
非常感谢您的任何帮助、想法或建议。
您没有提到如何确定每个请求将呈现哪个主题,但我认为最简单的方法是重写 res.render()
方法。
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';
}
这样做的好处是您在控制器中的调用仍然是干净的 - res.render('feature/index.hbs')
只要您在每个主题文件夹中都有该文件就应该是好的。
你可以让 getThemeFromRequest
更聪明,它可以检查是否存在该主题的模板,如果不存在,则从默认主题呈现文件,这可能有助于防止一堆重复 html.
我和团队的任务是为我们的项目实施多个主题(请记住,我们现在有一个单一主题的项目)。
主题我的意思不仅仅是CSS,我指的是不同的标记文件,某些事物的某些特征等等(如果你不喜欢这个词 'theme' 在这个上下文中不要使用它,我希望你明白这个想法:有些东西需要在代码库中重用,有些东西需要特定于主题)。总的来说,我们在以可维护的方式构建它并实现大部分方面没有问题,但我们不知道如何制作多个 express-handlebars 配置,我们可以根据这些配置进行切换某些因素。
现在我们有一个非常标准的 express-handlebars 项目结构,如下所示:
views/
index
layouts/
main.hbs
content.hbs
whatever.hbs
我们想要的是这样的:
views/
themes
theme1
layouts/
main.hbs
index.hbs
content.hbs
theme2
layouts/
main.hbs
index
我们使用非常标准的方式在我们的应用程序启动文件中初始化 express-handlebars,如下所示:
var handlebars = exphbs.create({
defaultLayout: 'main',
extname: '.hbs',
helpers: require('./server/hbsHelpers')
});
app.engine('.hbs', handlebars.engine);
app.set('view engine', '.hbs');
app.set('views', __dirname + '/views');
我正在考虑初始化几个 exphbs 对象并在运行时(请求时)切换它们,但这不会起作用,因为 app.set
将是一个应用程序-广泛的设置(长话短说,我们用一个应用程序托管多个网站,无法在应用程序级别进行任何更改,只能在明确请求级别进行更改)。
期望的行为是这样的:
res.render(‘/theme1/file.hbs’);
貌似不配置直接渲染没问题,但是我们还需要指定handlebars需要从特定的特定主题中抓取特定主题的布局和局部来源
或
res.render(‘file.hbs’, { theme: ‘theme1’ });
我们正在使用这种变体的快速车把 – https://github.com/ericf/express-handlebars (也许你可以建议一个替代方案,允许我上面描述的我们可以互换而不破坏很多东西 - 我们的代码库非常庞大)?
非常感谢您的任何帮助、想法或建议。
您没有提到如何确定每个请求将呈现哪个主题,但我认为最简单的方法是重写 res.render()
方法。
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';
}
这样做的好处是您在控制器中的调用仍然是干净的 - res.render('feature/index.hbs')
只要您在每个主题文件夹中都有该文件就应该是好的。
你可以让 getThemeFromRequest
更聪明,它可以检查是否存在该主题的模板,如果不存在,则从默认主题呈现文件,这可能有助于防止一堆重复 html.