static javascript not rendering in jade (with express/node.js) - node.js

I hope you are well.
I'm suddenly unable to render any external javascript in jade templates! To get to the bottom of things, I stripped it down to the bare minimum :
Node 0.6.11, Express 2.5.8, jade 0.20.3
app.js
var express = require('express')
, routes = require('./routes');
var app = module.exports = express.createServer();
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
app.get('/', function(req, res){
res.render('index', { title: 'Express' });
});
app.listen(3000);
layout.jade
!!!
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
script(type='text/javascript', src='/javascripts/script.js')
body!= body
script.js
alert('hello!');
It seems to me that when I run the server and load http://localhost:3000/, I should straightaway get a 'hello!' message, but it just runs straight to the normal page.
What's more, if I manually type
script
alert('hello!')
into the layout.jade template I get the message just as I should. It is just not loading the static script. And I have certainly checked that 'script.js' is in '/public/javascripts/' just as it should be.
Any advice would be very welcome!!!
Thanks in advance

you need to pass your script from the controller like that:
app.get('/', function(req, res){
res.render('index', { title: 'Express', scripts: ['javascripts/script.js']});
});
and then in your head in layout.jade:
- each s in scripts
script(src=s)

Make sure your js files are exposed as static resources.
In layout.jade...
!!!5
html
head
script(src='js/helper.js')
In app.js...
app.use(express.static(__dirname + '/public'));
Once I put the 'js' folder under the 'public' folder, helper.js loaded without issue. Simple, but I'm new to this whole thing and I didn't get that at first.

Why do you have a beginning forward slash '/' in your Jade script tag? With your script in <root_dir>/public/javascripts/script.js, the correct way to reference it in Jade is script(src="javascripts/script.js"). At least that is what is working on my installation. The same is true for other assets like CSS or images in the /public directory.

Thanks to Rob (you can find his answer above), for pointing in right direction. I just want to add a little reference so it might seem more natural than any magic.
In the express documentation here, its mentioned that if static files like css, images etc are to be served then one need to declare it using
app.use(express.static("_dirName"));
I was facing same issue with using images in html code. With this, it works fine now.

Related

Express NodeJS Cannot find module 'html'

I have a Node Server with Express. I get the cannot find module 'html' error even though my code looks like this and should be correct in my opinion:
app.set('views', path.join(__dirname, 'build/views'));
app.use(favicon(path.join(__dirname, "build/favicon.ico")));
app.use('/scripts', express.static(path.join(__dirname, 'node_modules')));
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function(req, res){
res.render('index.html');
});
You have to set engine for HTML
Include this code in your main file
var engines = require('consolidate');
app.engine('html', engines.mustache);
app.set('view engine', 'html');
If you only want to serve a static file without passing any variables from the server to the client the easiest solution would be:
res.sendFile(path.join(__dirname + '/build/views/index.html'));
Especially when you are using AngularJS for the client side. The problem with the solution above is that mustache uses {{}} as variables recognition. So does AngularJS which might causes errors!
It seems that you are trying to display a static index.html file but you serve it as if it was a template. Probably Express is trying to find a module for html template format, which doesn't exist.
You may try to send the index as a static file instead of with res.render which is for rendering templates.
Some time ago I wrote an example of serving static files with Express. It's available on GitHub:
https://github.com/rsp/node-express-static-example
See also my other answer, where I explain it in more detail.

Express JS - 404 on static files

I cannot seem to get express 3.x to server up static files in my public directory. They all request end with 404.
var express = require('express')
, engine = require('ejs')
, app = express();
app.configure(function () {
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
});
app.get('/', function(req, res) {
res.render('test.ejs')
});
app.listen(3000);
My test.ejs is had references to the js files that look like so:
<script type="text/javascript" src="js/testscene.js"></script>
I must be overlooking something simple. I have the following folder structure:
project
-public
-js
testscene.js
-views ]
Can someone tell me what I've missed?
Update
I actually created a new project and copied my script into this new project and it works?!
I guess Ill just have to close this as some sort of localized weirdness. Thanks for all of your time.
__dirname is the directory where the current .js file resides. Your filesystem ascii art diagram omits this essential piece of the puzzle. If your first code snippet lives at project/server.js, for example, then that is correct. I think then loading http://localhost:3000 in your browser should properly find the js/testscene.js file. However, using relative URIs is usually a bad idea unless you really are sure you want/need it, so for the sake of sanity, change that to be src="/js/testscene.js".

Opening Page with Express

