Archive for the ‘PHP Tutorials’ Category

An In Depth Overview of HTML5 Multimedia and Accessibility

Wednesday, January 4th, 2012

In this tutorial, you’ll learn how HTML5 helps to provide you with several ways of presenting your media content to users. As a result, you’ll increase the availability of your media to users with different
needs and requirements, making it more accessible.

This tutorial comes courtesy of the recently released HTML5 Multimedia book.


Media and Potential Accessibility Issues

I’d strongly encourage you to think about making your content accessible…

When thinking about the users who will be attempting to view your media content, you might make a number of assumptions:

All are fairly reasonable assumptions to make and most likely cover the vast majority of users who will want to access your content. You may be happy with your content being accessible to these users only; after all, majority rules, doesn’t it?

Well, I’d strongly encourage you to think about making your content accessible to users who do not fall into the category of the assumptions just listed. Who are these viewers? They include:

Because most media content will usually include some audio, not being able to hear or understand the audio it contains is quite a showstopper in comprehending the content’s message and information.

Equally, being able to access the content through a device such as a screen reader but then not being able to actually use it due to the media controls not being properly set up (e.g., for keyboard access) would annoy any user.

You’ll explore the accessibility of media controls later in this tutorial. You’ll also take a look at what HTML5 brings to the table in an attempt to address the issue of users being unable to see, hear, or understand your media content. But first, let’s take a quick look at what led to HTML5’s attempt to confront this accessibility problem — SRT.


A Brief Look at SRT

SRT is an existing file format for containing video subtitles and their timings.

SRT is an existing file format for containing video subtitles and their timings. An SRT file is often produced automatically using a Windows program called SubRip, which uses optical character recognition (OCR) to obtain the subtitles from the specified video source.

The SubRip file format is a basic text file with the .srt file extension that follows a basic format:

Each subtitle set begins with a unique subtitle number, followed by the start and end timestamps of the timing the subtitle represents on a separate line, which is then followed by one or more lines of subtitle text. Each subsequent subtitle set is separated by a blank line. The timestamp format hh:mm:ss,msmsms specifies the hours, minutes, seconds, and milliseconds of the time in question. Note that the millisecond separator is a comma.

An example of such a file follows:

1
00:00:10,500 --> 00:00:13,000
Elephant’s Dream
2
00:00:15,000 --> 00:00:18,000
At the left we can see...

The SRT file format is quite popular and is often the format that video subtitles are released in. This file format isn’t currently used as part of HTML5’s attempt to tackle accessibility, although it was to begin with but has now been extended and given a new name, WebVTT.


Introducing WEBVTT

WebVTT (Web Video Text Tracks) is a file format that is intended for marking up external text tracks. It was initially part of the WHATWG and the W3C HTML5 specifications, and was an extension of SRT called WebSRT (Web Subtitle Resource Tracks). But the W3C was concerned that HTML5 should be independent of any chosen captioning format, and therefore, it was removed from that specification.

Note: even though the SRT in WebSRT stands for subtitle resource Tracks, the original acronym didn’t stand for anything and merely reflected
the file extension used. WebSRT is a “backronym”; subtitle resource Tracks was shoe-horned into the three letters to actually mean something.

The presence of WebVTT is currently one major difference between the WHATWG HTML5 specification and the W3C specification.

Although no browser currently supports WebVTT, major browser vendors have indicated that they will implement support for WebVTT in the future. This indication has led to the creation of a WebVTT Working Group Charter at the W3C, whose mission is to:

“create a W3C specification starting from the WHATWG WebVTT (Web Video Text Tracks) language and solidify it through the creation of a WebVTT test suite and through the creation of semantic mappings of other subtitle formats to or from WebVTT in order to facilitate browser implementation and market adoption.”

This promise of vendor support will hopefully in turn eventually lead to a formal standardization of the WebVTT specification at the W3C. With browser support and that of the W3C, you can be sure that WebVTT is here to stay and is destined become the de facto method of marking up text tracks within audio and video content on the web.

So what is the WebVTT file format and how can it help you make your content accessible? Read on.

What Can WebVTT Do?

The WebVTT format also allows you to provide a textual description of the video content

You use the WebVTT file format to define WebVTT files. One of the main uses of these files is to provide subtitles to video content, although the format of the file doesn’t indicate what its contents are used for.

The WebVTT format also allows you to provide a textual description of the video content, which can then be used by various accessibility devices (which might read the descriptions out loud) to describe the content of the video to those who cannot see it. You inform the browser of the WebVTT file and of its purpose using HTML markup; you’ll find out how this is done later in this tutorial, when you read about the track element.

Let’s take a look at the WebVTT file format in more detail.

WEBVTT File Format

A WebVTT file is a simple text file with the .vtt extension that needs to follow a specified format, which you will look at shortly. The file must be encoded as UTF-8 and labeled with the MIME type text/tt. The line terminators within the file can only be \r (a carriage return), \n (a new line), or \r\n (a carriage return followed by a new line). It must also contain a WebVTT file body, which consists of the following:

WEBVTT
[cue]
[cue]
...

The WEBVTT string at the top identifies the contents as a WebVTT file and must then be followed by at least one blank line, which is then followed by any number of cues, each of which is separated by a blank line.

A cue is defined as:

[idstring]
[hh:]mm:ss.msmsms --> [hh:]mm:ss.msmsms [cue settings]
TextLine1
TextLine2
...

idstring is a unique identifier within the file that identifies the cue. It can consist of one or more characters that do not contain the substring “—>” or any of the line terminators mentioned earlier. [hh:]mm:ss.msmsms —> [hh:]mm:ss.msmsms indicates the timestamp range within the video file that the cue is specified for. [hh:]mm:ss.msmsms is a simple timestamp; the hour portion is optional (depending on the length of the video in question of course).

Note: The millisecond separators are full stops, not commas as in SRT.

cue settings allow you to specify the positioning of the text; you’ll read more about them in a moment.

TextLineN is the actual text in the video file that the timestamp range in the cue represents. The content can be all in one line or presented in any number of separate lines. Any lines will be contained within the cue until a blank line is encountered, which indicates the end of that particular cue.

