我正在使用Express和EJS来提供页面。我正在使用Bootstrap作为UI,特别是导航栏。
我想在当前页面的'active'
项目中添加<li>
类,以显示当前页面。但是,我无法找到如何从呈现页面的EJS代码中获取URL。
我找到了2个解决方法:我使用了包括将页面名称作为路由res.render('myview', {pageName: 'myView'});
中的参数传递 - 这是不可扩展的,可能会导致问题。
另一种方式是,在客户端使用jQuery在页面就绪时将'active'
类添加到项目中 - 但这意味着在每个视图中包含这段脚本+一些无用的客户端循环。< / p>
之前使用过几种服务器端渲染语言,我觉得我错过了一些东西。在线EJS文档并不是那么好。
有没有办法从EJS代码中找到我当前的路径/网址?
更新 我获取了前2个建议,并将视图名称作为参数传递给视图。我真的很喜欢@tandrewnichols的想法来自动计算它,但最终,复制粘贴字符串更容易:)
答案 0 :(得分:16)
据我所知,除非你在内部修改 EJS ,否则你不能做你要求的事。但是,一个不太麻烦的解决方案是在每次页面调用时传递请求的URL属性,而不是按路径定义它。
app.get('/url', function (req, res) {
res.render('view', {
page: req.url,
nav: {
'Page 1': '/page1',
'Page 2': '/page2',
'Page 3': '/page3'
}
});
});
如果您只想获取网址的第一部分并与之匹配,则可以在split('/')
上致电req.url
。然后,您可以在模板文件中放置一个循环,以创建导航栏的列表。
<% nav.forEach(function(title) { %>
<% if (nav[title] == page) { %>
<li class="active">This part of the navigation bar is active.</li>
<% } else { %>
<li>This part of the navigation bar is normal.</li>
<% } %>
<% }) %>
答案 1 :(得分:2)
在我使用的几乎所有节点/表达模板语言(ejs,kiwi,swig,jade)中,答案都是否定的。我总是只设置一个名为“active”的变量,然后检查它。正如你所说,虽然我不知道可扩展性是个问题,但这并不是一个好的答案。如果每个url呈现它自己的视图(或者即使你有一个用于视图呈现的公共处理程序),那么说req.active = "Somepage"
之类的东西应该不难。另一种可能性是根据路由添加为您完成的中间件。像
app.use(function(req, res, next){
req.active = req.path.split('/')[1] // [0] will be empty since routes start with '/'
next();
});
然后,您只需确保具有相应导航组件的任何路径都使用唯一路径,例如
app.get('/students', ....)
app.get('/classes', ....)
app.get('/teachers', ....)
// etc.
编辑:在回复你的评论时,我总是将我的所有视图内容放入req
内的一个对象键中,通常我用我正在使用的任何模板命名键。所以我可能实际上使用上面的例子来设置req.ejs.active
,然后再做
res.render('myview', req.ejs);
这种方法可以更容易地将逻辑分成多个中间件函数,而不必将一个巨大的匿名对象传递给res.render。
答案 2 :(得分:1)
index.js
/* object menu */
const menu = [
{
name: 'Home',
url: '/'
},
{
name: 'About',
url: '/about'
}
]
/* route */
app.get( '/', function( request, response) {
let data = {
title: 'Home',
url: request.url,
menu: menu
}
response.render( 'home', data )
} )
app.get( '/about', function( request, response) {
let data = {
title: 'About',
url: request.url,
menu: menu
}
response.render( 'about', data )
} )
menu.js
<% for ( let i in menu ) { %> // loop menu
<% if ( menu[i].url == url ) { %> // match, add active in class
<a class="active" href="<%= menu[i].url %>" ><%= menu[i].name %></a>
<% } else { %>
<a class="" href="<%= menu[i].url %>" ><%= menu[i].name %></a>
<% } %>
<% } %>