Passing raw Markdown text to Jade - node.js

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")}

Related

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)}

node, express, jade: How to create select options from a hash

I've just started to play around with node, express and thus, jade. I try to do something like this in a jade template:
my-options = {"this": "something", "that": "something else", "those": "more stuff", "these": "also included"}
form
select(name="myselection")
each option, key in my-options
option(value="#{key}") option
However, all I get is an 500 server error which is not helpfull at all. What am I doing wrong here? Any help would be much appreciated.
Update
I've just figured out, that jade templates themselves cannot contain variable definitions. Thus, the my_options hash needs to be defined in the corresponding router.js file and passed as an parameter to the appropriate result.render() function.
Your first line must be executable JS code and 'my-options' is not a valid JS variable name.
Actually, you can define variables in Jade, you just have to start the line with a hyphen. A - at the start of a line tells Jade to execute the code that follows without outputting it. A = at the start of a line tells Jade to execute the code that follows and output it after it's done.
So for example if you do
- var foo = "bar"
= 2+2
p #{foo}
you will see this in your page source:
4
<p>bar</p>

Config DustJS (ServerSide) do not escape new line?

I'm using DustJS with ExpressJS with NodeJS.
When ExpressJS renders, it auto escape the new line and white space in my dustJS; while since I'm putting JavaScript into my DustJS templates, I want to leave the white spaces as it is.
How to achieve that?
Thanks a lot.
Update: here's some further explanation:
In my template.dust, I have something like:
<script type='template' id="tempVO">{.vo|s}</script>
<script> {! Block to compile the dustJS into cache !}
$(function($){
dust.compile($("#tempVO").html(),"vo");
// register helper
dust.helpers.justToString = function(chunk, ctx, body, param){
console.log(param);
}
})();
The default behaviour of DustJS, when used with expressJS by doing:
app.get("/",function(req,res){
res.render("ajaxTemplate",xmlService.templates);
});
would escape all the white spaces so that it turns out something like:
$(function($){dust.compile($("#tempVO").html(),"vo");// register helperdust.helpers.justToString = function(chunk, ctx, body, param){console.log(param);}})();// AJAX Callback</script><script>$(function(){$(".tipNeeded").tooltip();$(".tabsNeeded").tabs();});
Which is certainly not what I want.]
Although I can just use some external JavaScript Import, like:
<script src="my/own/beautiful.js"></script>
Still I'd like to know how to put in-HTML script by not-escaping the white space when render my dustJS files.
From the Dust Tutorial on controlling whitespace suppression, the exact method would vary based upon the version you are using. If you are on v1.2.6 (the latest as of this writing) you would add this line to your code:
dust.optimizers.format = function(ctx, node) { return node };
To quickly test it, add that line immediately after your require for the dustjs-linkedin module:
var dust = require('dustjs-linkedin');
Edit:
From version 1.2.0 to 1.2.5, the compile function took three arguments:
dust.compile = function(source, name, strip)
If strip was set to false then whitespace would be preserved. However, it looks like this argument was removed in 1.2.6. Even with a version that has the strip argument, when using express, you aren't calling dust.compile directly. You might be able to use something like consolidate.js as a basis to write two render calls, one with whitespace and one without...but I don't see a plainly simple way.

Compile Jade to JSON?

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.

Get return value of `include` in jade template

What I basically try to accomplish is to re-use jade partials/templates when getting data through a socket connection. Non working example:
socket.on('company_created', function(company) {
var html = include _company;
$('#companies ul').append(html);
});
Normally I had to create a new li and set the content like so (which is working as expected):
$('#companies ul').append($('<li>').text(company.name));
This is okay for a simple list, but if I had complexer list and stuff, this could get messy pretty quick, plus I had to write plain HTML again, so I figured re-using my already existing jade templates with all their goodness would be awesome, but had not luck, yet.
Any clue?
PS: Please do not tell my to use Ember, Backbone, Derby, Meteor, Angular or whatsoever.
Thanks in advance!
You can compile your jade sources to JS with jade.compile. Then include these sources in the client-side javascript, include jade's runtime.min.js, and refer to your jade templates as to normal JS functions in your client-side code.
For example,
server.js
app.get('/templates/:template.js', function (req, res) {
var template = req.params.template;
response.end([
"window.templates = window.templates || {};",
"window.templates[\"" + template + "\"] = " + jade.compile(template + ".jade", { client: true; });
].join("\r\n"));
});
client.js
$(function() { $("#placeholder").html(window.templates["content"]({user: "Daniel" })); });
content.jade
h1: Hello #{user}!
index.jade
!!!
html
head
script(src='/lib/jquery/jquery.js')
script(src='/lib/jade/runtime.min.js')
script(src='/templates/content.js')
script(src='/scripts/client.js')
body
#placeholder
Note that the code above might be syntactically incorrect and is provided solely to illustrate the idea.
we have a build step that compiles them to functions sort of like penartur mentioned. I dont use extend or include (which dont work on the client anyway ATM), but personally I find we have absolutely no need for that on the client at all since the DOM provides all the separation we need.

Resources