I have read around about this a lot and it seems like its an issue that confuses a lot people. I am doing a project with express and I dont want to you any tempting engines, I am using backbone with underscore and thats enough for me. I want to write plain HTML and render them..
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set("view options", {layout: false});
app.use(express.static(__dirname + '/views'));
app.set('views', __dirname + '/views');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use( express.cookieParser() );
app.use(express.session({ secret: 'topsecret' } ));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
this is what I have so far.. I am having a hard time to understand how express knows to render the index.html file as my home page even though I have this:
app.get('/', function(req, res){
console.log("Heyyyyyy");
});
I would expect nothing to be rendered and "Heyyyy" to be printed but express renders the index.html and doesnt print "Heyyyy"
Express evaluates middleware in the order in which they are configured.
You have a static file handler before your app.router.
Take the index.html file out of the __dirname + '/views' directory.
You also have a static file handler at the bottom of your middleware stack. Static file handlers should be at the top of your middleware stack. When they're at the bottom of your middleware stack each request unnecessarily processes all of the stack. For example, you don't need to run express.bodyParser() when serving static files.

Serve static files and app.get conflict using Express.js

I have this piece of code here:
var express = require('express')
, http = require('http')
var app = express();
var server = app.listen(1344);
var io = require('socket.io').listen(server);
app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'secret'}));
app.get('/', function(req, res){
if(req.session){
console.log(req.session);
}
console.log('ok');
});
The code inside the app.get() callback is not being called. If I comment out the app.use(express.static(__dirname + '/public')) line, then the callaback works. I've tried changing the order, but its like a lottery! I would prefer to know whats going wrong here.
I'm sure this have to do with lack of knowledge from my part on how the middleware is called. Can someone help me understand this problem?
Basically I just want to perform some logic before the files are served and the index.html is load on the browser. By the way placing the app.get() before the app.use(express.static()) line, does not did the trick!
Your static file middleware should go first.
app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'secret'}));
And you should be adding a use for app.router as well.
app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'secret'}));
app.use(app.router);
Middleware is processed in order for each request. So if you have an index.html in your static files then requests for yourdomain.com/ will never make it to the app.router because they will get served by the static file handler. Delete index.html and then that request will flow through to your app.router.
Rename your index.html file to something else. It is that simple
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
if(req.session){
console.log(req.session);
}
console.log('ok');
res.sendfile(new_index_file);
});
I believe, you have 3 options here:
1) Mount your app.get('/') route (possibly, using app.router) before static middleware, so that they take precedence. Middleware that is mounted first, processes a matching request first.
2) Use a path prefix for your static paths like app.use('/static', express.static('public'));, so that statics is served from example.com/static/...
3) Want to act smart and shoot yourself in the leg? :) Sometimes people use Accept headers and content negotiation to serve 2 different content types from the same url in different circumstances. You can make your static middleware check for a specific content type in Accept header and process request, only if requests's Accept header wants a proper type. Otherwise, it will pass the processing down the stream to you / view. You can customise your static middleware content negotiation in req.accepts.

Passing user detail to jade with everyauth and express

I have started a small webapp with everyauth and express, based on the sample project in Mircosoft's WebMatrix 2.
What I cannot get my head around is how information is passed to the view and how the views are stiched together from partial views.
The view is generated from a parent view called layout.jade and the partial view for example index.jade. These views do however not seem to reference each other.
The routing seems to be managed with this code:
app.configure(function() {
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(require('./middleware/locals'));
app.use(express.cookieParser());
app.use(express.session({ secret: '[secret]' }));
app.use(everyauth.middleware());
app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
app.use(connect.static(__dirname + '/public'));
app.use(app.router);
});
and the routes are defined like this:
app.get('/', function(req, res) {
res.render('index', { title: 'Home Page. ' })
});
This seems to perfectly merge the layout and partial view, but I cannot work out how. Can anyone shed light how this works?
If you are not coming from a ruby background it can be kind of hard to grasp, hopefully this helps.
By default express will render a "layout" (in your case layout.jade). A layout is then rendered on every page unless specified else where. Although this maybe helpful with websites and blogs where the head is always the same, I find it to be cumbersome on web applications. You can disable if you like by adding the code below to your app settings:
app.set('view options', {layout: false});
Express will then render your view (in this case index.jade). The index is the majority of the content.
Express can also render partials, which is a partial view inside of a view. This is helpful for items like footers, but can effect performance. It is important to note that a partial is different then a view.
I find that people without Jade/Tempting experience have an smaller learning curve using EJS instead of Jade, since it flows much like HTML.
Below are some videos that really helped me grasp views/partials, and middleware when I first started with express. Nodetuts is an excellent resource. The Express documentation has also evolved to be a very valuable resource as well, happy coding, and good luck!
express documentation
nodetuts express

Resources