Literal partial with Mustache Php / Js? - javascript

I'm using Mustache to have the same templates on PHP side and on Javascript side, like this:
{{> myTemplate}}
<script id="myTemplate" type="x-tmpl-mustache">
{{> myTemplate}}
</script>
Problem: on page load, the partial "myTemplate" contained between the two "script" tags is changed by the data from my PHP. I need it unchanged in order to use it with my javascript.
Is there a way to do that please?
Edit:
I found a solution : Chevron.js (a jQuery plugin) in addition to Mustache. I did something like this:
html:
<head>
<link href="templates/myTemplate.mustache" rel="template" id="myTemplate" />
</head>
javascript:
$("#myTemplate").Chevron('render', data, function (html) {
// do something with 'html'
});

With Contemplate you could do sth like the following:
<% %>
<!-- server-side template -->
<% $server_data %>
<script id="myTemplate" type="x-contemplate">{% %}
<!-- client-side template -->
{% $client_data %}
</script>
Each template defines its own delimiters, in a modular way, thus any template combination and nesting, eg have a server-side template include a client-side template, is handled optimaly (see related issue, https://github.com/foo123/Contemplate/issues/5)

Related

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 :).

Mustache template with Javascript

I'm trying, without success, to add a javascript to a mustache template
<script id="nodeTemplate" type="text/template">
{{#myItem}}
<div class="divclass {{#myItemDet}}">
...
</div>
<script type="text/javascript">
alert('{{#myItemDet}}');
</script>
{{/myItem}}
</script>
Maybe, it is not possible with Mustache to create JS script...
--------------------------- NOTE 1
If a embeed
<script type="text/javascript"> ... <script>
inside a
<script id="nodeTemplate" type="text/template">...</script>
I suspect that mustache close the template at the first tag
Is it true?
Riccardo
--------------------------- NOTE 2
This is my solution:
1) fill with mustache several hidden divs with the class jshidden
2) Search objs with class=jshidden and append div-content as javascript
The solution now work only on Chrome... Still working
http://jsfiddle.net/ric79/zWEUK/
You are using the block form for myItemDet, rather than the value form.
Try this
<script id="nodeTemplate" type="text/template">
{{#myItem}}
<div class="divclass {{myItemDet}}">
...
</div>
<script type="text/javascript">
alert('{{myItemDet}}');
</script>
{{/myItem}}
</script>
Maybe try to obfuscate the ending </script> tag to not have the browser's parser take it for an inline script. Split it apart, just like advertisers do when writing to the document (e.g. document.write('<'+'/script>');).

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

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>

How do you use templates to generate dynamic HTML tag attributes in meteor?

I am using a Template to Generate HTML Tag Attributes in Meteor, but is seems to be broken. I can't put a template inside an HTML tag in meteor and I want to know why.
I'm using meteor-router for routing. Since meteor basically only allows a single layout, I wanted to add a class to the body indicating the current view name, like so:
/client/layout.html:
<head>
<title>Meteor App</title>
</head>
<body {{> body-attributes}}>
{{renderPage}}
</body>
<template name="body-attributes">data-view-name="{{page}}" class="{{page}}"<template>
So that I could do this in /client/layout.js:
Template['body-attributes'].page = function () {
return Meteor.Router.page();
};
But that didn't work, I got an error from the app saying that attributes on the body are not supported. Changing layout.html to this:
<head>
<title>Meteor App</title>
</head>
<body>
<div {{> body-attributes}}>
{{renderPage}}
</div>
</body>
<template name="body-attributes">data-view-name="{{page}}" class="layout-container {{page}}"<template>
Resulted in totally broken HTML. The browser shows a '>' before the page, and the console elements panel looks like so:
Why doesn't that work?
Calling {{> body-attributes}} inside an HTML tag (in your case, the body tag) ultimately means that Meteor will inject a DocumentFragment into the DOM at that location.
For the sake of reactivity, these DocumentFragments are not vanilla reproductions of the markup in your template, but rather are wrapped up in special Meteoresque reactivity tags that help the backend engine keep the Template updated. You can see this by invoking the Template function and investigating what _domFrag looks like:
var _domFrag = Template.myTemplateName();
So, Templates in a meteor context are not designed to be embedded as attributes on HTML tags because it's injecting additional tags within the tag itself. Your second attempt is more in line with the way the framework works.
Hope that helps explain this behavior.
I have no idea why meteor does not allow templates inside of HTML tags at the highest level, but I found a way to get around the problem. I changed layout.html to look like this:
<head>
<title>Meteor App</title>
</head>
<body>
{{> global-layout}}
</body>
<template name="global-layout">
<div data-view-name="{{page}}" class="global-container {{page}}">
{{renderPage}}
</div>
</template>
And then switched the name from body-attributes to global-layout in layout.js. This works perfectly and solver my problem, but I would still love to know why the first option (in my question) didn't work initially.

Categories