Archive for March, 2012

Behind The Scenes Of Tourism New Zealand (Case Study)


  

In 2011 we saw the rise in popularity of two relatively new trends: responsive Web design and the use of HTML’s canvas. While some websites had experimented with both, in the last 12 months we’ve seen these trends move from the fringes firmly into the mainstream.

Responsive Web design is more a concept than a technology — an ideal that many new websites aspire to. Canvas, on the other hand, is an HTML5-based technology that opens the door to a new wave of interactivity. In this article, we’ll look at a website that embraces both of these elements, one that has been nominated for a Technical Achievement award at SxSW Interactive 2012: Tourism New Zealand.

I spoke with the creative and technical teams at the New Zealand-based firms Shift and Assembly about the technology behind Tourism New Zealand’s home page, how it was made and how they balanced the breakthrough effect with bandwidth.

After we learn how Tourism New Zealand was built, we’ll look at the basics of putting together your own animated HTML5 canvas background.

The Inspiration

Tourism New Zealand has a history of strong media and advertising campaigns, particularly through TV commercials, and its destination marketing website has long featured these videos.

So, when a redesign of the website was planned without an accompanying TV commercial, the team at Shift had a new challenge: to showcase the landscape and breadth of activities in New Zealand to an audience that has come to interact with a website, not to watch a video.

Shift was inspired by, among other things, Nike’s Better World website (which Smashing Magazine has covered). But whereas that website used HTML5 animation to create an effect of parallax scrolling, Shift proposed a camera view that moves through the real world.

Shift’s first idea was to use video as a background, with the camera descending through some of New Zealand’s most exciting locations. The problem was bandwidth: at 25 frames per second, Shift would need to deliver thousands of full-screen frames. This was an impossible goal, so instead the team set a target of around 200 frames for the entire website. But 200 frames for the amount of footage they wanted worked out to about three frames per second, which doesn’t look particularly good.

At this point, they nearly abandoned the idea.

By chance, though, a solution was found. Scrubbing through a QuickTime video, Shift’s creative director, Mark Zeman, noticed that being able to control the frame rate as you move the play head gives the illusion of a smooth experience. He suspected that if the browser’s scroll bar could be used to scrub the footage, it would feel similarly smooth. And if the camera shot photographs as it moved through each scene, it would create the illusion that the user was practically controlling the camera as it descended through New Zealand.

The first prototype was made with a few images and some JavaScript, just to prove that the browser could handle this type of manipulation. Freelance front-end developer Jeff Nusz was then tasked with turning this proof of concept into a working website. The brief was simple: no loading bar, and the first frame must load almost instantly. Furthermore, the website had to be usable even when the user doesn’t wait for all of the images to download.

On Location

With the prototype built and approved by Tourism New Zealand, it was time to load up the trucks with scaffolding and start shooting.

Shift worked with directors Damon Duncan and Matt von Trott of Assembly throughout development of the project, which enabled them to build the large motion-control rigs that were required for the shoot.

A 15-meter-high motion-control rig was built, with a vertical dolly track that housed a Canon 5D DSLR. The rig was set up at each location, and the camera travelled 12 meters down it, taking anywhere between 750 and 950 stills, a process that lasted at least two hours each time (and six hours at Milford Sound, the first location on the website), because the camera moved around 15 millimeters every 10 seconds.


Milford Sound, New Zealand

Each location took three days to shoot. The first day was spent building the tower and putting together the motion-control rig. The second day was usually spent rehearsing the scene, and the third would be for the actual shoot, which included multiple passes of the scene. Indeed, the scene for Waiheke Island is a combination of two takes.


Time-lapse sequences from all four shoots (watch on Vimeo)

Front-end developer Jeff Nusz had built a suite of tools to help the crew plan the photography. The directors also showed the original prototype to the cast and crew, which helped to demonstrate what they were filming and how the time-lapse footage would work.

Post-Production

There were only five days between the final day of shooting and the launch of the website. Most of the code had been written and ported to JavaScript using prototype images, and so it was now a matter of editing the hundreds of photos from each location down to 200 hand-optimized 1280 × 720-pixel frames.

The team spent time testing the website in each browser, noticing different memory quirks in Chrome and Firefox, and it worked on optimizing the website’s performance. Because many of New Zealand’s tourists come from China, the time was also spent making sure the website worked even in IE 6. To better understand the toll of such a heavy home page, Shift used WebPagetest to test it from various parts of the globe.

From 25 MB To 300 KB

Although the entire website weighs in at 25 MB, it enables a usable experience after the first 300 KB of data and images have loaded.

On the initial loading of the page, a 40 KB image is loaded that contains all 200 frames at a very low resolution. This means that as soon as the initial frame of Milford Sound has loaded, you can scrub through the entire website and get some approximation of the full experience. Then, when you stop scrubbing, the website loads the frame you’re on and starts loading the frames before and after it. Moreover, as you scroll the page, all downloading activity stop to ensure the smoothest possible scrolling experience. When you stop scrolling, all downloading resume.

Interestingly, Jeff’s background is mainly in working with Flash, so the initial website was built in Flash and then ported to HTML5 at the last minute. Jeff says that the similarities between ActionScript and JavaScript made this a relatively pain-free process:

ActionScript 3 is a lot like JavaScript. I did a lot of the work in Flash, and I wanted to see how well it would translate, and it was pretty much cut-and-paste for the most part. I just had to structure things in a similar way and make a few semantic changes. Ninety percent of the code ported as it was, which was great.

One of the team’s early breakthroughs was in figuring out how to split up the website’s elements. You can see in the sketch below how a website normally works: you have a long page and, conceptually speaking, the browser’s viewport moves up and down the page (i.e. the latter moving across the former).

In this next sketch, the page itself is a giant empty GIF that you scroll up and down; but the website detects every time you scroll, calculates your position and then translates that to the frame you should be on. The height of the window also changes depending on how big your browser’s viewport is, because if the page is huge and your viewport is small, then the scroll bar would be tiny; Shift wanted to keep the size of the scroll bar consistent, regardless of the browser’s size.

As Jeff notes, “Although it’s not exact, the goal was that one click of your mouse-wheel would be one frame�:

The tag layer and the UI layer is just HTML and CSS, but the background is either an HTML5 canvas that we draw to or it’s Flash. There’s about a 20-millisecond lag between the frames moving and the background changing in Flash, so the canvas version became the primary method used for browsers that support it.

The tags do not scroll in the conventional sense, but for each frame, they are assigned specific x and y coordinates based on the frame. This allows tags to be “gluedâ€� to background elements — a tree, mountain top, etc. — and these coordinates would be recalculated on the fly if the browser window was resized.

To create this effect, the team used Adobe After Effects to keyframe each tag and output the coordinates. Jeff built a PHP script into which the team could copy and paste the After Effects keyframe data, whereupon the script would generate JavaScript that the website could use. Jeff then tweaked the tags in JavaScript to make sure they scrolled as expected.

Sprite Sheets

To create the illusion that the page loads quickly, Jeff came up with the idea of using sprite sheets. As he puts it, “The sprite sheets were the breakthrough that allowed us to make the website usable so quickly after the page loads�.

The first frame (of the background image) is 90 KB. So, together with the first low-resolution sprite sheet (which is 30 KB), these images initially weigh only 130 KB. Once the page has loaded all of the content, it loads a higher-resolution sprite sheet, and then another, and then it loads in the full-resolution images one by one. Rather than loading these large images in sequence, it loads them based on your scroll position within the document.

You can check that the sprite sheets load before the full-resolution images by turning the Webkit Inspector on and watching the “Network� activity after the page has started to render.

Using Inline JavaScript

