Fighting EJS and the scale of not-so-called "local" variables

I am wondering how can I write a node.js application using an EJS template. I am really looking for a suitable way to define local variables with default values ​​in a partial / template.

I will come out of this soon:

When I call the template, for example:

<%- partial(__view.partialPath('tagPopover'), { title_popover: sentence.nickname, content_tag: '#' + sentence.nickname, icon_popover: 'http://placehold.it/64x64' }) %> 

I manage the default values ​​this way, in _tagPopover.ejs partial:

 title_popover = typeof title_popover != 'undefined' ? title_popover : '' classes_tag = typeof classes_tag != 'undefined' ? classes_tag : 'tags' icon_popover = typeof icon_popover != 'undefined' ? icon_popover : false content_tag = typeof content_tag != 'undefined' ? content_tag : '' 

I do not use the var keyword because it does not work at all, for example, if I do:

 var title_popover = typeof title_popover != 'undefined' ? title_popover : '' 

Then EJS will match the var title_popover and create a local variable before reading the actual value of the title_popover variable. This way I get null even if I really sent the parameter ...

When I discovered this, I decided not to use the var keyword ... But I recently discovered that all the variables that I create this way are actually global ! This means this is a really bad decision, because I probably ended up rewriting the global variables by loading the view!

I believe that this will be a battle later, and I do not want my views to set default / reset global variables (who ?!)

Do you have a solution for this? I already thought of a few, but I do not like:

  • Use the var keyword, but also use the pattern before the local variable to avoid resetting the parameters: var l_title_popover = typeof title_popover != 'undefined' ? title_popover : '' var l_title_popover = typeof title_popover != 'undefined' ? title_popover : '' . It looks bad and confusing as hell.
  • Use a namespace like view.title_popover = typeof title_popover != 'undefined' ? title_popover : '' view.title_popover = typeof title_popover != 'undefined' ? title_popover : '' . I want my variables to be local, not global, if I do this, I will have something global that will exist in memory all the time.

How would you handle this? I am very curious, maybe there is an EJS way to handle this or an assistant, I don’t know.

+5
source share
4 answers

There is a concept of filters in ejs. Also see adding-filters .

Basically, I think you're looking for something similar to this. In the code below, the value will be set to title_popover if it exists in res.locals, otherwise it sets the value to "default"

 <%=: locals | get:'title_popover','some default value' %> ejs.filters.get = function(obj, prop, default) { return obj[prop] === undefined ? default : obj[prop]; }; 

I believe this is the easiest way to do this in ejs, but there may be other methods. It seems like this was actually discussed on the github ticket :)

EDIT - This blog post seems to provide some alternatives using the underscore library. It seems that they are somehow wrapping the template in the layout (I did not completely parse the article, but it seems to make sense on the surface).

However, I used only this method.

+2
source

EJS is not a good template, as you would expect, because it is very old and inactive. However, templates for JS are not so good when it comes to passing variables around. I use the Sails framework, and what I do is just passing the variables to the mind in my route settings (if they are hardcoded) or in my controllers if they are dynamic.

You can also set default route parameters to res.locals using a policy.

For example, I have the following settings in my sail routes:

  'GET /':{ controller: 'IndexController.js', action: 'displayIndexPage', title: 'Main page', }, 'GET /flowchart': { controller: 'FlowchartController.js', action: 'displayFlowchart', title: 'Flowchart' }, //... 

Then I have a viewToLocals.js policy with the following code:

 module.exports = function(req, res, next) { res.locals.view = req.options.title; return next(); }; 

This, btw, will not override any data that I pass to the view from the controller or any other file. What I could do if I had your problem would be something like this:

 //setPageParamsPolicy.js module.exports = function(req, res, next) { res.locals.popovers = { title: ('undefined') ? res.get('body').username : 'Default title', //or wherever you fetch data from icon : ('undefined') ? res.get('body').avatar : 'www.site.com/defaultAvatar.jpg' } return next(); }; 

Sails are built on Express, so perhaps this information will be useful. However, note that the sail policies apply to the actions of the controller, which means that if you define a simple route for viewing, it will not be applied - you must redirect it to a specific controller. However, you can put this object in themseleves routes:

 //routes.js 'GET /userpanel': { view: 'userpanel', locals = { popover: { title: ('undefined') ? res.get('body').username : 'Default title', //or wherever you fetch data from icon : ('undefined') ? res.get('body').avatar : 'www.site.com/defaultAvatar.jpg' } } } 

I also asked this question and came to the conclusion that there is no easy way to do this. But for me, Sails provides a relatively simple solution that is also relatively reliable.

0
source

EJS is a great template language if you like to use simple JS for things. The project is currently quite active.

The EJS module (now v2) on NPM is actively supported here: https://github.com/mde/ejs . (The old v1 repository is no longer supported.)

The landing site is here: http://ejs.co

The default values ​​for the data should not be set in the template. Templates should be used for rendering only. It would be best to pre-process your data before transferring it:

 var defaultVals = { foo: 'FOO', bar: 'BAR' }; // Mix in left to right: https://gist.github.com/mde/81b131ff6810ed7c4e0e var dataObj = mixin({}, defaultVals, {bar: 'NOT BAR'}); // Outputs "FOO, NOT BAR" ejs.render('<%= [foo, bar].join(", "); %>', dataObj); 

By the way, filters have been removed from EJS in v2. This is a non-standard function that has nothing to do with embedded JavaScript and is easily replicated using native code.

0
source

I defined default variables in ejs as follows:

 <% var username, password%> <script> var username = "<%= username %>",password = "<%= password %>" %> </script> 
0
source

Source: https://habr.com/ru/post/1215836/


All Articles