XSLTProcessor is not defined in node.js - node.js

I am trying to transform XML to XHTML. I have used XSLTProcessor in client side (Angular) and it's working fine. Now I am trying to use the same code in Node JS but it's not working and I am getting error message as XSLTProcessor undefined. Below is the client side code. Please suggest me the methods available for transformation in Node JS side.
transformXml(xml, xsl) {
var html;
if (this.isIE) {
html = xml.transformNode(xsl);
} else {
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
var xmlDom = xsltProcessor.transformToDocument(xml);
var serializer = new XMLSerializer();
html = serializer.serializeToString(xmlDom.documentElement);
}
return html;
}

XMLTProcessor() is not part of Node.js. You need a package like https://www.npmjs.com/package/xslt or similar - there are a number of packages for XSLT: https://www.npmjs.com/search?q=xslt.

Related

Server Side rendering in mongo with dust

Is it possible to fetch data from MongoDB and render a html template on the server side itself for a node-js project?
As of now in my serverside js file I've done the following.
//Failing array will be populated by a db.find later on.
var failing = [
{ name: "Pop" },
{ name: "BOB" }
];
/*Now i have to send a mail from the server for which I'm using nodemailer.
Where do i store the template ? This is what I've done in the same file */
var template = "<body>{#failing} <p>{.name}</p> {/failing}</body>"
// Add this as the body of the mail and send it.
I'm not sure how to render the data and how to get it displayed. I'm aware storing the template in the variable isn't right but I'm not sure what else to do.
If your template is that short, you can store it in a variable without problem. Obviously, you can store it in a file also.
Let's say you decide to store it in a file index.dust:
<body>{#failing} <p>{.name}</p> {/failing}</body>
Now, in your node controller you need to load the file and generate the html content from it:
const fs = require('fs');
const dust = require('dustjs-linkedin');
// Read the template
var src = fs.readFileSync('<rest_of_path>/index.dust', 'utf8');
// Compile and load it. Note that we give it the index name.
var compiled = dust.compile(src, 'index');
dust.loadSource(compiled);
// Render the template with the context. Take into account that this is
// an async function
dust.render('index', { failing: failing }, function(err, html) {
// In html you have the generated html.
console.log(html);
});
Check the documentation in order not to have to compile the template every time you have to use it.

Is there a way to render a NodeJs Express view to a variable?

Is there a way to render an express view to a variable as opposed to the response stream?
var view = path.join( __dirname, '/../customer-product/views/copysheet.html');
res.render( view, {
data: product
})
I need the html on the server side so that I can be passed to PhantomJs for PDF generation.
There's a pretty good article on it at Strongloop. The upshot is that you would interact directly with the view engine like so:
var templatePath = require.resolve('./copysheet.html');
var templateFn = require('jade').compileFile(templatePath); // or whatever view engine you're usingg
var output = templateFn({data:product});

Passing objects between nodejs and jade

I have the following code in my server.js
var cddata = [];
body.rows.forEach(function(doc) {
cddata.push([{id: doc.id, name: doc.key, text:doc.value.Time, group: 1}]);
});
response.render('timeline', {cddata: JSON.stringify(cddata)});
and I have the following in my Jade view file
script(src='vis/dist/vis.js')
link(rel="stylesheet", href="vis/dist/vis.css", type="text/css")
script.
//alert(cddata);
var options = {};
var data = new vis.DataSet(cddata);
var container = document.getElementById('visualization');
new vis.Timeline(container, data, options);
However, nothing related to the chart is rendered. I presume the object is not correctly passed to the jade file. Please help!
Also, is there a way to verify the incoming object in Jade? Alerts dont seem to work.
thanks
The <script> in your jade is a browser side script so won't be able to access variables in the templates generation scope. You'll need to output your data as JSON and read it in using browser side JavaScript, something like this:
script(src='vis/dist/vis.js')
link(rel="stylesheet", href="vis/dist/vis.css", type="text/css")
script.
var chartData = JSON.parse('#{cddata}')
var options = {};
var data = new vis.DataSet(chartData);
var container = document.getElementById('visualization');
new vis.Timeline(container, data, options);
After much deliberation, the following worked to pass object from node server to client side server scripting on Jade file.
on the server.js, where dbdata is an array of JSON objects
response.render('timeline', {dbdata:dbdata});
On the jade file,
script.
var chartData = !{JSON.stringify(dbdata)};
Thanks,

Handlebars Templates in Unit Tests, How To

I'm creating client-side tests in YUI3, and need to compile the handlebars template for the page I'm testing.
We're running a Node app with hbs set as the rendering engine, so when requests come into the server the router responds by calling res.render() and making a call directly to the .hbs file in the views directory.
In the tests I need to instantiate handlebars template, then assign it to the DOM, but as the tests are javascript I don't have access to file stream functionality and handlebars.compile() doesn't take a path as an argument.
Basically I want to do something like this, but where the Handlebars.compile() method successively compiles the referenced template file:
var body = A.one(document.body);
var container = A.Node.create('<div id="test-container"></div>');
var domTemplate = Handlebars.compile('../../../../views/campaign/set-campaign-properties.hbs');
var dom = A.Node.create(domTemplate);
container.append(dom);
body.append(container);
Keep in mind that there is a big differance between the client and the server, you are asking to test client side items on the server which can cause some strange issues, but there are some good tools to help. Generally when I unit test my template rendering I will use something like phantomjs or selenium. You could however use jsdom or jest to handle parsing the dom on the server side.
I have worked up a sample with jsdom, http://runnable.com/me/VIZN1VmFRzsBJu8r
var Handlebars = require("handlebars")
var source = "<p>Hello, my name is {{name}}. I am from {{hometown}}. I have " +
"{{kids.length}} kids:</p>" +
"<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>";
var template = Handlebars.compile(source);
var data = { "name": "Alan", "hometown": "Somewhere, TX",
"kids": [{"name": "Jimmy", "age": "12"}, {"name": "Sally", "age": "4"}]};
var templateResult = template(data);
var jsdom = require("jsdom");
jsdom.env(
templateResult,
["http://code.jquery.com/jquery.js"],
function (errors, window) {
console.log("contents of p tag:", window.$("p").text());
}
);

Retrieving HTML from CouchBase into Node.js / Express 4 leaves it unrendered

I'm having a small issue with rendering HTML, stored in CouchBase, fetched by Node.js
In CouchBase I have several small HTML-snippets. They contain text, tags such as <br /> and html entities such as <. They are of course stored as an escaped string in JSON.
So far, so good. However when I pull it out and display on the page, it is rendered "as-is", without being interpreted as HTML.
For example:
[ some content ...]
<p>Lorem is > ipsum<br />And another line</p>
[rest of content ...]
From the controller in Express 4:
var express = require('express');
var router = express.Router();
var couchbase = require('couchbase');
var cluster = new couchbase.Cluster('couchbase://myserver');
var bucket = cluster.openBucket('someBucket', 'somePassword');
var Entities = require('html-entities').XmlEntities;
entities = new Entities();
var utf8 = require('utf8');
/* GET home page. */
router.get('/', function(req, res) {
bucket.get('my:thingie:44', function(err, result) {
if(err) throw err
console.log(result);
var html = utf8.decode(entities.decode(result.value.thingie.html));
// var html = utf8.encode(result.value.thingie.html);
// var html = utf8.decode(result.value.thingie.html);
res.render('index', { title: 'PageTitle', content: html });
});
});
It is then passed to the template (using hogan.js) for rendering.
When looking into this I found that it might have something to do with the encoding of the <'s and <'s that prevent it from being parsed. You can see my converting attempts in the code, where none of the options gave the desired result, i.e. rendering the contents as HTML.
When using utf8.decode(), no difference.
Using utf8.encode(), no difference.
Using entities.decode() it convert < into < as predicted, but it's not rendered even if <div;&gt becomes <div>.
Any ideas?
I found the solution over here: Partials with Node.js + Express + Hogan.js
When putting HTML in a Hogan template, you have to use {{{var}}} instead of {{var}}.
And thus it renders beautifully, as intended :)
Wasn't encoding issues at all ;)

Resources