convert json to markdown and inject into jade using gulp - json

Currently I know how to inject json data into jade using gulp, but the markdown in my json data are not formatted in the right way. I have heard of marked but not sure how I can use it in my gulp file or jade file.
I am piping data directly using
.pipe(data(JSON.parse(fs.readFileSync(file)))
.pipe(pug())
.pipe(gulp.dest(destdir))
I have tried
.pipe(data(marked(JSON.parse(fs.readFileSync(file)))))
and
.pipe(marked(data(JSON.parse(fs.readFileSync(file)))))
both say TypeError: src.replace is not a function
I am not sure how I can embed marked here or in my jade codes. Any suggestions?
EDITED
So I did some preprocessing of the json object that I got from JSON.parse. I wrote a function to marked the strings in each json object first before inject into my jade data. Something like:
var marked = require("marked")
function preprocess(){
var data = JSON.parse(fs.readFileSync(file));
iterate through data and do marked(string)
return data
}
Now I am able to get the rendered string into jade, but jade is not able to understand the markdown symbols, for example <p> </p> are literally shown in my webpage as <p> </p>. Any workaround?

Since I haven't directly used a workflow like yours before, I cannot directly solve your issue with a single suggestion but I will try to share couple of things that might fix your problem when applied in a combination.
Let's start with Markdown. You can use marked together with gulp-markdown-to-json. A common workflow looks like this:
const gulp = require('gulp');
const markdownToJSON = require('gulp-markdown-to-json');
const marked = require('marked');
marked.setOptions({
pedantic: true,
smartypants: true
});
gulp.task('markdown', () => {
gulp.src('./content/**/*.md')
.pipe(markdownToJSON(marked))
.pipe(gulp.dest('.'))
});
This will take your markdown and wrap it in JSON format also converting the body of the markdown to HTML. If you look at the options of marked, there are methods available to clean up your markdown a bit. They might be useful since you've said there are problems with your formatting.
Now we have a JSON file that we need to pipe to Jade. You can also pipe via the Jade compile task using data(locals).
gulp.task('compilePug', function() {
return gulp.src('templates/**/*.pug')
.pipe(pug({
pretty: true,
data: {
'posts' : JSON.parse(fs.readFileSync('content/json/content.json'))
}
}))
.on('error', onError)
.pipe(gulp.dest('./'));
});
Once you compile, you will have access to your JSON under posts variable right in Jade.
And finally, you mentioned that paragraph tags are appearing in your Jade template. That sounds like you're trying to pipe plain HTML to Jade. Which is fine, in fact, you'll be piping HTML to Jade if you use the gulp workflow I shared in the beginning. You just need to tell Jade that HTML is coming:
!{posts.HTMLfromJSON} // Jade will expect HTML
#{posts.HTMLfromJson} // Jade won't expect HTML it will treat it like plain text
Hope any of these will help you fix the issue.

Related

Creating a UI/writing HTML from a JSON file

I have a really long, unwieldy, unformatted JSON file generated by Lighthouse (a tool that conducts page load time analysis- so this file has the results of the tests). In order to make it formatted to be readable by people, I need to apparently create a UI around this file. My problem is that I'm not sure how to begin working on it.
I've read about something like creating HTML from JSON objects, I think I'd like to try that to just display all the information from the tests in the browser right now... But where would I write that? I have one Node.js file right now, which is running the tests and using JSON.stringify() to stick the JSON'd results into a file. Can I generate the HTML right after I create the JSON? (And the main question- how would I create HTML from a JSON file?)
I'm just starting out with Node and JSON, any tips are highly appreciated.
Yes, you can create HTML from a JSON file.
Here's a simple example done with jQuery, first creating an array of all of the elements, and then using .join("") to parse them. Once parse, they can simply be appended anywhere in the DOM:
var json_file = {
"one": "Hi there",
"two": "Another item",
"three": "Third item"
}
var items = [];
$.each(json_file, function(key, val) {
items.push("<li id='" + key + "'>" + val + "</li>");
});
$("<ul/>", {
"class": "json-list",
html: items.join("")
}).appendTo("body");
// Sample extension showcasing manipulation of inserted HTML
$(".json-list #two").css('color', 'red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Obviously, the more complicated your JSON (and desired HTML structure), the more complicated the method of parsing the JSON is going to be.
A templating engine would make your job significantly easier,
and there and hunderds of these. Some of the more popular ones are:
EJS
jQuery.dForm
JQuote2
JSON Template
JTemplates
Mustache
PURE
Tempo
Hope this helps! :)

Node.js - where to find incoming parameter in the HTML/document

I have the following function in my Node.js code that renders an HTML page and passes it an javascript object called htmlParamObj
exports.getPage = function (req, res, next) {
var htmlParamObj= {
propertyOne: 'yada',
propertyTwo: 'yada yada'
};
res.render('myPage.html',htmlParamObj);
};
I can access the incoming parameter (htmlParamObj) with EJS like so: <% propertyOne %>, but I don't know how to access htmlParamObj via the document itself. I believe htmlParamOb' will be attached to the document of the html - but what field in the document can I find it in? Is it in the head, the body, the childNodes? Where?
The object passed is only used while rendering the HTML, and will not be passed to the browser in any way.
If you need that data inside the page you need to put it there.
The solution I've used when I need to pass complex data to a client side script is to place a script tag near the top of my HTML EJS file and populate that with my data. For example I might add the following to my template:
<script>
window.MY_DATA = <%= JSON.stringify(myData) %>
</script>
Notice that since JSON is a subset of javascript, I can use JSON.stringify to serialize my data into a form suitable for placement inside a script tag, and assign it to whatever variable I want.
The limitation here is that you can't send any data that can't be serialized with JSON.stringify. Not a heavy burden, but could trip you up if you want to send a function or other object.
The solution I found is to define a global attribute in my HTML like so:
<a name="team" value="<%=team._id%>"></a>
then I can access it in any script like so:
<script>
var team = document.getElementsByName('team');
</script>
This will return the correct object.
However, I don't think this is the best answer, especially given that any globally defined variable is usually a bad idea. I am hoping another answer is given to this question.

Node.js code in html file

It is possible to mix HTML with node.js commands?
I want to make my site like in PHP so:
<html>
<!-- Some HTML -->
<?php
echo "example";
?>
</html>
So, server makes all commands, which are included in HTML file and than returns pure HTML to show it in users browser. I need this, because I want to get data from MySQL database and then show it on my site.
In all tutorials I found only:
res.write("<Some html>");
And there is nothing about keeping html in separate files and add to them some server-side js.
Find a templating engine and build your application around that, because what you want is not possible.
For a list of compatible template engines, take a look here:
https://github.com/joyent/node/wiki/modules#wiki-templating
Your example using Express and EJS (which I use). Jade seems like overkill to me, but that's just my opinion.
// index.ejs (the html template)
<html>
<head></head>
<body>
<div><%= example %></div>
</body>
</html>
And in your node app:
app.get('/', function (req, res, next) {
res.render('index.ejs', {
layout: false,
locals: {
example: "Hello world!"
}
});
});
That's pretty much the basics of using EJS. I personally like it over Jade because the people I use to do up the html don't hand it to me in Jade format, and it's very similar to how I used to do php templating.
There is more you can do with the templates of course, you can put javascript in them to say, loop through an array returned by a database, include other .ejs files. You just need to dig into the docs and examples on the web.
Use the function res.write is enough.
You can generate some string with html syntax, like "<html>..</html>", then you put it into the res.write and you get response with a html file.
The point is how to generate the string with html syntax.
If we have a template file like this:
<html>
<body>
<h1>{{ "Hello" + " world!" }}</h1>
</body>
</html>
We want to get the "Hello world!" between <h1> and </h1>. So we can have the work done by:
read the template file with fs.readFile
use regular expression to get the content between {{ and }}
use eval to evaluate the content, and replace them.
After doing this, you can get the string with html syntax. and that is what most template engines(like ejs, jade) do, of course they have more complex works to do.
I hope that this can help you know more about template engine with node.js, and please forgive my poor English...
Have you tried a web application framework like express?
Check it out here!

How to turn a jade page into html?

I have a jade file called syntax.jade. What I need is a way to convert syntax.jade, along with the information I would normally pass it with a res.render statement, into a html document in node so that I can manipulate it in that form. Basically what I want is this:
when I use
res.render('syntax', {comment: comment}, function(err, html))
html contains the html of the page as a string. I need another way to get that code that doesn't require me to render the page in the browser.
The reason I want to do this is so that I can include the resulting HTML code in another res.render statement in order to provide formatting instead of doing all the formatting in the front end.
You can just require Jade as a Node module and use the renderFile() method.
var jade = require('jade');
jade.renderFile('syntax.jade', {comment: comment}), function (err, html) {
if (err) throw err;
// rendered string is in html variable
});
If there's no error, then you have a rendered HTML string as a result. If you want to do this synchronously, then just don't specify a callback:
var html = jade.renderFile('filename.jade', {comment: comment});
That is already what you have. From the express docs on res.render
When a callback is provided both the possible error and rendered
string are passed, and no automated response is performed.
So res.render(viewName, locals) does BOTH rendering of the HTML and sending that HTML as the HTTP response body. However res.render(viewName, locals, callback) with 3 arguments just renders the HTML and passes it to the callback without sending any HTTP response. Thus you can do whatever is needed with the HTML and then send a response later.
There is also app.render which is another general utility to render stuff without having anything to do with a particular http request/response.

Animating JSON data?

Dumb question time. I was trying to integrate my JSON data with a flipbook plugin, using a Mustache templating system. Needless to say, this wasn't working at all.
I'm a jQuery noobie, so is there any easy way to bind and animate the JSON data to/with a plugin (with or without the Mustache tags)??
From your question it is a bit hard to deduce what you want, but I feel you got already all the pieces together. First the example you have been linking to in a comment: https://github.com/blasten/turn.js/wiki/Making-pages-dynamically-with-Ajax
This fetches not yet loaded pages via Ajax, and the sample code assumes the Ajax call gets HTML back from the server, as can be seen in the code snippet from there (after adding a missing '}':
$.ajax({url: "app?method=get-page-content&page="+page})
.done(function(data) {
element.html(data);
});
Here the done function processes the data it got back from the server by straight injecting it into the element, which is expected to contain the current page.
I assume next that you do have a server side method, but that method returns JSON instead. Let me assume for the moment that it returns the following structure:
{ "title" : "the title of page N",
"text" : "here is some text for the page N." }
The next thing is to render this JSON into into html in the done funktion, before inserting the result into the page. Looking at the short tutorial on the README.md this might look like:
$.ajax({url: "app?method=get-page-content&page="+page})
.done(function(data) {
var pageHtml = Mustache.render("<h2>{{title}}</h2><p>{{text}}</p>", data);
element.html(pageHtml);
});
If the server returns the proper data you should now see a
<h2>the title of page N</h2><p>here is some text for the page N.</p>
appear on the page.