I have come up with the following code but the problem is, there will be duplication of the anchor tag for each menu item.Is there a better way to do this?
You can pass the pageName in the data.
each menu in ["Home", "Dashboard", "Contact", "About"]
if (menu == pageName)
li.active
a(href="/#{menu}")= menu
else
li
a(href="/#{menu}")= menu
You can call render
res.render("index", { pageName: 'Home'})
res.render("index", { pageName: 'Dashboard'})
res.render("index", { pageName: 'Contact'})
Very flexible without duplication:
ul
each menuitem in [{title:'Home',url:'/'},{title:'About',url:'/about'},{title:'Contact',url:'/contact'}]
if (menuitem.title == title)
li.active
a.active(href=menuitem.url) #{menuitem.title}
else
li
a(href=menuitem.url) #{menuitem.title}
You need to set the page's current title.
I think it's better to set a body class to current path like so
body(class = currentPath)
So you can then use selectors such as
body.home .nav li.home, body.dashboard .nav li.dashboard {
Style when current path
}
These selectors can be reduced to the minimal 'body.path .path' but it may be not isolated enough.
This will also be useful in the client side logic as this selectors could be used to determine the path in your JavaScript with something like
$("body.home").doSomethingSpecificToHome
This way your template has lot less logic.
Now, I don't think there is a way to set "currentPath" automatically depending on the URL. An helpers based on a 'url':'path' may be useful.
Here's an alternative that provides more flexibility in terms of anchor text and href
than Peter's solution.
nav
// suppose title local denotes the active nav item
- var nav = {}; nav[title] = 'active'
ul
// pass title to li class via nav object
li(class='#{nav.Home}')
// different href and anchor text
a(href='/') Home
li(class='#{nav.About}')
a(href='/about') About
li(class='#{nav.Contact}')
a(href='/contact') Contact
The caveat is that those li
that are not active will have an undefined
class, which does no harm in most cases.
Found this in another question that was similar:
Use a ternary at each "li"
ul
li(class=(title === 'Home' ? 'active' : ''))
a(href='#') Home
li(class=(title === 'Dashboard' ? 'active' : ''))
a(href='#') Dashboard
You can setup your routes to pass the "menu" value instead of using "title" if you want:
exports.index = function(req, res) {
res.render('index', {title: 'Home', menu: 'Home'});
}
This has a little less duplication.
ul.nav
each name in ["Dashboard", "About", "Contact"]
if (menu=="Home")
li.active
a(href="#")= name
else
li
a(href="#")= name
Adding the active
class might be better just done in javascript or perhaps you can get the presentation you need with the straight CSS a:active
selector.