I'm starting with the boilerplate code express generates for me. I'm requiring dustjs-linkedin
and compiling some simple templates in app.js
like so:
var dust = require('dustjs-linkedin');...
app.set('view engine', 'dust');...
var compiled = dust.compile("Hello {name}!","intro");
// add into dust.cache manually
dust.loadSource(compiled);
console.log(dust.cache);
dust.render("intro", {name: "Fred"}, function(err, out) {
if(err){console.log(err)}
console.log(out);
});
This is all works well and I see the HTML outputted in my terminal. Its only when I try and do the same thing from within a route when I start getting this error:
GET / 500 11.607 ms - 904
Error: Cannot find module 'dust'
app.get('/', function(req, res){
var compiled = dust.compile("Hello {name}!", "intro");
dust.loadSource(compiled)
dust.render("intro", {name: "Fred"}, function(err, out) {
console.log(out);
res.send(out);
res.close();
});
});
This is all within app.js
, only it works outside of a route, but not when I move it into a route callback. Does anyone know why it can't find 'dust'? I've required it and it should be visible from within the callback right?
Thanks for any help!
Edit 1 As per the comment below, 'dust' is getting required somewhere. I'm not doing it in my code; my guess is that Express is doing it behind the scenes because my templates have '.dust' file ending. I just tried deleting all my templates (wasn't using them anyways) and now I just get this error:
Error: Failed to lookup view "error" in views directory
All I want is to see the output: "Hello Fred"
Edit 2: I think I found what was wrong
Everything Interrobang posted is correct. The problem, I think, was this middleware block that was generated for me by express-generator:
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
So for every request, this middleware would fire and throw an error. I'm not 100% sure what its doing but if I comment it out, everything works. My secondary question now, if I may have one, is what exactly is going on and why is it set for all requests?
You're setting the view engine
to dust
, but you haven't registered an engine with Express to tell it how to render Dust-- and Express can't do it by default.
Consider using consolidate
, hoffman
, or adaro
(among others) as your Dust rendering engine for Express.
Here's a complete example using consolidate. I have tested and this works on my machine.
var express = require('express'),
cons = require('consolidate'),
app = express();
// assign the dust engine to .dust files
app.engine('dust', cons.dust);
// set .dust as the default extension
app.set('view engine', 'dust');
app.set('views', __dirname + '/views');
app.get('/', function(req, res) {
res.render('index', { name: 'Interrobang' });
});
app.listen(3000, function () {
console.log('Visit http://localhost:3000 woo!');
});
Alternatively, simply remove the view engine
line from your code. You're not using Express to do the rendering, so Express doesn't even need to know.
Here's a very simple example without any view engine that I've tested to work. Your Dust templates go in a folder called views
.
var fs = require('fs'),
path = require('path'),
express = require('express'),
dust = require('dustjs-helpers');
dust.config.whitespace = true;
dust.onLoad = function(tmpl, cb) {
fs.readFile(path.join('./views', path.resolve('/', tmpl + '.dust')),
{ encoding: 'utf8' }, cb);
};
var app = express();
app.get('/', function (req, res) {
dust.stream("hello", { "world": "World!" }).pipe(res);
});
app.listen(3000, function () {
console.log('Visit http://localhost:3000 woo!');
});