I'm confused with the app.set() method.
As far as I know, app.set() is like this
app.get('title');
// => undefined
app.set('title', 'My Site');
app.get('title');
// => "My Site"
but in tutorials, make 'views' folder and use like this.
app.set('views', __dirname + '/views')
app.get('/') or app.get('/admin')
shouldn't it be like this?
app.get(views)
app.set(name, value)
Assigns setting name to value, where name is one of the properties from the app settings table.
views
Type:String or Array
A directory or an array of directories for the application's views. If an array, the views are looked up in the order they occur in the array.
app.set('views', path.join(__dirname, 'views'));
This will set your apps view folder to something like:
/Users/adil/Project/myApp/views
When you actually go to use the view, the view name becomes the file path, minus the root directory and the file extension. For example, if you had the following file structure:
/views/
/views/index.hbs
/views/news/
/views/news/index.hbs
/views/news/article1.hbs
/views/news/article2.hbs
You would render the views as follows:
res.render('index', {});
res.render('news/index', {});
res.render('news/article1', {});
res.render('news/article2', {});
The methods app.get() and app.set() in express.js are not what we are used to using in OOP. When we use app.get('key') or app.set('key', 'value') in OOP like java, we just want to set/get a member of a object.
In express.js, however, app.set() is used to set one of the application settings. see: http://expressjs.com/en/4x/api.html#app.set . The app.get() and app.post() methods used here refer routes and request received by node.js server. eg: app.get() refers to GET request and app.post() refers to POST request
The views is a configuration variable that sets folder from which express will grab templates. app.get('/admin') also differs from app.get('variable'). First is a GET route, that would listen HTTP Server, the second is just environment variable of express.
Related
I have my API and Website in same Express Js Project and needs to use ejs view for the website only. But not for the API to return JSON for API routes.
const app = express();
// For static website
app.use(express.static(path.join(__dirname, "public"), {
extensions : ['html']
}));
// API Routes
const bookRoutes = require("./routes/event.route");
app.use("/v1/books", bookRoutes);
// Website
// Set the view engine for dynamic header, footer on website
const ejs = require('ejs');
app.set('view engine', 'ejs');
API
/v1/books
Website
/index.html
How can I skip the view engine for my API routes and apply to /public folder only or even for selected files?
Error message, when I open /v1/books in Postman
{"message":"Failed to lookup view \"C:\\Users\\admin\\github\\test-app\\public\\v1\\books\" in views directory \"C:\\Users\\admin\\github\\test-app\\views\""}
The JSON was expected for /books API
{
id : 1,
name : 'book name'
}
For starters, routes are matched in the order you declare them. So, if you put this first:
// API Routes
const bookRoutes = require("./routes/event.route");
app.use("/v1/books", bookRoutes);
first, then it will get processed before it tries to match any of the static routes. But, this really shouldn't be an issue because there shouldn't be any files in your public folder that would match a request for /v1/books/xxx anyway.
As for the error for /v1/books, you will have to show us what the code is for bookRoutes. It appears that error is coming from that router. express.static() does not make errors like that.
How can I skip the view engine for my API routes and apply to /public folder only or even for selected files?
The app.set('view engine', 'ejs'); line just configures what view engine will be used if/when some code calls res.render(). There's nothing happening with the view engine on one of your API requests because you should never be calling res.render() in an API route. You are presumably calling res.json() instead.
You should ONLY have files in your public folder that you want express.static() to match. That's how you control it. Don't put something in that folder that shouldn't be served statically.
I want to set the views directory for each route individually, rather than using /views/ for all of them.
So I have a main folder for each view, which has the route and the view in it:
var main = require('./main/main.js');
var test = require('./test/test.js');
app.use('/', main);
app.use('/test', test);
How do I tell that route to look in /main and /test for the view files, rather than in /views for all of them?
I want to be able to just pass the file name in res.render(), rather than a relative path.
Adding multiple views with app.set('views', ['main','test']); is okay, but I'd rather have the views linked to just that route, in case there are files with the same name in different folders. There's also the problem that it expects the layout file to be in the same folder, when I want them all to use the same layout file.
Use Express middleware to change view directory based on the router, You can write a middle either in application level or router level based on your application needs.
Below is the example for application level middleware to change view directory based on route,
app.use(function (req, res, next) {
if (req.path === '/main') app.set('views', './views2');
else app.set('views', './views');
next()
})
Code snippet will check for the request path, If it is /main route it will use views2 directory otherwise it will use views directory.
In my node app, I configured the views folder, later simply I am passing the html name alone. now the html file need to load from using the views config + html file right. ( am I wrong!)
But it's not working. any one give me the suggestion please?
here is my code :
var express = require('express'),
http = require('http'),
jade = require('jade'),
app = express();
app.set('view engine', 'jade');
app.set('views', __dirname + '/views'); // i configured the path so i am passing file name alone on get.
app.get('/', function(req,res){
res.sendfile('index.html'); //it's not working
res.sendfile('views/index.html') //it works
});
http.createServer(app).listen(3000, function () {
console.log('Express server listening on port ');
});
thanks in advance
You appear to have a misconception about what the view engine is. The view engine takes some non-HTML code, and transforms it into HTML. Here, you have it set to use jade.
The view engine is only good with the res.render() function. res.sendfile() merely sends a file from the current directory -- not the views directory.
Using express if you want to serve some static HTML files. You can just put those files directly in public folder.
When server will get a GET request of / it will search for /public/index.html serve that as response. You don't have to add router for that /.
Other wise if you want to use some template views then you have to use some views engine.
I'm writing a single page web application using node.js and express. After going through some online tutorials, I found out this is how express.js serves a client directory with HTML, javascript and css
app.use(express.static(__dirname + '/public'));
This works great except the fact that public directory has to have .html root file which is static. I'd like to know how can I serve a dynamic HTML file with this same approach.
I want to insert some data into the page for example "Hello user_name" at the top. How do I do that for this single file.
I want to only do it once, at the startup, after that my application will make rest API calls and get plain JSON responses which it will then put it in the page.
You cannot use the express static server to serve dynamic files as far as I'm aware. In order to serve a dynamic HTML you need to use a templating engine, such as jade or any of these templating engines.
Jade is pretty straightforward to use and is supported by express by default. To set up jade, include the following lines in your app configuration block:
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
The first line sets your views directory - from which the template files would be served. Since you want to serve only an index file, this directory would contain your index.jade template. The second line sets jade as the templating engine.
Now, instead of using the static server to serve the index.html, you need to create a get route '/' to serve the index file, like so:
app.get('/', function(req, res) {
res.render('index', {user_name: username});
});
I can't find an answer to this, despite it seeming rather useful.
I would like to host a site using node.js to serve compiled jade files instead of html files. Currently, I'm using:
app.get('/', function(req, res) {
app.use(express.static(__dirname));
});
How can I get it to find page.jade when someone types in domain.com/page? And furthermore, could I write links that way in the jade file (so a(href='page') link would link to the aforementioned page)?
Set your path as
app.get('/:pageName')
// more code
// then
res.render(req.params.pageName+'.jade')
req.params will contain the last part in property name pageName
Express has a number of possible options for what it calls a "view engine". In order to have it process jade files and serve them as html you must configure it to do so.
One of the easiest ways to do this, if you are starting fresh, is to simply create your project using the express command as mentioned in their guide. The default views engine is jade and the following command sets stylus as the css processor:
express --css stylus myapp
If, instead, you are configuring your own server you need to configure the views engine:
app.configure(function(){
app.set('views', path.join(staticDir,'views'));
app.set('view engine', 'jade');
... the rest of your setup ...
}