I am using Express and EJS to build a site and I have a directory structure somthing like:
+--www/
|
+--partials/
| |
| +--header.ejs
| +--(a bun
This is a very good question, it's one I had myself until very recently.
Really there appears to be no direct & central way to get the web root... it's just not something the node nor the express developers thought was valuable it seems.
However there are a few tools made available that can help but won't directly solve the problem.
GENERAL APPROACH:
METHOD ONE - globals
The first work around I found is passable.
It utilizes the ability to set a variable to the global scope.
It's not ideal but if you want to see more click HERE.
IMPORTANT:
All of the below require that in the main file of your express app (the one that instantiates the express app) you set a variable to the current working directory.
The three ways I know of are
I believe there is an advantage to the second method but I don't remember what it is currently... also I'm not sure it works in the latest (14.x) version of node... I started changing over to 3 once I started using 14.5...
METHOD TWO - passing variables
The second workaround I think is the worst... it will work but may become untenable if you have anything less than a simple setup.
This method is to pass the variables through your routes.
this would look like:
router.get('/', (request, response) =>
{
response.render('PATH TO TEMPLATE', {dataItem1: 'DATA STUFF TO PASS', dataItem2: 'MORE STUFF'});
});
METHOD THREE
This is definitely the method I prefer.
It makes it easier, simpler, and more clean.
There are really two methods here but they are very similar.
This method is utilizing either app.locals OR response.locals. When I say app I mean the instance of express, (whatever you called it). So this is as simple as:
const appDir = path.dirname(require.main.filename); app.use((request, response, next) => { response.locals.someVar = 'value of someVar'; response.locals.appDir = appDir; return next(); });
app.locals.appDir = path.dirname(require.main.filename);//const path = require('path');
In both cases the values are simply available in EJS templates.
So using them would look like:
<%= appDir %>
Looks like this is not supported by EJS however i found a workaround for this problem.
In the above setup the pain point is for all partial files you need to mention the relative paths and if you refactor code that becomes more pain. So rather mentioning the relative path at every include i declare a variable rootPath
once, and there i give the path to reach home. So that at every include i can simply mention the relative path just like path from root.
For example in guide/index.ejs
i mention the following in top of the ejs file
<% var rootPath = '../'; %>
and and code in ejs file looks like below
<%- include(rootPath + 'partials/header'); %>
Your HTML code
<%- include(rootPath + 'partials/footer'); %>
So in case i refactor index.ejs to some other folder all i need to do is change the value of rootPath