I asked the team at Shift why so much inline JavaScript was in the head of the document. Best practice would suggest it should be moved to a separate file. However, something more is going on here.

Shift’s solution architect, Glenn Wright, has been working on the website for the last six years. He explains:

The inline JavaScript is there to define the configuration for each page. We can cache each page’s configuration in JavaScript, then all the external libraries that the page loads utilize that data. It gives us an easy way to configure the responsive grid and all of the interactions that the page will have to use.

Testing Mode

A testing mode on the website lets you see some of this loading process in action. Clear your browser’s cache, load Tourism New Zealand’s home page, and then hit the tilde (~) key five times to enable testing mode. You won’t see any change immediately, but once in this mode you can use the following keyboard commands:

  • 1
    Turn on the visualizer for “frames loaded�
  • 3
    Toggle tags on and off
  • 0
    Toggle the high-resolution image on and off
  • -
    Go to the previous low-resolution sprite
  • +
    Go to the next high-resolution sprite

Building Your Own Canvas Background Animation

While websites like Tourism New Zealand take months to design and build, creating your own animated canvas background is relatively straightforward. All it takes is a little JavaScript, a pinch of HTML5 and an enormous amount of imagination to dream up a worthwhile use.

Indeed, a word of caution is in order. We all know that with great power comes great responsibility, and just because we can load 50 high-resolution frames and animate them as the user scrolls the window doesn’t mean we should. As mentioned earlier, websites that use this technique are both lauded and criticized. Make sure that you are enriching the user experience rather than needlessly slowing it down.

First, we need to do a couple of things. Let’s grab some video (a time-lapse video works best for this), and then create our 50 frames. You can create as many frames as you like, but we’ll stick with 50 because this is how many Tourism New Zealand uses for each scene.

Next, let’s grab some royalty-free time-lapse footage from Artbeats and import it into iMovie, where you can export individual frames.

Choose Share → Export Using QuickTime, and in the pop-up dialog box select “Movie to Image Sequence.â€�

We export the images as JPEGs, which leaves us with hundreds of images. So, we have to do two things:

  1. Batch process the images in Photoshop to the required size (here, we went with 480 × 270 pixels to maintain the aspect ratio).
  2. Edit the number of images down to 50. Shift was painstaking in doing this, retouching and editing thousands of images down to just 200. To keep things easy for this tutorial, let’s just delete three photos out of every four.

You should now have 50 photos that, when played in sequence, make for a somewhat choppy time-lapse video.

On to the next couple of steps. First, we’ll figure out how to load the images in the browser and control them with the scroll bar. Secondly, we’ll create our own sprite sheet and use that instead. Open your code editor of choice, and create a new JavaScript file. Or why not head over to GitHub and download the project to play around with?

You’ll also need an HTML file with a canvas element in it, which is as simple as this:

<canvas id="canvas"></canvas>

Hopefully, the comments in the code sufficiently explain what’s going on, but here’s a breakdown anyway.

First, we set up the canvas element and use some basic maths to set start and end points:

// Create our timeLapseVideo object and cache the window object
timeLapseVideo = new Image();
$window = $(window);

// Define the timeLapseVideo element
timeLapseVideo.onload = function(){
  videoContainer.width = 960;
  videoContainer.height = 540;
  videoContext.drawImage(timeLapseVideo, 0, 0, 960, 540);
}

// Load the first frame
timeLapseVideo.src = 'images/TimeLapse001.jpg';

// Calculate how far to scroll before changing a frame
var scrollDistance = $window.height() - $window.scrollTop(),
    totalHeight = $(document).height() - scrollDistance;
    frameDiff = totalHeight / (numberOfFrames - 1);

Then, when the window scrolls, we work out which frame needs to appear on screen:

// Which frame do we need to show?
frameString = (Math.round($window.scrollTop()/frameDiff) + 1).toString();

// Change the image in the canvas
timeLapseVideo.src = 'images/TimeLapse' + frameString + '.jpg';

Make sure to go through the full source code to see it in action. Be careful, because there is no check to determine whether an image has already loaded; you could end up hitting your server with hundreds of requests per page. So, like Tourism New Zealand, you need to build in a check to see whether an image has been cached.

Creating And Using A Sprite Sheet

We can also create our own sprite sheet with our image to emulate more of Tourism New Zealand’s behavior. Some apps and websites are available to help you do the job (see the “Related Links� section at the end), but it’s probably easier to run a simple script that pastes all of the images onto a canvas and then take a plain screenshot of that. The code for this script is in the GitHub repository in case you want to take a look.

There are two main differences with this technique. First, we load only one image onto the canvas, which is the sprite sheet:

timeLapseVideo.src = 'images/spritesheet.jpg';

When the window scrolls, we then draw part of this sprite to the canvas:

videoContext.drawImage(timeLapseVideo, x, y, 80, 45, 0, 0, 960, 540);

In the line above, x and y are the starting coordinates of the sprite, which in turn are dictated by the frame. We’re using a simple loop to iterate through the sprite to find the right coordinates, but you could set up an array of values to look up. These tiny frames are 80 × 45 pixels, and they are drawn from 0,0 to 960 × 540 pixels. CSS then stretches this canvas to fit the entire window.

You can improve this script a great deal by, for example, preloading images when the user isn’t scrolling (some links are below to point you in the right direction). If you make improvements, please do share your work in the comments below.

Creativity In Design And Development

Distilling 18 months of hard work into one article like this is an impossible task. Shift had the time and budget to fly around New Zealand and take thousands of beautiful photographs. This is not an option for the average Web designer!

However, what is perhaps most striking about Tourism New Zealand is the imagination in its concept and execution. By taking the leap from virtual to physical world (and back again!), the scroll bar has become a conduit by which the user can control their experience of New Zealand — if only for 200 frames.

Jeff’s ingenious loading techniques and the use of sprite sheets also kept away the loading bar that is so familiar with websites like this. On an average broadband connection, the experience is effortless and fun.

Perhaps the biggest lesson to be learned here is this. Despite its many bells and whistles, Tourism New Zealand encourages the user to discover the website in much the same way they would discover the country.

Technology supports the great design, not the other way around. If we could all exercise this level of creativity, imagination and user engagement, then we, too, would create amazing websites that shape the future of Web design.

Related Links

I must extend my very special thanks to Jeff (@jeffnusz), Glenn, Che and, in particular, Mark (@markzeman), who were patient with my intermittent Skype connection and who were so transparent in offering their thoughts and many of the images and resources featured in this article.

(al)


© Richard Shepherd for Smashing Magazine, 2012.


jQuery Mobile Tutorial: Creating a Restaurant Picker Web App


  

With an increase in the number, diversity and complexity of smartphones, more and more companies want to have their own mobile app, but creating a native app can be pretty expensive. It requires special skills, as well as special coding tools, and then there is also the need to build an app per platform (Android, iOs, BlackBerry, Windows Phone, etc).

All of this figures in to a higher price tag for the app development. Another solution for developers is then to create something called web-apps: HTML CSS apps, which users can access from their browsers. They are cross-platform, and cross device.

Restaurant Picker : creating a JqueryMobile web app from scratch and styling it.

The jQuery framework has been around the web for a while now, but the jQuery base technology was basically designed for browser apps. jQuery Mobile is a framework based on jQuery that enables web designers to create web-apps that are optimized for use on a mobile device (Smartphone and tablets). The framework is touch optimized, uses responsive layout so that elements will automatically adapt on different device sizes, and supports a range of different platforms and devices.

In this jQuery Mobile tutorial, we will create a nice demo app from scratch, to show some of the things that can be easily done using this powerful tool.

Before we start, you might want to download the files, or see a demo, or flash the qrcode for a direct demo on your mobile :

