How do I get and print an .hbs or .handlebars template? - javascript

Does anyone know how I can print an .hbs/.handlebars template in an HTML page? I've looked everywhere but I cannot figure out how to put the .hbs files in a directory and then print them in my index.html. Sorry for the question, but I am a new user of handlebars. Thanks in advance!

Let's say you have a handlebars template post.handlebars:
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>
Use handlebars precompiler to compile your templates:
$ handlebars post.handlebars -f templates.js
Include the compiled templates and handlebars runtime in your html doc
<script src="/libs/handlebars.runtime.js"></script>
<script src="templates.js"></script>
Now the compiled template will be accessible as a property of Handlebars.templates. Next pass data to the template, generate some html and append it to the DOM.
<script type="text/javascript">
var template = Handlebars.templates.post;
var context = {title: "My New Post", body: "This is my first post!"};
var html = template(context);

 $(document).append(html);
</script>
See http://handlebarsjs.com/precompilation.html for details on precompile. Also there is a great handlebars tutorial here: http://javascriptissexy.com/handlebars-js-tutorial-learn-everything-about-handlebars-js-javascript-templating/

Save your hbs file as a fragment file. Say myTemplate.jspf
Include this in your HTML/JSP file as below
<script type="text/x-handlebars-template">
<%# include file="myTemplate.jspf" %>
</script>

Related

How to remove div with id="app" in vue project public/index.html file?

I would like to remove the main div which is in public/index.html file.
Now when I build a project it looks like this:
<body>
<div id="app">
//my code is displayed here
</div>
</body>
But I need to remove div with app id so it should look like this:
<body>
//my code is displayed here
</body>
How I can achieve this in Vue3?
You could specify body as the mount point:
// main.js
createApp({}).mount('body')
If using a Vue CLI scaffold, note this would automatically replace the entire body contents from public/index.html, including the div#app and noscript boilerplate:
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>

Re-using components with handlebars.js

I am trying to create reusable components for the different webpages of my website. I started using handlebars.js and I have the code below right now, I am able to pass simple HTML code with it and display it on the webpage. But I would like to have a whole navbar component rendered instead, and preferably linked to from another html or handlebar file somehow. any ideas?
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.6/handlebars.js"></script>
</head>
<body>
<script id="template" type="template/handlebars">
<h1> my website </h1>
{{>navigationBar}}
</script>
<script>
var partialSrc = "some link to navbar";
Handlebars.registerPartial("navigationBar",partialSrc);
var templateSrc = document.getElementById("template").innerHTML;
var template = Handlebars.compile(templateSrc);
document.body.innerHTML += template();
</script>
</body>
What do you think about writing the template as string in a variable in an external JS-file and load it separate?
template.js
var templateSrc = '<h1> my website </h1>\
{{>navigationBar}}';
index.html
<body>
<script src="template.js"></script>
<script type="text/javascript">
var partialSrc = "some link to navbar";
Handlebars.registerPartial("navigationBar",partialSrc);
let template = Handlebars.compile(templateSrc);
document.body.innerHTML += template();
</script>
</body>
This is a simplified presentation. Ofcourse you have to make sure, that template.js is loaded before compiling with handlebars.
How do I include a JavaScript file in another JavaScript file?

How to access precompiled Handlebars templates from page's javascript file rather than in html?

I have a terrain.html file and a terrain.js. I have precompiled a handlebars template (templates/favorites.precompiled.js). I am trying to reference the favorites template in the terrain.js file so I can inject the context and then append it to a container with id "output".
I can access the template fine within the HTML, but I cannot figure out what I need to do to reference it from the terrain.js file.
<script src="scripts/terrain.js"></script>
<script src="https://cdn.jsdelivr.net/npm/handlebars#latest/dist/handlebars.runtime.js"></script>
<script id="favorites-template" src="partials/favorites.precompiled.js"></script>
<div id="output">
</div>
<script>
console.log(Handlebars.templates)
</script>
This outputs as expected: {favorites: ƒ}
However, if I try to print Handlebars.templates to the console in terrain.js I get undefined. I have also tried specifying the specific template Handlebars.templates['favorites'] and Handlebars.templates['templates/favorites.precompiled'] etc.

Use Handlebars.js with Web Forms

I need to figure out how to display JSON data from an ASPHX file into an
ASPX file without using C#. My theory is that I am not able to run the JavaScript because of the order of loading. Using web forms, how can I use a handlebars template inside of an ASP control content placeholder? The below code does not return any HTML to the page.
============= ASP CODE / HTML =============
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="unprocessed.aspx.cs" MasterPageFile="~/Default.Master" Inherits="SurplusApp.unprocessed" %>
<asp:content ContentPlaceHolderID="mainContent" runat="server">
<script id="entry-template" type="text/x-handlebars-template">
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>
</script>
</asp:content>
=============== JS CODE =================
var source = $("#entry-template").html();
var template = Handlebars.compile(source);
var context = { title: "My New Post", body: "This is my first post!" };
var html = template(context);
Update #1:
What I have discovered is that when using web form pages the content placeholder tag does not support the script tag <script id="entry-template" type="text/x-handlebars-template"> however, you can add the template code in your js file and render the template in your web dev console. An example of this can be found on the handlebars github page: https://github.com/wycats/handlebars.js/
Add a MIME type to your web.config file because a web forms page ASPX file with <asp:content></asp:content> does not support adding <script id="entry-template" type="text/x-handlebars-template">
Create a Handlebars template file.
Create a div with a unique id which we will use later to insert our Handbars rendered template.
On the bottom of your ASPX page add a script tag and add two AJAX handlers, one to return the data from a JSON feed and another to return a handlebars template. In our second AJAX call, this is where we will append our newly created HTML from Handlebars.
var responseObject;
$.get('jsonFeed.ashx', function(response){ responseObject = response });
$.get('handlebarsTemplate.hbs', function(response){
var template = Handlebars.compile(response);
var handlebarTemplateInsert = template(responseObject);
$('#element').append(handlebarTemplateInsert);
});

Create pages with pre-compiling the templates

In my current project, my work is only with html and css (HTML skinning). There are many pages which have repeated sections like Header, footer, sharing links etc.
I don't want to repeat this common sections again and again in each page. I want these repeated sections to call somehow using gulp or any other task runner.
Something like this for example (using lodash)
Index.html
<!Doctype html>
<html>
<%= _.template(templates['head'])() %>
<body>
<%= _.template(templates['header'])() %>
<!-- some unique content here -->
<%= _.template(templates['footer'])() %>
</body>
</html>
and then using gulp-template rendering it in each page. I am preferring lodash because I had already worked with it.
As you can see, I am assuming that if somehow I keep the repeating sections in a javascript object (with name templates), I can call it in one line code. And then if I change something in that repeating section, the change will occur in all pages.
To make this possible, first I need to generate the javascript object with that repeating html as string in it.
Can someone please tell me how to do this? or is there any better way to do this?
You can use Jade - node template engine
It gives option to include external jade files, where in it allows you to insert the contents of one jade file into another
index.jade:
doctype html
html
include ./includes/head.jade
body
h1 My Site
p Welcome to my super lame site.
include ./includes/foot.jade
head.jade
//- includes/head.jade
title My Site
script(src='/javascripts/jquery.js')
script(src='/javascripts/app.js')
foot.jade
//- includes/foot.jade
#footer
p Copyright (c) foobar
Compiles to:
index.html
<!doctype html>
<html>
<head>
<title>My Site</title>
<script src='/javascripts/jquery.js'></script>
<script src='/javascripts/app.js'></script>
</head>
<body>
<h1>My Site</h1>
<p>Welcome to my super lame site.</p>
<div id="footer">
<p>Copyright (c) foobar</p>
</div>
</body>
</html>
Explanation:
Whenever I used to search on google for "pre-compiling templates", I was ending up on sites which were combining all the HTML template files to one single js file. But in my case, I was looking for a way to compile the templates completely on system itself with no support of a "all template compiled js file". (So, I was looking for a solution which pre-renders the HTMLs)
Solution:
I found this awesome template engine, Nunjucks, which lets me compile the HTML templates to Independent HTML pages when used with gulp.
Check this one, gulp-nunjucks-render. By using this along with gulp, I am able to include section of .html files into other .html files. Here is the code (assuming you installed nodejs and gulp):
var gulp = require('gulp');
var nunjucksRender = require('gulp-nunjucks-render');
gulp.task('default', function () {
nunjucksRender.nunjucks.configure(['templates/'], { watch: false });
return gulp.src('templates/!(_)*.html')
.pipe(nunjucksRender({
css_path: "../assets/css/",
js_path: "../assets/js/",
img_path: "../assets/images/"
}))
.pipe(gulp.dest('html'));
});
gulp.task('watch', function () {
gulp.watch(['templates/*.html'], ['default']);
});
In the above code, I am keeping the HTML templates in templates folder and with the above gulp code, I am generating the new HTMLs in html folder. The above code will not generate the files which are prefixed with _. (something similar to sass)
and later in command prompt:
gulp watch // Watches the files for changes continuously --> OWNING :D
Here is an example:
<!-- // Index.html -->
<!DOCTYPE html>
<html>
{% include "_head.html" %}
<body>
{% include "_content.html" %}
{% include "_footer.html" %}
</body>
</html>
Which renders to:
<!DOCTYPE html>
<html>
<head>
<title>Website title</title>
<link rel="Stylesheet" href="../assets/jcss/main.css" type="text/css"/>
</head>
<body>
<div class="page">
<!-- content here -->
</div>
<div class="footer">
<!-- footer content here -->
</div>
</body>
</html>
Advantages:
No need of server support to compile the templates.
No need to include any pre-compiled js file in index.html.
Whenever we do some change in common section, no need to include that section again in every page.
Disadvantages:
Till now, I didn't find any :).

Categories