使用express时在EJS视图中查找当前url

Finding current url inside EJS view when using express

本文关键字:查找 url 视图 express 时在 EJS 使用      更新时间:2023-09-26

我正在使用Express和EJS来提供页面。我使用Bootstrap作为UI,特别是导航栏。

我想在当前页面的<li>项中添加一个'active'类,以显示当前页面。但是,我找不到如何从呈现页面的EJS代码中获取URL。

我找到了两个解决方案:我使用include将页面名称作为路由的res.render('myview', {pageName: 'myView'});中的参数进行传递,这是不可扩展的,可能会导致问题。

另一种方法是在客户端使用jQuery,在页面就绪时将'active'类添加到项目中,但这意味着在每个视图中都包含这段脚本+一些无用的客户端循环。

以前使用过几种服务器端渲染语言,我觉得我缺少了一些东西。在线EJS文档也不是很好。

有没有办法从EJS代码中找到我当前的路径/url?

更新:我接受了前两个建议,并将视图名称作为参数传递给视图。我真的很喜欢@tandrewnichols自动计算它的想法,但最终,只复制粘贴字符串更容易:)

据我所知,除非您在内部修改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的第一部分并与其匹配,那么您可以在req.url上调用split('/')。然后,您可以在模板文件中放置一个循环,为导航栏创建列表。

<% 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>
  <% } %>
<% }) %>

在我使用过的几乎每一种node/express模板语言(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.

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>
        <% } %>
    <% } %>