2

Basically I want to build a site wide navigation bar that contains links as specified in the local variables in express.js

So I build my list of links I want to include on a page:

class NavigationLink
  constructor: (@title,@url) ->

app.use (req,res,next) ->
  res.locals.navigationLinks = [
    new NavigationLink "About", "/about"
    new NavigationLink "Projects", "/projects"
    new NavigationLink "Skills", "/skills"
    new NavigationLink "Contact", "/contact"
  ]
  next()

Then if I hit the home page:

app.get '/', (req,res) ->
  res.render('about')

Jade tries to render this layout file, which is supposed to loop through the navigationLinks array and render for each one:

!!! 5
html
include header
body
    .container
        .row
            .span3
                ul.nav.nav-tabs.nav-stacked
                    for navigationLink in navigationLinks
                        include navigationLink
            .span9
                block content

However I am getting a reference error 'navigationLinks is not defined' which I assume to mean to mean the locals aren't getting passed through. Would love advice on how to fix the problem, or another design paradigm that is better suited for this kind of thing (dynamic building of links on every page of the site). Thanks!

Msencenb
  • 5,675
  • 11
  • 52
  • 84

1 Answers1

3

Jonathan Ong is correct. Your code above should work in the default middleware order which would run all the app.use middleware before the app.router middleware. Thus I would agree that elsewhere in your code you probably have a line app.use app.router that comes before the app.use in your code snippet.

Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
  • Ok so I have verified that the code I had before works when I put app.router below it. Peter's original code using app.locals also works. Convention wise, which way is better? App.locals or setting res.locals like I do above? – Msencenb Aug 25 '12 at 23:01
  • 2
    `res.locals` makes more sense for data that is specific to this request like `res.locals.currentTemp` in your `/weather` route. `app.locals` is better for things that most or all of your views will need. In your case, if most of your views use the same layout, it seems appropriate to use `app.locals.navigationLinks` – Peter Lyons Aug 26 '12 at 02:26