qrcode for the demo

The Concept of the Mini App: Restaurant Picker

We will create an application that will enable the user to choose a restaurant based on what they want to eat tonight, the town where they want to eat and other user’s ratings of the restaurants. The jQuery Mobile mini app we’re creating will be called “Restaurant Pickerâ€�.

Please note that this is only the front development, you will of course need a server and a database if you want to create a real app. Also note that jQuery Mobile uses Ajax navigation, so you’ll need to put the files either on a local server (xampp, mamp, etc) or on a real server to make the demo work properly.

Wireframing Our Application.

In order to see where we are going, we will first draw some wireframes to see what each screen of the app will look like.

Home Screen : Choose a Plate

Homescreen: choose a plate

On the first screen we will put the logo of our application. We will then give the user a choice between different plates. Each choice comes with an image illustrating the plate, and each is a link that will lead to the second page where the user can choose the town.

Choose a Town

Choose a town wireframe

On the second screen, the user can choose the town where they want to eat. The towns are displayed in a list of clickable items. Beside each town there is a bubble that gives the user the number of restaurants available for the chosen plate in this town.

Since the list of towns can be pretty long, we will provide a filter so that the user can quickly search for a town at the end of the list. The title bar will use the branding of the application, and a “back� button that user can click to go back to the previous step.

When the user clicks on a town, they are lead to the page where they can choose a restaurant.

Choose a Restaurant

Choose a restaurant wireframe

The user can now choose in which restaurant he wants to eat. The application displays a list of restaurant with a little image, the name, and the number of rating stars the previous users gave to this restaurant.

The title bar will use the branding of the application, and a “back� button that user can click to go back to previous step. The user can then click on a specific restaurant, to see the details.

Restaurant Details

Restaurant details wireframe

The restaurant’s details view is composed of three parts: restaurant details, contact details, and the establishment’s user rating.

The restaurant details will display a short description of the restaurant, some plates, a picture and a link to their website if they have one.

The contact details will display the address of the restaurant, and an image of a Google map that will locate the restaurant in the town. A link enables the user to open Google maps (either using the browser or the Google map app if available depending on the device) to locate the restaurant on the map. Another link will dial the restaurant phone number directly on the mobile device so that user can place a reservation.

The last part of this view is a select box, where the user can rate the restaurant.

Building the web-application base

Now that we’ve see the direction that we are heading, we can begin digging a little bit into the code.

Some jQuery Mobile Basics

First let’s take a look at what the header of our first HTML page will look like :

<!DOCTYPE HTML>

<HTML>

<head>

<meta charset="UTF-8">

<title>Restaurant Picker</title>

<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="jquery.mobile.structure-1.0.1.CSS" />

<link rel="stylesheet" href="jquery.mobile-1.0.1.CSS" />

<script src="js/jquery-1.7.1.min.js"></script>

<script src="js/jquery.mobile-1.0.1.min.js"></script>

</head>

The first thing to notice is the “new� HTML5 doctype. jQuery Mobile makes a heavy use of the data- HTML5 attribute to add some elements in the DOM to style the page, so we will need an HTML5 doctype to make it all work nicely.

The second thing to notice is the meta name=viewport tag. We will use this meta tag to gain better control of our viewport. Without this tag, the browser will squeeze our layout in the whole page, and it will look ugly and very tiny. With width=device-width we will use our device width, making the app fit the whole size of the device without being squeezed. The initial-scale property controls the zoom level when the page is first loaded and we will set it to 1, meaning no zoom in or out when page is loaded.

Then we will call our CSS files. In older jQuery Mobile versions the CSS was in one file, but in the newer version they made a distinction between the structure and the actual design (colors, gradients etc) which makes it easier to create custom styles.

We then need to load our jQuery, and jQuery Mobile JavaScript code at the end, since it needs the jQuery library to work.

What You’d Like to Eat: First Page

Now let’s take a look at the HTML code of our first page, in this exercise we will call this page index.HTML

<body>

<div data-role="page" id="home" data-theme="c">

<div data-role="content">

<div id="branding">

<h1>Restaurant Picker </h1>

</div>

<div class="choice_list">

<h1> What would you'd like to eat? </h1>

<ul data-role="listview" data-inset="true" >

<li><a href="choose_town.HTML" data-transition="slidedown"> <img src="sushis.jpg"/> <h3> Some Sushis</h3></a></li>

<li><a href="choose_town.HTML" data-transition="slidedown"> <img src="pizza.jpg"/> <h3> A Pizza </h3></a></li>

<li><a href="choose_town.HTML" data-transition="slidedown"> <img src="kebap.jpg"/> <h3> A Kebap</h3></a></li>

<li><a href="choose_town.HTML" data-transition="slidedown"> <img src="burger.jpg"/> <h3> A Burger</h3></a></li>

<li><a href="choose_town.HTML" data-transition="slidedown"> <img src="nems.jpg"/> <h3> Some Nems </h3></a></li>

<li><a href="choose_town.HTML" data-transition="slidedown"> <img src="tradi.jpg"/> <h3> Something more traditional</h3></a></li>

</ul>

</div>

</div>

</div><!-- /page -->

</body>

</HTML>

jQuery Mobile makes the distinction between HTML documents and pages. A jQuery Mobile app can be composed of one HTML document with multiple pages in it, using the data-role=“page� attribute each page is linked using anchors; or of many documents, each one having its own data-role=�page� linked using “normal� links. In our case, we will go for creating one HTML document per page.

So first we will open our body, and create our page using <div data-role=”page” id=”home” data-theme=”c”>

We will then open a content division, in which we put the branding of the app, and our first title followed by the list of different plates.

To create a jQuery Mobile list, we will put the data-role=”listview” attribute on our <ul> element. data-inset=”true” is here to style the list as an inset list (with rounded corners and padding around it).

Each list element <li> that contains an <a href> link will be automatically converted in a link list item by jQuery Mobile. To add the image, we simply add an image inside our < a href> link, and jQuery Mobile will do the work for us: it will display it on the left part of the list. Pretty easy.

The data-transition=”slidedown” creates the transition between two pages. You can find more transitions in the official documentation.

Here is what our first page looks like:

First page

In Which Town Do You Want To Eat: Second Page

We will name the second page choose_town.HTML . Here is the HTML code, explanation of the tricky parts follows. Note that the header won’t change.

<body>

<div id="choisir_ville" data-role="page" data-add-back-btn="true">

<div data-role="header">

<h1> Restaurant Picker</h1>

</div>

<div data-role="content">

<div class="choice_list">

<h1> In which town do you want to eat? </h1>

<ul data-role="listview" data-inset="true" data-filter="true" >

<li><a href="choose_restaurant.HTML" data-transition="slidedown"> Amiens <span > 3 </span></a> </li>

<li><a href="choose_restaurant.HTML" data-transition="slidedown"> Bastia <span > 2 </span></a> </li>

<li><a href="choose_restaurant.HTML" data-transition="slidedown"> Belfort <span class="ui-li-count" > 5 </span></a> </li>

<li><a href="choose_restaurant.HTML" data-transition="slidedown"> Bordeaux <span class="ui-li-count" > 1</span></a> </li>

…

</ul>

</div>

</div>

</div><!-- /page -->

</body>

We changed the id, so that jQuery Mobile can understand that this is another page. Notice that we used the data-add-back-btn=”true” on the page div, this will enable the Ajax back navigation and automatically add a back button to our title bar.

To create our title bar, we will create a div element, with the data-role=”header”.

To add a filter to our list, we will simply put data-filter=”true” on the ul element defining the list. Note that this is a filter that will filter the items of the list, and is not a search bar.

