How to set the default views folder in express? - node.js

I am having a lot of trouble getting my routes to direct correctly.
This is my code:
in express.js
app.set('views', config.root + '/app/views')
app.set('view engine', 'jade')
in routes.js
module.exports = function (app) {
// home route
app.get('/', home.index)
}
I keep on getting an error saying that home is not defined, even though I believe that I set the views correctly. Any idea on what the mistake may be.
If it helps, my file structure for my views is under app/views and my config files are config/express.js and config/routes.js

In your routes.js you have not defined home so you will certainly get undefined error. Views does not have anything to do with request handler.
You will use res.render inside your request handler to render the view. Please look in to express.js guide to get started.
Are you trying to do this?
module.exports = function (app) {
// home route
app.get('/', function(req, res){
res.render('home');
});
}
If your request handlers are in separate module you can do this:
if your home request handler is home.js in same path as routes.js you can do following.
Your route.js file
var home = require('./home');//path to your home request handler module
module.exports = function (app) {
// home route
app.get('/', home.index)
}
Your home.js file
exports.index = function(req, res){
res.render('home/index');
}
It will expect you have index.jade view file in your /app/views/home folder.

Related

How redirect from a hbs(handlebars) page to a html page

I am working on my portfolio project. I am using handlebars and nodeJS.
I have a section called projects where I list 4 different projects to showcase. I have an index.js where all my routing is done. Projects 1,3,4 work just fine. These all will be clicked on from a project section on my index page.
However, I am so lost on how to route my project 2. Projects 1,3,4 are all handlebars(.hbs). But my project 2 is an html page. As seen in my code snippet, the html is store under the same /public folder as all my other code. However, I still get the error "Failed to lookup view "../public/views/fountainWebsite/html/home" in views directory". I am not sure how this needs to be done??
// === VARIABLES === //
var express = require('express');
var app = express();
var handlebars = require("express-handlebars");
var path = require("path");
var router = express.Router(); //creates a router object
//===== view ENGINE SET UP =====//
app.set('view engine', 'handlebars');
app.engine(
"hbs",
handlebars({
layoutsDir: path.join(__dirname, "/public/views/layouts"),
partialsDir: path.join(__dirname, "/public/views/partials"),
extname: ".hbs", //expected file extension for handlebars files
defaultLayout: "layout" //default layout for app, general template for all pages in app
})
);
app.set("views", path.join(__dirname, "views"));
//thought this would maybe fix the error?? It didn't//
// app.set("fountainWebsite", path.join(__dirname, "fountainWebsite")); //
app.set("view engine", "hbs");
app.use("/public", express.static(path.join(__dirname, "public")));
//===== .GET PAGES =====//
app.get('/', (req, res, next) => {
res.render('../public/views/index', {title: 'Home Page', css:['../public/css/style.css'], js:['../public/js/navBar.js']});
});
app.use('/', router);
router.get('/project1', (req, res, next) => {
res.render('../public/views/partials/project1', {title: 'Data Structures', css:['../public/css/projects.css'], js:['../public/js/navBar.js']});
});
//error here//
router.get('/project2', (req, res, next) => {
res.render('../public/views/fountainWebsite/html/home');
});
router.get('/project3', (req, res, next) => {
res.render('../public/views/partials/project3', {title: 'This Portfolio', css:['../public/css/projects.css'], js:['../public/js/navBar.js']});
});
router.get('/project4', (req, res, next) => {
res.render('../public/views/partials/project4', {title: 'Dictionary', css:['../public/css/projects.css'], js:['../public/js/navBar.js']});
});
It is important that we understand what our code is doing. Let's start with the route handler for /project2:
router.get('/project2', (req, res, next) => {
res.render('../public/views/fountainWebsite/html/home');
});
This is telling Express to listen for a request with the path /project2 and to render the file at ../public/views/fountainWebsite/html/home.
Handlebars requires an extension (like .hbs) in order to know which view engines to use to render the file. As we have omitted an extension from our file path, Express will assume the extension is .hbs because that's what we told it to do when we called app.set("view engine", "hbs");
I have to assume that your file path with extension is ../public/views/fountainWebsite/html/home.html since you have put it in a folder called "html". If this is the case, Handlebars is not going to find this file because it is looking for ../public/views/fountainWebsite/html/home.hbs and it will throw an Error.
The simple solution would be to rename this file with a .hbs extension. This will at least allow Express to locate the file and render it through the Handlebars view engine.
However, one problem with this approach may be that this view gets rendered wrapped in your layout.hbs file and you do not want that. Perhaps you want this HTML file to be unprocessed and served as a static asset.
In this case, you could remove the /project2 route handler and let Express serve this file as a static asset. Since you have already registered your public/ folder as static assets folder with the call app.use("/public", express.static(path.join(__dirname, "public"))); and your file path shows that this HTML file is already within the public/ folder, you should be able to request this HTML directly from your browser at the path /public/views/fountainWebsite/html/home.html.

