prismo
prismo

Reputation: 1899

Make variable available globally in EJS templates

I'm working on setting up authentication in a node application. I've decided to use EJS as my templating solution and PassportJS for authentication. This is all running on ExpressJS. The problem I'm having is, I need some way to make req.isAuthenticated() or any variable and its properties available globally within the templates. This is a problem because I've decided to do some conditional rendering within a partial that is being used on all templates. If I were to attempt to make this application work, I would need to pass every single res.render("template") an object containing, req.isAuthenticated(). I don't think that's the best approach. Is there some solution to this problem I'm missing?

Here is a sample of my current set up

header.ejs (PARTIAL)

<!DOCTYPE html>
<html>

<head>
    <title>formla</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" />
    <link rel="stylesheet" href="/stylesheets/style.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</head>

<body>

    <head>
        <nav>
            <ul>
                <li><a href="/">Home</a></li>
                <li><a href="/protected">Profile</a></li>

                <%if(!isUserAuth){%>

                <li><a href="/register">Register</a></li>
                <li><a href="/login">Login</a></li>

                <%}else{%>
                    <li><a href="/logout">Logout</a></li>
                <%}%>    
            </ul>
        </nav>
    </head>

index.ejs

<%- include("./partials/header.ejs") -%>

<div class="container">
    <h1>Home</h1>

    <a href="/register">Register</a>
    <br />
    <a href="/login">Login</a>
</div>
<%- include("./partials/footer.ejs") -%>

Any help would be appreciated.

Upvotes: 2

Views: 1460

Answers (1)

anees
anees

Reputation: 1855

Express res.locals object is used for this purpose. you just need to add an auth check middle-ware for the private routes. and add it to the locals object of the response which will be accessible inside the ejs.

e.g:

// auth middleware will automatically add isAuthenticated to all the routes.
app.use((req, res, next) => {
    res.locals.isAuthenticated = isAuthenticated();
    return next();
});

The better approach will be to even check for the auth and redirect to the login within the middleware for private routes and for public routes you can pass isAuthenticated in locals of response.

Upvotes: 3

Related Questions