Let’s take a quick look at a sample WebVTT file containing two timestamp ranges:

WEBVTT
1
00:00:10.500 --> 00:00:13.000
Elephant’s Dream
2
00:00:15.000 --> 00:00:18.000
At the left we can see...

This example defines two cues: The first one starts 10 seconds and 500 milliseconds into the video and ends at 13 seconds in, and the second one starts 15 seconds into the video and ends 3 seconds later. The subtitle text for each cue is given below its timestamp.


How a subtitle cue might appear on a video with no cue settings specified.

Using cues is relatively straightforward, and you can see how the file can be built up with a number of cues to cover the length of an entire video. You can also specify some settings on a per-cue basis. These affect the positioning of the cue on the related video. You can have a number of setting values, and a cue setting can contain one or more values, each one separated by a space. The various settings are listed below:

If no cue settings are specified, the text will align to the middle, at the bottom of the video frame.

Let’s add some of these settings to the example used earlier:

WEBVTT
1
00:00:10.500 --> 00:00:13.000 A:start Elephant’s Dream
2
00:00:15.000 --> 00:00:18.000 A:end L:10% At the left we can see...

The text in the first cue will be aligned to the left of the video (much the same way as the CSS rule text-align:left works).


How a cue subtitle might appear on a video with a cue setting of A:start.

The second cue has two settings applied to it: The text will be aligned to the end of the line (similar to text-align:right in CSS) and will be placed on the line 10 percent down from the top of the video.


How a cue subtitle might appear on a video with a cue setting of A:end L:10%.

In addition to specifying cue settings for controlling the positioning and alignment of cue text, there are also a number of inline styles that you can apply to the text. These look and act the same as HTML elements. They contain a start and an end tag, and the formatting is applied to the text in between.

Let’s extend the example further and use some of the text tags to format the cue text:

WEBVTT
1
00:00:00.000 --> 00:00:14.999 Elephant’s <c.dream>Dream</c>
2
00:00:15.000 --> 00:00:18.000 A:end L:10% At the <i>left</i> we can <b>see</b> ...
3
00:00:18.167 --> 00:00:22.000
At the right <00:00:20.000>we can see the...

With the first cue, a class name of “dream” has been added, a style for which you can define within your HTML file in the same way as you’d create any CSS style rules.


Video-cue text with a style defined using CSS and the WebVTT c text tag.

Note: any CSS class names that you might use within your WebVTT subtitle definitions can be defined in the containing HTML file or an external css file in the same way as you’d specify any other css classes.

The second cue now has tags that will display the word “left” in italics and “see” in bold type.


Video-cue text that uses the i and b text tags.

An extra cue is added to this example to show how the timestamp is used to display the text “karaoke style.” When the cue starts, the words “At the right” will appear first. Then the text “we can see…” will be displayed at the appropriate time- stamp (Figure 8.6).

Note: if you want the characters &, <, and > to appear in the text of a video cue, you need to escape them with &amp; &lt; and &gt; respectively.


This video-cue text shows the text in stages.

WEBVTT Future Developments

It’s worth noting that because the WEBVTT file format is relatively new to the specification and with the recent creation of the WEBVTT Working Group Charter, additions to the specification are likely.

If you want to keep abreast of any changes to this specification, keep an eye on the Working Group Charter’s site and the blog of Silvia Pfeiffer who is currently editor of the Working Group Charter. Silvia also blogs regularly about HtML5-related accessibility topics.

You can see how the complete narrative in a video could be added to a WebVTT text file with formatting and styling.

But how do you connect a WebVTT file with a particular video? This is where the new HTML5 track element steps in.


The Track Element

The track element is one of the new HTML5 elements. Its purpose is to allow external text tracks to be specified for media elements, such as audio and video. The track element does not represent anything on its own and must be used in conjunction with, and as a child of, a media element.
The track element takes a number of attributes, which are listed below:

The following example shows how a track element might be used in connection with a video to provide subtitles:

<video controls>
    <source src="video-file.mp4" type="video/mp4">
    <source src="video-file.webm" type="video/webm">
    <track src="en.vtt" kind="subtitles" srclang="en" label="English p subtitles">
</video>

The track element in the example specifies that the en.vtt file contains English subtitles (as the label says) in the English language (srclang is set to en) of kind: subtitles for the surrounding video element. From this example, you can see just how easy it would be to add a second subtitles file that might be in a different language:

<video controls>
    <source src="video-file.mp4" type="video/mp4">
    <source src="video-file.webm" type="video/webm">
    <track src="en.vtt" kind="subtitles" srclang="en" label="English p subtitles" default>
    <track src="de.vtt" kind="subtitles" srclang="de" label="German p subtitles">
</video>

Here, another track definition has been added, pointing to a de.vtt file that contains German subtitles; srclang is set to de.

Notice that the default attribute has been added to the English subtitles definition, marking it as the default subtitle set to be used if the user doesn’t specifically select one.

If you wanted to extend the example further and add a chapter listing in each language (English and German), you would do the following:

<video controls>
    <source src="video-file.mp4" type="video/mp4">
    <source src="video-file.webm" type="video/webm">
    <track src="en.vtt" kind="subtitles" srclang="en" label="English p subtitles" default>
    <track src="de.vtt" kind="subtitles" srclang="de" label="German p subtitles">
    <track src="ch-en.vtt" kind="chapters" srclang="en" p label="English chapter listing" default>
    <track src="ch-de.vtt" kind="chapters" srclang="de" p label="German chapter listing">
</video>

Once the various WebVTT files have been created with the content you want, it’s a fairly simple process to add them to the appropriate video.

Everything you’ve just read about WebVTT all sounds quite promising; however, even though some browsers support the track element to some degree, currently no browser supports the WebVTT file format.

Note: at the time of this writing, the Webkit (which chrome and safari are based on) nightly build has some support for WebVTT.
All is not lost, though, because several JavaScript libraries are available that enable you to start using WebVTT today.

Using WEBVTT and the Track Element Now

