We’ve come a long way already and we’ve got some pretty hefty default templates and boilerplates for business. In this chapter, we’re going to simplify and focus on some other things. We are going to create an aggregating news site based off social media. Until now, we’ve paid close attention to progressive enhancement. For this chapter, we leave that behind. This will require JavaScript.
In this chapter you will learn the following:
Client-side templating options JsRender
Patching into JSON API (Twitter) Programmatically changing pages
Generated pages and DOM weight management Leveraging RSS feeds (natively)
HTML5 Web Storage
Leveraging the Google Feeds API
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Client-side templating
(In a grumpy old man’s voice) Back in my day, we rendered all the pages on the server, and we liked it! Times are changing and we are seeing a massive ground swell in client- side templating frameworks. At their heart, they’re pretty much all the same; in that they take JSON data and apply an HTML based template contained within a script tag.
If you know what JSON is, skip this paragraph. I spent a little time last chapter discussing this, but just in case you skipped ahead and don’t know, JSON is JavaScript written in such a way that it can be used as a data exchange format. It’s more efficient than XML and can be read natively by all modern web browsers. Web browsers can even request JSON data across domains using JSONP, or JSON with padding. For more on JSON, read http://en.wikipedia.org/wiki/JSON. For more on JSONP, read
http://en.wikipedia.org/wiki/JSONP. Bear in mind that the responding server needs to allow JSONP or this won’t work.
All these client-side libraries have some sort of notation in them to show where the data goes and gives ways to implement looping and conditionals. Some are logic-less and operate on the philosophy that there should be as little logic as possible. If you subscribe to this wonderfully academic approach, good for you. From a purely pragmatic
perspective, I believe that the JavaScript template is the perfect place for code. The more flexible, the better. JSON holds the data and the templates are used to transform it. To draw a parallel, XML is the data format and XSL templates are used for transformation.
Nobody whines about logic in XSL and so, I don’t see why it should be a problem in JS templates. But all of this discussion is purely academic. In the end, they’ll pretty much all do what you’re looking for. If you’re more of a designer than a coder, you may want to look more at the logic-less templates.
Following is a list of popular client-side templating frameworks; I’ll probably miss a few and there will inevitably be more by the time this book gets published, but it’s a start:
Chibi.js
Closure templates
Dust.js
Embedded JavaScript (EJS)
Handlebars.js Hogan.js
Jade JsRender Mustache Nunjucks
T.js
Underscore templates
doT.js
templayed.js
Note
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Notably absent is the jQuery template library. Sadly, shortly after learning to love it, the jQuery team abandoned the project and pointed people to JsRender as the continuation of the project.
Whether that will be the continued direction in the future is another question, but, in the mean time, the features and power of JsRender make it a compelling offering and the basis for template work for the rest of this chapter. Not to mention, it’s only 14K minified and fast as lightning. You can download the latest edition from
https://github.com/BorisMoore/jsrender.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Patching into JSON APIs (GitHub)
It’s always interesting to visit GitHub to check out popular repositories. GitHub, like so many other popular online destinations, has a JSON API.
Let’s build a simple application which lets us view the most popular jQuery Mobile repositories. You can see the list view containing repositories on the left side and the details view on the right side.
The following code is our starting base page, index.html. It can be found in the code bundle for this chapter. It contains the jQuery Mobile page definition, along with a single JsRender template; identified with a text/x-jsrender type. The code is:
<!doctype html><html><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<title>Chapter 5 - Repos</title>
<link rel="stylesheet" href="css/jquery.mobile-1.4.5.css" /><script src="js/jquery-1.10.2.js"></script>
<script src="js/jsrender.min.js" type="text/javascript"></script>
CuuDuongThanCong.com https://fb.com/tailieudientucntt
<script src="js/jquery.mobile-1.4.5.js"></script>
<script src="js/application.js"></script>
<style> .ui-content .ui-listview { margin-top: 0;}
</style>
</head>
<body>
<div id="repo_listing" data-role="page">
<div data-role="header"><h1>Popular Repos</h1></div>
<div role="main" class="ui-content">
<ul id="results" data-role="listview" data-dividertheme="b"></ul>
</div>
</div>
<script id="repositories" type="text/x-jsrender">
<li class="trendingItem">
<a href="repo.html?owner={{>owner.login}}&repo={{>name}}"
class="githubSearch" data-search="{{>name}}">
<img src="{{>owner.avatar_url}}"></img>
<h3>{{>name}}</h3>
<p>{{>owner.login}}</p>
</a>
</li>
</script>
</body>
</html>
The following code, found at the top of the js/application.js file, is the processing core of the index.html file:
$(document).on("pagecontainerbeforeshow", function(){ var repoUrl = 'https://api.github.com/search/repositories?q=jquery+mobile&sort=s
tars&order=desc'; $.getJSON(repoUrl) .done(function(data){
var context = data.items, template = $("#repositories").render(context);
$("#results").html(template).listview("refresh");
});});
Normally, to pull data into a web page, you are subject to the same-domain policy even when you’re pulling JSON. However, if it’s coming from another domain, you’ll need to bypass the same-domain policy. To bypass the same-domain policy, you could use some sort of server-side proxy such as PHP’s cURL (http://php.net/manual/en/book.curl.php) or the Apache HTTP core components (http://hc.apache.org/) in the Java world.
In GitHub’s case, they allow JavaScript to make requests directly to their API using Cross Origin Resource Sharing (CORS), (https://developer.mozilla.org/en-
US/docs/Web/HTTP/Access_control_CORS). CORS defines a way in which the browser and the server can interact to determine whether or not to allow the cross-origin request.
CORS allows servers, via additional HTTP headers, to describe the set of origins that are permitted to read that information using a web browser. Luckily GitHub has robust
support for CORS and allows AJAX requests to be made with zero modifications to our code. That’s convenient for us!
Because we know GitHub’s API will respond with JSON, we can use jQuery’s
$.getJSON() method which will perform the GET request and parse the JSON for us.
Handy, isn’t it? Upon receiving the data from GitHub, we whittle down the response to the
CuuDuongThanCong.com https://fb.com/tailieudientucntt
part we want and pass that array into JsRender for, well, rendering. It may seem more simple to just loop through the JSON and use string concatenation to build your output;
but take a look at the following template and tell me that’s not going to be a lot cleaner to read and maintain:
<script id="repositories" type="text/x-jsrender">
<li class="trendingItem">
<a href="repo.html?owner={{>owner.login}}&repo={{>name}}"
class="githubSearch" data-search="{{>name}}">
<img src="{{>owner.avatar_url}}"></img>
<h3>{{>name}}</h3>
<p>{{>owner.login}}</p>
</a>
</li>
</script>
The text/x-jsrender type attribute on the script will ensure that the page does not try to parse the inner contents as JavaScript. Since we passed in an array to JsRender, the
template will be written for every object in the array. After putting this code in place, you should be able to load up the index.html file in a browser window and see a list of jQuery Mobile repositories. But we wanted to be able to dive into one of them didn’t we? Open up the repo.html file containing the code to view the details of a repository.
CuuDuongThanCong.com https://fb.com/tailieudientucntt
Passing query params to jQuery Mobile
The functionality in the repo.html file is much the same as the index.html file; (page definition and JsRender templates) so it’s the differences we’ll focus on. Clicking on any link within the index.html file opens that specific repository, along with its most commit activity. jQuery Mobile has built in the ability to pass URL parameters between pages.
Let’s see how that works. Notice that in the JsRender template for the index.html file, we’re defining owner, and repo parameters:
<a href="repo.html?owner={{>owner.login}}&repo={{>name}}"
class="githubSearch" data-search="{{>name}}">
This matches up with the information GitHub needs to retrieve repository details.
These URL parameters are accessed by jQuery Mobile and stored as a data attribute on the current page. They can be accessed like:
$(this).datắurl')
If you open the application.js file you can see where we’re referencing those query params and passing them through a helper method to convert them into usable key/value pairs. The object containing those pairs is then passed as context into a JsRender template which returns the URL of the GitHub repository selected by the user on the index.html file.
Note
These are simple implementations. Check out
http://borismoore.github.com/jsrender/demos/ for more detail on creating more complex templates. This is a rapidly changing library, so don’t be surprised if, by the time you read this, there are a lot more options and slightly changed syntaxes.
CuuDuongThanCong.com https://fb.com/tailieudientucntt