using partials with express in node.js - javascript

I am trying to render partials using node.js. Here is my code.
app.js:
var express = require('express')
, routes = require('./routes');
var app = module.exports = express.createServer();
// Configuration
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());
});
// Routes
app.get('/', routes.index);
var products = require('./products.js');
app.get('/products', function(req, res) {
res.render('products/index', {locals: {
products: products.all
}
});
});
app.listen(3000);
When I go to localhost:3000/products it should render index.jade which is in the products folder which is in the views folder.Above I set the views directory using app.set('views', __dirname + '/views');
index.jade:
h1 Products:
#products!= partial('partials/product', {collection: products})
This should render the partial equivalent to (partials/product.jade) because jade is my view engine.
I am getting an error back saying "partial is not defined"
Any help would be great. thanks
UPDATE:
That solved my partial error thank you. I reinstalled 2.5.9.

Check what version of Express JS you have installed -- you may have the 3.0 alpha:
$ npm ls
...
└─┬ express#3.0.0alpha1
...
If you're interested in trying the alpha, be sure to checkout the documentation on Migrating from 2.x to 3.x. In it, you'll notice that res.partial() and partial() (within templates) have been removed -- as described under "View system changes:"
By removing the concept of a "layout" & partials in Express 3.x template engines will have greater control over file I/O. This means integration with template engines much easier, and greatly simplify the view system's internals.
You can see an example of the intent in the linked article, Use Jade blocks, not layouts.
If you're not interested, then just make sure you have 2.x installed.
$ npm install express#2.x
Or via package.json:
{
...
"dependencies": {
...
"express": "2.x"
}
}

Related

Express res.render is not rendering the page

I am trying to get an input from my main site. After the input is submitted the page should redirect to /view. It seems like it successfully redirects to /view (because console.log() is getting triggered, but res.render is not working. If i manually go to /view it is rendering the page.
Here is the code of my app.js file:
// load the things we need
var express = require('express');
var app = express();
let bodyParser = require("body-parser");
let article = '';
//Set the view engine to ejs
app.set('view engine', 'ejs');
app.use('/static', express.static('static'))
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json())
//Index page
app.get('/', function (req, res) {
res.render('index')
});
//Get the input from the form
app.post('/searcharticle', function (req, res) {
article = req.body.article;
res.redirect('/view')
return article;
});
//Page to output the input
app.get('/view', function (req, res) {
console.log(article)
res.render('view', {
article: article
})
})
app.listen(8080);
console.log('Server on 8080');
And here is my
folder structure
Thank you for your help!
use view engine first then set the directory where to use it.
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
and for static files use
app.use('/static',express.static(PATH.join(__dirname+'/static'));
You have to mention the layout
app.get('/', function (req, res) {
res.render('index',{layout:false})
});
supposed you have al your .ejs files in views folder try adding this line in your code:
const path = require('path'); //npm install -S path in your console to install path.
//Set the view engine to ejs
app.set('views', path.join(__dirname, 'views')); // add this one, change 'views' for your folder name if needed.
app.set('view engine', 'ejs');
app.use('/static', express.static('static'))
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json())
If you are running your server from a diff directory than static you need to add a relative path
app.use('/static', express.static(__dirname+'/static'))
I was just given the solution to a very similar problem by my wonderful tutor. The login form 'submit' was passed to jQuery on('click') and after authetication called a Res.Render of the results of an API call. The API call result set was log-abled, but the page never rendered, and there was no error.
He told me that jQuery acts as a 'shadow' DOM, and that the Res.Render was likewise taking place in that shadow DOM. I changed the login form to a form Post instead of the jQuery on Click.
That WORKED!
I worked on this for several days without ever thinking jQuery could cause that obstacle.
My way is to go back the version of ejs to 2.5.2, and that works. However, I don't know the reason why it cannot support the version 3..

NodeJS multiple instances and require routes in subfolder