A small number of browsers support the track element to some degree. The latest WebKit browsers (e.g., Chrome 12 and Safari 5.0.5) recognize the element but don’t do anything with it. The current version of Firefox (5) parses the element but also does nothing with it. Although these browsers are taking steps in the right direction, they don’t really help you implement WebVTT now.

Fortunately, four JavaScript libraries allow you to define the track element with WebVTT files in your web document that will deliver what you want:

SRT Support

Although only a handful of JavaScript players support WEBVTT, a number of them support SRT subtitle files. those players that support WebVtt (Playr, LeanBack, Captionator, and MediaElementJS) also support SRT in addition to the following that provide support for SRT only:

None of these libraries offer support for all the different values for the kind attribute of the track element: They only support the subtitle value (Playr also supports the chapter value). Because subtitles are one of the most important values, it’s a good start. This support also allows you to begin adding subtitles to your videos now and seeing them in action.

Let’s look at how you might use the Playr JavaScript library to add subtitles and chapters to a video.

Playr Example

To use Playr, you must first download it from the Playr download website. Once downloaded, you need to include the Playr CSS file and JavaScript in your web document:

<link rel="stylesheet" href="playr.css" />
<script src="playr.js"></script>

When defining your video, you simply add the CSS class “playr_video” to your video element, and Playr will automatically be used for that video.

A sample of Playr with a short animated film called Elephant’s Dream (© copyright 2006, Blender Foundation, Netherlands Media Art Institute, www.elephants dream.org) is available here.

The code used for this video is as follows:

<video class="playr_video" preload="metadata" controls p poster="elephants-dream.title.jpg">
   <source src="elephants-dream-medium.mp4" type="video/mp4">
   <source src="elephants-dream-medium.webm" type="video/webm">
   <track label="English subtitles" kind="subtitles" srclang="en" p src="elephants-dream-subtitles-en.vtt" default>
   <track label="German subtitles" kind="subtitles" srclang="de" p src="elephants-dream-subtitles-de.vtt">
   <track label="Chapters" kind="chapters" srclang="en" p src="elephants-dream-chapters-en.vtt">
</video>

The Playr video player with Elephant’s Dream.

Also, three track elements are used to point to English and German subtitles, and English chapters.

Note: Playr currently doesn’t support multiple chapter files or the default attribute but will do so in a future release.

Playr’s menu allows viewers to choose English and German subtitles plus chapters.

Subtitles have been placed 6 percent from the top (using L:6%) and bolded with <b>.

The same video with German subtitles chosen.

A sample of how chapter selection looks in Playr.

Playr is a handy video player, and its ability to display subtitles and chapters is very useful. Support for the other kinds of track element contents are planned, so like other available video players, it will keep on improving.

Another important part of making media content accessible are the controls. Next, you’ll learn how accessible the default players are and what can you do to make your own custom controls more accessible.


Media Controls and Accessibility

It’s quite important for accessibility that the media controls can be accessed from the keyboard.

As mentioned earlier, it’s quite important for accessibility that the media controls can be accessed from the keyboard. Browsers have their own set of controls for media elements, but how accessible are they from the keyboard? Unfortunately, at the moment, the answer is not very. Opera seems to be the only browser whose default control set is immediately accessible from the keyboard. You can easily tab from one control to the other, use the Return key to toggle the Play/Pause button, and use the arrow keys to control the seek bar and volume control.

So, if you want to make your media content fully accessible across all modern browsers, you need to implement your own custom controls.

Improving the Accessibility of Custom Controls

You’ve already used the HTML button element to implement nearly all of the controls. Using button elements immediately increases the accessibility of the controls because the button element is automatically accessible from the key- board. That fact alone makes the custom controls keyboard accessible. Because the controls are also listed in the same order as they appear on the player, their tab order is also pretty much in the required logical order. However, you might want to change the tab order of the progress bar and the Play/Pause button. Most likely, users would want to play the video first, so that button should be the first control that they can access.

You can specify the tab order of HTML controls using the tabindex attribute. The order specified by this attribute is the one that the browser will tell the key- board to follow. So you apply a tabindex of 1 to the Play/Pause button and 2 to the progress bar, and then apply subsequent tabindexes in the order in which they appear in the source:

<div id="controls">
    <div id="progressBar"><span id="played" tabindex="2"></span></div>
    <button id="playpause" alt="play" title="play" tabindex="1">play</button>
    <button id="stop" alt="stop" title="stop" tabindex="3">stop</button>
    <button id="rewind" alt="rewind" title="rewind" tabindex="4">&laquo;</button>
    <button id="ffwd" alt="fast forward" title="fast forward" tabindex="5">&raquo;</button>
    <button id="volumeDown" alt="decrease volume" title="-" tabindex="6">button>
    <button id="volumeUp" alt="increase volume" title="+" tabindex="7">+</button>
    <button id="mute" alt="mute" title="mute" tabindex="8">mute</button>
</div>

In this code listing, the onclick() events have been omitted for brevity.

The Range Element

The range element would be ideal for use as a progress bar if support was better because it too automatically provides keyboard accessibility, and the seek bar would work via the keyboard (the up and down keys would toggle the seek when the element has focus) without any further requirements.

Because the buttons provide keyboard accessibility automatically, all you need to tackle now is the progress bar, which uses a div and a span.
You need to add an event listener for the keypress event, which fires when a key is pressed, and then act on it. You’re interested in just a key press on the progress bar, so the event is added to the progress bar only:

var progressBar = document.getElementById(“progressBar");
progressBar.addEventListener(“keypress", function(e) {
    checkKey(e.keyCode);
}, false);

The function that is called when a key press is detected is called checkKey() with a parameter indicating the numeric code of the key that was pressed:

function checkKey(code) {
    if (code == 38) { // up arrow key
        video.currentTime += 0.5;
    }
    else if (code == 40) { // down arrow key
        video.currentTime -= 0.5;
    }
}

The checkKey() function simply checks the key code to see if it’s the up arrow key (code 38) or the down arrow key (code 40). Depending on which key it is, the video’s currentTime attribute is increased or decreased by 0.05 (an arbitrary time value, but it seems a good step to move the video forward or backward by).

