I study the MEAN conceptions by this video course by Joe Eames.
This course interesting because teach how to use JADE templates as partials instead of HTML.
\bin
\node_modules
\public
\app
\main
someCntr.js
otherCntr.js
main.js
\server
\views
\partials
main.jade
featured-courses.jade
new-courses.jade
And all was going well until he moved this jade templates from \views\includes to \public\app\main and \public\app\courses in his Express 3.4. This trick does not work in my Express 4
his server.js file before
app.set('views', path.join(__dirname, '/server/views'));
app.set('view engine', 'jade');
app.get('/partials/:partialPath', function(req, res) {
res.render('partials/' + req.params.partialPath);
});
and after moving
app.set('views', path.join(__dirname, '/server/views'));
app.set('view engine', 'jade');
app.get('/partials/*', function(req, res) {
res.render('public/app/' + req.params);
});
You have to update jade to it's latest version:
http://expressjs.com/guide/migrating-4.html
I'm studying this course too, and I come to same problem...
The solution is to use req.params[0]. In server.js file the route to partials views like this:
insted of
app.get('/partials/*', function(req, res) {
res.render('public/app/' + req.params);
});
write:
app.get('/partials/*', function(req, res) {
res.render('../../public/app/' + req.params[0]);
});
Related
app.js
app.engine('.hbs', expressHbs({
defaultLayout: 'layout',
extname: '.hbs',
layoutsDir:'views/layouts',
partialsDir:'views/partials'
}));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', '.hbs');
app.use(express.static(path.join(__dirname, 'public')));
it work correctly in this route [admin.js]
router.get('/', function(req, res, next){
res.render('admin/admin', {title: 'Admin'});
});
});
//will render http://localhost:3000/admin
however, when i add new route in [admin.js]
router.get('/insert-scene', function(req, res, next){
res.render('admin/insert-scene', {title: 'Insert Scene'});
});
//will render http://localhost:3000/admin/insert-scene
example:
<link href="./stylesheets/site.css" rel="stylesheet">
http://localhost:3000/public/stylesheets/site.css[work][/admin]
http://localhost:3000/admin/stylesheets/site.css[wrong path][/admin/insert-scene]
public folder not work in this route so hbs view just render /admin/.... in my ref source. How to solve this problem?
Do not serve static files with node, while node can handle it, it's not the intended use case of the technology.
Use a specific web server for that like nginx or a CDN.
If I path to a view in ./views express will render it but it doesn't that for example ./views/api/login.jade and it send 500: Internal Server Error.
my codes:
/* GET api/... */
router.get('/login', function(req, res, next) {
res.render('api/login.jade', { title: 'Login' });
});
Thanks
You have to set the views path as well.
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
router.get('/login', function(req, res, next) {
res.render('api/login', { title: 'Login' });
});
step 1: you have to make sure you are using jade as the view engine.
app.set('view engine', 'jade');
step 2: set view path
app.set('views', __dirname);
or you can write it in every render call, res.render(__dirname+'api/login')
Step 3: do not write extension names
router.get('/login', function(req, res, next) {
res.render('api/login', { title: 'Login' });
});
P.S.
i recommend that you start using pug instead of jade since pug is jade 2.0
I've got a pretty basic expressjs application with the / route loading a view located in views/main/. However, I'm getting the following error:
Error: Failed to lookup view "main/index" in views directory "/Users/n0pe/Sync/src/proj/views/"
Here's my structure (omitting the unimportant):
/proj
/views
/main
index.hbs
app.js
And here's my app.js (the important parts):
var express = require('express');
var app = express();
app.set('views', __dirname+'/views/');
app.set('view engine', 'handlebars');
And here's the controller:
router.get('/', function(req, res, next) {
res.render('main/index', {title: 'test'});
});
What's missing from this pretty basic setup?
I tested it in local and everything works. Just one mistake
from app.set('view engine', 'handlebars'); to app.set('view engine', 'hbs');
my example
var express = require('express'),
app = express();
app.engine('html', require('hbs').__express);
app.set('views', __dirname+'/views/');
app.set('view engine', 'hbs');
app.get('/', function(req, res) {
res.render('main/index',{title :"page index"});
});
app.listen(3000);
I changed two things and it worked for me.
First
app.set('views', [path.join(__dirname, 'views'),path.join(__dirname, 'views/main')]);
I passed an array to the app.set and added the subdirectory
Second
res.render('../main/index', {title :"page index"}, function(err, html) {
console.log(err);
});
I changed the directory path to relatively navigate from the parent directory.
Using the ../ makes it work somehow. Also, once you add the directory to the app.set, you can call index directly e.g., res.render('index',...
Change your set views. it should be
app.set('views', path.join(__dirname, 'views'));
I think you need to change the file extension of the views from hbs to handlebars
I'm stuck on it since Friday, please.. somebody help me!!!
I have this route in my app.js:
app.get('/', function(req, res) {
res.render('login', {
user: req.user
});
});
He is rendering the layout inside the views folder, which is inside the server folder.
I have this configuration in my app.js:
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
It's not working put:
app.set('views', __dirname + '../public');
Because it's searching like this:
"app/server../public"
and i need this:
"app/public"
Please, if someone know fix this, please help me!
Always use the path module to join paths.
var path = require('path');
var uri = path.join(__dirname, '../public');
I want to build a simple app using node.js that 'functions' like IIS/classic ASP where all the content (html, png, js, css, ejs) can be in one directory and the ejs file uses javascript vs. VBScript.
I've gathered the following from API's and other examples, but the ejs file arrives at the browser as a binary and gets saved....
My node.js file:
var express = require('express');
var app = express();
app.use(app.router);
app.use(express.static(__dirname + '/html'));
app.engine('.ejs', require('ejs').__express);
app.set('views', __dirname + '/html');
app.set('view engine', 'ejs');
app.get('*.ejs', function(req, res) {
res.render(__dirname + '/html' + req.url, function(err, result) {
res.end(result);
});
});
app.listen(8080);
My test.ejs file:
<!DOCTYPE html>
<html>
<head><title>A test</title></head>
<body>
My Test Page
<% if (1==1) { %>
Working
<%}%>
</body>
</html>
What am I missing or where can I find a working example?
I FIGURED IT OUT... SOLUTION ADDED ABOVE
express.js won't magically try to render static files, you have to explicitly call render somewhere.
I believe something like this would work:
var express = require('express')
var app = express()
app.engine('.ejs', require('ejs').__express)
app.set('views', __dirname + '/html')
app.set('view engine', 'ejs')
app.use(app.router) // only in express 3, remove that in express 4
app.get('/test.html', function(req, res, next) {
res.render('test.ejs')
})
app.use(express.static(__dirname + '/html'))
app.listen(8080)
I believe is not necessary to run render in every place, I use this example to render my static content by migrating express 2.3.7 to 4 and works fine with :
app.engine('.ejs', require('ejs').__express);
app.set('views', __dirname + '/public')
app.set('view engine', 'ejs')
app.use(express.static(__dirname + '/public'))
My static content is in 'public' directory.
I just want to add that express supports EJS out of the box these days:
https://expressjs.com/en/starter/generator.html