Compile Jade to JSON? - node.js

Odd idea, but looking for the simplest approach to define some data files in Jade, and then directly convert them to JSON.
I looked at extending Jade to support a custom doctype, but quickly got lost in the code. For example:
doctype json
Only manual hacky approach I could come up with is convert the Jade to an XML file with jade, and then using better-require to read the XML file in node as an object, and then JSON.stringify the object (yikes)

If you want to use data/JSON in jade, instead of defining some data inside jade, you can pass json directly into response via response.locals or when returning response.render(view, [locals], callback) from node.
In your app.js
res.local.data=JSON.stringify(dataobj);
//or pass variable when rendering
res.render('/index', {
data : JSON.stringify(dataobj)
});
In your jade
function yourfunc(){
var data = !{dataobj};
}
This is dynamic, you can control the variables you are sending into the file, unlike statically defining them in jade.

Related

How can get a normal array without quote after being placed in html dataset

I am using express js on my server and ejs as a template engine.
After getting array from my database, I send it to ejs, I then store the data in a dataset in the ejs, while trying to get the dataset using vanilla javascript, I realized that the dataset has stringify my array... How can I get it back as an array?
//ejs
<div class="news_grid" data-kkk="<%=newsData%>">
let a = document.querySelector(".news_grid").dataset.kkk
Make sure the template variable is a properly formatted JSON string, eg, when rendering:
newsData: JSON.stringify(newsData)
Then, in your frontend JS, parse the dataset into an object first:
const newsData = JSON.parse(document.querySelector(".news_grid").dataset.kkk);
// do stuff with newsData.a

How can put Numeral.js library in pug file Node js?

I am using nodoe js and nodemailer. How can I use numeral.js to format numbers in pug file. Something like this.
#{numeral(number).format('0,0.00')}
If try this i getting numeral is not a function
You need to pass numeral function to your template otherwise (as you already stated) it will not be defined. Since you did not specify any code it is hard to tell how exactly you start the rendering of you pug file.
I usually handle it that way that I define a helper function which I then pass to the template:
const numeral = require('numeral');
function formatNumber(num) {
return numeral(number).format('0,0.00');
}
Usage in the template works like this:
#{formatNumber(number)}

Assign jade variable to Angular

In my application, I'm using NodeJS, Express in the backend and Angular in the frontend. I'm also using Jade template engine.
jade obtains a variable called "adv" by this code.
res.render('page',{adv:result[0]})
In controller.js (for angular)
$scope.content = [];
I would like to do something like
form(ng-init="content=#{adv}")
h5 {{"content" + content}}
i.e. assign that jade variable to the scope. It is not working. I could use http.get and get the content directly to angular scope, but just wondering if it is possible to do this
Thanks
This worked.
- var str_adv = JSON.stringify(adv)
form(ng-init="content = #{str_adv}")
or even (where getContent is a function defined in controller doing the same thing)
form(ng-init="getContent(#{str_adv})")
Both these also parsed the string and stored the object in 'content'
But directly using
form(ng-init="content = JSON.stringify(#{adv})")
gives the same error
It seems assigning objects in ng-init is not possible.
Thanks #ivarni for the hint about stringify

Jade template, how to pass concrete object to pages?

I have a jade template for my node.js project. I would like to send an object to the jade template and pass it to a function inside the page (to render something).
I am sure I send the right stuff from the server like this
res.render(__dirname + '/pages/viz.jade', {
vizJson: newJson,
});
in the client I do something like this:
script
sunburst(#{vizJson})
Thus, inside a script function, I want to call a function that creates my visualization with some json I created on the server side.
The problem is that when rendered I have something like sunburst([Object object]). I also tried to send the stringified version of the JSON but when I do JSON.parse(#{vizJson}) it complains like Unexpected token &.
The json I send is always different and has different level of depths.
Does anyone knows what to do?
Thanks
I hope this is going to help someone. I solved it like this:
script
sunburst(!{JSON.stringify(vizJson)})
Notice the ! and the {...} wrapping the stringify method.
For this to work, you need to stringify on the server.
res.render(__dirname + '/pages/viz.jade', {
vizJson: JSON.stringify(newJson),
});
Then, as you mentioned, parse the JSON on the client.
script
sunburst(JSON.parse(#{vizJson}))
Hope that helps!
Oddly enough, for me the solution involved no calls to JSON.parse. I stringified my object on the server and just used the !{vizJson} method and got my object clientside.
Per the docs, unescaped string interpolation: http://jade-lang.com/reference/interpolation/
On the JS side, you send back
res.render(__dirname + '/pages/viz.jade', {
vizJson: JSON.stringify(newJson),
});
On the HTML side, I have found that something like:
JSON.parse( '!{vizJson}' )
works.

Passing raw Markdown text to Jade

I'm playing around with my first Node.js Express application, and as every programmer knows, the first thing you should build when testing out a new framework is a blog! Anyway, I'd like to write the articles in Markdown and then render it in the view. I saw that Jade allows for this to be done inside the view itself, using filters, but I can't get that working.
To simplify the situation, here's an example of what I'm talking about.
//app.js
res.render("article", {
md : "Hello World!\n\n*Woo*"
});
//article.jade
section
:markdown
#{md}
But, that outputs this: <section><h1>{md}</h1></section>... it isn't substituting in the variables I've passed to it.
Then I tried this:
//article.jade
section
:markdown
!{md}
And the output is this:
<section><p>Hello World!
*Woo*</p></section>
So, now it's not parsing the markdown!
I have been able to get this to work by parsing the markdown in the app.js file and then passing the HTML to the view to display, but I don't know, that seems a bit messier.
Is there a way to pass variables into Jade filters?
You can do this with a function passed in to jade from node:
var md = require("node-markdown").Markdown;
Then pass it into the view as a local:
res.render('view', { md:md, markdownContent:data });
Then render it in the jade view by calling the function:
!= md(markdownContent)
The node module node-markdown is deprecated. The marked is advanced new version. You can try like this
var md = require('marked');
Inside your router
res.render('template', { md: md });
Inside your jade template
div!= md(note.string)
I don't think jade can do this out of the box. One way to accomplish it that might feel slightly cleaner than pre-rendering the markdown is to create a helper function called markdown that takes a markdown string and returns HTML. Then you could do something like
section
!= markdown(md)
The markdown function should be included in the locals data when you render the jade template and can directly use a markdown library to convert the markdown syntax to HTML.
If you are using Scalate's Jade support you can enter:
section
:&markdown
#{md}
You can also import external files with:
section
:&markdown
#{include("MyFile.md")}

Resources