How to get all locals in Express view - node.js

I am trying to figure out a way to get access to all the app.locals in the views. In my app.js I have
app.locals.title = "Title"
app.locals.page = "Page 1"
This is good, and in the views, I can access each with
<%= title %>
<%= page %>
However, is there a way (without doing something like app.locals.xyz.title) to get all the locals in the view so I can do something like this:
<% for(var i=0; i < locals.length; i ++ ){ %>
<li><%= locals[i] %></li>
<% } %>

You have to explitly pass it:
res.locals.locals = res.locals;
Then in the view:
<%= locals %>

Related

In Nodejs, how can i check params in Ejs render

I want to display another view if there is :id in Semantic URL
app.get(['/topic', '/topic/:id'], function(req, res){
id = req.params.id
if(id){
res.render('view',{topics:rows, topic:row[0]}
}else{
res.render('view', {topics:rows}
}
}
and view.ejs
for(var i = 0; i < topics.length; i++){
<li><%= topics[0].title%></li>
}
<% if(topic) {%>
<%= topic.description %>
<%} else {%>
<h1>Welcome</h1>
<% } %>
it did works correctly when i connect to localhost:3000/topic/1
but when i connect to localhost:3000/topic
console said topic is not defined
what is the problem?
When i use
res.render('views', {topics:rows, topic:''}
it did works correctly
Do i have to use like this?
In view.ejs it is best to check the if condition as follows. Not only in ejs but in entire javascript world
<% if(typeof topic !== 'undefined') {%>
<%= topic.description %>
<%} else {%>
<h1>Welcome</h1>
<% } %>
And you can use also use res.render('views', {topics:rows, topic:''}

ejs + nodejs - compare two variables doesn't work

I pass two variables during rendering in nodejs. Let's say they're templates & treeInfo.
In template.ejs I have.
<% for(var i=0; i<templates.length; i++) {%>
<%= templates[i]._id %> = <%= treeInfo.owner[0] %><br>
<% if (templates[i]._id == treeInfo.owner) { %>
ok
<% } %>
<% } %>
So actually if == doesn't work as expected. Here's the output.
59519779f36d284c166f9bea = 5941789e36593262bed9256b
5941789e36593262bed9256b = 5941789e36593262bed9256b
So it doesn't compare them the right way. If I just replace treeInfo.owner with something like '5941789e36593262bed9256b', it does work fine.
I assume ejs doesn't support variables comparation?
Thanks
Variable type can't understand.That's why toString() is required.
<% for(var i=0; i<templates.length; i++) {%>
<%= templates[i]._id %> = <%= treeInfo.owner[0] %><br>
<% if (templates[i]._id.toString() == treeInfo.owner.toString()) { %>
__append('Hello World');
<% } %>
To compare two objects / variables in EJS, as well as in nodejs
if(user1.equals(user2))
{
console.log("Both are equal");
}

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.

Multiple variables declaration in ejs

I am trying to declare and assign a default value to multiple variables. But the value is only getting assigned to last variable
<% var scale_text,scale_image = 'free_transform'; %>
This print empty:
<%- scale_text %>
This prints free_transform
<%- scale_image %>
What am i missing?
Separate the variables with = to set them to the same default value.
<% var scale_text, scale_image; %>
<% scale_text = scale_image = 'free_transform'; %>
What your writing will declare scale_text as an empty variable.
To work the way you want it to you need to do the following
<% var scale_text = scale_image = 'free_transform'; %>
However this is probably preferable
<% var scale_text, scale_image; %>
<% scale_text = scale_image = 'free_transform'; %>

Resources