Serving a mix of static and dynamic content with node.js & express

This is similar to entry 21105801, but not quite.

(Versions: express@4.7.2, node@0.10.29)

I'm trying to create one route that will serve either a dynamic page if it is found or pass to a static router (via next()) if not.

My route should operate like this, app.get('/' -> authenticate -> try to serve dynamic -> try to serve static.

I've added an authorize route that handles Oauth 1 & 2, and everything was working fine with just static pages. But I would like to serve customized pages after authentication and there are three problems I've encoutered.

  1. I don't want to explicitly serve every dynamic page by name using 'render()' so I build the filepath by hand and bypass the 'view' logic. This works for the HTML, but...
  2. it doesn't work for the JS and CSS that I use for my Foundations. In fact, render() never calls the callback with an error because it can't find the css/js files, it even thinks the path is a module?
  3. Seems odd that the view engine requires everything to be in one view path. Or am I missing an obvious design pattern?

Here is the route:

app.use(
    "/", // i like being pedantic
    authorize, // pass through the auth filter
    function(req, res, next) { // try to serve dynamic page
        // build the filename
        var file = __dirname + '/restricted' + req.url;
        console.log("Rendering file "  + file);
        res.render(file, { username: req.user.username } , function(err, html) {
            if (err) {
                console.log("ERROR: " + err);
                next(); // pass to static router
            } else {
                res.send(html); // or send the page
            }
        })
    },
    // fallthrough route for js/css statics
    express.static(__dirname + "/restricted")
);

Here's the error, it is trying to read index.html which calls a CSS template and JS rel.

GET /auth/twitter/callback?oauth_token=... 302 329.979 ms - 78
Rendering file /home/pt/www/restricted/index.html
ERROR: null
       ^---- this worked!
GET /index.html 200 7.097 ms - 838
Rendering file /home/pt/www/restricted/css/foundation.css
               ^---- that's the file I want to read!
GET /css/foundation.css 500 9.846 ms - 871
    ^---- keep going!!!
Error: Cannot find module 'css'
                   ^---- DOH! Why does it look for a module?!?!? Why no error callback?
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)

Thanks in advance.

I think I'm trying to do something really obvious but just about all of the dynamic view engine examples call res.render('filename') for each explicit file which seems absurd: why change your router code every time you add a new dynamic page?