Node.js Express not rendering html view - node.js

so I was trying to follow a tutorial to use node.js as the front end of a wordpress site
This one http://www.1001.io/improve-wordpress-with-nodejs/
Here is the code from server.js
var frnt = require('frnt');
var fs = require("fs");
var path = require("path");
var express = require('express');
var app = express();
var doT = require('express-dot');
// Define where the public files are, in this example ./public
app.use(express.static(path.join(__dirname, 'public')));
// Make sure this is set before the frnt middleware, otherwise you won't
// be able to create custom routes.
app.use(app.router);
// Setup the frnt middleware with the link to the internal server
app.use(frnt.init({
proxyUrl: "http://localhost:8888/frnt-example/wordpress", // The link to your wordpress site
layout: false // We simplify this example by not using layouts
}));
// define rendering engine
app.set('views', path.join(__dirname, "views"));
app.set('view engine', 'html' );
app.engine('html', doT.__express );
// respond with "Hello World!" on the homepage
app.get('/', function (req, res) {
res.send('./views/index.html');
});
app.listen(8080); // listen to port 8080
It keeps outputting the following
./views/index.html
Rather than rendering the html?

I've never used frnt, but res.send sends a string so that's no big surprise.
Look at res.sendfile which sends the contents of a file.

I prefer to use ejs , it's sems like html just edit index.html to index.ejs
1- install ejs module npm install ejs
2- add this in app.js
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
and render the index.ejs by using
app.get('/', function (req, res) {
res.render('index'); // or res.render('index.ejs');
});
res.send() // it send just a string not file
Hope it usefull !

Related

How to use route for html file already served as static

