使用Express时在EJS视图中查找当前URL

问题描述 投票:6回答:3

我正在使用Express和EJS来提供页面。我在UI上使用Bootstrap,尤其是在导航栏上。

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

我发现了两种解决方法:我使用了将页面名称作为参数传递给路由的res.render('myview', {pageName: 'myView'});-这是不可扩展的,可能会引起问题。

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

以前使用过几种服务器端渲染语言,我感觉好像丢失了一些东西。而且在线EJS文档也不是很好。

有什么方法可以从EJS代码中找到我当前的路径/网址吗?

更新:我采纳了前2条建议,并将视图名称作为参数传递给视图。我真的很喜欢@tandrewnichols的想法来自动计算它,但是最终,仅复制粘贴字符串就很容易了:)

javascript node.js express ejs
3个回答
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。


19
投票

据我所知,除非您在内部修改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>
  <% } %>
<% }) %>

0
投票

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>

        <% } %>
    <% } %>
© www.soinside.com 2019 - 2024. All rights reserved.