The last trick will be creating the little bubbles on the right of list elements, and we will do that by creating a span with the class and the numbers in it. And here is how the second page will look:

Second page

Choose a Restaurant: Third Page

We will name this page choose_restaurant.HTML and below is what the HTML code will look like.

<body>

<div id="choisir_restau" data-role="page" data-add-back-btn="true">

<div data-role="header">

<h1> Restaurant Picker</h1>

</div>

<div data-role="content">

<div class="choice_list">

<h1> Please choose a restaurant.</h1>

<ul data-role="listview" data-inset="true" >

<li><a href="restaurant.HTML" data-transition="slidedown"> <img src="restau01_mini.jpg"/> <h2> Le Mouffetard</h2> <p> 4 stars </p></a></li>

<li><a href="restaurant.HTML" data-transition="slidedown"> <img src="restau02_mini.jpg "/> <h2> Chocolate bar </h2> <p> 4 stars </p> </a></li>

<li><a href="restaurant.HTML" data-transition="slidedown"> <img src="restau03_mini.jpg "/> <h2> Restaurant Diona</h2> <p> 1 star </p> </a></li>

<li><a href="restaurant.HTML" data-transition="slidedown"> <img src="restau04_mini.jpg "/> <h2> Tai Shan</h2> <p> 3 stars </p> </a></li>

<li><a href="restaurant.HTML" data-transition="slidedown"> <img src=" restau05_mini.jpg"/> <h2> Arcade</h2> <p> 2 stars </p> </a></li>

</ul>

</div>

</div>

</div><!-- /page -->

</body>

This page is pretty similar to the first one, except for the title bar and the notation of the customer. We already saw how to create a title bar in previous section. For the customer rating, we add a p element with two classes: .classement is mutual to all the elements and will enable us to style this element with little stars, and then we use the class .one, .two, .three and .four to make the distinction between how many stars the customers gave to the restaurant. We will later in the article see how to style this in a nice way, but for the moment, we’ll leave it plain text.

Here is our third page:

Third page

Restaurant Details: Fourth Page

This page called restaurant.HTML is the trickiest of all, mainly because it has lots of elements on it. We will split the code in three parts: the restaurant description, the contact details, and the user rating. Here is our full HTML code.

<body>
<div id="restau" data-role="page" data-add-back-btn="true">

	<div data-role="header">
		<h1> Restaurant Picker</h1>
	</div> 

	<div data-role="content">
	<div class="ui-grid-a" id="restau_infos">
		<div class="ui-block-a">
		<h1> Le Mouffetard</h1>
		<p><strong>  Restaurant bar in the center of Strasbourg</strong></p>
		<p> On the menu: </p>
			<ul>
				<li> Milkshake with chocolat</li>
				<li> Planchettes </li>
				<li> Leek pie </li>
			</ul>
		</div>
		<div class="ui-block-b">
		<p><img src="restau01.jpg" alt="jeannette photo"/></p>
		<p><a href="http://www.google.fr" rel="external" data-role="button"> See our website</a></p>
		</div>
	</div><!-- /grid-a -->
	<hr/>

	<div class="ui-grid-a" id="contact_infos">
		<div class="ui-block-a">
		<h2> Contact us</h2>
		<p>30 Rue des Tonneliers</p>
		<p> 67000 Strasbourg	</p>
		</div>
		<div class="ui-block-b">
		<img src="01_maps.jpg" alt="plan jeanette"/>
		</div>
	</div><!-- /grid-a -->
	<div id="contact_buttons">
		<a href="http://maps.google.fr/maps?q=jeannette+et+les+cycleux&hl=fr&sll=46.75984,1.738281&sspn=10.221882,18.764648&hq=jeannette+et+les+cycleux&t=m&z=13&iwloc=A" data-role="button" data-icon="maps"> Find us on Google Maps </a>
		<a href="tel:0388161072"  data-role="button" data-icon="tel"> Call us </a>
	</div>
	<hr/>

	<div id="notation">
	<form>
	<label for="select-choice-0" class="select"><h2> User rating </h2></label>
		<select name="note_utilisateur" id="note_utilisateur" data-native-menu="false" data-theme="c" >
		   <option value="one" class="one"> Not good at all </option>
		   <option value="two" class="two">Average </option>
		   <option value="three" class="three">Pretty good </option>
		   <option value="four" class="four"> Excellent </option>
		</select>
	</form>
	</div>
	</div>

</div><!-- /page -->
</body>

Last page

For the restaurant details, we used the build in two column elements of jQuery Mobile. To create a two column block, we create a block with two child blocks. To create a nice button for the website, we added the data-role=”button” to the a href element, and a rel=”external” so that jQuery Mobile knows that Ajax should not used to open this link, but that this is an external link.

For the contact details, we once again used the two column trick. What’s to emphasize here are the buttons. The data-icon=”maps” and data-icon=”tel” will enable us to add custom icons to those buttons.

The interesting part about adding a GoogleMap link, is that some mobiles will be able to detect it, and will ask the user if they want to open them using the browser; if the Google maps app is installed on the device. The other interesting part is the href=tel:0388161072 protocol. This won’t work on a classic browser, but Smartphones will be able to open this link in the phone dial box, to directly call the number.

The last part is the user rating. For this we will use a simple select menu. The data-native-menu=”false” enables us to style the select using jQuery Mobile, so that we will be able to add some nice stars here too. Here again you will notice that we added the one, two, three, four class for further styling.

And here we have a fully functional jQuery Mobile webapp. But this app looks very “JqueryMobile-like�, so we now have to give it a little more styling to make it look nicer.

Next up on Page Two: Adding Some Style

The tutorial is not quite finished yet! There is more to learn over on page two.


Designing Engaging And Enjoyable Long-Form Reading Experiences


  

Finally, some good news from the media industry: digital subscriptions are growing. We’re seeing positive reports from newspapers such as the New York Times and magazine publishers such as Conde Nast: announcements about increases in their digital content sales and paywall members.

When you have fantastic and original content, ensuring the best possible reading experience is critical to keeping and building your audience. The following practices will help you design your content in a way that improves the experience for readers.

Navigation Methods

We often think that having many methods for finding things is easier for users. Unfortunately, the result can be mess of unhelpful and unrelated links, menus, widgets and ads. Many news websites place lists of “most-read articles� or “articles that your Facebook friends are reading� on their websites because they can. Analytics will tell you whether these methods are useful for your particular website. If no one is clicking on them, why are they taking up valuable space?

One way to quickly see the effect of slimmed-down navigation is to use Ochs, a Chrome browser extension specifically for the New York Times, written by Michael Donohoe. Open the New York Times in a different browser, then install Ochs and look at the website in Chrome. Ochs provides the massive benefit of a cleaner layout and clutter-free navigation. Things like reading tools and extra modules are removed from articles. The increased white space and removal of the New York Times’ dense navigation bars are a breath of fresh air.

New York Times with Ochs extension
The Ochs extension cleans up the UI of the New York Times.

There is a difference between having a reasonable way to navigate a website versus having one-click access to all of the website’s content. How do your users typically find what they want? Do they use the navigation links or jump straight to the search box?

Changing the navigation methods may be as straightforward as removing redundant menu bars or as involved as conducting user research to see which methods people use and don’t use.

Another thing to consider when looking at navigation usage patterns is that people rarely click on things that appear hard to read or cluttered. If that’s the case with your website, perhaps it’s time to look at your typography and spacing.

Experimenting With Type And Spacing

Not every typeface was designed to be read on a digital screen. Typefaces can have a huge effect on both the appeal of content and its readability. The typefaces for headlines may be beautiful and attention-grabbing, but if the ones for the copy are difficult to read, you could be turning away readers.