Web App with Node and Express Routing and Express-ejs-layout

I have a server.js file where I require my routing file as below..
userRouter = require('./controllers/user.js');
In the server.js file I have routing for home as..
server.get('/', function(req, res){
res.render('home');
});
The home.ejs is put into the layout.ejs body and displays fine. The problem I am having is with the users/new route in the controllers folder..
router.get('/new', function(req, res){
res.render('users/new')
});
router.post('/', function(req, res){
var newUser = User(req.body.user);
})
The code above isnt being injected into the body of the layout.ejs. If I type in the route http://localhost:3000/users/new it works, but its not in the layout.ejs body. How can I fix this?
Also, how can I get my links in the web app to redirect to the correct route; i.e, signup link goes to http://localhost:3000/users/new

Express.js (4.13.1) and Handlebars view engine - how to setup?

My project directory is called travel which has required dependencies node_modules and a subdir called views. Views subdirectory has layouts subdirectory. In the ~/travel/views/layouts there is .handlebar templates for the views. But when I go to the browser and type in localhost:3000/about or just localhost:3000 regardless of that I get 404 - not found I tried switching the res.render("about"); to res.render("/views/layouts/about"); but that does not work neither. It has something to do with the paths but I'm not sure what.
var express=require("express");
var app=express();
// set up handlebars view engine
var handlebars=require("express3-handlebars")
.create({defaultLayout:"main"});
app.engine("handlebars",handlebars.engine);
app.set("view engine","handlebars");
app.set("port",process.env.PORT || 3000);
app.get("/",function(req,res){
res.render("home");
});
app.get("/about",function(req,res){
res.render("about");
});
// custom 404 page (middleware)
app.use(function(req,res,next){
res.status(404);
res.render("404");
});
// custom 500 page (middleware)
app.use(function(err,req,res,next){
console.error(err.stack);
res.status(500);
res.render("500");
});
app.listen(app.get("port"),function(){
console.log("Express started on http://localhost:"+app.get("port")+";press ctrl+c to terminate,");
});
Assuming you have a subdirectory called views within the same directory as your Express app script, you need to set the Express views app setting like:
app.set('views', __dirname + '/views');
By default, the path is relative to the current working directory.
Additionally, you may wish to update your express3-handlebars module to be express-handlebars instead, as the latter is the newer of the two and is recommended by the current maintainer.
Try this by overriding the default layout
app.get('/', function (req, res, next) {
res.render('home', {layout: false}); });

Express 4 Route Issues

Just learning nodejs, express, jade. While making progress, I am having trouble understanding how the routes work. I have the routes in a routes folder and the views (Jade files) in a views folder. And that works, but I don't see how.
Let's say I have a page foo. In routes, I have foo.js:
var express = require('express');
var router = express.Router();
/* GET foo page*/
router.get('/', function(req, res) {
res.render('foo', {title: 'Foo' });
});
module.exports = router;
The menu link in the Jade file that calls Foo has an href="/foo" attribute. How come router.get('/', ... ) works? Shouldn't it have to be
router.get('/foo', function(req, res) {
res.render('foo', {title: 'Foo' });
});
When I try to do that, however, it can't find the route and I get a 404, which seems counter to the router docs. I could just go with it and have all the routes get('/', ...) or post('/', ...), which does work, but it just seems wrong.
What am I missing?
Thanks for your insight.
Your app.js file probably contains a line that looks like the following:
app.use('/foo', require('./routes/foo'));
This means that any route defined in ./routes/foo will be relative to /foo. Therefore, your / route is accessed via /foo/.

Node/Express.js - Overriding where to look for the 'Views' folder for each request

In my Node/Express.js project I can set the views folder globally like so:
app.configure(function() {
app.set('views', __dirname + '/views');
.... snip ....
});
...and all my view templates go into the views folder.
Is it possible to override where Express looks for views on a request by request basis? For instance, something like the following:
app.get('/', function(req, res) {
res.render('index', { viewFolder: 'otherViews' });
});
The reason I ask is I'm trying to replicate Microsoft ASP.NET MVC's Areas functionality where each Area gets it's own views folder.
The 'views' setting is the root directory, so you should be able to specify a sub-folder in the hierarchy:
app.get('/', function(req, res) {
res.render('areaName/viewName');
});
It means your 'areas' need to be sub-folders, but it allows you to accomplish the separation you are looking for.
As a more modular solution, I did something like this in sails.js.
Just over-ride the render function for the given request in your middleware. :)
var curRender = res.render;
res.render = function(path, locals, func) {
var args = [res.locals.explicitPath + '/' + path, locals, func];
curRender.apply(this, args);
};
Full path works too
app.get('/', function(req, res) {
res.render(path.join(__dirname, 'view.jade'));
});

Resources