我正在使用Express和EJS来提供页面。我在UI上使用Bootstrap,尤其是在导航栏上。
我想在当前页面的'active'
项目中添加<li>
类,以显示当前页面。但是,我找不到如何从呈现页面的EJS代码中获取URL。
我发现了两种解决方法:我使用了将页面名称作为参数传递给路由的res.render('myview', {pageName: 'myView'});
-这是不可扩展的,可能会引起问题。
另一种方法是,在客户端使用jQuery在页面准备就绪时将'active'
类添加到项目中-但这意味着在每个视图上都包含此脚本+一些无用的客户端周期。
以前使用过几种服务器端渲染语言,我感觉好像丢失了一些东西。而且在线EJS文档也不是很好。
有什么方法可以从EJS代码中找到我当前的路径/网址吗?
更新:我采纳了前2条建议,并将视图名称作为参数传递给视图。我真的很喜欢@tandrewnichols的想法来自动计算它,但是最终,仅复制粘贴字符串就很容易了:)
我使用的几乎每个节点/表达模板语言(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。
据我所知,除非您在内部修改EJS,否则您将无法满足您的要求。但是,较不麻烦的解决方案是在每次页面调用时传递请求的URL属性,而不是按路由定义它。
app.get('/url', function (req, res) {
res.render('view', {
page: req.url,
nav: {
'Page 1': '/page1',
'Page 2': '/page2',
'Page 3': '/page3'
}
});
});
[如果您只想获取URL的第一部分并进行匹配,则只需在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>
<% } %>
<% }) %>
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>
<% } %>
<% } %>