I use passport.js to authenticate user after he enters login page. To keep user logged in when he returns to home page i'm going to use something like:
app.use(express.static(__dirname + '/public'));
app.get('/', function(req,res){
if(req.user){
// connect to database ....
} else{
res.sendFile(__dirname +'/index.html');
}
});
Note that index.html file is inside "public" folder. Recently i realized that having a code like above, node.js doesn't use app.get('/'....) route but it serves index.html directly. So i'm unable to check if req.user exists. Any suggestion?
As You might understand express.static handles index.html before Your router.
But You cannot avoid express.static also (otherwise You have to use nginx or write own static file output).
So You've to re-think Your folder structure or have to develop 2 separate apps: api (backend) and frontend (that will request to api for data)
In context of Your question I wrote an example app where I organize assets, html files and app routes:
1) Have such folder structure:
2) and example app.js :
'use strict';
const express = require('express');
const app = express();
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
app.set('trust proxy', 1);
// attaching renderer
app.engine('.html', require('ejs').renderFile); // ejs renderer will render .html files as ejs files
app.set('view engine', 'html'); // views has .html extension
app.set('views', __dirname + '/public'); // views live in public folder
// attaching common middlewares
app.use('/assets', express.static('public/assets')); // our static assets will live in public/assets folder
app.use(cookieParser());
app.use(bodyParser());
// implement and attach passport auth somewhere (:
// remove it after passport has been attached:
const authorizeUser = (req, res, next) => {
req.user = {id: 1, username: 'test'};
next();
};
app.get('/', authorizeUser, (req, res) => {
res.render('index', {user: req.user}); // render get index.html from views folder (see above)
});
app.listen(8080, () => {
console.log('App listening');
});
p.s. download example app from here (don't forget to call npm i inside extracted folder (; )
p.s. implement passport.js Yourself

Node.js / Express app not returning the correct EJS page

I am building a website using Node.js, Express and EJS. For now I have two EJS templates, each corresponding to a page on the website:
the home page URL should be / or /home. The "staff" URL should be /staff. The home one works fine, but for some reason even when I visit the /staff or even a nonsense address (e.g., /eduwshduhwudhwud) I still get the home page. Here is my code that's inside the app.js which is used to build the routes.
Here is my folder structure and code:
var express = require("express");
var app = express();
app.use(express.static("public")); // To allow static files
app.set("view engine", "ejs");
// -------------------------------- HOME PAGE-----------------------------------
app.get("/", function(req, res){
res.render("home");
});
app.get("/home", function(req, res){
res.render("home");
})
// -------------------------------- STAFF PAGE-----------------------------------
app.get("/staff", function(req, res){
res.render("staff");
});
// -------------------------------- HOME PAGE-----------------------------------
// -------------------------------- HOME PAGE-----------------------------------
// -------------------------------- HOME PAGE-----------------------------------
app.listen(process.env.PORT, process.env.IP, function(){
console.log("SERVER IS RUNNING!");
})
Use path.join(__dirname, 'views') to combine the application's directory (i.e., _dirname) to your views directory.
This is how I am doing it in my application:
var express = require('express');
var path = require('path');
...
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views')); // <-- add this line before your view engine definition
app.set('view engine', 'ejs');
...
Given this, within my routes I can refer to any view in the views folder with res.render(). For example:
res.render('dashboard', { title: 'My App', greeting: 'Hello' });

Expressjs routing precedence again

As my question in Order of router precedence in express.js. I know that the order of express.js is first come first serve. But as code bellows, I don't understand that why the '__dirname' has declared and fixed in above of other code but whaterver I call javascript from ./public/abc.js, the app return a HTML markup of mainpage.
My pages include some javascript and it cannot be loaded. The server return 100% HTML
I am using express generator and folders is structured follows.
NodeJS
var routes = require('./routes/index');
var api = require('./routes/api');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', api);
app.use('/users', users);
app.use('/:shopName', function(req, res, next) {
req.shopName = req.params.shopName;
next();
}, routes);
app.use('/', function(req, res) {
res.render('index', {
title: 'MainPage'
});
});
Client Javascript put in script tags like
<script type="text/javascript" src='./public/javascripts/Crypto/crytoUtils.js'></script>
The browser send out error "Uncaught SyntaxError: Unexpected token < cryptoUtils.js " in console and when I click in a link, I see the mainpage HTML markup..
Help me solve the problem ... pls. Thank
The path to the js file should be ./abc.js, public is left out unless you set that as the root for static files using:
app.use('/public', express.static(path.join(__dirname, 'public')));
To be clear, I suggest NOT using the above code, and instead modify your url in the script tag src attribute to appropriately target the file at it's location of /javascripts/Crypto/crytoUtils.js

How can I use Express and EJS to serve static and dynamic content?

I want to build a simple app using node.js that 'functions' like IIS/classic ASP where all the content (html, png, js, css, ejs) can be in one directory and the ejs file uses javascript vs. VBScript.
I've gathered the following from API's and other examples, but the ejs file arrives at the browser as a binary and gets saved....
My node.js file:
var express = require('express');
var app = express();
app.use(app.router);
app.use(express.static(__dirname + '/html'));
app.engine('.ejs', require('ejs').__express);
app.set('views', __dirname + '/html');
app.set('view engine', 'ejs');
app.get('*.ejs', function(req, res) {
res.render(__dirname + '/html' + req.url, function(err, result) {
res.end(result);
});
});
app.listen(8080);
My test.ejs file:
<!DOCTYPE html>
<html>
<head><title>A test</title></head>
<body>
My Test Page
<% if (1==1) { %>
Working
<%}%>
</body>
</html>​
What am I missing or where can I find a working example?
I FIGURED IT OUT... SOLUTION ADDED ABOVE
express.js won't magically try to render static files, you have to explicitly call render somewhere.
I believe something like this would work:
var express = require('express')
var app = express()
app.engine('.ejs', require('ejs').__express)
app.set('views', __dirname + '/html')
app.set('view engine', 'ejs')
app.use(app.router) // only in express 3, remove that in express 4
app.get('/test.html', function(req, res, next) {
res.render('test.ejs')
})
app.use(express.static(__dirname + '/html'))
app.listen(8080)
I believe is not necessary to run render in every place, I use this example to render my static content by migrating express 2.3.7 to 4 and works fine with :
app.engine('.ejs', require('ejs').__express);
app.set('views', __dirname + '/public')
app.set('view engine', 'ejs')
app.use(express.static(__dirname + '/public'))
My static content is in 'public' directory.
I just want to add that express supports EJS out of the box these days:
https://expressjs.com/en/starter/generator.html

Serve assets before other routes

I am developing a web app using Node.js, Express and AngularJS.
I am serving my front-end JavaScript from the public folder, so e.g. that HTTP GET /lib/angular/angular.min.js would presumably return the AngularJS JavaScript.
However, as I want all requests to get handled by the Angular router in the browser, I have a catch-all route defined as follows:
app.get('/*', function(req, res) { res.send('template.jade'); });
The problem is that this route overrides the static asset routing, in which case it always run, even when a static asset is requested.
Is there a way to tell Express to process static assets before the custom routes propagate? Are there perhaps any other clever ways of avoiding this issue?
The Express configuration is as follows:
// Generated by CoffeeScript 1.7.1
(function() {
var ExpressConfig, crypto, express, path, pkg;
crypto = require('crypto');
express = require('express');
path = require('path');
pkg = require('../package');
ExpressConfig = (function() {
function ExpressConfig() {}
ExpressConfig.prototype.configure = function(ENV) {
var APP_ROOT, app;
APP_ROOT = path.join(__dirname, '../');
app = express();
app.set('port', pkg.config.port);
app.set('views', APP_ROOT + 'webapp');
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(express.cookieParser(crypto.randomBytes(20).toString('hex')));
app.use(express.session());
app.use(app.router);
app.use(require('stylus').middleware(APP_ROOT + 'public'));
app.use(express["static"](APP_ROOT + 'public'));
if (ENV === 'development') {
app.use(express.errorHandler());
}
return app;
};
return ExpressConfig;
})();
module.exports = ExpressConfig;
}).call(this);
//# sourceMappingURL=express-config.map
I can verify that the configuration is run before the catch-all route definition, as I have checked it by logging in each place to check the order.
I can also verify that the assets configuration works when the catch-all route is removed.
The static middleware should appear before app.router and the specific route.
// first
app.use(express["static"](APP_ROOT + 'public'));
// second
app.use(app.router);
// last
app.get('/*',whatever);

Resources