Reputation: 1311
I am working on a template where I am trying to render template using express and ejs. As to the standard structure of node app, I have app.js file which which contains functions like following:
app.locals.getFlag = function(country) {
var flag_img_name = "";
if (country.toLowerCase() == "us") {
flag_img_name = "flag_us16x13.gif";
}
else if (country.toLowerCase() == "ca"){
flag_img_name = "flag_ca16x13.gif";
}
return flag_img_name;
}
I have some_template.ejs file which calls this function like follows:
<img src="http://some_url_path/<%=getFlag(data_point[0].country_name) %>" width="16" height="14" alt="country" >
and it works just fine. However, I have around 15-20 functions like this and I don't want to define all of them in app.js. Is there any other place where I can define these functions and call them in the template same way as I am doing now? If yes, what would be the way to define them so that they are accessible like they are right now.
I am new to node, express and ejs and not sure of different techniques. If someone could shed a light over it, it would be great. Thank you in advance.
Upvotes: 33
Views: 70876
Reputation: 700
I have two solutions that may not suit everyone.
At the top of main.ejs
write the following construct
<% const helpers = {}; include('./helpers', { helpers }); %>
Inside helpers.ejs
write the following:
<%
Object.assign(helpers, {
lower(arg) { return String(arg).toLowerCase() },
upper(arg) { return String(arg).toUpperCase() },
// some other helpers here
})
%>
Now in main.ejs we can use these functions
<h1><%= helpers.upper('your text here') %></h1>
This is similar to the previous method, but instead of mutating the local helpers
variable, a "variable_object" from the parent context is passed inside the helpers.ejs file, which is supplemented with the necessary variables.
This is what it looks like:
At the top of main.ejs
write the following:
<% include('./helpers', { locals }); %>
In helpers.ejs
Object.assign(locals, {
lower(arg) { return String(arg).toLowerCase() },
upper(arg) { return String(arg).toUpperCase() },
// some other helpers here
});
now in main.ejs
<%= upper('lololo') %>
Good luck!
Upvotes: 0
Reputation: 391
Create common functions in js file helper.js.
function common1() {
//function body
}
function common2(key) {
//function body
}
module.exports = {
common1: common1,
common2: common2
}
And then require this file in your node function
var helper = require('./helper');
and then pass this helper with ejs render
res.render('index', { helper:helper });
And use your function is ejs file
<%= helper.common1() %>
That's It
Upvotes: 39
Reputation: 13500
The order you setup your file has an importance on how the functions are defined. The execution is top to bottom not on document evaluation. Example below to setup your functions.
document.html
<section class="container">
<%- include('./helpers/common') %>
<%- include('./home') %>
</section>
common.ejs
<%
MyFunction = function() {
// Write your code here
}
%>
home.ejs
<% if(MyFunction() ) { %>
<!-- Write your HTML markup -->
<% }%>
Upvotes: 2
Reputation: 1987
You can just require a separate file and set app.locals to this
app.locals = require('./path/helpers')
In helpers.js:
getFlag = function(country) {
var flag_img_name = "";
if (country.toLowerCase() == "us") {
flag_img_name = "flag_us16x13.gif";
}
else if (country.toLowerCase() == "ca"){
flag_img_name = "flag_ca16x13.gif";
}
return flag_img_name;
}
anotherFunction=function(x){
return 'hello '+x
}
module.exports={getFlag, anotherFunction}
Upvotes: 8
Reputation: 1
In a js file, create a instance of the function like: if your function name is test ()
, Var ren = test ();
will create a reference to this function.
Before rendering data to the ejs page add the reference variable ren to that object:
Data.ren = ren();
Res.render(Data)
And now in ejs while when you call <% ren() %>
it will call the fonction.
Upvotes: -1
Reputation: 31
It seems the easiest way to do this is to pass the function in attached to the object with all the data for the render:
in your js:
const data = {
...all other data,
getFlags: function(country) {
var flag_img_name = "";
if (country.toLowerCase() == "us") {
flag_img_name = "flag_us16x13.gif";
} else if (country.toLowerCase() == "ca"){
flag_img_name = "flag_ca16x13.gif";
}
return flag_img_name;
}
};
ejs.render(template, data);
in your template:
<img src="http://some_url_path/<%=getFlag(data_point[0].country_name) %>" width="16" height="14" alt="country" >
Upvotes: 3
Reputation: 2732
Well, for some reason the accepted answer didn't worked out for me. Also it doesn't makes sense to create a separate *.ejs
file for each of my functions and then importing the file in view - specially when I have very simple logic to be implemented.
In fact it is very simple and easy to define function and use it in the view
I did this:
<%
// ------ Define a function
get_tree = function(tree){
for(var i in tree){
%>
<%= tree[i].title %>
<%
}
}
// ----- Call the above declared function
get_tree(tree);
%>
And it works!
Thanks
Upvotes: 13
Reputation: 1311
Just posting this answer here for someone who would might end up on this question while resolving same issue.
All you have to do is create new file (say functions.ejs
) and include it in the .ejs file where you want to call that function. So, I have function like this in file named functions.ejs
:
<%
getPriceChgArrow = function(value) {
arrow_img_name = "";
if (value < 0) {
arrow_img_name = "arrow_down12x13.gif";
}
else {
arrow_img_name = "arrow_up12x13.gif";
}
return arrow_img_name;
}
%>
Then include functions.ejs
into the file you want to call function from. Say, I want to call this function in quote.ejs
file. So, I would include it as follows:
<% include *file_path*/functions %>
Just use this function at appropriate location in your ejs file from where you want to call it. For example:
<img src = "http:/some_url/<% getPriceChgArrow(data_point[0].value) %>" />
and you are all set. Hope this helps someone.
Upvotes: 56