Not everyone will read your content exactly as it was designed. Some people set their own default font size, while others change their screen’s resolution. Still others use assistive technology, such as screen readers, to peruse content. During the course of a day, I read blogs on my iPad, pan and zoom through news on my mobile phone, edit documents on
an enormous desktop monitor and browse the Web from my television screen (at low resolution). For this same reason, tools such as Instapaper, Readability and Evernote are growing massively. The ability to control the format of what you read — and where you read it — is becoming increasingly useful.

The Boston Globe’s recent overhaul of its website received a lot of well-deserved praise, and two of the nicest things about it are the use of white space and the typography. The fonts chosen are central to the Boston Globe’s Web style, and they feel relevant to its almost 240-year-old print identity. Compare the new design to the original one, and the contrast is staggering. The Boston Globe’s new look is a great case study for news websites and readability in general. Definitely have a look if you haven’t yet.

The Boston Globe
The Boston Globe’s new interface has carefully chosen fonts plus more white space.

While some fonts were created specifically for digital reading, there is no magical formula for selecting type. To find out what works, do some testing. User testing, A/B testing and even testing within your own team can yield insights. Have everyone on your team read through a handful of long-form content on various devices. If people can’t make it through more than a few paragraphs, try different fonts, sizes or spacing. Or maybe rethink some of those distracting ads.

Respectful Advertising

How often do you see people rush to turn the page of a magazine just to skip an ad? Probably rarely. But people do it on websites all the time, panicking to find the small “Close� icon on a pop-up ad, or flummoxed as to which browser tab is playing an audio ad. I hope the people who create these creepy auto-play ads will one day experience the terror of being alone at the office late at night as a rogue audio clip begins speaking to them.

As an avid reader of both print and digital magazines, I’m overwhelmed by the stark difference in advertisements between them. Print magazine ads regularly hold my interest and engage me — I do not tear out pages of magazines, nor do I cover the ads. Magazines select advertisements that are relevant to their audience and that are attractive and well designed. Advertisers usually do not spend big money on print ads only to create unattractive content for them.

For some reason, all of this goes out the window when it comes to online ads. Companies are told that no one notices ads unless they grab attention, and so they create loud, garish ads — ads that do nothing for the product and that most likely diminish the viewer’s interest. It doesn’t have to be this way.

The advertising network The Deck prides itself on tasteful, targeted ads for an influential audience of creative professionals. Its ads are uniform in size and amount of text. The Deck does not pay for or run ads unless it has used the products themselves, so it vouches for all of its advertisers. The emphasis on small graphics forces advertisers to be creative, and advertisers get a return of 3% of all page views in The Deck’s current network.

Ads from The Deck
The Deck’s ads are tasteful and subtle.

Both advertisers and audiences have something to gain when ads are relevant and attractive. The growing shift towards responsive and respectful advertising has been written about at length by people such as Mark Boulton and Roger Black (see the related links at the bottom of this article). It’s worth reading their takes on these new Web ads, and you might even want to have an internal discussion at your company about how the advertising on your website could be made more valuable for everyone.

Moreover, if the ads on your website are respectful and relevant, people might check out the advertisers’ products, increasing both visited metrics and click-through rates, thus allowing you to charge more for advertising. So, do dive into your website’s analytics.

Check Your Analytics

We want to do the right thing: build websites that are responsive and that adapt to devices. But we have to be reasonable, too. What is achievable given your budget and time frame? Analytics are one of the best ways to hone in on what to prioritize. Even a simple free tool like Google Analytics can yield important insight into who is viewing your website and how. Google Analytics can also track readers’ paths through the website, showing you what content and sections are being avoided or ignored.

The Financial Times keeps a close eye on its visitor analytics. It has over 1 million registered users. In November, it announced that its Web app (which launched in June 2011) was replacing its native mobile app. The Financial Times also released data indicating the types of devices that are being used to access its website and the times of day. And it recently launched a native Android app — perhaps because the number of people accessing its website on Android devices is growing.

The Financial Times
The Financial Times ditched the App Store for its own Web apps.

If you notice that most of your traffic is coming from people on tablets, you can optimize for that experience first. Management at your company may be pushing hard for a native app, but you should determine a couple of things before writing the design specifications for a native app:

  1. Does the audience for such an app exist, or is one growing?
  2. Is that audience not getting a good enough experience from your website.

If your current audience barely has any iOS users but has a significant chunk of Android users, why not start there instead? Additionally, what are those Android users doing on your website? Are they sticking around and enjoying your mobile experience, or do they bounce quickly? The latter could indicate that the experience on your website isn’t ideal.

But if you want to know for sure, ask them.

Has Anyone Asked Your Users?

It sadden me how often content and experience decisions are made without consulting the people who those decisions will affect. Facebook users are familiar with the pandemonium that occurs every time a new interface goes live — people often struggle to find what was once familiar and obvious.

The Sunday Times’ iPad app was updated in August based on user feedback. Users requested to be able to download all sections with the click of a button. The Sunday Times added the ability to download all or individual sections, improved the functionality for deleting sections and editions, and bundled sections more usefully. These changes were the result of direct comments and feedback from users.

The Sunday Times iPad app
The Sunday Times listened to users and changed its downloading options.

Short in-person interviews or widespread surveys are fast and easy ways to get feedback directly from readers about what they like and don’t like about your content. Find out about their reading habits. Learn when and where they read articles — the answers may surprise you. Perhaps the section you were considering cutting has a growing audience. Maybe a feature that gets very good engagement in print doesn’t translate so well online and needs to be rethought.

And if users tell you they’re frustrated by trying to read anything on your website, consider offering them a quiet room.

“A Quiet Room�

Walking from the cacophony of New York’s Times Square into a tiny, quiet office can bring a feeling of relief. All of a sudden, no one is in your face trying to get you to buy something or take a tour or give them money. You can just relax and focus.

Finding a website or app that lets you read and enjoy its content is just like this. The experience is not stressful, and you can take your time and enjoy the writing, which seems to have been created just for you. As a designer, you can create this “quiet room� for readers, a place where they can fully absorb the content without having to close pop-ups or be confronted by an animation that screams that they are the 1,238,901st visitor that day. A quiet room is why applications like Instapaper and Readability get effusive praise.

A List Apart does a good job of avoiding clutter and letting the reader focus. Articles have minimal sidebar navigation and only a couple of small, tasteful advertisements. The majority of the page has a simple format: easy-to-read text (peppered with images), a conclusion that points you to related material, and a chance to discuss the article.

A List Apart
A List Apart creates room for readers to enjoy the content.

When Doesn’t This Work?

These approaches will not work for every group of content or every website. Some content is meant to be skimmed for quick comprehension. Other websites contain no narrative content. And many websites rely too much on advertising revenue to be able to change their ad strategy.

If your content changes rapidly, is short and to the point, contains little analysis or has any combination of these, then it’s likely not a good fit for this approach. But if you have done your research and you have content that is well written and that your audience likes to get lost in, then perhaps some of the ideas mentioned above are worth a try.

Regardless of the length and type of your content, here’s a useful exercise: go through each of the issues covered above and think of one thing you could change to make your content more readable. Some of the revisions might be long term and big picture, but you might be surprised by the easy opportunities to make a big impact. Give your readers a reason to enjoy your website as it is, instead of a reason to reformat the content and turn the page as fast as possible.

Resources

(jvb) (fi) (al)


© Martha Rotter for Smashing Magazine, 2012.


Designing Engaging And Enjoyable Long-Form Reading Experiences


  

