How to place an EJS tag within another - node.js

I am using EJS as my templating engine. I am passing variables from node js to ejs like...
router.get("/AdminDatabase", function(req, res) {
res.render('Pages/AdminDatabase', {title: 'WebFormsAdmin', role: 'System Admin' });
});
I am building a role base control and for this I want to change the header of the page base on the role of user.
<% include ../partials/Common/header_<%= role %> %>
The problem is with the above segment. How can I place the variable role inside this EJS code segment?
My header files are
header_System Admin.ejs,
header_Survey Admin.ejs,
header_Survey Taker.ejs

A workaround would be to do a conditional render like so:
<% switch (role) {
case 'System Admin': %>
<% include ./partials/header_System_Admin %>
<% break; %>
<% case 'Survey Admin': %>
<% include ./partials/header_Survey_Admin %>
<% break; %>
<% default: %>
<% include ./partials/header_Survey_Taker %>
<% break; %>
<% } %>
Note that the first case must be grouped with the switch declaration. Make sure the paths are correct for your partials.

You can concatenate the path and the variable.
<%- include('../partials/Common/header_'+role) %>

Related

Unexpected token '/' in {FILE} while compiling ejs

I am working on this: https://www.youtube.com/watch?v=6FOq4cUdH8k
For some reason, the following line is causing the error in the title.
<% include ./partials/messages %>
Removing the line above solves the problem.
I have confirmed that it is not the messages file as there are no slashes in it.
<% if(typeof errors != 'undefined') { %>
<% errors.forEach(function(error){ %>
<%= error.msg %>
<% }); %>
<% } %>
as you can read in the official documentation
Includes are relative to the template with the include call. (This
requires the 'filename' option.) For example if you have
"./views/users.ejs" and "./views/user/show.ejs" you would use <%-
include('user/show'); %>.
You'll likely want to use the raw output tag (<%-) with your include
to avoid double-escaping the HTML output.
so instead of
<% include ./partials/messages %>
Write
<%- include ("./partials/messages") %>
Why?
Template tag <%- outputs the unescaped value into the template, whereas <% 'scriptlet' tag is used for control-flow, no output. The parenthesis and " " are used for filename location

Express/EJS - if it's a specific view file thats rendered do something

I have a view that is:
/views/signup.html
I want to have different elements on the page in my main layout template depending on what view is loading.
In my main layout file, when that specific view is rendered I want to do something like:
<% if (ecomHeader) { %>
<% include includes/signup-nav.html %>
<% } %>
<% else { %>
<% include includes/nav.html %>
<% } %>
This obviously doesn't work
ReferenceError: ../views/layout.html:9
7| </head>
8| <body>
>> 9| <% if (ecomHeader) { %>
10| <% include includes/signup-nav.html %>
11| <% } else { %>
12| <% include includes/nav.html %>
Can you do that? is that how that works?
render code:
...
let token = createCSRFToken(req);
let ecomHeader = true;
res.render('premium/signup', {
message: req.flash('signupMessage'),
token: token,
ecomHeader: true
});
...
There is a exports. thing that wraps this, not sure if thats relevant or not
You're else condition is missing certain things. Make sure you pass signup: true/false boolean from the back-end to your views.
res.render("main-template", {
signup: true/false
});
Then in your html, you need to do this - Make sure you use <%-.
<% if(signup){ %>
<%- include('includes/signup-nav.html'); %>
<% } else { %>
<%- include('includes/nav.html'); %>
<% } %>

EJS linting error - remove unnecessary <% and %>

In our webpack build, we have a file with ejs template:
<% switch (type) {
case 'homepage' : %>
<%- include partials/top -%>
<% break;
case 'amsterdam' : %>
<%- include partials/1 -%>
<% break;
case 'company' : %>
<%- include partials/2 -%>
<% break;
case 'new york' : %>
<%- include partials/3 -%>
<% break;
case 'paris' : %>
<%- include partials/4 -%>
<% break;
} %>
This works. But is it possible to remove all the <% and %> as the whole block is actually to be interpreted by <% %>.
I tried leaving only the first <% and the ending %> as shown below but the build fails suggesting a ejs linting error.
<% switch (type) {
case 'homepage' :
include partials/top
break;
case 'amsterdam' :
include partials/1
break;
case 'company' :
include partials/2
break;
case 'new york' :
include partials/3
break;
case 'paris' :
include partials/4
break;
} %>
Is it possible at all to remove all those <% %> ?
<% %> is for conditionnal statement or variable evaluation, to display you have to use <%= %> or <%- %> but those expect a value and not an expression
The only way to do it it's to include your switch in a function and return the result :
<% var a = 1; %>
<%- (function(){
switch(a){
case 1:
return include("c.ejs");
break;
case 2:
return include("d.ejs");
break;
default:
break;
}
})()
%>

EJS: Pass array of pages into include(page)

I've created a dashboard page where a user can save different components of the site to one page for quick viewing. I'm able to dynamically load one component as follows:
index.js
res.render('dashboard',{comp: 'component1'});
dashboard.ejs
<%- include(comp) %>
but I would like to do something like this:
index.js
res.render('dashboard',{comp: ['component1', 'component3']});
And have the ejs page loop through the include(), this way i can show 0 to n components on the dashboard page.
I've tried wrapping the include in a for loop like so:
<%- for(c in comp){include(c)} %>
but ejs did not like this.
Am I going about this the wrong way?
Try this
<% for(var i=0; i < comp.length; ++i) { %>
<%- include(comp[i]) %>
<% } %>
in your code, c is the index not value, comp[c] is your component.
<% for(c in comp){ %>
<%- include(comp[c]) %>
<% } %>

How to pass custom variable to partial in hexo?

I want to create an alternating layout using the static site generator hexo – the text of every second post on an overview page should be on the right.
The partial I’m using needs to pass on a custom variable like textOrientation = "left" to the partial function.
<%site.tags.findOne({name: 'featured'}).posts.sort('date', -1).limit(5).each(function(post, index) {%>
<%- partial('_partial/project-excerpt', {item: post}) %>
<% })%>
The template project_excerp.ejs then needs to generate the according classes bases on the passed variable.
My template (project_excerp.ejs):
<a class="???" href="/project/<%= item.slug %>"><%= item.title %></a>
So the questions are:
How can I extend the post variable with my own variable textOrientation and
How can I use an if then else in my project_excerp.ejs-template?
Okay, found a solution myself.
index.js:
<%site.tags.findOne({name: 'featured'}).posts.sort('date', -1).limit(5).each(function(post, index) {%>
<% if(index % 2 === 0) { %>
<% post.textOrientation = "left"; %>
<% } else { %>
<% post.textOrientation = "right"; %>
<% } %>
<%- partial('_partial/project-excerpt', {item: post}) %>
project_excerp.ejs:
<% var projectInfoClass = "ta-right"; %>
<% if(item.textOrientation === "right") {%>
<% projectInfoClass = "ta-left"; %>
<% } %>
<a class="<%= projectInfoClass %>" href="/project/<%= item.slug %>"><%= item.title %></a>
Also helpful to read the EJS-docs.

Resources