And that’s it. The progress bar’s seek capabilities can now be accessed via the keyboard with the up and down arrow keys when it’s in focus. The end result renders your media custom controls a lot more accessible than they would have been.


Wrapping Up

With regard to accessibility, HTML5 has advanced and expanded from its initial definition of the WebSRT file format to WebVTT. With browser vendors planning to support this format, a new W3C Working Group was formed with the intention of formalizing the WebVTT specification for browsers to start supporting. So hope- fully, browser support is only a matter of time.

Although native support is currently patchy, you can use existing JavaScript libraries to add subtitles to your videos now. These libraries will undoubtedly increase their functionality and capabilities in the future.

Overall, accessibility is a goal you should be thinking about when serving multimedia content to your users. The more users who can access your content the better, right?

Be sure to visit the HTML5 Multimedia website, or buy the book to learn more!


Tags: , , ,
Posted in PHP Tutorials | No Comments »

Create a Scalable Widget Using YUI3: Part 4

Tuesday, January 3rd, 2012

Welcome to the last part in the YUI3 widget tutorial; although we’ve actually finished building the widget, we’re going to look at how easy it is to add extra functionality to a widget without having to re-write it.

Let’s get started right away!

If the functionality is required for a particular module it’s an extension. Otherwise, it’s a plugin.

There are two ways of adding functionality – extensions and plugins. The difference between them is subtle but essentially boils down to whether or not the functionality is required or optional. If the functionality is required for a particular module it’s an extension, if the functionality is optional, it’s a plugin.

The plugin that we’ll add will handle the paging functionality for our widget; maybe not all developers will want to add paging, or some may want to add it to some instances of the widget but not others. Adding the functionality makes sense when viewed in this way – if the developer wants to make use of paging, they can use the plugin, but we don’t force developers to run all the extra code that is required if they aren’t going to use it.


Creating a Plugin

The process for creating a plugin is similar to that for creating a widget, so many of the constructs that we’ll use here should be familiar from the previous parts of this tutorial. Just like when creating a widget, we use YUI’s add() method as a wrapper for our code:

YUI.add("tweet-search-paging", function (Y) {

},

The Constructor and Namespace

Just like with our widget, we need to add a constructor for our plugin so that it can initialised and set the namespace for it. Unlike our plugin, setting the namespace is required. Add the following code within the anonymous function we just added:

var Node = Y.Node;

function TweetSearchPaging(config) {
    TweetSearchPaging.superclass.constructor.apply(this, arguments);
}

Y.namespace("Plugin.DW").TweetSearchPaging = TweetSearchPaging;

We start by caching references to any frequently used YUI resources, which in this case is just the Node utility. We add the constructor for the plugin in the same way as before; the TweetSearchPaging plugin method is defined as a function that accepts a configuration object. The class is initialized using the apply() method of the superclass’s constructor.

We set a namespace for our plugin, but this time the namespace is attached to the Plugin namespace as opposed to the YUI object.


Static Properties

As before there are some static properties we should set for our plugin, these are as follows:

TweetSearchPaging.NAME = "tweetsearch-paging";

TweetSearchPaging.NS = "paging";

TweetSearchPaging.ATTRS = {

    origShowUIValue: null,

    strings: {
        value: {
            nextLink: "Next Page",
            prevLink: "Previous Page"
        }
    }
};

TweetSearchPaging.PAGING_CLASS = Y.ClassNameManager.getClassName(TweetSearchPaging.NAME, "link");

TweetSearchPaging.LINK_TEMPLATE = "<a class={linkclass} href={url}>{linktext}</a>";

The name of the plugin is set with the NAME property, and also the NS property, which can be used to refer to the plugin from the host (the host is the widget or module that the plugin is connected to) class.

We can also use the ATTRS property to set any configuration attributes for the plugin. These attributes also use the YUI3 Attributes module, just like the widget attributes, and can be used in the same way. The attributes we define are the origShowUIValue attribute, which the plugin will set to store whether the search UI was initially displayed in the widget when the plugin is initialized. We also store the text strings used by the plugin, again for easy internationalization.

We manually generate a class name for the elements that we’ll create using the classNameManager, and define the template that our paging links will be created with. As there is only a single class name and template we don’t need to worry about using a for loop.


Extending the Plugin Base Class

Just like we did when creating the class for our widget, we use YUI’s extend() method to extend an underlying module. In the case of a plugin, it’s the Plugin.Base class that we’re extending. The extend() method should appear as follows:

Y.extend(TweetSearchPaging, Y.Plugin.Base, {

});

We pass in our plugin as the first argument to the extend() method, the class we’re extending as the second method and an object literal containing the functionality we’re adding.


Life Cycle Methods

Plugins also get access to several life-cycle methods that can be overridden to add custom code that the plugin will execute for us at appropriate times. We can make use of use the initializer and destructor life-cycle methods:

initializer: function () {

    Y.StyleSheet("tweetSearchPagingBase").set(".yui3-tweetsearch-paging-link", { float: "right" });

    if (Y.one(".yui3-skin-sam")) {
        Y.StyleSheet("tweetSearchPagingSkin").set(".yui3-skin-sam .yui3-tweetsearch-paging-link", { marginLeft: "2%" });
    }

    var widget = this.get("host");

    if (!widget.get("showUI")) {
        this.set("_origShowUIValue", false);
        widget.set("showUI", true);
    } else {
        this.set("_origShowUIValue", true);
    }

    this.afterHostEvent("tweetsChange", this._afterHostTweetsChange);
},

destructor: function () {
    Y.StyleSheet("tweetSearchPagingBase").unset(".yui3-tweetsearch-paging-link", "float");

    if (Y.one(".yui3-skin-sam")) {
        Y.StyleSheet("tweetSearchPagingSkin").unset(".yui3-skin-sam .yui3-tweetsearch-paging-link", "marginLeft");
    }

    if (!this.get("_origShowUIValue")) {
        this.get("host").set("showUI", false);
        Y.one(".yui3-tweetsearch-ui").remove();
    }
},

The initializer method will be executed when the plugin is initialized; in this method we first create the base style sheet our plugin needs. We could just include a separate CSS file, but as we only need a single style rule it makes sense to cut down on the number of files that any implementing developer needs to manage.

We use YUI’s StyleSheet() method to create our new style sheet. This method accepts a single argument which is the name of the new style sheet. We then use the set() method to set the styles that we require. The set() method takes two arguments; the first is the selector we wish to target and the second is an object literal containing the styles that should be applied to the selector, which in this case is simply float: right.

We then check whether the .yui3-sam-skin selector exists in the document; if it does, we then go ahead and create a skin style sheet for the plugin. If the sam skin is not in use, it is not worth creating any skin styles as the implementing developer will no doubt have custom styles that they may wish to apply.

Next, we need to check whether the showUI attribute of the widget is enabled. We can get access to the host class that the plugin is attached to using the built-in host attribute, which we get using the get() method just like any other attribute. The showUI attribute of the widget must be enabled if the plugin is used, so if the attribute is not set originally we set it here.

When using plugins we have the ability to detect and react to any of the host’s attributes changing. We add an attribute change-handler for the when the tweets attribute of our widget changes using the afterHostEvent() method. This method accepts two arguments; the first is the attribute to monitor, the second is the method to execute when the attribute changes.

The destructor function is called when the plugin is destroyed; this method is used to tidy up after the plugin. Any changes to the page should be reversed, as well as any changes we make to the widget. The changes we make to the page that we have to undo are the addition of the style sheets, so this is what we do first. The style sheet styles can be removed using the unset() method; this method takes the selector to unset as the first argument and the styles to unset as the second argument.

We then check whether the _origShowUiValue variable is set to true or false; if the variable is set to false we know we have to revert its value, so we set the attribute of the host back to false. If the value was changed and the UI was shown by the plugin, we hide it so that the widget is returned to its original state.


Attribute Change-Handlers

We only use a single attribute change-handling method in this plugin; the one that is called when the tweet attribute of the host changes. This method should appear as follows:

_afterHostTweetsChange: function () {

    var widget = this.get("host");

    if (widget.get("tweets").next_page) {
        var nextPageUrl = widget.get("tweets").next_page,
            nextLink = Node.create(Y.substitute(TweetSearchPaging.LINK_TEMPLATE, {
            linkclass: TweetSearchPaging.PAGING_CLASS, url: ["http://search.twitter.com/search.json", nextPageUrl, "&callback={callback}"].join(""), linktext: this.get("strings").nextLink }));

        if (this._nextLinkNode) {
            this._nextLinkNode.remove();
        }

        this._nextLinkNode = widget._uiNode.appendChild(nextLink);

        Y.on("click", Y.bind(this._getPage, this), this._nextLinkNode);
    }

    if (widget.get("tweets").previous_page) {
        var prevPageUrl = widget.get("tweets").previous_page,
            prevLink = Node.create(Y.substitute(TweetSearchPaging.LINK_TEMPLATE, {
            linkclass: TweetSearchPaging.PAGING_CLASS, url: ["http://search.twitter.com/search.json", prevPageUrl, "&callback={callback}"].join(""), linktext: this.get("strings").prevLink }));

        if (this._prevLinkNode) {
            this._prevLinkNode.remove();
        }
        this._prevLinkNode = widget._uiNode.appendChild(prevLink);
        Y.on("click", Y.bind(this._getPage, this), this._prevLinkNode);
    }
},

We first store a reference to the host class once more as we’ll need to refer to it several times. We now need to determine whether or not there are paged results in the response from Twitter and whether there are previous or next pages of results. The cool thing about the response from twitter is that it will automatically maintain which page of results we are viewing if there are more results than the configured number of results per page.

If there is another page of results after the current page, there will be a property in the JSON response object called next_page. Similarly, if there is a previous page of results, there will be a previous_page property. All we need to do is check for the presence of these properties and create next page and previous page links.

The links are created using the template we stored earlier in the plugin class, and are given the generated CLASS_NAME. The next_page and previous_page response objects are obtained from Twitter using a URL with a special ID in the query string. When we create these new nodes, the URL provided in these properties is added to each link respectively. The links are appended to the searchUI node of the host, and click handlers are added for them. These click handlers point to a utility method called _getPage(). We’ll add this method next.


Custom Prototype Methods

Just like when creating the widget, we can add any number of custom prototype methods that are used to execute any custom code required by our plugin in response to user interaction or state changes. In this plugin, we only need to add a single method, which should appear as follows:

_getPage: function (e) {
    var widget = this.get("host");

    e.preventDefault();

    widget._viewerNode.empty().hide();
    widget._loadingNode.show();

    widget.set("baseURL", e.target.get("href")),

    widget._retrieveTweets();

    Y.all(".yui3-tweetsearch-paging-link").remove();
}

First, we store a reference to the host class, and then prevent the paging link that was clicked being followed. We then remove any existing tweets in the widget’s viewer and show the loading node. Remember, each paging link (or whichever link exists if we are on the first or last page) will have the URL that retrieves the next (or previous) page of results, so we retrieve this URL from the link’s href and set the baseURL attribute of the widget. One this is done, we call the _retrieveTweets() method of our widget to request the next page. Finally, we remove the current paging links as they will be recreated if there are next or previous pages included in the new response object.


Using the Plugin

Now that we’ve created our plugin we can see how easy it is to use with our widget. We need to update our use() method to use our plugin, and call the plug() method before the widget is rendered:

YUI().use("tweet-search", "tweet-search-paging", function (Y) {
    var myTweetSearch = new Y.DW.TweetSearch({
        srcNode: "#ts"
    });
    myTweetSearch.plug(Y.Plugin.DW.TweetSearchPaging);
    myTweetSearch.render();
});

The plug() method connects our plugin, which is accessible via the Plugin namespace and whatever namespace we specified when defining the plugin’s class. Now when we run the page, we should have paging links at the bottom of the widget:

Nettuts+

One of the features of our plugin (just like our widget) is easy internationalization; in order to provide strings for the plugin in another language (or override any attributes if a plugin), we can simply provide the configuration object as the second argument to the plug() method, e.g.:

myTweetSearch.plug(Y.Plugin.DW.TweetSearchPaging, {
    strings: {
        nextLink: "Página Siguiente",
        prevLink: "Página Anterior"
    }
});

The paging link should now appear like so:

Nettuts+

Wrapping Up

In this part of the tutorial, we looked at how easy it is to create a plugin that can be used to enhance existing widgets or other modules. This is a great way of providing extra functionality that is not essential, which developers can choose to include if they wish. We saw that the structure of a plugin is similar to that of a widget on a smaller scale.

In this example, the plugin was very tightly coupled to our widget; it wouldn’t be possible to use the plugin with a different widget for example. This does not have to be the case and plugins, as well as extensions can be much more loosely coupled to add or enhance functionality for a range of different modules.

This now brings us to the end of the series on YUI3 widgets; I hope I’ve given some insight into the powerful mechanisms put in place by the library that enable us to easily create scalable and robust widgets that leverage the strengths of the library.

Let us know what you think in the comments section below and thank you so much for reading!


Tags: , , ,
Posted in PHP Tutorials | No Comments »

Introducing Nettuts+ Fetch

Monday, January 2nd, 2012

In addition to producing various helpful apps for web developers, in 2012, we’ll also be commissioning and releasing smaller plugins and extensions. Today, I’d like to announce the first entry in this initiative: “Nettuts+ Fetch” – a Sublime Text plugin.


The 20 Second Example


Choose 720p for a clearer picture.

The Dilemma

Let’s say that you’re a fan of Normalize.css. Perhaps, you download it and save it to a snippet, or store the stylesheet, itself, in an assets folder. That way, for future projects, you only need to copy and paste.

The only problem with this method – as we’ve all discovered – is that, if a few months have passed, it’s more than possible that the asset (in this case, Normalize.css) will have been updated by the creator. So your options are to either use the, now, out-dated version of Normalize, or, once again, return to the GitHub page and pull in a fresh copy. This all seems tedious.


The Solution

Created by Weslly Honorato, Nettuts+ Fetch is the solution to our dilemma.

I thought to myself: “What if there was a plugin that would automatically pull in the latest copy of a file, simply by typing a keyboard shortcut. It’ll perform a curl request to your specified URL (saved away for future use), and allow you to rest assured that, for all new projects, you’re using the latest copy of a particular asset.

Created by Weslly Honorato, Nettuts+ Fetch is the solution to our dilemma.


Installation Instructions

Nettuts+ Fetch

While you can manually download Nettuts+ Fetch from GitHub, the easiest way to set it up is through Package Control (which all ST2 users should be using). Once you’ve installed package control, press ctrl+shift+p (Windows, Linux) or cmd+shift+p (OS X), and type “Package Install.” Next, search for “Nettuts+ Fetch,” press enter, and you’re done. Simple.


Usage

You’ll only use two commands, when working with Fetch. First, we need to save some file references. Again, bring up the command palette, and search for “Fetch.” For now, choose “Manage Remote Files.”

Manage Remote Files

What’s great about Sublime Text 2 is that configuration is incredibly simple. To assign references to online asset files, we only need to create an object, like so (don’t worry; one will be pre-populated for you, after installation):

So, to pull in the latest copy of jQuery (if you don’t want to use a CDN):

{
	"files":
	{
		"jquery": "http://code.jquery.com/jquery.min.js"
	}
}

Packages

Even better, I can pull in entire packages, or zip files. What if we want to start a new project, using HTML5 Boilerplate? In that case, we add the reference to the “packages” object.

{
	"files":
	{
		"jquery": "http://code.jquery.com/jquery.min.js"
	},
	"packages":
	{
		"html5-boilerplate": "http://github.com/h5bp/html5-boilerplate/zipball/v2.0stripped"
	}
}

Fetch, Boy

Now that we have a package and script saved (add as many as you like), we can pull them in by using the Fetch command. Pull up the command palette – ctrl+shift+p (Windows, Linux) or cmd+shift+p (OS X) – type “Fetch,” and make your selection.

Choose HTML5 Boilerplate from the list, give it a few seconds, and, bam, you’re ready to go with the latest release.

Pretty sweet, huh? I hope you like it! Thanks again to Weslly Honorato for building it for us.


Tags: , , ,
Posted in PHP Tutorials | No Comments »

Best of Tuts+ in December 2011

Monday, January 2nd, 2012

Each month, we bring together a selection of the best tutorials and articles from across the whole Tuts+ network. Whether you’d like to read the top posts from your favourite site, or would like to start learning something completely new, this is the best place to start!


Psdtuts+ — Photoshop Tutorials


Happy New Year!

We’d like to wish all our readers a very Happy New Year! Why not take a look at our Holiday Wishes post to see a video message from the Envato HQ team, and find out more about what you might have missed over the Christmas period.

We hope you’ve enjoyed everything that we’ve had to share this year, and look forward to publishing thousands more top-quality tutorials, articles, freebies, and resources in 2012.

Thanks for being part of the Tuts+ community!


Tags: , , ,
Posted in PHP Tutorials | No Comments »

The Tools of Modern Mac-Based Web Development: New on Premium

Sunday, January 1st, 2012

In this week’s Premium screencast, I provide a brain-dump on all of the various tools I use for web development. Sometimes, simply watching another person work can be incredibly helpful. What tools do they use? How do they work with their code editor? I’ll cover all of these things today.

If you’re not a Tuts+ Premium member, it’s our subscription-based portion of Tuts+, where we provide high quality tutorials, ebooks, and courses on a variety of subjects. Be sure to check it out!


Tools Discussed in the Video


Tags: , , ,
Posted in PHP Tutorials | No Comments »

Nettuts+ – A Year in Review (And What’s Next)

Friday, December 30th, 2011

Good gosh; another year comes to a close. Sometimes, it feels as if every year passes by more quickly than the one before it. Nonetheless, 2011 was a great year for Nettuts+. Here’s why…


Traffic

Honestly, these days, I don’t focus on traffic too much. That might come as a surprise, considering that this is a blog that, yes, brings in income. However, I’ve come to learn that obsessing over traffic only translates to you spending less time creating content. I’ve never taken a stance, such as, “Next month’s traffic needs to be up by 15%.” It doesn’t work that way.

Personally, I only use Google Analytics to:

Beyond that, I honestly don’t see much point in obsessively focusing on traffic.

Dedicate your life to a given topic, write about it as well as you are capable of, and I promise that the traffic will come as a result.

In 2012…

To project numbers for 2012 would almost be a contradiction of what I just wrote. That said, I suppose it would be nice for us to continue reaching more and more people!


Editorials

Nettuts+ was initially created with one simple goal: provide high quality, step-by-step web development tutorials. This year, I decided that we need to have more of a voice in the community. Initially, this took the form of me venting to an online journal… read by millions of people. Since then, though, the Editorials category has morphed into developers providing their own strong opinions on one issue or another. The reader is then left with the article (and the comments) to determine what his or her own views on the subject are. The most important thing is that it gets us talking.

In 2012…

I hope to provide even more opinion-based editorials on Nettuts+. My goal is that, when a well-known developer needs to get something off his chest – whether it be the state of the industry, the people, or the tools available – he comes to Nettuts+ to write and publish it.

I want Nettuts+ to be the central location for the web development industry to come together and discuss important issues and events.


Apps

One of my goals for 2011 was to have Nettuts+ branch out a bit. Yes, we have the blog, but what about books, tools, and apps? We’re still very much in the early stages of these goals, though, we’ve made some good progress.

Nettuts+ Prefixr

Nettuts+ Prefixr

Prefixr was built out of necessity, and provides us with a way to automate the creation of all those tedious CSS vendor prefixes. Now, from your favorite code editor, you only need to type a shortcut key, and your entire stylesheet will be run through the Prefixr web service, and automatically optimized. No longer do you need to worry about which browsers support which CSS3 properties. Prefixr does that for you.

Nettuts+ Builder

Unfortunately, it costs money to commission these apps; so we’ve experimented with selling them as cheaply as possible on the popular CodeCanyon marketplace.

Nettuts+ Builder

Nettuts+ Builder turns the process of compressing scripts and stylesheets, and uploading a project to your server into as simple a process as possible.

Let’s say that you finished a coding project or demo. Simply drag the folder onto the Builder menu icon, and it will:

If you’ve found yourself manually compressing your files and uploading them to your server, this automates the entire process!

Structurer Pro

Structurer Pro

Structurer is a wonderful project tempting interface for the Mac. It allows you to rapidly create directory structures with ease, and a few of the features include:

In 2012…

Branching out to provide apps and web services is a fantastic way to both spread your brand, and provide helpful services to your peers. In 2012, I’ll be focusing on commissioning more cross-OS apps, and creating additional web applications and services. For example, I don’t think that the online code snippet management and community idea has been executed well enough by anyone. Sites like Snipplr are helpful, but fall far short of what they could be.

Additionally, we’ll also focus on smaller tools, such as plugins, code editor extensions, and more.


The Best Way to Learn…

Newcomers are begging for these sorts of resources.

Something I’ve thought about quite a bit – particularly in the last several months – is syllabus based education. For instance, if you want to learn JavaScript, you have literally thousands of resources available to you. As amazing as that is, it’s almost a hindrance; where do you start? Very quickly, you can become overwhelmed. Wouldn’t it be helpful if you were given a syllabus by a pro? Want to learn JavaScript? Great – read this, then this, then this, follow and become friends with these people on Twitter, try out this first project, etc. Newcomers are begging for these sorts of resources.

As a first step, we’ve created a series tailor-made for this group of people: The Best Way to Learn.

In 2012…

We’re only four entries in so far; in 2012, I’d like to increase this number to cover all sorts of languages and tools.


Two Man Ship

While Nettuts+ is a part of the Envato network, when it comes to the day-to-day management, it had always been little-ole me at the helm. Thankfully, this year, Siddharth has come on board as my assistant, and has been doing an excellent job. In addition to helping me edit and publish articles (so that I can focus more on Premium courses and books), he’s also the man behind our fun Nettuts+ Quizzes that you guys seem to enjoy. He’s been a huge asset to the site.

Nettuts+ Quizzes

In 2012…

I hope to transition Sid into more of a co-pilot, rather than assistant. It’ll be nice to reach a point when we are both responsible for finding, commissioning, and scheduling top quality content.


Nettuts+ Live

Take the Nettuts+ format (step by step tutorial), and translate it to a live, real-time coding tutorial on stage.

A few months ago, when speaking at a WordPress meetup in New York, I experimented with a format that I call “Nettuts+ Live.” The basic idea is that you take the Nettuts+ format (step by step tutorials), and translate it to a live, real-time coding tutorial on stage.

For my presentation, I discussed WordPress custom post types and taxonomies, and how they can be used to extend your WordPress application. Now, in hindsight, I’m not sure I would do it the same way again. Coding from scratch in front of a hundred people is very, very difficult. With that in mind, I think I did quite well, though there were a few points when I had to stop and stare at the code blankly for a couple moments…desperately trying to determine what typo I had made.

And then, when I finished the presentation, I was met with the realization that only a handful of the people in the audience were actual coders; the rest were mostly WordPress users. Yikes!

In 2012…

Nonetheless, I think the format has merit, if molded a bit more. In 2012, I’m going to experiment with more local meetups and this format. No slides; just a code editor, a speaker, and lots of questions from the audience along the way. It may crash and burn, but it also may…not!


Courses

Tuts+ Premium

As part of the newly relaunched Premium brand of Tuts+, Tuts+ Premium, I’m the head of web development courses. Mostly, what this translates to is me creating the best possible content for learning how to be a web developer – in video form.

Particularly in the last few months, I’ve immersed myself in the art of screencasting and teaching. I’ve watched countless video tutorials around the web to determine what I enjoyed, what it irritated me, and what makes me press stop. At a glance…

In 2012…

At the moment, I’m still working to get the bread and butter courses up on the site, such as CSS3, JavaScript, jQuery, PHP, etc. Once the staples are finished, we’ll transition into more specific courses, such as Backbone Essentials, CodeIgniter, Dojo, etc. It’s a really exciting time to be a Tut+ Premium member.


Changing the Landscape of Online Education

Brick and mortar colleges are dated, and incredibly expensive.

Nettuts+ began in 2008, when Envato was still referred to as Eden. Since then, the site has come a really long way. My favorite part has been the process of determining and defining exactly what sort of site it is. I love that we offer video tutorials, and sessions, and in depth articles from some of the most respected developers in our industry. Every time one of my dev heroes links to a Nettuts+ article, it makes me feel amazing. This site will continue to grow; so “stay the course” is the name of the game for Nettuts+ and 2012.

In 2012…

Tuts+ Premium has taken the first step. The next one will be a significantly larger leap forward.

For me, I want to redefine the landscape of online web development education entirely. I want to take the basic college experience, and translate it to the web. No, I’m not talking about keg parties, I’m talking about a community for students.

I’ve heard it too many times: “My college hasn’t taught me a fraction of what Nettuts+ has in two weeks.” I’m not being conceited here; replace Nettuts+ with any popular web development blog, and the outcome will still be true. Because our industry is accelerating at such an incredible speed, traditional schools and professors can not keep up. Brick and mortar colleges are dated, and incredibly expensive.

I want Tuts+ Premium to bridge the gap: provide students with instructors, courses, quizzes, assignments, one-on-one lessons, certifications, and forums to learn and collaborate with their peers. In its current form, Tuts+ Premium has taken the first step. The next one will be a significantly larger leap forward.


Help Me

This final question is for you, John Q Reader. How can I make Nettuts+ the best web development resource on the web? In the last three years, we’ve come a very long way toward this goal. How can I take it further? What do you need more of from us? In return, I promise we’ll do our best to provide it. We’re currently working on the next design for the Tuts+ sites; your input will help define the shape it takes!


Tags: , , ,
Posted in PHP Tutorials | No Comments »

Creating an API-Centric Web Application

Friday, December 30th, 2011

Planning to start working on a new web application? In this tutorial, we’ll discuss how to create an API-centric web application, and explain why this is essential in today’s multi-platform world.


Introduction

API?

For those who are unfamiliar with the term, API is short for Application Programming Interface. According to Wikipedia:

An application programming interface (API) is a source code based specification intended to be used as an interface by software components to communicate with each other. An API may include specifications for routines, data structures, object classes, and variables.

In simpler terms, an API refers to a set of functions built into an application, which can be used by other applications (or by itself, as we’ll see later), to interact with the application. An API is a great way to expose an application’s functionality to external applications safely and securely, since all functionality that these external applications can do is limited with what functionality is exposed in the API.

What’s an “API-Centric” Web Application?

An API-Centric Web Application is a web application that basically executes most, if not, all its functionality through API calls.

An API-Centric Web Application is a web application that basically executes most, if not, all its functionality through API calls. For example, if you were to log in a user, you would send his credentials to the API, and the API would return to you a result saying if the user provided the correct user-password combination.

Another characteristic of an API-Centric Web Application is that the API will always be stateless, meaning it can’t recognize API calls by session. Since API calls will be made by usually via the backend code, it will be hard to implement session handling, since there are usually no cookies involved in that. This limitation is actually good — this “forces” a developer to build an API that works not based on the state of the current user, but rather on functionality, which in turn, makes it easier to test, since the current state of a user doesn’t need to be recreated.

Why go through all this trouble?

As web developers, we’ve seen technology evolve first hand. It’s common knowledge that people today don’t just use applications via a browser, but through other gadgets, like mobile phones and tablets. For example, this article on Mashable, entitled “Consumers Now Spending More Time on Mobile Apps Than the Web”, states:

Consumers are spending more time on mobile apps than on the web for the first time, a new report claims.

Flurry compared its mobile data to stats from comScore and Alexa, and found that in June, consumers spent 81 minutes per day using mobile apps, compared to 74 minutes of web surfing.

Here’s a more recent article from ReadWriteWeb, entitled “More People Browse On Mobile Than Use IE6 & IE7 Combined:

The latest data on browser trends from Sitepoint show that more people browse the Web on smartphones than use Internet Explorer 6 and 7 combined. Those two old clunkers have been the bugbears of Web developers for years, requiring sites to degrade as nicely as possible to that least common denominator of browsers. But it’s a new world now; 6.95% of Web activity in November 2011 was on mobile browsers, and only 6.49% was on IE 6 or 7.

As we can clearly see, more and more people get their news from alternative venues, specifically mobile devices.

What does this have to do with me creating an API-Centric Web Application?

This would inevitably lead to more usage of our application, since it can be used anywhere a person wants.

One of the main advantages of creating an API-centric application is that it helps you build functionality that can be used by ANY device, be it a browser, a mobile phone, a tablet, or even a desktop app. All you need to do is to create the API in such a way that all these devices can communicate with it, and voila! You’ll have built a centralized application that can take input and execute functionality from any device that a person has!

API-Centric Application Diagram

API-Centric Application Diagram

By creating an application in this manner, we’re able to easily take advantage of the different mediums used by different people. This would inevitably lead to more usage of an application, since it can be used anywhere a person wants.

To drive the point home, here’s an article about Twitter’s new redesigned website, which tells us about how they now use their API to power Twitter.com, essentially making it API-centric:

One of the most important architectural changes is that Twitter.com is now a client of our own API. It fetches data from the same endpoints that the mobile site, our apps for iPhone, iPad, Android, and every third-party application use. This shift allowed us to allocate more resources to the API team, generating over 40 patches. In the initial page load and every call from the client, all data is now fetched from a highly optimized JSON fragment cache.

In this tutorial, we’ll be creating a simple TODO list application that is API-Centric and create one front-end client on the browser that interacts with our TODO list application. By the end, you’ll know the integral parts of an API-Centric application, and at the same time, how to facilitate secure communication between the two. With that in mind, let’s begin!


Step 1: Plan the Application’s Functions

The TODO application we’ll be building in this tutorial will have the basic CRUD functions:

Each TODO item will have: