HoganJs and AngularJs with NodeJs - javascript

We are trying to use NodeJs with HoganJs for server side templating. However we are also wanting to use AngularJs for our client side needs.
The problem is that both HoganJs and AngularJs use "{{" and "}}" to full fill their compiler needs. Because of this Hogan strips out if at all there is a angular's "{{", because of the way hogan works.
My question is is there a out of the box solution that allows me to use both Angular and Hogan together, without clashing with each other.
If not, does anyone knows what/where/how to tweak one of these to make them love each other and work gracefully.
Thanks in advance...

If you're using express, you can change hogan's delimiters like so:
var app = express();
app.locals.delimiters = '<% %>';
Place the above before :
app.set('view engine', 'hjs');
Now in your page.hjs file, for the data { template : "Template test" }, you can do :
<p>This is a <% template %></p>

Try with
Hogan.compile(text, {delimiters: '<% %>'});
so you can change the delimeters Hogan
uses by passing the compile method an option overriding them.
http://comments.gmane.org/gmane.comp.lang.javascript.express/1426
NB
imo using a template system is useless using angularjs because
of https://stackoverflow.com/a/20270422/356380

Alternative to changing Hogan delimeters as other answer shows... change Angular's! I did this while using doT (which also uses {{ and }}) and it works fine:
say you have this in your layout HTML:
<html ng-app="cooApp">
Add this script to call up Angular with custom delims (I'm also including reference to Angular just for clarification):
<script src='//ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.min.js'></script>
<script>
var cooApp = angular.module('cooApp', [], function($interpolateProvider) {
$interpolateProvider.startSymbol('{%');
$interpolateProvider.endSymbol('%}');
});
</script>
Now just use {% and %} for Angular stuff.

Without changing delimiters, on Angular 1.x you can use the ng-non-bindable directive for in the elements that uses HoganJS, Mustache or any other code of this kind:
Example:
<div>
{{angularjs_variable}}
<div ng-non-bindable>{{hogan_variable}}</div>
</div>
This is useful if the element contains what appears to be AngularJS directives and bindings but which should be ignored by AngularJS. [...]

Related

jQuery - simple way to bind json content to element?

Ever since Knockout and Angularjs presented a simpler way to otput content from JSON files, I find myself resorting to using them in instances when I would much rather use jQuery for simple tasks.
What would be the simplest way to display some content on the page using jQuery that would be equivalent to {{ model }} in angularjs?
For example, if I have a json file:
{
"something-1": "A",
"something-2": "B",
"something-3": "C"
}
this allows me to output content from data.json in a template by simply using curly brackets...
$http.get("data.json").success(function(data)
{
$scope.content = data;
});
Then in HTML:
{{ content['something-1'] }} <br/>
{{ content['something-2'] }} <br/>
{{ content['something-3'] }}
In jQuery using a simple ajax call to a json file allows me to read the file contents but I am unaware of any way that would allow me a simple and practical data output such as angularjs does.
Can someone suggest a practical way?
I think the simplest way is to use something like mustache.js (https://github.com/janl/mustache.js), jquery has some plugin but nothing inside the core library.
underscore.js also provides this option.
var compiled = _.template("hello: <%= name %>");
compiled({name: 'moe'});
=> "hello: moe"

Using blur.js with angularjs

I'm trying to make a blurred background efect with angular on a div, something like the image above, for this i'm using blur.js and everything work fine with jquery but the real question is this posible with angularjs, and what is the best way?
I'm really newbie with angular
thanks in advance
here another example of using blurjs http://www.designedbyaturtle.co.uk/2013/blur-a-background-image/
SOLVED (with help of gtramontina):
you can download the code here demo-blurjs-angular
The result (with my images)
This demo contain a issue (that is really of blur.js) like Edd Turtle mention on his post
Important Note: This technique doesn’t work with local files and has to run through a server, likewise if the background is hosted on the Amazon S3 service you will need to enable cross-domain calls (CORS)..
I suggest you create a directive, restricted to attribute maybe, and have that applying your effect.
Something like this (not tested - and assuming you've included, in this order, jquery, blur.js, then angular;
angular.module('myApp', []).
directive('blurred', function () {
var directive = { restrict: 'A' };
directive.compile = function compile (tElement) {
// taken from blur.js homepage
tElement.blurjs({
source: 'body',
radius: 7,
overlay: 'rgba(255,255,255,0.4)'
});
};
return directive;
});
Then use it:
<p blurred>lorem ipsum</p>
The point with the order I mentioned above, is that if you include jquery before angular, then angular uses it to wrap its dom elements, otherwise it'll use jqlite.
You need to write a angularjs directive for blur.js. Here is an example of how to write a directive for a query plugin:
http://amitgharat.wordpress.com/2013/02/03/an-approach-to-use-jquery-plugins-with-angularjs/

Force Backbone or Underscore to always escape all variables?

I'm new to Backbone, and am helping maintain an app. I'd like to make the default in all normal situations for Backbone to be escaping model data, to help avoid XSS attacks by default.
I know we can do this using
<%- someModelAttribute %>
and
model.escape('attr')
to escape data in our app, but I'd like to switch it so
<%= someModelAttribute %>
and
model.get('attr')
did the same as well.... So by default, all existing code and future code that uses these tags and methods is escaped by default. Then I'd like to introduce another model method like "model.getDataThatShouldBeSafeHtml" to make it 100% clear to developers when they're getting data that should include HTML.
So is there some way for me to switch the "<%=" tag and the "model.get" methods to be the same as their escape equivalents?
I only ask as I thought this might've been done somewhere before, or already be part of backbone, and I want to avoid rebuilding the wheel!
I found an easy way to make it so all templates by default are escaped. Since Backbone uses Underscore for it's templating engine, I googled around and found that you can customize the underscore delimiters using _.templateSettings, described here on the Underscore site. Note that if you make sure all of your html is written out using these templates, then you're covered for all XSS. So don't skip using templates in some simple scenarios, use them to avoid XSS in those cases as well!
You can test it out using this fiddle: http://jsfiddle.net/vx0pw2n0/
So all I did was make it so both <%= and <%- are used to display escaped data by default. The evaluate tag <% still remains, and can be used to output whatever HTML you want using the print statement. I also introduced a new tag, <%cleanHtml that can be used to output HTML without it being escaped, and without needing to say print(someVariable)
<script type="text/javascript">
//
// This is the important part - The part that changes what underscore uses
// for template delimiters.
//
_.templateSettings =
{
escape: /<%[=-]([\s\S]+?)%>/g,
interpolate: /<%cleanHtml([\s\S]+?)cleanHtml%>/g,
evaluate: /<%([\s\S]+?)%>/g
};
// Test it out
var t = _.template($('#t').html());
var html = t({ title: '<b>pancakes</b>' });
$("#target").html(html);
console.log(html);
</script>
<!-- Sample Underscore Template showing different ways of using it -->
<script id="t" type="text/x-underscore">
<div><%= title %></div>
<div><%- title %></div>
<div><%safeHtmlOnly title safeHtmlOnly%></div>
<div><% print(title) %></div>
</script>
<div id="target"></div>
Making this work globally
To get this to work globally, you may have to configure Underscore as a module, which can be done like so:
Implement as a dependency on Backbone
Configure Require.js modules
// When you initially setup require.js, add a new module to configure underscore
// Make it a dependency of backbone, so it'll always be loaded whenever
// backbone is used.
require.config({
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscoreConfig', 'underscore', 'jquery'],
exports: 'Backbone'
},
jquery: {
exports: 'jQuery'
}
}
});
underscoreConfig.js
define(['underscore'], function (_) {
'use strict';
_.templateSettings =
{
escape: /<%[=-]([\s\S]+?)%>/g,
interpolate: /<%cleanHtml([\s\S]+?)cleanHtml%>/g,
evaluate: /<%([\s\S]+?)%>/g
};
return _;
});
You could extend Backbone.Model to create a reusable base class that does this for you. Something like this (untested):
BaseModel = Backbone.Model.extend({
getSafeAttributes: function() {
var safe = {};
_.each(this.attributes, function(key, value) {
safe[key] = _.escape(value);
});
return safe;
}
});
I'm guessing your render functions look something like
this.$el.html(this.template(this.model.attributes));
So, instead of that, you'd write:
this.$el.html(this.template(this.model.getSafeAttributes()));
and just make sure your models extend the base class instead of Backbone.Model.
It's perfectly acceptable to modify backbone.js and underscore.js to achieve a similar outcome, but it does make it a pain to upgrade, which is why I'd go with the base class instead.
As far as I know backbone depends on the template engine provided by underscore.
How to use underscore.js as a template engine?
By underscore you can change the regex patterns to always escape, but it won't call the escape method of your model, so you have to create your own template engine to do that...
For example you can fork the templating code from underscore and develop it in your own way and use that instead of _.template().

Escape double braces {{ ... }} in Mustache template. (templating a template in NodeJS)

I'm trying to template a template, like below:
{{{
{
"name" : "{{name}}",
"description" : "{{description}}"
}
}}}
{{{debug this}}}
<h1>{{name}}</h1>
Where I want to triple brackets to stay, but double brackets to be replaced with the JSON passed in. Anyone know the best way to do this without writing post-process JS code, and if not, is there a good nodeJS template engine for this type of scenario?
As described in this Question handlebars doesn't support changing the delimiters. But you can escape the double braces with a backslash like this:
HTML:
... \{{ myHandlbarsVar }} ...
You can switch delimiters to something that won't conflict with the triple mustaches, like erb-style tags:
{{=<% %>=}}
{{{
{
"name": "<% name %>",
"description": "<% description %>"
}
}}}
{{{debug this}}}
<%={{ }}=%>
Note that you can do this as many times as you like throughout your template. Any time you run into something that conflicts, pick a new set of delimiters :)
You can also assign Mustache.tags = ["[[", "]]"]; before your template compilation.
http://jsfiddle.net/fhwe4o8k/1/
e.g.
$(function () {
Mustache.tags = ["[[", "]]"];
var template = $('#test').html();
Mustache.parse(template);
var rendered = Mustache.render(template, {test: "Chris"});
$('#content-placeholder').html(rendered);
});
another option is create a helper for outputing curly brackets.
Handlebars.registerHelper('curly', function(object, open) {
return open ? '{' : '}';
});
and then use it in the template like this:
<script id="template" type="text/x-handlebars-template">
{{curly true}}{{name}}{{curly}}
</script>
which then outputs:
{Stack Over Flow Rocks}
The template contains HTML, so you could use HTML-Entities, for example the ASCII-codes 123 and 125 for braces:
{{{myValue}}}
I just wanted slightly different approach. I have tried few other other ways and here are few things which I didn't like about them:
Changing Angular default {{obj.property}} brackets to something else is a bad idea. Mainly beacause as soon as you start using third party components which are not aware of you non standard angular configuration, bindings in those third part components will stop working. Also worth mentioning that AngularJS team doesn't seem to want to go the route of allowing multiple binding notations, check this issue
I quite like Mustache templates and don't want to switch the whole project to something else because of this small issue.
Quite a few people recommend not to mix client and server side rendering. I don't fully agree, I believe if you are building a multipage website which has few pages with angular and some other which are static (something like about us or Terms and Conditions pages) it is perfectly fine to use server side templating to make maintaining those pages easier. But that said, for parts which are Angular you shouldn't mixing server side rendering.
Ok no my answer:
If you are using NodeJS and Express you should be to the following:
Replace bindings {{}} in your angular part with something like {[{}]} (or something completely unique)
Now in you route add a callback to you render method:
app.get('/', function(req, res){
res.render('home', {
title: 'Awesome Website',
description: 'Uber Awesome Website'
}, function(err, html){
var htmlWithReplacedLeftBracket = html.replace(/{\[{/g, '{{');
var finalHtml = htmlWithReplacedLeftBracket.replace(/}\]}/g, '}}');
res.send(finalHtml);
});
});
This should allow you to use Mustache together with AngularJS. One improvement you could do is extract that method into a separate module to reuse across all routes.
This is a good solution I have found for this type of problem where you can easily switch delimiters in the template settings in runtime:
http://olado.github.com/doT/
You can do the RegEx settings like this:
doT.templateSettings = {
evaluate: /\{\{([\s\S]+?)\}\}/g,
interpolate: /\{\{=([\s\S]+?)\}\}/g,
encode: /\{\{!([\s\S]+?)\}\}/g,
use: /\{\{#([\s\S]+?)\}\}/g,
define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,
iterate: /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,
varname: 'it',
strip: true,
append: true,
selfcontained: false
};

Templating Engine for Node that's NOT Jade

Jade is indeed very neat, but I personally dislike the syntax and look of it. Yeah, being able to write just :
body
h1 Hello
p This is
b bold
Thats cool and all, but I prefer the look and feel of HTML/XML still. It was made to be human and machine readable and overall I think it's easier to glance at and understand.
Are there any templating engines that work more like:
<body>
<h1>{title}</h1>
<p>{content}</p>
</body>
Using the same Jade like concept of:
res.render('index', {
title:pageTitle,
content:pageContent
});
Take a look at EJS. Allows you to use regular HTML and embed Javascript code.
For example:
<div>
<% if (foo) { %>
foo
<% }else { %>
bar
<% } %>
</div>
Also, what you're looking for is an "Express-compatible" templating engine, and EJS is Express-compatible. It's made by one of the main guys behind Express.
You can use straight HTML in Jade, give this a try:
<body>
<h1>#{title}</h1>
<p>#{content}</p>
</body>
Something that specifically looks like that would probably be Mustache for Node.js. Check the demo.
Consider jQuery templates. You can provide your data in JSON and apply it to a template.
If you're already using underscore.js
var compiled = _.template("hello: <%= name %>");
compiled({name : 'moe'});
=> "hello: moe"
Templates can be only a matter of taste. I don't like Jade either and favouring HTML is a better option.
Most of times, webdesign layouts cannot be easily converted to those templates.
the sample provided moustache:
<h1>{{header}}</h1>
{{#bug}}
{{/bug}}
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
{{/first}}
{{#link}}
<li>{{name}}</li>
{{/link}}
{{/items}}
{{#empty}}
<p>The list is empty.</p>
{{/empty}}
It can be mixed with Angular.js syntax... could be a problem for people using it.
I recommend a new template engine: Saker, it enables fluid coding workflow, unlike most template syntaxes, you do not need to interrupt your coding to explicitly denote server blocks within your HTML.
Github: https://github.com/eshengsky/saker
The code looks like:
<body>
<h1>#title</h1>
<p>#content</p>
</body>
I personally use Nunjucks with all of my Node JS projects for a few years now and still loving it. I switched from Swig because Swig was lacking in some of extensibility when a project became more complex.
I, too, am not a fan of Jade / Pug. I prefer normal HTML syntax and inject some custom templating schemes.

Categories

Resources