Using handlebars.js for dynamic user content? - javascript

Handlebars is commonly used on static predefined html templates and then given dynamic data via JSON, but what if the template itself comes from json?
I'm trying to build a community forum whereby I have a template that gets filled in for where the users post goes. The post itself however also contains template information (which is dynamic). How can I get handlebars to process a dynamic template that just came out of ajax?
For example, a users post can contain any or all of the following in any order: text, pictures, links, videos, etc.
The content will look something like this:
{{text-open}} blablabla heres a picture {{text-close}}{{image-open}}
http://someRandomUrl.com {{image-close}} {{image-open}}
http://anotherRandomUrl {{image-close}}
I'm not sure how to do this with handlebars. I have the feeling maybe I should just use a string replace function? But would that be the optimal method?

You just have to compile the template:
fetch("post.hbs")
.then(source => Handlebars.compile(source))
.then(postTemplate => {
// Do stuff, then fill the template:
postElement.innerHTML = postTemplate(postData);
});

Related

How to make a page for every single object from JSON data - JavaScript

I've JSON data
[{"name":"Zohir","id":"151232", "code":"ZO"},{"name":"Tuhhin","id":"151233", "code":"TU"}, .....]
I want to show every single object in different page & also i want to render a single student page based on "code", Like www.mylink.com/student/ZO
I don't know is my question correct or not, I'm new in JavaScript
I tried to show all data in a page from JSON file & i did that, but i can't render a single student page
function getStudent() {
fetch('https://myjesondatas123211.herokuapp.com/v/students')
.then((res) => res.json())
.then((data) => {
let output = '<h2>Students</h2>'
data.forEach(function (student) {
output += `
<div class="col-md-4">
<h4>${student.name}</h4>
<p>${student.id}</p>
<p>${student.code}</p>
</div>
`;
});
document.getElementById('output').innerHTML = output;
})
};
A solution to this problem would be fairly complex to create in plain Javascript.
You would need to have an understanding about single page applications and routers to start tackling this problem.
You might want to look over here or search for another tutorial to get the basics:
https://dev.to/rishavs/making-a-single-page-app-in-ye-good-olde-js-es6-3eng
You want to do a single-page app, which is not simple in plain javascript.
You may want to consider using frameworks for this, such as Angular or React to do this quite easily
They have native routers and allow you to create routes with parameters, and display a component depending on this parameter.

Storing HTML in Firebase (AngularFire), good idea or bad?

Is it a good idea to store HTML in Firebase (AngularFire)?
I have a website where I am creating an admin site where users can make HTML elements. I want people to save these elements and the order and the content within the elements. So I thought it would be much easier to just store the whole HTML as a string and load it in when they return. Bad idea?
Here is what I have (simplification):
$scope.save = function() {
var refState = new Firebase("https://<name>.firebaseio.com/users/" + currentAuth.uid + "/state");
var html = "<div>hello</div>";
refState.set({
"state": html
}, function(error) {
if (error) {
console.log("not been saved")
}
})
}
And in my HTML I retrieve want to display it like this using Angular, (yeah I know now how to render HTML in Angular thanks to the comments :)
<div class="well col-md-12">
{{sync[3].state}}
</div>
Storing stringified HTML in firebase is no worse than storing it in a different datastore. You'll want to consider XSS issues, including things like what if they define <style>body{display:none}</style> in their html.
Are you creating a real full fleshed content creation system? If so, it's sometimes hard to get away from user defined HTML, usually from CKeditor, tinymce, etc. However, if the items that they're building are all similar, you should consider how you can store/restore them in a better data format. Most of the time there is a better way to save and restore user defined content that storing straight HTML.
I'd suggest checking out Firepad.
Firepad is a drop-in "Open source collaborative code and text editing" experience for Firebase apps.
"Firepad can use either the CodeMirror editor or the Ace editor to render documents."
Easily allows for a rich text-editor experience that seamlessly stores/syncs the content in a Firebase instance.
As the documentation describes, this is how you initialize Firepad:
<div id="firepad"></div>
<script>
var firepadRef = new Firebase('<FIREBASE URL>');
var codeMirror = CodeMirror(document.getElementById('firepad'), { lineWrapping: true });
var firepad = Firepad.fromCodeMirror(firepadRef, codeMirror,
{ richTextShortcuts: true, richTextToolbar: true, defaultText: 'Hello, World!' });
</script>
It's perfectly fine to store HTML in Firebase.
Koding.com, Nitrous.io, and more use Firepad for their collaborative code editor products.
I think it's very bad idea to store html in firebase, store only pain text
How to render html with angular templates

Writing handlebars in Ember

I have a small app which is multilingual. The text of the app is coming from the server. The text can be in different language. For now lets stick to Swedish and English. User can switch between languages. What I am trying to do is when the app loads get the text in both languages and store it in models in Ember.
Then I am trying to write a Handlebars helper which will allow me to switch between the languages. For example the data from the server I am getting is in this form.
langData: {
sv_SE: {
start_page: "..."
},
en_US: {
start_page: "..."
}
My model for this is language.js which is like this
App.Language = DS.Model.extend({
language: DS.attr('string'),
start_page: DS.attr('string'),
});
In my handles bar I am trying to do something like this
Ember.Handlebars.helper('__', function(key, lang, options) {
// get the text specified for the language. A function which will check the language model and
// fetch data for the particular key from it
});
I am calling the handles bar like this
{{__ start_page en_US}}
What I am thinking that, this will return me start page text in English language.
Is this the right way? If not what will be the right way? Also, I will have different text strings which will be used in different hbs files.
I've used Ember-I18n for a project successfully. It gives you a place to put your translations outside a model. I then load the current language based on a cookie or a setting on the user model. Switching to a different language does require a full-page reload for me, but you might be able to get it to work without that.

How to manipulate HTML table once it's returned from backend like Node.js?

Here's the situation: I use Node.js as my backend, and use markdown to edit and post my blog article. And when a client requests the specific URL, such as http://www.example.com/blog/article_1, I returned the blog contents from Node.js with some template like ejs, which would be something like the follows:
app.get("/blog/article1", function(req, res) {
var article = something // this is a valid HTML converted from a markdown file
res.render("article1", {
title: "my blog article 1",
article: article
});
});
In the above code, I render article.ejs with title and article variable. The article variable is a valid HTML to be injected to the ejs template. So far, it' fine.
However, if I want to display a HTML table which is written in the original markdown file, with Bootstrap 3's responsive table functionality, (i.e. <div class="table-responsive"><table class="table">...actual table...</table></div>), how can I do it? Right now the table in my markdown file is just a markdown file, and I don't think that it's the best idea to just modify all of my markdown files on which I insert or wrap with the <div class="table-responsive">...</div> line; the files might also be used in a situation other than Bootstrap.
In other words, is it feasible to dynamically or programmatically inject the responsive functionality to the table once the template is returned by Node.js? And is it also feasible to inject the responsive table functionality selectively? (in other words choose arbitrarily some tables that I want to add the responsive function?)
Continuing on from the comments: It's actually not that difficult to fork and modify a project. The faster you can get used to working with open source libraries the better your experience will be with Node. Things move pretty quickly in the Node world, and sometimes things won't work like they are expected to. You can either wait around for a fix, or roll up your sleeves and pitch in.
I found a way to update the markdown templates using their addTemplate method. However the version of Marked the project is using (2.8) doesn't support custom templates. I've forked the repository and updated the version of marked as well as fixed the issues this caused with the tests. I also added a restriction to prevent it from using Express 4 which breaks all the tests. I submitted these as a pull request to the original repo, but in the mean time you could use my version to write something like the following.
untested
var
express = require('express'),
app = express(),
Poet = require('poet'),
marked = require('marked'),
renderer = new marked.Renderer();
renderer.table = function(header, body) {
return '<div class="table-responsive"><table class="table">' + header + body + '</table></div>';
}
var poet = Poet(app, {
posts: './_posts/',
postsPerPage: 5,
metaFormat: 'json'
});
poet.addTemplate({ ext: 'markdown', fn: function(s) {
return marked(s);
}});
Alternatively, if all you're using poet for is the markdown conversion, you might as well use marked directly and cut out the dependency on poet.

base link and search api

I am attempting to query a database through an API which I don't fully understand. I have been sent an example of the API being used with a keyword search form. The form is an html file and uses jquery return JSON documents, format items into an array array, and display.
I tried to build the design of my application and manipulate the form to work within my pages. The file the uses the API requires that the a base link be used.
<base href="{{app_root}}">
If I remove this base link my functionality of the search is lost. If I use the base link all of presentation and CSS is lost.
I thought maybe I could change the base link dynamically when I needed to call the search file with:
<script type="text/javascript">
function setbasehref(basehref) {
var thebase = document.getElementsByTagName("base");
thebase[0].href = basehref;
}
//setbasehref("{{app_root}}");
setbasehref("{{app_root}}");
</script>
Then use setbasehref() to change it back to my original base link, but that didn't work.
I'm new to javascript and JSON, and I'm not entirely sure what app_root is doing. Any thoughts?

Categories

Resources