Finally, some good news from the media industry: digital subscriptions are growing. We’re seeing positive reports from newspapers such as the New York Times and magazine publishers such as Conde Nast: announcements about increases in their digital content sales and paywall members.

When you have fantastic and original content, ensuring the best possible reading experience is critical to keeping and building your audience. The following practices will help you design your content in a way that improves the experience for readers.

Navigation Methods

We often think that having many methods for finding things is easier for users. Unfortunately, the result can be mess of unhelpful and unrelated links, menus, widgets and ads. Many news websites place lists of “most-read articles� or “articles that your Facebook friends are reading� on their websites because they can. Analytics will tell you whether these methods are useful for your particular website. If no one is clicking on them, why are they taking up valuable space?

One way to quickly see the effect of slimmed-down navigation is to use Ochs, a Chrome browser extension specifically for the New York Times, written by Michael Donohoe. Open the New York Times in a different browser, then install Ochs and look at the website in Chrome. Ochs provides the massive benefit of a cleaner layout and clutter-free navigation. Things like reading tools and extra modules are removed from articles. The increased white space and removal of the New York Times’ dense navigation bars are a breath of fresh air.

New York Times with Ochs extension
The Ochs extension cleans up the UI of the New York Times.

There is a difference between having a reasonable way to navigate a website versus having one-click access to all of the website’s content. How do your users typically find what they want? Do they use the navigation links or jump straight to the search box?

Changing the navigation methods may be as straightforward as removing redundant menu bars or as involved as conducting user research to see which methods people use and don’t use.

Another thing to consider when looking at navigation usage patterns is that people rarely click on things that appear hard to read or cluttered. If that’s the case with your website, perhaps it’s time to look at your typography and spacing.

Experimenting With Type And Spacing

Not every typeface was designed to be read on a digital screen. Typefaces can have a huge effect on both the appeal of content and its readability. The typefaces for headlines may be beautiful and attention-grabbing, but if the ones for the copy are difficult to read, you could be turning away readers.

Not everyone will read your content exactly as it was designed. Some people set their own default font size, while others change their screen’s resolution. Still others use assistive technology, such as screen readers, to peruse content. During the course of a day, I read blogs on my iPad, pan and zoom through news on my mobile phone, edit documents on
an enormous desktop monitor and browse the Web from my television screen (at low resolution). For this same reason, tools such as Instapaper, Readability and Evernote are growing massively. The ability to control the format of what you read — and where you read it — is becoming increasingly useful.

The Boston Globe’s recent overhaul of its website received a lot of well-deserved praise, and two of the nicest things about it are the use of white space and the typography. The fonts chosen are central to the Boston Globe’s Web style, and they feel relevant to its almost 240-year-old print identity. Compare the new design to the original one, and the contrast is staggering. The Boston Globe’s new look is a great case study for news websites and readability in general. Definitely have a look if you haven’t yet.

The Boston Globe
The Boston Globe’s new interface has carefully chosen fonts plus more white space.

While some fonts were created specifically for digital reading, there is no magical formula for selecting type. To find out what works, do some testing. User testing, A/B testing and even testing within your own team can yield insights. Have everyone on your team read through a handful of long-form content on various devices. If people can’t make it through more than a few paragraphs, try different fonts, sizes or spacing. Or maybe rethink some of those distracting ads.

Respectful Advertising

How often do you see people rush to turn the page of a magazine just to skip an ad? Probably rarely. But people do it on websites all the time, panicking to find the small “Close� icon on a pop-up ad, or flummoxed as to which browser tab is playing an audio ad. I hope the people who create these creepy auto-play ads will one day experience the terror of being alone at the office late at night as a rogue audio clip begins speaking to them.

As an avid reader of both print and digital magazines, I’m overwhelmed by the stark difference in advertisements between them. Print magazine ads regularly hold my interest and engage me — I do not tear out pages of magazines, nor do I cover the ads. Magazines select advertisements that are relevant to their audience and that are attractive and well designed. Advertisers usually do not spend big money on print ads only to create unattractive content for them.

For some reason, all of this goes out the window when it comes to online ads. Companies are told that no one notices ads unless they grab attention, and so they create loud, garish ads — ads that do nothing for the product and that most likely diminish the viewer’s interest. It doesn’t have to be this way.

The advertising network The Deck prides itself on tasteful, targeted ads for an influential audience of creative professionals. Its ads are uniform in size and amount of text. The Deck does not pay for or run ads unless it has used the products themselves, so it vouches for all of its advertisers. The emphasis on small graphics forces advertisers to be creative, and advertisers get a return of 3% of all page views in The Deck’s current network.

Ads from The Deck
The Deck’s ads are tasteful and subtle.

Both advertisers and audiences have something to gain when ads are relevant and attractive. The growing shift towards responsive and respectful advertising has been written about at length by people such as Mark Boulton and Roger Black (see the related links at the bottom of this article). It’s worth reading their takes on these new Web ads, and you might even want to have an internal discussion at your company about how the advertising on your website could be made more valuable for everyone.

Moreover, if the ads on your website are respectful and relevant, people might check out the advertisers’ products, increasing both visited metrics and click-through rates, thus allowing you to charge more for advertising. So, do dive into your website’s analytics.

Check Your Analytics

We want to do the right thing: build websites that are responsive and that adapt to devices. But we have to be reasonable, too. What is achievable given your budget and time frame? Analytics are one of the best ways to hone in on what to prioritize. Even a simple free tool like Google Analytics can yield important insight into who is viewing your website and how. Google Analytics can also track readers’ paths through the website, showing you what content and sections are being avoided or ignored.

The Financial Times keeps a close eye on its visitor analytics. It has over 1 million registered users. In November, it announced that its Web app (which launched in June 2011) was replacing its native mobile app. The Financial Times also released data indicating the types of devices that are being used to access its website and the times of day. And it recently launched a native Android app — perhaps because the number of people accessing its website on Android devices is growing.

The Financial Times
The Financial Times ditched the App Store for its own Web apps.

If you notice that most of your traffic is coming from people on tablets, you can optimize for that experience first. Management at your company may be pushing hard for a native app, but you should determine a couple of things before writing the design specifications for a native app:

  1. Does the audience for such an app exist, or is one growing?
  2. Is that audience not getting a good enough experience from your website.

If your current audience barely has any iOS users but has a significant chunk of Android users, why not start there instead? Additionally, what are those Android users doing on your website? Are they sticking around and enjoying your mobile experience, or do they bounce quickly? The latter could indicate that the experience on your website isn’t ideal.

But if you want to know for sure, ask them.

Has Anyone Asked Your Users?

It sadden me how often content and experience decisions are made without consulting the people who those decisions will affect. Facebook users are familiar with the pandemonium that occurs every time a new interface goes live — people often struggle to find what was once familiar and obvious.

The Sunday Times’ iPad app was updated in August based on user feedback. Users requested to be able to download all sections with the click of a button. The Sunday Times added the ability to download all or individual sections, improved the functionality for deleting sections and editions, and bundled sections more usefully. These changes were the result of direct comments and feedback from users.

The Sunday Times iPad app
The Sunday Times listened to users and changed its downloading options.

Short in-person interviews or widespread surveys are fast and easy ways to get feedback directly from readers about what they like and don’t like about your content. Find out about their reading habits. Learn when and where they read articles — the answers may surprise you. Perhaps the section you were considering cutting has a growing audience. Maybe a feature that gets very good engagement in print doesn’t translate so well online and needs to be rethought.

And if users tell you they’re frustrated by trying to read anything on your website, consider offering them a quiet room.

“A Quiet Room�

Walking from the cacophony of New York’s Times Square into a tiny, quiet office can bring a feeling of relief. All of a sudden, no one is in your face trying to get you to buy something or take a tour or give them money. You can just relax and focus.