I'm writing a multi instance NodeJS application serving my Chrome extensions.
I think I got stuck in all that is related to subfolders, requiring and exporting modules.
Here's my app structure:
At the very bottom, I have start.js which bootstraps some major parts of the application like Express, models, views, controllers, routes, etc..
var express = require('express'),
http = require('http'),
arguments = process.argv.slice(2),
port = arguments[0] || 3000;
var app = express(),
server = app.listen(port),
io = require('socket.io' ).listen(server ),
routes = require('./config/routes')(app);
app.configure(function(){
"use strict";
app.set('views', __dirname + '/app/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.static(__dirname + '/app/public'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
});
app.configure('development', function() {
"use strict";
app.use(express.errorHandler());
});
console.log('Server is running on port ' + port);
module.exports = app;
In root folder of app, I have the instance files themselves. Like app.js (main), dealer.js (dealer instance), etc...
I run them like this:
[deb0rian#localhost www.bkbot.org]$ node ./app/dealer.js 3003
app/dealer.js itself for now is pretty simple:
var app = require('../start.js');
app.get('/', app.routes.dealer.index);
And my config/routes/index.js is:
var fs = require('fs' ),
required_files = [];
module.exports = function(app){
fs.readdirSync(__dirname).forEach(function(file) {
if (file == "index.js") return;
var name = file.substr(0, file.indexOf('.'));
require('./' + name)(app);
});
}
And it fails to read my route files with this error:
[deb0rian#localhost www.bkbot.org]$ node ./app/dealer.js 3003
info - socket.io started
path.js:299
return splitPathRe.exec(filename).slice(1);
^
RangeError: Maximum call stack size exceeded
Is there something wrong with my file structure?
I want to be able to read only routes in /config/routers/dealer if I run that particular instance, no problem giving it command line argument, but i have to overcome this issue first and I don't know how to read only specific routes subdirectory.
Any help or advise will be appreciated!
Thanks

trying to render html files using jade but it still adresses it as a jade

i have read theses two posts regrading my issue:
http://stackoverflow.com/questions/4529586/render-basic-html-view-in-node-js-express
http://stackoverflow.com/questions/12046421/how-to-configure-express-js-jade-to-process-html-files
and my code is as follows:
app.engine('.html', require('jade').__express);
app.set('views', __dirname + '/app/views');
app.set('view engine', 'html');
it is clear that for some reason it is trying to read index as if it was still a jade file and thus i am getting the error. i believe i configured it correct to server a .html file. what is the problem here? i am getting lost...
i have tried to reorder the lines but still same error.
but for some reason i get this error:
Error: ....\views\index.html:4
2| <html lang="en" ng-app="squashApp">
3| <head>
> 4| <meta charset="utf-8">
5| <title>Squash Organizer</title>
6| <link rel="stylesheet" href="css/app.css"/>
7| <link rel="stylesheet" href="css/bootstrap.css"/>
unexpected token "indent"
at Object.Parser.parseExpr (C:\Users\workspace\squash\node_modules\jade\lib\parser.js:241:15)
at Object.Parser.parse (C:\Users\workspace\squash\node_modules\jade\lib\parser.js:133:25)
at parse (C:\Users\workspace\squash\node_modules\jade\lib\jade.js:93:62)
at Object.exports.compile (C:\Users\workspace\squash\node_modules\jade\lib\jade.js:156:9)
at Object.exports.render (C:\Users\workspace\squash\node_modules\jade\lib\jade.js:210:15)
at Object.exports.renderFile (C:\Users\workspace\squash\node_modules\jade\lib\jade.js:247:18)
at View.exports.renderFile [as engine] (C:\Users\workspace\squash\node_modules\jade\lib\jade.js:232:21)
at View.render (C:\Users\workspace\squash\node_modules\express\lib\view.js:76:8)
at Function.app.render (C:\Users\workspace\squash\node_modules\express\lib\application.js:505:10)
at ServerResponse.res.render (C:\Users\workspace\squash\node_modules\express\lib\response.js:756:7)
thanks.
With this line:
app.engine('.html', require('jade').__express);
You told express to render templates ending with .html using jade.
With this one:
app.set('view engine', 'html');
you told express that it should interpret template names without extension as ones ending with html.
So my guess is that you're trying to render 'index', express interprets it as index.html and then passes to jade as it was instructed to do.
It's better to map jade to it's own extentension (.jade is an obvious candidate). And render your index.html using it's full name.
Add consolidate.js to your project:
var engines = require('consolidate');
Tell jade to render stuff ending with .jade.
app.engine('jade', require('jade').__express);
Register simple html renderer for stuff ending with .html:
app.engine('html', function(str, options) {
return function(locals) {
return str;
};
});
Tell express to render templates with no extension as jade:
app.set('view engine', 'jade');
Use this to render your index:
res.render('index.html');
and this:
res.render('view-name-without-extension');
to render jade template.
By Default express takes Jade template engine. Your app.js should look like this.
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade'); // <<<---- CHANGES FROM EJS TO JADE !!!
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
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());
}
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'));
});

Using connect vhost to serve multiple express.js apps

I want to use connect's vhost functionality to deploy several express.js apps to my dev vps. Here is my server.js file that is supposed to send requests to the appropriate place:
var express = require('express')
var quotes = require('quote-of-the-day/lib/app.js');
var server = express();
server.use(express.vhost('inspiringquoteoftheday.com',quotes));
server.listen(80);
Running node server.js throws this error:
Error: Cannot find module 'quote-of-the-day/lib/app.js'
Even though I can cd into app.js straight from the directory where server.js is located.
Here is the lib/app.js file in which I export my express app (I think)
// Generated by CoffeeScript 1.3.3
(function() {
var app, express, pub;
express = require('express');
module.exports = app = express();
pub = __dirname + '/public';
app.use(express["static"](pub));
app.use(express.errorHandler());
app.use(app.router);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.get('/', function(req, res) {
return res.render('home');
});
}).call(this);
Assuming a directory structure that looks something like this:
|-. quote-of-the-day
|-- server.js <-- the file you list in your question
|-. lib
|-- app.js
Then you should require your app.js with
require('./lib/app');
Might be helpful to use the __dirname global variable here.
it provides 'the name of the directory that the currently executing script resides in.'
thus you could do:
var otherApp = require(__dirname + 'quote-of-the-day/lib/app.js')
http://nodejs.org/docs/latest/api/globals.html

nodejs peepcode tutorial - can't get it to work

I bought the latest nodejs peepcode tutorial and followed it, however I can't get past the initial step.
I'm getting frustrated after spending several hours to find out where I got an error since debugging nodejs is a riddle for me.
app structure looks like this:
example
|__public
|__views
|__assets
|__apps <- instead of routes
server.js
package.json
Here is my simple code:
server.js
/**
* Module dependencies.
*/
require('coffee-script');
var express = require('express');
var app = module.exports = express.createServer();
// Configuration
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());
});
// routes
require('./apps/authentication/routes')(app);
app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
/apps/authentication/routes.coffee:
routes = (app) ->
app.get '/login', (req, res) ->
res.render "views/login",
title: 'Login'
stylesheet: 'login'
module.exports = routes
apps/authentication/views/login.jade template:
form(action='/sessions', method='post')
label
| Username
input(type='text', name='user')
label
| Password
input(type='password', name='password')
input(type='submit', name='Submit')
nothing fancy, i got a stylesheet file and login.css in public/stylesheet/login.css
instead of a login template from authentication/routes.coffe when browsing http://localhost:3000/
Cannot GET /
no any other error message from node either:
Express server listening on port 3000 in development mode
I can't figure out where the problem is and this is really frustrating.
Probably some dumb typo somewhere but I can't figure this out :(
You do not have a route configured for the root '/'. Navigating to http://localhost:3000/login should return your login view as specified by the route to the resource '/login'. You need to add something along the lines of:
app.get '/', (req, res) ->
#if not logged-in then send to /login else
res.render('/views/authenticated', 'Home', 'index')
For more details on routing see http://expressjs.com/guide.html#routing.
It looks like everything is working as intended. The problem is that you haven't defined a route that matches the request GET /. You've only defined a route matching GET /login in your routes.coffee; also, GET /anythinginyourpublicdir will work thanks to the express.static middleware.

Categories