Finding current url inside EJS view when using express

耗尽温柔 提交于 2019-11-27 07:50:25

问题


I'm using Express and EJS to serve pages. I'm using Bootstrap for the UI, specifically the navbar.

I'd like to add an 'active' class to the current page's <li> item, to show the current page. However, I cannot find how to get the URL from within the EJS code rendering the page.

I found 2 workarounds: I used included passing the page name as a parameter in the route's res.render('myview', {pageName: 'myView'}); - which is not scalable and may cause issues.

The other way, was to use jQuery on the client side to add the 'active' class to the item upon page ready - but that means including this piece of script on every view + some useless client side cycles.

Having used several server side rendering languages before, I feel like I'm missing something. And the online EJS documentation is not that great.

Is there any way to find my current path/url from the EJS code?

Update: I took the top 2 suggestions, and passed the view name as a parameter to the view. I really liked @tandrewnichols' idea to calculate it automatically, but ultimately, it was easier to just copy-paste strings :)


回答1:


In pretty much every node/express templating language I've used (ejs, kiwi, swig, jade), the answer is no. I've always just set a variable called "active" and then checked for it. As you say, it's not a great answer, though I don't know that scalability is the issue. If every url renders it's own view (or even if you have a common handler for view rendering), it shouldn't be that hard to say something like req.active = "Somepage". Another possibility would be to add middleware that does it for you based on the route. Something like

app.use(function(req, res, next){
    req.active = req.path.split('/')[1] // [0] will be empty since routes start with '/'
    next();
});

Then you just make sure any routes that have a corresponding nav component use unique paths, like

app.get('/students', ....)
app.get('/classes', ....)
app.get('/teachers', ....)
// etc.

EDIT: In response to your comment, I always throw ALL my view stuff into one object key inside req, and usually I name the key by whatever templater I'm using. So I would probably actually use the above example to set req.ejs.active and then do

res.render('myview', req.ejs);

This method makes it much easier to separate logic out into multiple middleware functions and not have to pass a huge anonymous object to res.render.




回答2:


As far as I know, you can't do what you're asking for unless you modify EJS internally. However, a less bothersome solution would be to pass the URL property of the request on each page invocation, rather than define it per route.

app.get('/url', function (req, res) {
  res.render('view', {
    page: req.url,
    nav: {
      'Page 1': '/page1',
      'Page 2': '/page2',
      'Page 3': '/page3'
    }
  });
});

If you only wanted to get the first part of the URL and match it, then you could just call split('/') on req.url. You could then put a loop inside your template file to create the list for your navigation bar.

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



回答3:


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>

        <% } %>
    <% } %>


来源:https://stackoverflow.com/questions/18501402/finding-current-url-inside-ejs-view-when-using-express

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!