How to convert ejs to jade? - node.js

I have troubles converting the following ejs to jade:
<% if (message.length > 0) { %>
<div class="alert alert-danger"><%= message %></div>
<% } %>
How does this block look in jade?

I'd write this as follows:
if message.length
.alert.alert-danger= message
... as message is a string, message.length evaluates to a falsy value (0) only if it's an empty string. I've also used buffered output here (note that = character) so that message value will be HTML escaped.
An alternative approach is comparing message with an empty string directly:
if message !== ''
.alert.alert-danger= message
Note that I dropped div in div.alert.alert-danger expression, as it's kind of default element for Jade templates. Have you used any other element, you'd have to start the expression with its tagname.

Try the following snippet
https://github.com/visionmedia/jade
- if(message.length>0){
div.alert.alert-danger #{message}
- }

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

Why does a semicolon in ejs template throws error

In the following code if the semicolon is removed the template engine does not throw error, else the error is thrown.
<ul>
<% for (i = 0; i < array.length; ++i) { %>
<%= JSON.stringify(array[i]); %>
<% } %>
</ul>
Although putting semicolon syntactically correct, why does the template engine throw error ?
As #torazaburo said, the contents between <=% and %> are an expression that gets parsed by ejs. However, think of it this way:
Your goal is to render the contents returned from JSON.stringify to the page right? So in that case, think of ejs expressions as implicitly calling .toString() on the result of the expression and then inserting that string into the page. By adding a semi-colon you've terminated the statement without assigning the returned value to anything.

Underscore Js _.each used with ejs error

I am trying to display the value in array using _.each and EJS dynamically. I am getting the values when i do it manually,but getting Unexpected token ; error while using _.each loop.
Here is the code
`<% _.each(pro,function(prof) { %>
alert(prof.Name);
<% } %>`
pro = {[object Object],[object Object]}
when i do it manually,i get the output.
i.e.
`<%= pro[0].Name %>`
Need help! Any other suggestions? Thanks
You seem have missed a parentheses here:
<% }) %>`
Beyond that, I'm not sure you can use underscore inside your EJS templates.
Try using a regular for.
<% for(var i=0; i<prof.length; i++) {%>
<li><%= prof[i] %></li>
<% } %>

Render a variable as HTML in EJS

I am using the Forms library for Node.js (Forms), which will render a form for me on the backend as so:
var signup_form = forms.create({
username: fields.string({required: true})
, password: fields.password({required: true})
, confirm: fields.password({
required: true
, validators: [validators.matchField('password')]
})
, email: fields.email()
});
var signup_form_as_html = signup_form.toHTML();
The final line var signup_var signup_form_as_html = signup_form.toHTML(); creates a block of HTML which looks as such:
<div class="field required"><label for="id_username">Username</label><input type="text" name="username" id="id_username" /></div><div class="field required"><label for="id_password">Password</label><input type="password" name="password" id="id_password" /></div><div class="field required"><label for="id_confirm">Confirm</label><input type="password" name="confirm" id="id_confirm" /></div><div class="field"><label for="id_email">Email</label><input type="text" name="email" id="id_email" /></div>
Basically just a long string of HTML. I then try to render it using EJS and Express using the following code:
res.render('signup.ejs', {
session: loginStatus(req)
, form: signup_form_as_html
});
But on rendering the HTML is simply the string that I posted above, rather than actual HTML (and thus a form as I want). Is there any way to make that string render as actual HTML using EJS? Or will I have to use something like Jade?
With EJS you can have several tags:
<% code %>
... which is code that is evaluated but not printed out.
<%= code %>
... which is code that is evaluated and printed out (escaped).
<%- code %>
... which is code that is evaluated and printed out (not escaped).
Since you want to print your variable and NOT escape it, your code would be the last type (with the <%-). In your case:
<%- my_form_content %>
For more tags, see the full EJS documentation
October 2017 update
The new ejs (v2, v2.5.7) development is happening here: https://github.com/mde/ejs
The old ejs (v0.5.x, 0.8.5, v1.0.0) is available here https://github.com/tj/ejs
Now with ejs you can do even more. You can use:
Escaped output with <%= %> (escape function configurable)
Unescaped raw output with <%- %>
Newline-trim mode ('newline slurping') with -%> ending tag
Whitespace-trim mode (slurp all whitespace) for control flow with <%_ _%>
Control flow with <% %>
So, in your case it is going to be <%- variable %> where variable is something like
var variable = "text here <br> and some more text here";
I had the same issue with rendering the textarea input from from a wysiwyg editor saved as html in my database. The browser will not render it but displayed the html as text. After hours of searching, I found out
<%= data %> escaped data while
<%- data %>left data 'raw'(unescaped) and the browser could now render it.
As per the ejs doc
<% 'Scriptlet' tag, for control-flow, no output
<%_ ‘Whitespace Slurping’ Scriptlet tag, strips all whitespace before it
<%= Outputs the value into the template (HTML escaped)
<%- Outputs the unescaped value into the template
<%# Comment tag, no execution, no output
<%% Outputs a literal '<%'
%> Plain ending tag
-%> Trim-mode ('newline slurp') tag, trims following newline
_%> ‘Whitespace Slurping’ ending tag, removes all whitespace after it

How to print a variable directly using EJS template engine?

I'm using Node.js with Express web framework (and EJS template engine).
When I have to print a variable I do something like:
<% if (value) { %>
<%= value %>
<% } %>
Can I do the same thing without open others brackets ? Like:
<% if (value) { PRINT VALUE } %>
Is this possible? How to print the variable?
I'm amazed to find that apparrently you can't do it, like in PHP:
<?php if ($value) : ?>
<?php echo $value; ?>
<?php endif; ?>
However a slightly better solution may be to do
<%= (value) ? value : '' %>
I say this assuming that the condition may occasionally be more complex, i.e.
<%= (str.length > 100) ? truncate(str) : str; %>
Which is much nicer than
<% if (str.length > 100) { %>
<%= truncate(str) %>
<% } %>
even if it is a slightly contrived example.
I'd love to be shown a direct command to do it, as per your original question.
There is now an outputFunctionName parameter that you can use. According to the documentation:
outputFunctionName Set to a string (e.g., 'echo' or 'print') for a function to print output inside scriptlet tags.
<% console.log(posts) %>
NB: Make sure you define your variable in any other file you have eg app.js file...
let posts = [];
app.get("/", (req, res) => {
res.render("home", {
posts: posts
});
});

Resources