jQuery - simple way to bind json content to element? - javascript

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"

Related

Laravel string localization and AngularJS

So recently i started to convert my jQuery stuff to AngularJS, but there was a solution what i did not think about.
Not all my pages will use Angular, and i am using Laravel's built in localization.
So the views used by Angular are just plain html, no php or blade included.
So i do not really want to mix the 2 in a view.
Where i use blade i use the built in function example: {{ trans('user.first_name') }}
But since i don't want to mix, and my AngularJS views are pure html, i do not want to use it this way <?php echo trans('user.first_name') ?> in my Angular view.
So i was thinking to include Angular localization for AngularJS, but maintaining 2 different localization structure will be a pain and building a good logic for it is another pain.
So anybody with a solution? currently i am clueless. Because for example with jQuery i did not had to worry about this, because it was just dom manipulation, but now its is more complex
I have developed a package that create a JavaScript file from all Laravel's messages. I think you could use it to have access directly in Laravel.
Basically, after installing the package and running the bundled command you will have a global object: windows.Lang. From there you can do different basic operations such as:
Get a localized message
var message = Lang.get('messages.first_name');
Get a localized message with replacements
var message = Lang.get('messages.welcome', { name: 'Joe' });
Change the current locale (applies to JavaScript)
Lang.setLocale('es');
You can find more information: https://github.com/rmariuzzo/laravel-js-localization
Solved this with a ViewComposer:
app/Http/ViewComposers/TranslateComposer.php
<?php
namespace App\Http\ViewComposers;
use Illuminate\Contracts\View\View;
class TranslateComposer
{
/**
* Bind data to the view.
*
* #param View $view
* #return void
*/
public function compose(View $view)
{
$view->with('jstrans', json_encode(trans('my_locale_resource')));
}
}
app/Providers/AppServiceProvider.php
public function boot()
{
view()->composer(
'*', 'App\Http\ViewComposers\TranslateComposer'
);
}
resources/views/index.blade.php
<script type="text/javascript">
var trans = JSON.parse('{!! $jstrans !!}');
</script>

HoganJs and AngularJs with NodeJs

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. [...]

Use TAL:defined variable in javascript

I'm creating a page template for a plone-based website. I've defined some variables using the template attribute language:
<tal:macro metal:define-macro="sample" tal:define="var python: here.getThisVar();">
Now I would like to use var in an extern javascript file, that I call by clicking a button inside my template. How can I transfer my variable, that I can work with it in my javascript file?
In your template define a javascript variable by writing it out using TAL like this:
<script type="text/javascript" tal:content="string:var MY_VAR=${view/myVar};"></script>
Now MY_VAR should be available in scope of your external js as long as you call it after the line above...
Another way: inject your variable into HTML using an HTML 5 data attribute::
<div id="myVar" tal:attributes="data-myVar python:here.getThisVar();">
Then read it using JAvaScript/jQuery::
$('#myVar').data('myVar');
There are a variety of ways to do it. All involve constructing Javascript code as if it's text, then returning the result for insertion into a page or rendering as a JS resource in the javascript registry.
If you'd like a robust example that includes provisions for message translatability and works with the JS resource registry, see the way Plone itself does it: https://github.com/plone/Products.CMFPlone/blob/4.2.7/Products/CMFPlone/browser/jsvariables.py

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