I am trying to get dustjs-linkedin working with an express 3 project, however I can't seem to get past this error:
Error: Template name parameter cannot be undefined when calling dust.compile
at Object.compiler.compile (/home/user/project/node_modules/dustjs-linkedin/lib/compiler.js:21:16)
at Object.dust.compileFn (/home/user/project/node_modules/dustjs-linkedin/lib/dust.js:109:37)
at Function.exports.dust.render (/home/user/project/node_modules/consolidate/lib/consolidate.js:226:56)
at /home/user/project/node_modules/consolidate/lib/consolidate.js:146:25
at /home/user/project/node_modules/consolidate/lib/consolidate.js:99:5
at fs.js:266:14
at Object.oncomplete (fs.js:107:15)
I can reproduce this with a brand new express 3 project like so:
app.js
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var app = express();
// added these 3
var dust = require('dustjs-linkedin');
var cons = require('consolidate');
app.engine('dust', cons.dust);
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
// added this 1
app.set('view engine', 'dust');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
package.js
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.4.7",
"dustjs-linkedin": "*",
"consolidate": "*"
}
}
routes/index.js
exports.index = function(req, res){
res.render('index', { title: 'Express' });
views/index.dust
Title: {title}
The strange thing is, I have a project using express 3 and dustjs-linkedin that is working just fine. I ran a diff on the files in the dustjs-linkedin module and the working version has a lot of files in dist while the project throwing the error only has a few, namely:
working/node_modules/dustjs-linkedin/dist:
dust-core.js dust-core.min.js dust-full.js dust-full.min.js LICENSE
workingProject/node_modules/dustjs-linkedin/dist:
dust-core-1.1.1.js dust-core-2.0.0.min.js dust-full-1.2.0.js dust-full-2.0.1.js
dust-core-1.2.0.js dust-core-2.0.1.js dust-full-1.2.1.js dust-full-2.0.2.js
dust-core-1.2.1.js dust-core-2.0.2.js dust-full-1.2.2.js dust-full-2.0.3.js
dust-core-1.2.2.js dust-core-2.0.3.js dust-full-1.2.2.min.js dust-full-2.1.0.js
dust-core-1.2.2.min.js dust-core-2.1.0.js dust-full-1.2.3.js dust-full-2.2.0.js
dust-core-1.2.3.js dust-core-2.2.0.js dust-full-1.2.3.min.js dust-full-2.2.2.js
dust-core-1.2.3.min.js dust-core-2.2.2.js dust-full-1.2.4.js dust-full-2.2.2.min.js
dust-core-1.2.4.js dust-core-2.2.2.min.js dust-full-1.2.5.js dust-full-2.2.3.js
dust-core-1.2.5.js dust-core-2.2.3.js dust-full-1.2.6.js dust-full-2.2.3.min.js
dust-core-1.2.6.js dust-core-2.2.3.min.js dust-full-2.0.0.js
dust-core-2.0.0.js dust-full-1.1.1.js dust-full-2.0.0.min.js
This demo of a 'working' project gives me the same error:
https://github.com/chovy/express-template-demo
[Edit]
An issue is discussed here:
https://github.com/linkedin/dustjs/commit/e5ebff0f7b32f8ff0883be7f7924507b314eef1d
In [/node_modules/]consolidate/lib/consolidate.js go to exports.dust.render function:
...
try {
var tmpl = cache(options) || cache(options, engine.compileFn(str));
tmpl(options, fn);
} catch (err) {
fn(err);
}
...
engine.compileFn is called sending str as parameter, str is actually the template itself:
Title: {title}
engine.compileFn is compiler.compile(source, name) in [/node_modules/]dustjs-linkedin/lib/compiler.js.
source is template sent, however name which is the template name and should be index in our case, is never set (undefined).
Alternatively, I prefer to use Payapl's Adaro library for express 3.x and linkedin-dustjs. It's part of their project kraken.js, but can be used as a standalone dust wrapper for express:
https://github.com/paypal/adaro
As mentioned in README.md:
var express = require('express');
var dustjs = require('adaro');
var app = express();
app.engine('dust', dustjs.dust({});
app.set('view engine', 'dust');
// For rendering precompiled templates:
// app.engine('js', dustjs.js({ ... ));
// app.set('view engine', 'js');
Related
I'm trying to define some Node routes using Coffeescript in the following way:
My app.js file:
/**
* Module dependencies.
*/
require('coffee-script');
var express = require('express');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
require('./routes')(app);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
My routes.coffee file (located at the same level as app.'s):
routes = (app) ->
app.get '/login', (req,res) ->
res.render "views/login",
title: 'Login'
stylesheet: 'login'
module.exports = routes
My issue are:
1 when I try to run node app - I get:
module.js:340
throw err;
^
Error: Cannot find module './routes'
If I explicitly specify the .coffee suffix: require('./routes.coffee')(app); - I get:
routes = (app) ->
^
SyntaxError: Unexpected token >
What is the proper way of doing this, please?
In CoffeeScript 1.7, the line require('coffee-script') no longer allows you to require CoffeeScript files. Instead, you need to either:
require('coffee-script/register')
or
require('coffee-script').register()
See the documentation.
I am working on a single page web app with node/angular and jade. I am fairly new to angular, and I wanted to know what I have to do with my app.js file so that my first page template loads from my angular file rather than from my jade template.
I structured my files as such:
public/
index.html
javascript/
img/
stylesheets/
routes/
index.js
views/
partials/
a.jade
b.jade
app.js
This is what my app.js looks like:
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.cookieParser('cookies monster')); // Cookie secret
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
/*
* Views
*/
app.get('/', routes.index);
app.get('/a', routes.a);
app.get('/b', routes.b);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
My index.js looks like this:
exports.index = function(req, res){
res.render('index', { title: 'Test Application' });
};
// View A
exports.a = function(req, res) {
res.render('partials/a', { layout: false, test: 'LOL' });
};
// View B
exports.b = function(req, res) {
res.render('partials/b', { layout: false, test: 'YOLO' });
};
When I run this, It does not use the index.html as the first page. How would I go about doing so, so that the initial page template is actually the index.html? I can't seem to find the answer anywhere.
You could return the actual index.html file from your router.
app.get('/', function(req, res, next){
return res.sendfile(app.get('public') + '/index.html');
});
I should note that I also put app.set('public', path.join(__dirname, 'public')); inside app.js for easy access to the public directory.
I've been playing around with node using jetbrains webstorm IDE. Last night I was trying to setup nib and bootstrap-stylus. However I always get an error that nib or bootstrap cant be found in the import tags.
#import 'nib'
or
#import 'bootstrap'
however if i use
#import '../../node_modules/bootstrap-stylus/lib/bootstrap'
everything works as expected. I don't think this is the right way? there must be some way to tell stylus where to look for imports?
my app.js looks like this
/**
* Module dependencies.
*/
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var nib = require('nib');
var bootstrap = require('bootstrap-stylus');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
function compile(str, path) {
return stylus(str)
.set('filename', path)
.set('compress', true)
.use(nib());
}
app.use(stylus.middleware({
src: path.join(__dirname, 'public')
, compile: compile
}));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
Thanks!
It should be as simple as rewriting your compile() function as follows:
function compile(str, path) {
return stylus(str)
.set('filename', path)
.set('compress', true)
.use(nib())
.use(bootstrap()); // each plugin has to be loaded
}
More information about plugin usage and stylus can be found here: https://gist.github.com/jenius/8263065
And in the official documentation: http://learnboost.github.io/stylus/docs/js.html#usefn
I want to run Express 3.3.x with its default implementation.
Express uses its routes module, so what I have to do, if JS and CSS is accessible by any view in any route?
/**
* Module dependencies.
*/
var express = require('express');
var http = require('http');
var path = require('path');
var piler = require('piler');
var mongoose = require('mongoose');
var config = require('./config');
var app = exports.app = express();
var js = piler.createJSManager();
var css = piler.createCSSManager();
var srv = require('http').createServer(app);
// all environments
js.bind(app,srv);
css.bind(app,srv);
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(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
js.addUrl("http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.js");
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
/**
* Routes
*/
var routes = require('./routes');
app.get('/', routes.index);
srv.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
In the example of piler:
app.get("/", function(req, res){
res.render("index.jade", {
layout: false,
js: js.renderTags(),
css: css.renderTags()
});
});
This works. But I have
app.get('/', routes.index);
So what I have to do, that js.renderTags() works in every view?
If you are trying to pass variables to render, you can use res.locals
app.use(function(req,res,next){
res.locals.layout= false;
res.locals.js= js.renderTags();
res.locals.css= css.renderTags();
next();
});
Use this before your router but don't overwrite your locals (res.locals={...})
A razor view engine for nodejs.
https://github.com/nufyoot/kally-razor
I have tried something like this.. but no luck.
var razor = kallyrazor({
root: __dirname + '/views/',
layout: 'shared/layout.html'
});
app.engine('html', function (path, options, fn) {
fn(null, razor.render(path, options));
});
Worked for me. Did you include the view engine?
app.set('view engine', 'cshtml');
Note: I chose the use the cshtml extentionm just for vanity.. (And also in Sublime if that is your editor the razor syntax highlighter, https://github.com/joseph-turner/Razor)
Full code:
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var KallyRazor = require('kally-razor');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'cshtml'); // NOTE THE VIEW ENGINE
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// Setup KallyRazor
var razor = KallyRazor({
root: __dirname + '/views/',
layout: '/shared/layout.cshtml'
});
app.engine('cshtml', function (path, options, fn) {
fn(null, razor.render(path, options));
});
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});