How to pass an array in hogan-express template engine - node.js

How do I pass an array like the below to a HTML page using hogan-express? I am trying but it doesn't seem to be working.
My code:
apiRouter.get('/myPosts', function(req, res, next){
userModel.findOne({'profileID':req.session.facebookProfileId}, function(err, userPosts) {
if(userPosts) {
res.render('myPosts', {title:siteName + ': My Posts', posts:userPosts.posts});
} else {
console.log('You do not have any posts');
}
})
})
By the way, the userPosts.posts looks like the below:
["123","124","125"]
myPosts.html page is as below:
<!doctype html>
<head>
<meta charset="UTF-8">
<title>{{title}}</title>
</head>
<body>
<p>Post 1</p>
<p>Post 2</p>
</body>
</html>
By the way, the {{title}} bit is coming through.

In short: you can't, at least not like that.
What you can do is iterate over the posts:
{{#posts}}
<p>Post 1</p>
{{/posts}}
However, that would leave you with the problem of the text content for each link ("Post 1"). To fix that, you need to process the array server-side, before you pass it to render.
For example:
res.render('myPosts', {
title : siteName + ': My Posts',
posts : userPosts.posts.map(function(postId, idx) {
return { postId : postId, postNum : 1 + idx };
})
});
And the template:
{{#posts}}
<p>Post {{postNum}}</p>
{{/posts}}
The rendered HTML will look like this:
<p>Post 1</p>
<p>Post 2</p>
<p>Post 3</p>

Related

How to escape '-' hyphen symbol from xml in MathJax

<!DOCTYPE html>
<html>
<head>
<title>MathJax MathML Test Page</title>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/mml-chtml.js">
</script>
</head>
<body>
<p>
<math overflow="scroll"><mfrac><msup><msub><mi mathvariant="-italic">Q</mi><mrow><msub><mi mathvariant="italic">T</mi><mi mathvariant="italic">i</mi></msub><mo mathvariant="italic">max</mo></mrow></msub><mn mathvariant="normal">0.75</mn></msup><msup><mi mathvariant="italic">β</mi><mn mathvariant="normal">0.75</mn></msup></mfrac><mo>≤</mo><mn mathvariant="normal">5</mn><mo>×</mo><msub><mi mathvariant="italic">AEL</mi><msub><mi mathvariant="italic">T</mi><mi mathvariant="italic">i</mi></msub></msub><mo>×</mo><msup><msub><mi mathvariant="italic">Q</mi><msub><mi mathvariant="italic">T</mi><mi mathvariant="italic">m</mi></msub></msub><mrow><mo>−</mo><mn mathvariant="normal">0.25</mn></mrow></msup><mo></mo></math>
</p>
</body>
</html>
Getting parsing error with new CDN https://cdn.jsdelivr.net/npm/mathjax#3/es5/mml-chtml.js
Here is a configuration you can use to post-filter the MathML to fix the invalid -italic math variant value.
MathJax = {
startup: {
ready() {
MathJax.startup.defaultReady();
MathJax.startup.input[0].postFilters.add(({data}) => {
data.walkTree(node => {
if (node.attributes) {
if (node.attributes.get('mathvariant') === '-italic') {
node.attributes.set('mathvariant', 'italic');
}
}
});
});
}
}
}
Place this in a <script> tag just before the script that loads mml-html.js.

Issue regarding converting of Arraybuffer of image to image and displaying it in html page

I have my js code as
app.get("/", function(req, res) {
var sql="SELECT image FROM images WHERE img_id=2";
connection.query(sql, function(err, result){
if(result.length <= 0)
message = "Profile not found!";
console.log(result);
res.render('image.ejs',{data:result});
});
});
and the image.ejs code is:
<html>
<head>
<title>Images</title>
</head>
<body>
<%= data %>
</body>
</html>
When I have runned it I just got the response like
[object Object]
but I need to my image to get displayed.will you guys help me out?
An ArrayBuffer/Buffer can't be a value for an img tag, what you can do is base64 encode the image, and display it
res.render('image.ejs',{ data: result[0].image.toString('base64') });
Now on your HTML
<html>
<head>
<title>Images</title>
</head>
<body>
<img src='data:image/png;base64,<%= data %>' />
</body>
</html>
If your images have different extensions, you can use: file-type package on the buffer and add the image type to the data passed to res.render
const imageBuffer = result[0].image;
const { mime } = await FileType.fromBuffer(imageBuffer)
res.render('image.ejs', { data: imageBuffer.toString('base64'), mime });
<img src='data:<%= mime %>;base64,<%= data %>' >

Change polymer attributes externally

I see a lot of questions regarding on how to listen for changes in attributes. But none on how to actually change them.
Even in debug, I can't find the attributes in the object tree. How do I achieve this? is there a more polymeric way of doing the following ?
<polymer-element name="my-element" attributes="owner">
<template>
<p id="el">{{owner}}</p>
</template>
<script>
Polymer({
owner: "Miguel",
});
</script>
</polymer-element>
<my-element id="el1" owner="blabla"></my-element>
<script>
$(document).ready(function(){
$("el1").owner = "Mary"
})
</script>
It prints blablab, but doesn't change it to Mary
In 0.5, you need to wait for polymer-ready. See docs here.
<head>
<link rel="import" href="path/to/x-foo.html">
</head>
<body>
<x-foo></x-foo>
<script>
window.addEventListener('polymer-ready', function(e) {
var xFoo = document.querySelector('x-foo');
xFoo.barProperty = 'baz';
});
</script>
</body>
Ideally, your app would be one element like <my-app></my-app> so that you'd have a binding for the owner attribute like so:
<my-element owner="{{owner}}"></my-element>
And my-element would reside in another Polymer element in which you can set the owner attribute like so:
// Parent Polymer element
Polymer({
_someFunctionYouCall: function() {
this.owner = 'Mary';
}
});

Writing to a particular div in node js

I have this simple file hello.html and looks like this.
<!DOCTYPE html>
<html>
<head>
<style>
p { background:yellow; }
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<div class="thediv">
</div>
</body>
</html>
I am using fs module to write to my file like this
var fs = require('fs');
var randomnumber = Math.floor((Math.random()*100393)+433334);
fs.createReadStream('test.txt').pipe(fs.createWriteStream(randomnumber+'.txt'));
fs.writeFile(randomnumber+".txt", "Lorem ipsum"+randomnumber, function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
console.log(randomnumber);
I want to write
<article>
<p> lorem ipsum </p>
</article>
to the div with the id thediv.Is the fs module used for this kind of thing or is there a module more suited for this task?.
I believe the only answer to get an HTML parser, parse the file into a DOM, make the adjustments and then save the DOM back to a file. Here's a question that answers where to find an HTML parser.

is there a way to add CSS/JS later using EJS with nodejs/express

i'm using the EJS template engine with nodejs/express and i'm wondering if it's possible to add another css or js file in e.g the index.ejs (not the layout.ejs)
layout.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<link rel='stylesheet' href='/stylesheets/smoothness/jquery-ui-1.8.14.custom.css' />
</head>
<body>
<%- body %>
</body>
</html>
index.ejs
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
i don't want to add the second css file in every template but only the index.ejs - is there any way i can do that?
found a solution here: Node.js with Express: Importing client-side javascript using script tags in Jade views?
it's using jade instead of EJS but works all the same.
here are some code-snippets for express 2.4.0.
you have to add the following "helpers" to your app.js
app.helpers({
renderScriptsTags: function (all) {
if (all != undefined) {
return all.map(function(script) {
return '<script src="/javascripts/' + script + '"></script>';
}).join('\n ');
}
else {
return '';
}
}
});
app.dynamicHelpers({
scripts: function(req, res) {
return ['jquery-1.5.1.min.js'];
}
});
the layout.ejs looks sth like this:
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<%- renderScriptsTags(scripts) %>
</head>
<body>
<%- body %>
</body>
</html>
if you don't add any scripts to the scripts-array, only 'jquery-1.5.1.min.js' will be included - if you want to add files to a subpage you can do this like so:
test.ejs
<% scripts.push('jquery-ui-1.8.14.custom.min.js', 'jquery.validate.min.js') %>
<h1><%= title %></h1>
<p>I'm a template with 3 js files in the header</p>
that's it.
As helpers and dynamicHelpers are gone in Express > 3, I rewrote pkyeck code so it works in Express 3.
So in app.js have this instead of the helpers / dynamicHelpers. Leave everything else as is.
app.locals({
scripts: [],
renderScriptsTags: function (all) {
app.locals.scripts = [];
if (all != undefined) {
return all.map(function(script) {
return '<script src="/javascripts/' + script + '"></script>';
}).join('\n ');
}
else {
return '';
}
},
getScripts: function(req, res) {
return scripts;
}
});
In app.js add line:
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/public')); // This line.
In layout.ejs:
<!DOCTYPE html>
<html>
<head>
<title>Authentication Example</title>
<link rel="stylesheet" href="/stylesheets/style.css"/>
<script src="/javascripts/jquery.js"></script>
</head>
<body>
<%- body %>
</body>
</html>
In index.ejs or login.ejs:
<h1>Login</h1>
<form method="post" action="/login">
<p>
<label>Username:</label>
<input type="text" name="username">
</p>
<p>
<label>Password:</label>
<input type="text" name="password">
</p>
<p>
<input type="submit" value="Login">
</p>
</form>
<script src="/javascripts/test.js"></script> <!-- Second Script -->
In test.js:
$(document).ready(function() {
try{
alert("Hi!!!");
}catch(e)
{
alert("Error");
}
});
Regards.
Thanks #asprotte for providing this for express 4.x. Did you tested this?
Because it does not appears to be working for me. So I have made some changes to your code here are they:
Put this in app.js file
app.locals.scripts = [];
app.locals.addScripts=function (all) {
app.locals.scripts = [];
if (all != undefined) {
app.locals.scripts = all.map(function(script) {
console.log(script);
return "<script src='/js/" + script + "'></script>";
}).join('\n ');
}
};
app.locals.getScripts = function(req, res) {
return app.locals.scripts;
};
then in template file put (I am using ejs template here) :
<% addScripts(['cart.js']) %>
Then in the layout file we need these to append at the bottom of the page get the scripts
<%- getScripts() %>
I have tested it and its working for me. Please correct me if I am wrong.
Thanks,
Thanks for illustrating this option pkyeck!
In express 4.x app.locals is an object. Here's pkyeck's answer rewritten to work in express 4.x:
app.locals.scripts = [];
app.locals.addScripts=function (all) {
app.locals.scripts = [];
if (all != undefined) {
return all.map(function(script) {
return "<script src='/javascripts/" + script + "'></script>";
}).join('\n ');
}
else {
return '';
}
};
app.locals.getScripts = function(req, res) {
return scripts;
};

Resources