Jade helper for FontAwesome - node.js

I want to write some helper for FontAwesome in jade template in Express.js, so I did in app.js:
app.locals.icon = function(icon){ return '<i class="fa fa-' + icon + '"></i>'; };
and called in template:
block content
h1= title
p Welcome to #{title}
= icon('users')
however it returns me escaped HTML code. What is a good practise for writing this kind of helpers ? How to return raw HTML ?

Try with != operator
!= icon('users')
Refrence from http://jade-lang.com/
Unescaped buffered code starts with != and outputs the result of evaluating the JavaScript expression in the template. This does not do any escaping, so is not safe for user input.

Related

Cascading Template Use in mustache-express?

My intent is to define a page_layout template and a form template as well. Within the route handler i was going to parse the inner (form) template and inject into the greater layout than return.
After several plot twists i'm able to use the response.app to get access to my mustache template engine and parse a view, but the HTML is getting escaped :(
let router = require('express').Router();
let mustache = require('mustache');
router.get('/plant', function(request,response) {
response.app.render('plantForm', {pageTitle: "Plant"},function (err, html) {
response.render ('layout', { pageContent : html});
});
});
yields the outer template with escaped html where I expect content:
<div class="form-group">
<label for="plantNameInput">Plant Type</label>
Perhaps I'm misusing the technology?
From the Mustache documentation:
All variables are HTML escaped by default. If you want to return unescaped HTML, use the triple mustache: {{{name}}}.

Gathering document fragments at rendring time using `pug`

I use pug to generate HTML email messages from a template:
doctype html
html
head
title Hello #{name}
body
...
The title is the subject of the email.
Currently, I extract the title text content by parsing the HTML document rendered by pug. But it doesn't seem to be a very efficient way of doing.
Is there some feature or hook available in pug to collect part of the document while rendering it? I considered pug filters, but as far as I understand, those are not suitable since they are triggered at compile time. Not while rendering the document.
I came to a solution using a mixin:
mixin collect(name)
-
// This is just an ugly hack to
// capture the inner block rendered
// text
const savedHtml = pug_html;
pug_html = "";
if (block) block();
const innerHtml = pug_html;
self[name]=innerHtml;
pug_html = savedHtml+innerHtml;
html
head
title
+collect('title')
| Hello #{self.name}
var pug = require("pug");
const compiledFunction = pug.compileFile('template.pug', {debug:true,self:true});
console.log(compiledFunction(out={
name: 'Timothy',
}));
console.log(JSON.stringify(out));
Displaying:
<html><head><title>Hello Timothy</title></head></html>
{"name":"Timothy","title":"Hello Timothy"}
The code of the collect() mixin is not particularly pretty because as far as I know it there is no elegant way to capture the block() output. So I had to tackle into the internal undocumented pug_html variable.
Or is there a cleaner way to achieve that?

Conditionals within script. in jade

In Jade, is it possible to create a conditional if statement in a dynamicscript section?
For example:
doctype html
html
head
script.
-if( locals.display_JS )
console.log("Display_JS is TRUE")
-else
console.log("Display_JS is FALSE")
(locals.display_JS is a parameter pass to Jade in res.render.)
If display_JS is true, the desired output should look like:
<script ...>console.log("Display_JS is TRUE")</script>
However the output is:
<script>
-if( locals.display_JS )
console.log("Display_JS is TRUE")
-else
console.log("Display_JS is FALSE")
</script>
It could be that I am thinking wrong. My objective is to render different javascript functions based on parameters sent to res.render.
It can be done the other way, use the . whenever you want to nest javascript code.
doctype html
html
head
script
if( locals.display_JS )
.
/** Some JS code **/
console.log("Display_JS is TRUE")
else
.
console.log("Display_JS is FALSE")
Jade will not mess with anything within a script block. If you really need to use jade logic inside a script block you can get a little tricky and do something like this:
Router Code:
router.get('/', function(req, res){
res.render('index', {run_this:true});
});
Jade Code:
div
| <script type='text/javascript'>
if(run_this)
| console.log("Ran this!");
else
| console.log("Didn't run this");
| </script>
Another approach to running logic based on jade variables within a script tag is to do something like this:
script.
if(!{run_this}){
console.log("Ran This!");
}
When you use script. everything that comes after will be interpreted as plain text by jade. If you need to mix markup and plain text you can use |. For example:
script
| function bar(){
if(true)
| console.log("Ran this")
else
| console.log("Don't run this")
| }

split string in nodejs

I am working on node js with mongodb. I am getting the value of doc in view file.
{{#each doc}}
<div class="abstract" data-reactid=".1ejbmifi4u8.1.1.0.1.2.0:$35.0.0.1.2.0" id="content">
{{this.content}}</div>
{{/each}}
this will print the value of content.
I want to print only 40 characters of this content on view page and then want to implement "read more" to go to full content page.
Guessing by the syntax, you are using Handlebars or some similar derivative. If it's not Handlebars, you'll have to modify the below a little to match your framework, but it should be similar. Leave a comment if it's not and I'll edit.
Handlebars supports what is known as helpers which allow you to manipulate data fed into your views.
You could write a helper named, for example, excerpt, like so:
Handlebars.registerHelper('excerpt', function(data, url) {
if (data.length > 40) {
return new Handlebars.SafeString(
data.substring(0, 40) + '… Read more"
);
}
return data;
});
You can then use it like {{excerpt this.content this.readMoreUrl}}, where this.readMoreUrl is whichever property provides the relevant URL.
I am not familiar with the JavaScript MVC but You can do something like this in JS:
content = this.content
if(content.length > 40)
content_to_print = content.substr(0,40)
content_to_print = content_to_print+' Read More...'
Hope this helps!

converting a jade if statement to handlebars (hbs)

I've been following this tutorial and I've been able to convert each jade line to hbs apart from this one;
- if (user_open.id != user.id)
I tried this;
{{#if "user_open.id != user.id" }}
but it doesn't seem to work. Any ideas???
Handlebars is logicless so you can't use the != operator directly. You'll need to pre-compute in javascript a boolean value you can pass to the template when you render such as isOther so you can do {{#if isOther}} in your template or create a block helper function so you can do {{#isOther user user_open}}

Resources