I am not able to use Swig templates with Express for Node.
I get the following error :
Error: Failed to lookup view "index" in views directory
The Swig templates are not being compiled into .html files
My code is below :
var express = require('express');
var cons = require('consolidate');
var swig = require('swig');
var app = express();
//Set template engine
app.engine('html', cons.swig);
app.set('view engine', 'html');
app.set('views', __dirname + '/views')
// Disable Express's and Swig Cache
app.set('view cache', false);
swig.setDefaults({ cache: false });
app.get('/', function(req, res){
res.render('index', {'title': 'Design'});
});
app.listen(3000);
I just had the same issue. In order to use swig templates with the swig extension working you can follow the swig Docs and then replace the two following lines with
app.engine('html', cons.swig);
app.set('view engine', 'html');
with
app.engine('swig',swig.renderFile);
app.set('view engine', 'html');
Should look something like this.
var express = require('express');
var swig = require('swig');
var app = express();
// view engine setup
// This is where all the magic happens!
app.engine('swig', swig.renderFile);
app.set('view engine', 'swig');
app.set('views', path.join(__dirname, 'views'));
app.set('view cache', false);
swig.setDefaults({ cache: false });
Expressjs 4.x docs app.engine
The app.engine takes a extension and a callback. So to all files found with the swig extension have a callback of swig.renderFile. Each file with generated to HTML.
Expressjs 4.x docs app.set
Setting the view engineto swig is setting the default engine extension to use when omitted. Were also saying that all the views can be found in the /blaha/blaha/blah/views directory.
NOTE: All files in the views directory must end int .swig.
So just a friendly reminder make sure when you "include" or reference another template you must put the filename and extension it the path. ex: layout.swig. I hope this gets your project working.
As explained here:
http://mherman.org/blog/2015/08/23/primer-on-swig-templating/#.VhWxVvlVhBc
Simply use .html files instead of .swig files. I don't know where you got the idea of using .swig files. Maybe an older version? I dunno. The current Swig's documentation Basic Usage shows using a .html file as well:
http://paularmstrong.github.io/swig/docs/
If you rename your index.swig to index.html I would expect it to work fine.
Yes, i think it's more semantic to store your templates as .swig files, if you using SWIG as template engine. So, all you need is set 'swig' as engine:
// view engine setup
app.engine('swig', swig.renderFile);
app.set('view engine', 'swig');
app.set('views', path.join(__dirname, 'views'));
Then you can store your views like ./views/layout.swig
for latest version of swig we need to include swig package which needed to installed through package manager or package.json file
var express = require('express');
var swig = require('swig');
var app = express();
// Here we need to set up and engine as per latest version of swig
//for latest version of swig we need to include swig package which //needed to installed through package manager or package.json file
app.engine('swig', swig.renderFile);
app.set('view engine', 'swig');
app.set('views', path.join(__dirname, 'views'));
app.set('view cache', false);
swig.setDefaults({ cache: false });
//Here we are setting cache defaults to false.
`
Related
I use "express": "^4.14.0", "pug": "^2.0.0-beta6"
app.set('view engine', 'jade');
...
app.get('/', function (req, res) {
res.render('index.pug', {...});
}
When I use Express render function, it renders a template just once. If I change pug-template I'll get an old page version based on an already compiled template. For dev purposes, I need express recompiling .pug template for every render call. How can I achieve this?
I tried something like:
app.disable('view cache'); OR
app.set('view cache', false); OR
app.set('view cache', 'disabled');
But none of those were helpful.
Disappointing, but working:
const pug = require('pug');
const path = require('path');
res.send(pug.renderFile(path.join(__dirname,'template.pug'), templateObj));
I have a Node.js app. I've been building this app for a while and it currently uses Swig as the view engine. I'm setting it as the view engine using the following code:
// Use swig.
const swig = require('swig');
app.engine('html', swig.renderFile);
if (app.get('env') === 'development') {
swig.setDefaults({ cache: false });
}
app.set('views', path.join(__dirname, '../views'));
app.set('view engine', 'html');
This has been working well. However, I have some downtime so I thought now would be a good time to migrate to Nunjucks. So, I replaced the above with:
// Use nunjucks.
const nunjucks = require('nunjucks');
app.engine('html', nunjucks.renderFile);
if (app.get('env') === 'development') {
nunjucks.setDefaults({ cache: false });
}
app.set('views', path.join(__dirname, '../views'));
app.set('view engine', 'html');
When I start up my site, I now get an error. The error is:
throw new Error('callback function required');
^
Error: callback function required
at EventEmitter.engine (C:\MyProject\node_modules\express\lib\application.js:294:11)
at EventEmitter.module.exports (C:\MyProject\src\index.js:16:9)
at EventEmitter.configure
...
What am I doing wrong? What callback is being sought after? I know I'm going to have some syntactical errors once I start using the Nunjucks engine. However, I'm just trying to figure out how to get the Nunjucks engine loaded.
Templating engines usually have their own method of configuration. For Nunjucks, you should use this:
const nunjucks = require('nunjucks');
nunjucks.configure('views', {
express : app,
noCache : app.get('env') === 'development',
...
});
Documentation here.
I am trying to learn node.js.
I have the following code.
var express = require('express');
var app = express();
var port = process.env.PORT || 5000;
app.use(express.static('public'));
app.use(express.static('src/views'));
app.set('view engine', 'ejs');
app.get('/', function(req, res) {
res.render('index', { title: 'Hello from render', nav: ['Books', 'Author'] });
});
Failed to lookup view "index" in views directory
I have the file named index.ejs. How can I get rid of this error?
Try with
app.set('views', __dirname + '/views');
This is how I fixed it.
app.set('views', './src/views');
app.set('view engine', 'ejs');
I had the same problem too. I have saved the index file as .html file. But it should be index.ejs. then it worked. Check that too
For me it was a banal problem: when I named my 'views' folder, accidentally I typed a white space before the name, so the name was ' veiws', thus, ejs couldn't find the 'views' folder.
i fixed this error by writing below line befor my
app.set('viewengine' , 'ejs')
app.set('views',path.join(__dirname,'views'));
using path is more convenient ,also note to require path befor using it
I had the same issue, then I saved my index file inside the views folder. Now the issue is gone. Also add this line of code in your file
app.set('views', path.join(__dirname, '/views'))
I have a node.js application rendering in ejs 3 template.
let 's say -there is one template, course.ejs, it used to work well in node.js.
res.render('course', locals);
However, today when I tried to change the content, let 's say - course.ejs, it doesn't take effect, there is no error with node.js application and the data passed to the template is all right.
I even copy-pasted the content of this template, and make a new template with a different name - course1.ejs. and change my code to
res.render('course1', locals);
then when the app runs again, it pops up a error saying
Error: Failed to lookup view "course1" template.
The code in node.js and template are all right, it is supposed to work in the ways above. Why it doesn't work now. I have my ejs version 0.8.3, while express in 3.1.0 and node.js in 0.10.0
This is my app configuration.
app.configure(function(){
app.engine('.html', require('ejs').__express);
app.set('view engine', 'html');
app.set('views',__dirname+'/views');
app.use(express.favicon(__dirname + '/public/favicon.ico'));
app.use(express.compress({
filter: function (req, res) {
return /json|text|javascript|css/.test(res.getHeader('Content-Type'));
},
level: 9
}));
app.use(express.bodyParser({uploadDir:__dirname+'/public/uploads',keepExtensions: true,limit: '50mb'}));
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({
cookie: { maxAge: 24 * 60 * 60 * 1000 }
,store: sessionStore
,secret: config.sessionSecret
,key: 'express.sid'
,clear_interval: 3600
}));
app.use(express.csrf());
app.use(function(req, res, next){
res.locals.token = req.session._csrf;
next();
});
app.use(express.static(__dirname+'/public'));
}
my static files is in the public folder, and all the templates are in the view folder.
I wonder has anyone met this kind of problem before
I don't think this configuration can work if your templates have the .ejs extension:
app.engine('.html', require('ejs').__express);
app.set('view engine', 'html');
Using that configuration, Express will look for TEMPLATENAME.html when you call res.render('TEMPLATENAME', ...), and not TEMPLATENAME.ejs. For that, you need this:
app.engine('ejs', require('ejs').renderFile);
app.set('view engine', 'ejs');
So that's the course1 part solved: Express was looking for course1.html, which it couldn't find, so it would generate the error you got (Failed to lookup view...).
However, I don't see how rendering course.ejs could have worked. Perhaps you have another route which is handling the request you're testing? Or you have a course.html in the views folder (besides the course.ejs)?
How can I use a subfolder for my 'views'?
In the main 'app.js' I've set the root folder for the views like so:
app.configure(function(){
app.set('view engine', 'jade');
app.set('views', __dirname + '/apps' );
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(__dirname + '/apps' ));
app.use(app.router);
});
And my controller loos like this:
module.exports = function(req, res, base) {
res.render( 'hello/views/');
};
The folder looks like this:
./apps/hello/views/index.js
But still it can't find it. "ERROR: Failed to lookup view "hello/views"
Thanks!
Actually, I made a vastly better solution.
In the app configuration I just set the default view like so:"
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');
Later on I inlcude a boot.js (based on the mvc example of expressjs ) in which I include the following:
// allow specifying the view engine
if (obj.engine) app.set('view engine', obj.engine);
app.set('views', __dirname + '/../apps/' + name + '/views');
This will override the view folder to the one specified in the folder 'apps/xxx/views' and will even allow you to specify a new viewtype in the root of that folder like so:
// filename = /apps/hello/index.js
exports.engine = 'jade';
// Render the indexpage
exports.index = function(req, res, next){
res.render('hello');
};
I am surprised that your self answer works, since you should be telling express to render a particular view, and hello/views is a folder. However I'm not familiar with the code pattern you're using for your controller (the base argument is what's throwing me off, since Express middleware uses function(req,res,next).)
My routes look like this:
app.set('views', __dirname + '/apps' );
...
app.get('/hello', function(req,res){
res.render('hello/views/index')
});
In this case ./apps/hello/views/index.jade is a jade file, not a javascript file. If your templates are javascript, perhaps you should set view engine to something other than jade.
You can set views as array of paths
app.set('views', [path.join(__dirname, 'views/users/'), path.join(__dirname, 'views')])
You can check the resulting paths using app.get('views'); which should return an array.
[/server/views/users/, /server/views]
Express will search through the array for available paths. You can then render with just the file name like this
res.render( 'index');
res.render( 'profile');
I fixed this problem by setting the basis view to the root of the directory like so:
app.set('views', __dirname);
And the added the folders from the root on in the controller like so:
res.render( 'apps/hello/views/');