Finding a website or app that lets you read and enjoy its content is just like this. The experience is not stressful, and you can take your time and enjoy the writing, which seems to have been created just for you. As a designer, you can create this “quiet room� for readers, a place where they can fully absorb the content without having to close pop-ups or be confronted by an animation that screams that they are the 1,238,901st visitor that day. A quiet room is why applications like Instapaper and Readability get effusive praise.

A List Apart does a good job of avoiding clutter and letting the reader focus. Articles have minimal sidebar navigation and only a couple of small, tasteful advertisements. The majority of the page has a simple format: easy-to-read text (peppered with images), a conclusion that points you to related material, and a chance to discuss the article.

A List Apart
A List Apart creates room for readers to enjoy the content.

When Doesn’t This Work?

These approaches will not work for every group of content or every website. Some content is meant to be skimmed for quick comprehension. Other websites contain no narrative content. And many websites rely too much on advertising revenue to be able to change their ad strategy.

If your content changes rapidly, is short and to the point, contains little analysis or has any combination of these, then it’s likely not a good fit for this approach. But if you have done your research and you have content that is well written and that your audience likes to get lost in, then perhaps some of the ideas mentioned above are worth a try.

Regardless of the length and type of your content, here’s a useful exercise: go through each of the issues covered above and think of one thing you could change to make your content more readable. Some of the revisions might be long term and big picture, but you might be surprised by the easy opportunities to make a big impact. Give your readers a reason to enjoy your website as it is, instead of a reason to reformat the content and turn the page as fast as possible.

Resources

(jvb) (fi) (al)


© Martha Rotter for Smashing Magazine, 2012.


Writing Unit Tests For WordPress Plugins


  

When my WordPress plugin had only three users, it didn’t matter much if I broke it. By the time I reached 100,000 downloads, every new update made my palms sweat.

My first goal for the WordPress Editorial Calendar was to make it do anything useful. I was new to JavaScript and PHP and didn’t really know what I could pull off. In a few days I had a proof of concept. In a few more I had a working version and was asking friends to install it. The calendar worked… sort of.

I spent three times as much time fixing bugs as I did coding. Once the plugin worked, I wrote unit tests to make sure it kept working.

The unit tests for my calendar use QUnit, but they really use just three functions: test, expect and ok. This article shows you how to integrate unit tests into your WordPress plugin, where to write unit tests and how they can help you.

QUnit Basics

Unit tests follow a basic pattern: do something, then check the results. (“Is this variable 4 when it should be 5?� “Does this line of my table show up where it’s supposed to?�)

function myTest() {
    test('My test run', function() {
        expect(2);
        ok(5 === 5, 'This test will always pass');
        ok(5 === 6, 'This test will always fail');
    });
}

This structure forces you to think of your code in simple units that return true or false. The test function starts a test run with two arguments: the title for this test run, and the function containing the tests. The expect function tells QUnit how many tests are in the run. If we call too few or too many, it causes an error.

The ok function performs the test of the expression. It takes two arguments: a boolean indicating whether the test was successful, and a message.

Test runs are added to a special list section, which shows the total number of tests, whether each test passed or failed, and how long the tests took.

A Real Unit Test

WordPress plugins complicate testing by using a combination of PHP and JavaScript. Even passing a simple value from PHP to JavaScript gets tricky.

The function below finds a WordPress preference with the get_option function and creates a JavaScript variable with the resulting value.

function getOption($myOption, $myVariable) {
    if (get_option($myOption) != "") {
        ?><script type="text/javascript">
            <?php echo($myVariable); ?> = <?php echo(get_option($myOption)); ?>;
        <php
    }
}

Now we’ll call it to get the name of the blog and set it to a variable named myBlogName.

getOption("blogname", "myBlogName");

Little helper functions like these glue your plugin together, but they always worry me. Did I access the JavaScript variable with the right name or did I mistype it? Did I use the same name twice? A simple unit test makes all of these worries go away.

function wpPrefTest() {
    test('Get access to WordPress preferences', function() {
        expect(1);
        ok(myBlogName, 'The variable (myBlogName) should be available.');
    });
}

This unit test checks whether the variable myBlogName exists. We could also look for a specific value or compare it to something else from the application.

Once you have this unit test, you’ll never need to worry about getting the blog’s name. It will always be there, and you’ll find out fast if you ever break it.

Integrating QUnit With WordPress

Testing in special development environments isn’t accurate. I wanted to add QUnit directly to my calendar, but I didn’t want to make the page’s size larger. The solution is a URL parameter and a little PHP to include QUnit only when I need it:

wp_enqueue_script( "qunit", path_join(WP_PLUGIN_URL, basename( dirname( __FILE__ ) )."/lib/qunit.js"), array( 'jquery' ) );
wp_enqueue_script( "edcal-test", path_join(WP_PLUGIN_URL, basename( dirname( __FILE__ ) )."/edcal_test.js"), array( 'jquery' ) );

This tells WordPress to include the QUnit JavaScript and my unit tests from edcal_test.js. I could have just embedded the script’s reference directly on my page, but I might have run into trouble if other plugins on the same page use QUnit.

You can see the full source code here.

The next step was to make sure that these scripts load only when I need them. To do this, I wrapped the code in a check for a URL parameter:

if ($_GET['qunit']) {
    wp_enqueue_script( "qunit", path_join(WP_PLUGIN_URL, basename( dirname( __FILE__ ) )."/lib/qunit.js"), array( 'jquery' ) );
    wp_enqueue_script( "edcal-test", path_join(WP_PLUGIN_URL, basename( dirname( __FILE__ ) )."/edcal_test.js"), array( 'jquery' ) );
}

This loads the scripts only if I’m running unit tests, and everything else in the plugin stays the same. You can run the unit tests at any time just by adding &qunit=true to the end of the URL. That’s a good thing because my unit tests actually change what’s going on in the blog.

You can run the Editorial Calendar’s unit tests in your browser right now. Scroll down to see the unit test results at the bottom of the page.

The PHP makes sure that my scripts get to the browser. The last step is to call them from my JavaScript. Once again, I want to call them only if we’re in unit test mode. So, I add a small function to get the parameters from the URL:

getUrlVars: function() {
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for (var i = 0; i < hashes.length; i++) {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}

And then I call my unit tests if the QUnit parameter is there:

jQuery(document).ready(function() {
    if (edcal.getUrlVars().qunit) {
        edcal_test.runTests();
    }
});

This ensures that we call the unit tests only if they’re available.

The last step is to set up a space for the unit test’s output. QUnit writes its test results into specially designated tags on your HTML page. You could embed these tags directly in your HTML output, but because they need to be there only when QUnit is active, I create the HTML in JavaScript instead.

jQuery('head').append('<link>');
css = jQuery('head').children(':last');
css.attr({
    rel: 'stylesheet',
    type: 'text/css',
    href: '../wp-content/plugins/edcal/lib/qunit.css'
});

jQuery('#wpbody-content .wrap').append('<div id="edcal-qunit"></div>');

jQuery('#edcal-qunit').append(
    '<h1 id="qunit-header">WordPress Editorial Calendar Unit Tests</h1>' +
    '<h2 id="qunit-banner"></h2>' +
    '<div id="qunit-testrunner-toolbar"></div>' +
    '<h2 id="qunit-userAgent"></h2>' +
    '<ol id="qunit-tests"></ol>' +
    '<div id="qunit-fixture">test markup</div>');

QUnit needs a list tag, a couple of divs and a style sheet.

Now we’re ready to write our first test.

The First Unit Test

The first calendar unit tests scroll the calendar up and down and make sure we see the correct number of days.

moveTests: function() {
    var curSunday = edcal.nextStartOfWeek(Date.today()).add(-1).weeks();
    edcal.moveTo(Date.today());

    test('Move to today and check visible dates', function() {
        expect(2);
        ok(edcal_test.getFirstDate().equals(curSunday.clone()),
           'firstDate should match ' + curSunday);
        ok(edcal_test.getLastDate().equals(
           curSunday.clone().add(edcal.weeksPref).weeks().add(-1).days()),
           'lastDate should match ' + curSunday);
    });
}

Our first test moves the calendar to today and checks to see if the first and last days are what we expect. We set up a variable, move the calendar and start the test by calling the test function.

In this case we want to make sure the dates are correct, so we compare the date from the calendar to the one we expect and then pass the result to the ok function. The test succeeds if they match and fails if they don’t.

This test may seem simple, but a lot is going on under the hood. We’re testing date handling, drawing and the fundamental arithmetic of the calendar.

Unit tests can do anything. The WordPress Editorial Calendar unit tests automate the plugin like a robot. They cover everything a user could do with the calendar.

What To Unit Test

I write a lot more unit tests for JavaScript than I do for compiled languages. In Java and C++, the compiler catches many of my mistakes, whereas JavaScript lets you pass a string when you meant to pass a number and lets you call a function with two arguments when it needs three.

Here’s the basic list of areas I test in JavaScript applications:

  • Tests that make sure the program does what it is meant to do
    These tests ensure the basic functionality keeps working; they do not test interactions. (The calendar lets you drag and drop posts, but writing unit tests for dragging and dropping wouldn’t make sense; instead, we would focus on what happens after the drop event.)
  • Tests that make sure the program doesn’t do what it’s not meant to do
    These tests ensure the program fails properly when it gets garbage.
  • A unit test for every major bug I’ve found
    These tests ensure that none of these bugs creep back in.

APIs and other clear boundaries in the code lend themselves well to unit tests, as do utility functions that you call from many places in the application. With the calendar, this means testing calendar movements and testing how we create and modify posts in WordPress, like this:

  1. Move the calendar and check the dates;
  2. Create a post and make sure it was created properly;
  3. Edit the post we just created and make sure it saves properly;
  4. Move the post and make sure it shows up at the correct date;
  5. Move the post from two places at the same time and make sure we get the proper warning message;
  6. Delete the post from the server and make sure it isn’t there anymore.

The penultimate test covers an error condition in which two people move the same post at the same time. Unit tests work well for this kind of error, because the error type is difficult to test and manual testing is less likely to uncover problems.

For your own application, you should have at least one unit test for every data-changing operation that users can perform. I like to add them for all of the places where a user can get data, too. It might sound like a lot of work, but you can cut down on it by writing single tests that cover multiple areas.

Asynchronous Unit Tests

Many of these combination unit tests make AJAX calls. QUnit provides a special function for handling AJAX called asyncTest. This function works just like test, but it pauses the test run at the end of the function. The QUnit framework waits until your AJAX call completes and you call the start function before restarting the test run.

The asyncTest function handles all of the tests that edit posts from the calendar, including deleting the post at the end:

asyncTest('Delete the post created for testing', function() {
    expect(1);

    edcal.deletePost(edcal_test.post.id, function(res)
    {
        equals(jQuery('#post-' + res.post.id).length, 0,
               'The post should now be deleted from the calendar.');
        start();
    });
});

When you restart the test framework you can call more tests. Calling the next test function at the end of the previous one chains them together, and it supports calling all of your tests with just a call to the first function.

These tests, which call AJAX, ensure that the integration between the JavaScript on the client side and the PHP on the back end works properly.

That’s Not a Unit Test

When I first learned to write unit tests in C++ the rule was this: a single test should only call code in a single module or CPP file. That is, a unit test should test one unit of code.

Changing posts from unit tests violates that rule. Instead of just testing JavaScript, I’m really testing JavaScript, PHP, WordPress itself and MySQL all at once. That makes it an automated integration test.

Integration tests aren’t traditional unit tests, but they work well for WordPress plugins. When I create a post, I’ll know that the AJAX code in my plugin works as well as the JavaScript code. Covering a larger portion of the application with fewer tests makes it easier to focus on what I should be testing.

What Not To Unit Test

You could write unit tests forever, but some are more useful than others. Here are some guidelines.

  • Don’t unit test the UI.
    The test has to run by itself. It can’t wait for you to click a button or look at something to make sure it appears correctly.
  • Don’t unit test performance.
    Tests take a variable amount of time on different machines and browsers. Don’t write unit tests that depend on a function being returned in a set amount of time.
  • Don’t unit test code from other projects.
    Adding unit tests for WordPress or a jQuery plugin you depend on might be tempting, but it rarely pays off. If you want to contribute unit tests to WordPress.org that’s great, but your unit tests should check that your plugin works.

The Editorial Calendar has 26 unit tests, at about 3,500 lines of code. That may not sound like much, but they’ve saved many of my releases.

Unit Tests Saved My Butt

I didn’t add unit tests until the thirteenth release of my plugin. By then, the calendar had a couple of hundred users and was growing fast. My plugin was working, and I was getting close to release 1.0.

Instead of adding new features, I took in a new framework, added special code to load it, wrote 381 lines of unit tests and integrated all of this into the plugin. It seems like a lot of work, but it saved my butt.

Right before a release, I wrote some harmless-looking PHP code like the following to get the JSON data that represented a set of posts to show up in the calendar:

function edcal_postJSON($post) {
    setup_postdata($post);
    ?>
    {
        "date" : "<?php the_time('d') ?><?php the_time('m') ?><?php the_time('Y') ?>",
        "title" : <?php echo($this->edcal_json_encode(get_the_title())); ?>,
        "author" : <?php echo($this->edcal_json_encode(get_the_author())); ?>
    },
    <?php
}

function edcal_posts() {
    header("Content-Type: application/json");

    global $post;
    $args = array(
        'posts_per_page' => -1,
        'post_status' => "publish&future&draft",
        'post_parent' => null // any parent
    );

    $myposts = query_posts($args);

    ?>[
        <?php
        $size = sizeof($myposts);
        for($i = 0; $i < $size; $i++) {
            $post = $myposts[$i];
            edcal_postJSON($post, $i < $size - 1);
        }
    ?> ]
    <?php
}

I ran the code and everything worked. I was about to release the new version but ran my unit tests first to make sure. They failed. Can you spot the bug? I didn’t.

I was returning a JSON array, but the last item in the array had a trailing comma. That’s invalid JSON. Firefox accepts it, but Safari, Chrome and IE don’t. I almost shipped a broken plugin to over half of my users.

Now I run the unit tests on all major browsers whenever I release a new version. Any time WordPress releases a new version, I run the unit tests. WordPress 3.3 broke the calendar — and I found out exactly why in 15 seconds.

Popular Plugins Are Stable Plugins

Most WordPress plugins are free and open source, but free doesn’t always mean cheap. The total cost of ownership of unstable plugins is more than people would pay. That’s a fancy way of saying that users will run from your plugin if it’s a bug fest.

My plugin became popular because of its features, but stability kept it popular. People remember one buggy release for a long time. If the Editorial Calendar deletes or corrupts posts from just one blog, thousands of people would stop using it. And they’d be justified.

Unit tests add the stability you need to support the multitude of browsers, mobile devices and dark corners involved in any JavaScript application. They’re easy to write, and they pay you back: because you find the bugs, and your users don’t.

(al)


© Zack Grossbart for Smashing Magazine, 2012.


  •   
  • Copyright © 1996-2010 BlogmyQuery - BMQ. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress