I'm trying to work on Peepcode's Node.js Full Stack videos and it seems they're using an older version of express/jade. No mention of using block/extends to render layouts.
The setup used in the app is to have a /views/layout.jade file that loads for all sub-apps. The sub-apps' views are located in /apps//views.
My server.js seems pretty standard. Express is version 3.0.0rc1
require('coffee-script');
var express = require('express')
, http = require('http')
, path = require('path');
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
require('./apps/authentication/routes')(app)
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
My routes file for the sub-app is in /apps/authentication/routes
routes.coffee
routes = (app) ->
app.get "/login", (req,res) ->
res.render "#{__dirname}/views/login",
title: "Login"
stylesheet: 'login'
module.exports = routes
The view I intend on rendering for this.
login.jade
extends layout
block content
form(action='/sessions', method='post')
label
| Username
input(type='text', name='user')
label
| Password
input(type='password', name='password)
input(type='submit', name='Submit')
And Finally the layout.
doctype 5
html
head
title= title
link(rel='stylesheet', href='/stylesheets/#{stylesheet}.css')
body
block content
Going to localhost:3000/login renders this:
Express 500 Error: /Users/StevenNunez/code/HotPie/apps/authentication/views/login.jade:1 > 1| extends layout 2| 3| block content 4| form(action='/sessions', method='post') ENOENT, no such file or directory '/Users/StevenNunez/code/HotPie/apps/authentication/views/layout.jade'
My folder structure:
.
├── '
├── apps
│ └── authentication
│ ├── routes.coffee
│ └── views
│ └── login.jade
├── package.json
├── public
├── server.js
└── views
├── index.jade
└── layout.jade
Thank you for your time.
It looks like I had to just give the relative path in the extends call.
extends ../../../views/layout
block content
form(action='/sessions', method='post')
label
| Username
input(type='text', name='user')
label
| Password
input(type='password', name='password')
input(type='submit', name='Submit')
I didn't have to set app.set('view options',{layout:false});
You can use variable __dirname to connect views from other directories.
Example:
app.get('/otherurl/' , (req, res) => {
res.render(`${__dirname}/../other_project/views/index`)
});
You are trying to use two methods of rendering...
The first layout that extends the layout and the second is block content.
When using a layout you are extending automatically the layout file in the folder of login.jade.
It isn't necessary to use extends and you can't use block sentence, but if you want to use extends you have to disable layout.
Add this to the app:
app.set('view options',{layout:false});
after
app.set('view engine', 'jade');
and extend the files like layout extends:
layout.jade
doctype 5
html
head
title= title
link(rel='stylesheet', href='/stylesheets/#{stylesheet}.css')
body
block content
login.jade
extends layout
block content
form(action='/sessions', method='post')
label
| Username
input(type='text', name='user')
label
| Password
input(type='password', name='password)
input(type='submit', name='Submit')
The login file has to be in the same dir. If you want to call other layout you can use the dir like this:
appDirectory
views
layout
otherViews
login
login.jade
extends ../views/layout
block content
form(action='/sessions', method='post')
label
| Username
input(type='text', name='user')
label
| Password
input(type='password', name='password)
input(type='submit', name='Submit')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With