Reputation: 411
I code like this
app.set('view engine', 'ejs');
app.get('/test', (req, res) => {
res.render('show.ejs');
})
but almost every dev (and docs), don't write the filename extension like this
app.get('/test', (req, res) => {
res.render('show');
})
so I tried to make two ejs files in views dir, (test.ejs) and (test.ejs.ejs)
1st attempt
app.get('/test', (req, res) => {
res.render('test'); //renders the first template (test.ejs)
})
2nd attempt
app.get('/test', (req, res) => {
res.render('test.ejs'); //renders the first template (test.ejs)
})
3rd attempt
app.get('/test', (req, res) => {
res.render('test.ejs.ejs'); //renders the second template (test.ejs.ejs)
})
I got confused, I'm more accurate than everyone!!?, so my question is why docs doesn't write the file extension and is there a difference?
I know it's an unlikely scenario
Upvotes: 0
Views: 67
Reputation: 81
If you look inside Express Code - you will find the following :
/**
* Register the given template engine callback `fn`
* as `ext`.
*
* By default will `require()` the engine based on the
* file extension. For example if you try to render
* a "foo.ejs" file Express will invoke the following internally:
*
* app.engine('ejs', require('ejs').__express);
*
* For engines that do not provide `.__express` out of the box,
* or if you wish to "map" a different extension to the template engine
* you may use this method. For example mapping the EJS template engine to
* ".html" files:
*
* app.engine('html', require('ejs').renderFile);
*
* In this case EJS provides a `.renderFile()` method with
* the same signature that Express expects: `(path, options, callback)`,
* though note that it aliases this method as `ejs.__express` internally
* so if you're using ".ejs" extensions you dont need to do anything.
*
* Some template engines do not follow this convention, the
* [Consolidate.js](https://github.com/tj/consolidate.js)
* library was created to map all of node's popular template
* engines to follow this convention, thus allowing them to
* work seamlessly within Express.
*
* @param {String} ext
* @param {Function} fn
* @return {app} for chaining
* @public
*/
app.engine = function engine(ext, fn) {
if (typeof fn !== 'function') {
throw new Error('callback function required');
}
// get file extension
var extension = ext[0] !== '.'
? '.' + ext
: ext;
// store engine
this.engines[extension] = fn;
return this;
};
This is the link to the file : https://github.com/expressjs/express/blob/508936853a6e311099c9985d4c11a4b1b8f6af07/lib/application.js#L259
so as far as I understand , if you set in your code the view engine
app.set('view engine', 'ejs')
Then when you don't add the extension , Express will complete that for you automatically because it knowns what engine to use and thus the correct extension
but if you didn't set the engine , then Express will use the extension to get the Engine needed.
So basically if you didn't set the engine view , then adding the extension is required But if you did set it, then it is optional if you want to add the extension, as express will auto complete it for you
Upvotes: 3