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:
- Users will view your content on a desktop, laptop, tablet, or phone.
- Users will have some way of listening to the audio of your content, be it via
headphones or speakers. - Users will be able to understand the language in which you deliver the media.
- Users will be able to successfully download and play your media.
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:
- Users who have a sensory impairment that prevents them from listening to your content’s audio or viewing video.
- Users who don’t understand the language the media is delivered in.
- Users who use devices such as screen readers and/or use keyboards to access
media content on the web. - Users who can’t successfully hear or view your content due to the environment they are in or because of device limitations.
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:
- Subtitle number
- hh:mm:ss,msmsms —> hh:mm:ss,msmsms
- Subtitle Text (one or more lines)
- …
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
&<and>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:
- J Playr – Supports: subtitles, chapters, some cue settings Browsers: Opera, Chrome, Safari, Firefox
- LeanBack Player – Supports: subtitles
Browsers: All major browsers with fallback to Flash if required - Captionator – Supports: subtitles, all cue settings Browsers: Opera, Chrome, Safari, Firefox, IE9
- MediaElementJS – Supports: subtitles (timing format uses SRT format)
Browsers: All major browsers with fallback to Flash if required
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.
<b>.
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">«</button>
<button id="ffwd" alt="fast forward" title="fast forward" tabindex="5">»</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!
learn, php, rss, tutorials
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 name of the plugin (the name that developers will use to initialize the plugin) is the first argument of the method
- an anonymous callback function is the second parameter. The function receives a reference to the current YUI instance.
- the third argument is the version number of the plugin and
- the fourth is an object listing any dependencies required by the plugin.
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:
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:
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!
learn, php, rss, tutorials
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
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.”
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.
learn, php, rss, tutorials
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
-
Create a Festive Cocktail Using Photoshop’s 3D Capabilities
For many of our readers, this time of year is filled with family, friends, and celebration. In this tutorial, we will explain how to create a festive cocktail using Photoshop’s 3D capabilities just in time for your New Year’s celebrations. Let’s get started!
-
Create a Dark, Conceptual Photo Manipulation With Stock Photography
In this tutorial we will be teaching how to integrate elements from different sources to create a realistic photo manipulation with dark and conceptual elements. You will learn some lighting and blending techniques as well as some interesting post-production tips. Let’s get started!
-
Create High-End Action Figure Packaging – Tuts + Premium Tutorial
With collectables, the packaging of the product is often as important as the craftsmanship of the product itself. In this two-part Tuts+ Premium tutorial, author Tim Kyde will explain how to create packaging for a high-end 1/6 scale action figure. Part 1 of this tutorial will explain how to shoot your own photography and create a print-ready outer sleeve and inner packaging for our action figure. This tutorial is available exclusively to Tuts+ Premium Members — Join Now to get started!
-
Wrangling with the Facebook Graph API
Have you ever wanted to learn how to make your applications more social with Facebook? It’s much easier than you think!
-
From Idea to Market: How We Built Gradient
Retracing the steps you’ve taken is a helpful way to understand how well you’ve executed your vision – whatever that might be. What could you have done better? What should have been avoided? Today, I’ll share what we’ve learned (and are still learning) while crafting Gradient. It’s an experience that has changed everything for us.
-
Should You Learn CoffeeScript?
I’d imagine that I represent a large portion of the web development community. I’m very intrigued by CoffeeScript; I’ve even learned the syntax and used it in a few demos. However, I haven’t yet taken the plunge and used it in a real project. It comes down to this one question for me: is CoffeeScript something that is truly worth investing time and effort into learning?
-
Outstanding Tutorials, Quick Tips, Articles and Interviews from Vectortuts+ in 2011
As the year comes to an end and we pack up our vector tools for some well deserved rest and relaxation, let’s take a look back at some of the best and most inspiring Vectortuts+ articles and tutorials for 2011.
-
Community Project: 2012 Calendar Design Project
Vectortuts+ loves Illustration and discovering new talent, so today we are proud to be launching a new community project that combines both, the Vectortuts+ 2012 Calendar Design Project. The best thing is, you can be a part of it! Find out how to get involved, at the jump.
-
Quick Tip: How to Create a Watercolor Background Using Adobe Illustrator
In this tutorial we will learn how to create Watercolor Background using a Gradient Mesh, tools of deformation and Blending Modes. The techniques which are described here allow the creation of complex textural backgrounds in a simple and effective way.
-
A Year in Web Design: How the Experts Saw 2011
“What did you find most memorable about the world of web design in 2011?” That’s the question I posed to some of our industry’s shining stars last week. One word cropped up more than any other (can you guess?) and everyone had plenty to say. See for yourself after the jump, and let us know what rocked your boat in 2011!
-
Get Into LESS: the Programmable Stylesheet Language
I don’t like CSS. Plain and simple. It makes the World go round on the web, yet the language is restrictive and hard to manage. It’s time to spruce up the language and make it more helpful by using dynamic CSS with the help of LESS.
-
Say Hello to the HTML Email Boilerplate
Figuring out html email will test the patience of any human being. A seemingly small formatting issue will inevitably arise and you think to yourself, “self, I’m a world class web developer type person schooled in the latest and greatest html5/css3/whatever, I can tackle this with plenty o’ keystrokes to spare.”
-
Tips to Get Started with Still Life Photography
There arent many photographic practices that date back further than still life photography. When photography originated, it was necessary for exposures to be quite long, so photographing static objects was the ideal subject matter. However, as the technology developed, the fascination for capturing still life has remained and is still one of the most viable photographic professions today.
-
Is It Worth It? Some Gear Buying Advice
A lot people believe their photography will improve “if only…” With the holidays approaching, a lot of avid wanna-be photographers, amateurs, and professionals will be making wish lists for gear that they erroneously believe will make them better photographers. There are many forums, YouTube videos, and articles pandering how camera/lens/light/brand/voodoo doll will make your photos better. Today, we’ll examine that idea.
-
Superb Photos of Paths and Stairways
“Follow the Yellow Brick Road,” an infamous movie quote inspired by a pathway to a land of dreams. Wherever your paths take you and whatever amount of stairs you have to climb, its always worth it to see whats at the end, but more importantly to enjoy the journey. Today’s collection gathers dozens of images of paths and stairways, images that symbolize something different to every person.
-
Freebie: Epic 3D Character Model Of Pyro From Team Fortress 2
Today we’re super excited to bring you this amazingly detailed character model from Cgtuts+ regular Shaun Keenan. Shaun has re-created “Pyro” from Valve’s hit game Team Fortress 2 in glorious detail, and is making the model available to the Cgtuts+ community for free!
-
Digital Matte Painting And Projection Basics: From Photoshop To Maya To Nuke, Part 1 – Tuts+ Premium
This Tuts+ Premium tutorial series covers a variety of basic techniques for both creating and projecting matte paintings using Photoshop, Maya and Nuke. The first part of the tutorial will cover how to approach the creation of a matte painting, the research and background knowledge you need, the concept, and finally starting to create your matte painting in Photoshop. Log in or Join Now to get started!
-
Create A Flying Paper Animation In 3D Studio Max With Thinking Particles
In this tutorial by Cristian Pop, you’ll learn how to create a nice flying papers effect in 3d Studio Max using the power of Thinking Particles. We’ll start by creating the paper shapes and materials, then move into Thinking Particles to set up the rules and look at how we can combine them to create the flying paper effect.
-
How To Track Footage That Is Out Of Focus
In this tutorial we are going to take a look at a simple, but interesting idea. The main point will be to show you how to work with footage that is out of focus making if difficult to track. After we track it we are going to attach the camera interface elements and fake some depth of field to create the illusion that they are floating in space and shift in and out of focus like the rest of the scene.
-
DIY – Create A Camera Dolly Completely From Scratch
Ever wonder how to get smooth footage from your video camera? Today you will learn how to build a Camera Dolly that will help you acquire this type of footage. Get out those dusty power tools, buy some cheap supplies at your local hardware store, and you’ll be on your way to capturing some amazing footage in no time!.
-
How To Create A Dr. Who Time And Space Vortex – Tutsplus Premium
In this tutorial well be creating a Time & Space Vortex (like that used in Doctor Who) completely inside of After Effects. We will be using Trapcode Particular and Trapcode Shine to create the vortex. I will then teach a vital Expression that drives the camera and completes the Effect. Once you have mastered the effect, you can personalize it to create whatever Time-Tunnel you desire! All of Time and Space awaits you…
-
Drum Compression: Get Your Attack and Release Times Correct
Compression can be a tricky one to get your head around, and even if you’ve got your head around the threshold and ratio settings without the attack and release times being set correctly it will always be difficult to get the desired effect. This quick tip will outline a really handy trick I learned from a friend a few years ago which allows you to get your attack and release times just right. It’s primarily designed to work on drums but the same principles will apply to any percussive sound.
-
Quick Tip: Punchier Drums with the New York Compression Trick
Ever have a mix where you wish the drums were bigger, more energetic, more in-your-face? I first heard about this technique in Bobby Owinksis, The Mixing Engineers Handbook, and it has since become a staple in my bag of tricks. The technique is a more aggressive take on parallel compression that can really add punch to your mix.
-
D Mixing Part 6: Depth
In this segment of our mix down tutorial, we are going to begin to look in depth into depth. Depth within any mix and listening situation is paramount to proper sonic understanding. Much like we see in 3D, we hear in 3D and taking out any one of these dimensions only serves to create a flat and unnatural sound. As such, the most common tools which give the illusion of depth (reverb and delay) become an important and necessary part of mixing.
-
Getting Started With EaselJS: A Flash-Like Interface for the HTML5 Canvas
There’s been some resistance from Flash developers to our new HTML5 content. In this article – aimed at experienced AS3 coders – we’ll look at EaselJS, a JavaScript library that makes working with the HTML5 canvas very similar to working with the Flash display list.
-
AS3 Quick Tip: Hacking the Event Flow
Sometimes you may find yourself needing to modify the behavior of a component for a user input event. This article will explain how to do so by modifying the event object in-flight, before it’s processed by the component. That’s right, you can lie and cheat. In code.
-
in Flash and Web Apps: A Retrospective
With the year 2011 at a close, it is time to reflect upon some of the major industry events of the year. A lot happened… we’ll pick out some of the bits and pieces that will be most interesting to browser app and game developers from the world of industry, web, runtimes, operating systems, mobile, and more!
-
WordPress 3.3 “Sonny” Is Finally Here! What’s New?
The latest and greatest version of the WordPress software — 3.3, named ’Sonny” in honor of the great jazz saxophonist Sonny Stitt — is immediately available for download or update inside your WordPress dashboard. We’ll be covering lots of the new features of 3.3 this week, but for now, go and great the latest version! As we’ve mentioned before, it’s the best way to keep your WordPress site safe and stable.
-
Getting Loopy – Ajax Powered Loops with jQuery and WordPress
In this tutorial, we give you a starting point for creating AJAX interaction in your blog. We follow a step by step process, showing you how to load posts based on the viewers page scroll. The tutorial covers enqueueing scripts, setting up an AJAX handler, how to get a file outside of WordPress to use WordPress functions and access the database, and logic for loading posts on user page scroll.
-
Saintly” Practices that All WordPress Developers Should Strive For
Here on Wptuts+, we talk a lot about the ‘how’ and less about the ‘why.’ Of course, we are a tutorial site, so that’s the goal, right? Well, as a followup to last month’s article on the “Cardinal Sins of WordPress Plugin Development“, today we’re going to look at a few practices that, if every developer followed, would make the world a better place (well, at least our world!).
-
Getting Started With Kindle Fire Development
The Kindle Fire is the new touchscreen and e-book reader from Amazon. This device has generated a lot of buzz, and for good reason! It is currently the best selling Android tablet, with millions of units already sold. This tutorial will teach you how to begin making apps with the Android SDK specifically targeted for the Kindle Fire.
-
iOS 5 SDK: Storyboards
Storyboarding is one of the most exciting new features about the iOS 5 SDK. Take a look at the wealth of functionality offered by Storyboards in today’s iOS 5 SDK tutorial!
-
Titanium Mobile: Build an Image Uploader
This tutorial will demonstrate how to build a custom progress bar by creating an image uploader with Titanium Mobile. Specifically, the demo project will allow you to select an image from the device photo gallery and upload it to a remote server for storage. Both the Titanium Mobile code and the server-side code will be explained. Now, let’s get started!
Nettuts+ — Web Development Tutorials
Vectortuts+ — Illustrator Tutorials
Webdesigntuts+ — Web Design Tutorials
Phototuts+ — Photography Tutorials
Cgtuts+ — Computer Graphics Tutorials
Aetuts+ — After Effects Tutorials
Audiotuts+ — Audio & Production Tutorials
Activetuts+ — Flash, Flex & ActionScript Tutorials
Wptuts+ — WordPress Tutorials
Mobiletuts+ — Mobile Development 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!
learn, php, rss, tutorials
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
- Sublime Text 2
- MacVim
- Zen Coding
- Package Control
- Alfred
- Snippets
- Nettuts+ Builder
- Nettuts+ Structurer
- Prefixr
- Prefix-free
- Git
- GitHub
- iTerm 2
- Chrome Autosave
- Stylus
- LiveReload
- CodeKit
- Transmit
learn, php, rss, tutorials
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:
- Determine what sorts of content you readers don’t enjoy as much.
- Get a birds eye view of how the site is performing. For example, 2011′s numbers, as a whole, are up 23% over 2010′s. That may not sound like much, but for us, that amounts to millions and millions of new visitors.
- Pinpoint which search queries are most popular. That way, I can be sure to commission appropriate tutorials.
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.
- Should You Learn CoffeeScript? Developers Sound Off.
- Are jQuery Users Fools?
- Is Conference Pricing Out of Control?
- Why Many Developers Hate ASP.NET…and Why They’re Wrong
- An Introvert Reflects On His First Presentation
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
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 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:
- Create a new “Publish” directory
- Compress all JavaScript files
- Compress all Stylesheets
- Concatenate all assets
- Optionally upload them, via FTP , to a designated folder on your server.
If you’ve found yourself manually compressing your files and uploading them to your server, this automates the entire process!
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:
- Always find yourself manually creating the same files and directories? Not anymore.
- Need to download the latest version of the CodeIgniter framework? Or how about WordPress? With Structurer, it can be done in two seconds!
- Need to assign custom text to new files – for example, adding a base plugin snippet to a JavaScript file? That’s a cinch in Structurer!
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.
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
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…
- Umms: I can’t help it; when a teacher speaks too many umms and ahhs, it drives me crazy. “Next we’re uhhhhhhh going to create this
div. - Massive Snippets: If you’re creating a screencast, your goal is to teach right? In that case, don’t paste twenty lines of code into the editor at a time. Many of the viewers will be working along; don’t flood them with unexplained code snippets. Write that stuff by hand, but…
- Wasting Time: Don’t make the viewer wait for you. A pet peeve of mine is watching a screencaster take 60 seconds to write a single line. You can edit these pauses out when you’re finished recording. For instance, rather than, over the course of twenty seconds, writing
document.getElementById('myElem');, simply say, “Next, we’re going to retrieve the element with anidofmyElem. Then, either immediately cut to the finished line, or speed up the video while you write it. It’s painful otherwise. - Teach, Fool: I’m amazed by how many people don’t make the connection that they should be teaching. A screencast is not a place to illustrate how smart and clever you are. Explain exactly what each line is doing; never assume that all viewers are on the same skill-level. In my videos, I often say, “I’m going to explain this section in more detail, but, if you already understand it, fast-forward a couple minutes in the video.”
- Audio Quality: My first videos were awful, and used the built-in microphone. Thankfully, I’ve come a long ways since then. If you enjoy creating video tutorials, please invest in a good microphone; it makes an enormous difference. In the last few months, I’ve switched to the Rode NTG. Highly recommended!
- Zooming: This is the worst of the bunch; especially for coding tutorials, don’t record at 600×400, and make the viewer dizzy every time your mouse moves from one side of your screen to the other, while the video recorder transitions left to right quickly. Instead, reduce the resolution of your monitor to around 1280×720, and record full screen.
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!
learn, php, rss, tutorials
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
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:
- Create TODO Items
- Read TODO Items
- Update TODO Items (rename, mark as done, mark as undone)
- Delete TODO Items
Each TODO item will have:
- a Title
- a Date Due
- a Description
- a flag to tell if the TODO Item Is Done
Let’s mockup the application as well so we have a guide on how it should look like afterwards:

SimpleTODO Mockup
Step 2: Create the API Server
Since we’re developing an API-Centric application, we’ll be creating two “projects”: the API Server, and the Front-end Client. Let’s begin by creating the API server first.
On your web server’s folder, create a folder named simpletodo_api, and create an index.php file. This index.php file will act as a front controller for the API, so all requests to the API server will be made through this file. Open it up and put the following code inside:
<?php
// Define path to data folder
define('DATA_PATH', realpath(dirname(__FILE__).'/data'));
//include our models
include_once 'models/TodoItem.php';
//wrap the whole thing in a try-catch block to catch any wayward exceptions!
try {
//get all of the parameters in the POST/GET request
$params = $_REQUEST;
//get the controller and format it correctly so the first
//letter is always capitalized
$controller = ucfirst(strtolower($params['controller']));
//get the action and format it correctly so all the
//letters are not capitalized, and append 'Action'
$action = strtolower($params['action']).'Action';
//check if the controller exists. if not, throw an exception
if( file_exists("controllers/{$controller}.php") ) {
include_once "controllers/{$controller}.php";
} else {
throw new Exception('Controller is invalid.');
}
//create a new instance of the controller, and pass
//it the parameters from the request
$controller = new $controller($params);
//check if the action exists in the controller. if not, throw an exception.
if( method_exists($controller, $action) === false ) {
throw new Exception('Action is invalid.');
}
//execute the action
$result['data'] = $controller->$action();
$result['success'] = true;
} catch( Exception $e ) {
//catch any exceptions and report the problem
$result = array();
$result['success'] = false;
$result['errormsg'] = $e->getMessage();
}
//echo the result of the API call
echo json_encode($result);
exit();
What we’ve essentially built here is a simple front controller that does the following:
- Accept an API call with any number of parameters
- Extract the
ControllerandActionfor the API call - Make the necessary checks to ensure that the
ControllerandActionexist - Execute the API call
- Catch errors, if any
- Send back a result to the caller
Besides the index.php file, create three folders: a controllers, models and data folder.
- The controllers folder will contain all the controllers we’ll be using for the API server. We’ll be building it using the MVC architecture to make the structure of the API server cleaner and more organized.
- The models folder will contain all the data models for the API server.
- The data folder will be where the API server saves any data
Go into the controllers folder and create a file called Todo.php. This will be our controller for any TODO list related tasks. With the functions we’ll be needing for our TODO application in mind, create the necessary methods for the Todo controller:
<?php
class Todo
{
private $_params;
public function __construct($params)
{
$this->_params = $params;
}
public function createAction()
{
//create a new todo item
}
public function readAction()
{
//read all the todo items
}
public function updateAction()
{
//update a todo item
}
public function deleteAction()
{
//delete a todo item
}
}
Now, add the necessary functionality to each action. I’ll provide the code for the createAction method and I’ll leave it up to you to create the code for the other methods. If you’re not in the mood though, you can just download the source code for the demo and copy it from there.
public function createAction()
{
//create a new todo item
$todo = new TodoItem();
$todo->title = $this->_params['title'];
$todo->description = $this->_params['description'];
$todo->due_date = $this->_params['due_date'];
$todo->is_done = 'false';
//pass the user's username and password to authenticate the user
$todo->save($this->_params['username'], $this->_params['userpass']);
//return the todo item in array format
return $todo->toArray();
}
Create TodoItem.php inside the models folder so we can create the “item creation” code. Take note that I won’t be connecting to a database, rather, I’ll be saving the information into files. It should be relatively easy though to make this work with any database.
<?php
class TodoItem
{
public $todo_id;
public $title;
public $description;
public $due_date;
public $is_done;
public function save($username, $userpass)
{
//get the username/password hash
$userhash = sha1("{$username}_{$userpass}");
if( is_dir(DATA_PATH."/{$userhash}") === false ) {
mkdir(DATA_PATH."/{$userhash}");
}
//if the $todo_id isn't set yet, it means we need to create a new todo item
if( is_null($this->todo_id) || !is_numeric($this->todo_id) ) {
//the todo id is the current time
$this->todo_id = time();
}
//get the array version of this todo item
$todo_item_array = $this->toArray();
//save the serialized array version into a file
$success = file_put_contents(DATA_PATH."/{$userhash}/{$this->todo_id}.txt", serialize($todo_item_array));
//if saving was not successful, throw an exception
if( $success === false ) {
throw new Exception('Failed to save todo item');
}
//return the array version
return $todo_item_array;
}
public function toArray()
{
//return an array version of the todo item
return array(
'todo_id' => $this->todo_id,
'title' => $this->title,
'description' => $this->description,
'due_date' => $this->due_date,
'is_done' => $this->is_done
);
}
}
The createAction method calls two functions on the TodoItem model:
- save() – this saves the
TodoIteminto a file, as well as set thetodo_idfor theTodoItemif necessary - toArray() – this returns an array version of the
TodoItem, where the variables are the array’s indexes
Since the API is called via HTTP requests, let’s test that API call by calling it through the browser:
If everything worked, you should see a new folder inside the data folder, and inside that folder, you should see a file with the following content:

createAction() result
Congratulations! You’ve successfully created an API server and made an API call!
Step 3: Secure the API Server with an APP ID and APP SECRET
Currently, the API server is set to accept ALL API requests. We’ll need to limit it to our own applications only, to ensure that only our own front-end clients are able to make API requests. Alternatively, you can actually create a system wherein users can create their own applications that have access to your API server, similar to how Facebook and Twitter applications work.
Begin by creating a set of id-key pairs for the clients that will be using the API server. Since this is just a demo, we can use any random, 32 character string. For the APP ID, let’s say it’s application APP001.
Open the index.php file again, and then update it with the following code:
<?php
// Define path to data folder
define('DATA_PATH', realpath(dirname(__FILE__).'/data'));
//Define our id-key pairs
$applications = array(
'APP001' => '28e336ac6c9423d946ba02d19c6a2632', //randomly generated app key
);
//include our models
include_once 'models/TodoItem.php';
//wrap the whole thing in a try-catch block to catch any wayward exceptions!
try {
//*UPDATED*
//get the encrypted request
$enc_request = $_REQUEST['enc_request'];
//get the provided app id
$app_id = $_REQUEST['app_id'];
//check first if the app id exists in the list of applications
if( !isset($applications[$app_id]) ) {
throw new Exception('Application does not exist!');
}
//decrypt the request
$params = json_decode(trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $applications[$app_id], base64_decode($enc_request), MCRYPT_MODE_ECB)));
//check if the request is valid by checking if it's an array and looking for the controller and action
if( $params == false || isset($params->controller) == false || isset($params->action) == false ) {
throw new Exception('Request is not valid');
}
//cast it into an array
$params = (array) $params;
...
...
...
What we’ve done here is actually implement a very simple way of authenticating our front-end clients using a system similar to public-private key authentication. Basically, here is the step-by-step breakdown of how the authentication happens:

Public-key encryption
- an API call is made, in it an $app_id and $enc_request is provided.
- the $enc_request value is the API call parameters, encrypted using
APP KEY. TheAPP KEYis NEVER sent to the server, it’s only used to hash the request. Additionally, the request can only be decrypted using theAPP KEY. - once the API call arrives to the API server, it will check its own list of applications for the
APP IDprovided - when found, the API server attempt to decrypt the request using the key that matches the
APP IDsent - if it was successful in decrypting it, then continue on with the program
Now that the API server is secured with an APP ID and APP SECRET, we can begin programming a front-end client to use the API server.
Step 4: Create the Browser Front-end Client
We’ll begin by setting up a new folder for the front-end client. Create a folder called simpletodo_client_browser on your web server’s folder. When that’s done, create an index.php file and put this code inside:
<!DOCTYPE html>
<html>
<head>
<title>SimpleTODO</title>
<link rel="stylesheet" href="css/reset.css" type="text/css" />
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui-1.8.16.custom.min.js"></script>
<style>
body {
padding-top: 40px;
}
#main {
margin-top: 80px;
text-align: center;
}
</style>
</head>
<body>
<div class="topbar">
<div class="fill">
<div class="container">
<a class="brand" href="index.php">SimpleTODO</a>
</div>
</div>
</div>
<div id="main" class="container">
<form class="form-stacked" method="POST" action="login.php">
<div class="row">
<div class="span5 offset5">
<label for="login_username">Username:</label>
<input type="text" id="login_username" name="login_username" placeholder="username" />
<label for="login_password">Password:</label>
<input type="password" id="login_password" name="login_password" placeholder="password" />
</div>
</div>
<div class="actions">
<button type="submit" name="login_submit" class="btn primary large">Login or Register</button>
</div>
</form>
</div>
</body>
</html>
That should look something like this:

SimpleTODO Login Page
Take note that I’ve included 2 JavaScript files and 2 CSS files here:
- reset.css is your standard CSS reset script. I use the meyerweb.com css reset.
- bootstrap.min.css is the Twitter Bootstrap
- jquery.min.js is the latest jQuery library
- jquery-ui-1.8.16.custom.min.js is the latest jQuery UI library
Next, let’s create the login.php file so we store the username and password inside a session on the client.
<?php
//get the form values
$username = $_POST['login_username'];
$userpass = $_POST['login_password'];
session_start();
$_SESSION['username'] = $username;
$_SESSION['userpass'] = $userpass;
header('Location: todo.php');
exit();
Here, we simply start a session for the user, based on the username and password combination the user will provide. This acts as a simple combination key, which will allow a user to access stored TODO items for a specific combination of both the username and password. We then redirect to todo.php, where we start interacting with the API server. Before we start coding the todo.php file though, let’s first create an ApiCaller class, which will encapsulate all the API calling methods we’ll need, including encrypting the requests.
Create apicaller.php and put the following inside:
<?php
class ApiCaller
{
//some variables for the object
private $_app_id;
private $_app_key;
private $_api_url;
//construct an ApiCaller object, taking an
//APP ID, APP KEY and API URL parameter
public function __construct($app_id, $app_key, $api_url)
{
$this->_app_id = $app_id;
$this->_app_key = $app_key;
$this->_api_url = $api_url;
}
//send the request to the API server
//also encrypts the request, then checks
//if the results are valid
public function sendRequest($request_params)
{
//encrypt the request parameters
$enc_request = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->_app_key, json_encode($request_params), MCRYPT_MODE_ECB));
//create the params array, which will
//be the POST parameters
$params = array();
$params['enc_request'] = $enc_request;
$params['app_id'] = $this->_app_id;
//initialize and setup the curl handler
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->_api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, count($params));
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
//execute the request
$result = curl_exec($ch);
//json_decode the result
$result = @json_decode($result);
//check if we're able to json_decode the result correctly
if( $result == false || isset($result['success']) == false ) {
throw new Exception('Request was not correct');
}
//if there was an error in the request, throw an exception
if( $result['success'] == false ) {
throw new Exception($result['errormsg']);
}
//if everything went great, return the data
return $result['data'];
}
}
We’ll be using the ApiCaller class to send requests to our API server. This way, all the necessary encryption and cURL initialization code will be in one place, and we won’t have to repeat our code.
-
the
__constructfunction takes in three parameters:- $app_id – the
APP IDfor the client (which is APP001 for the browser client) - $app_key – the
APP KEYfor the client (which is 28e336ac6c9423d946ba02d19c6a2632 for the browser client) - $api_url – the URL of the API server, which is
http://localhost/simpletodo_api/
- $app_id – the
-
the
sendRequest()function:- encrypts the request parameters using the
mcryptlibrary in the same manner that the API server decrypts it - generates the
$_POSTparameters to be sent to the API server - executes the API call via cURL
- checks the result of the API call was successful or not
- returns the data when everything went according to plan
- encrypts the request parameters using the
Now, let’s begin with the todo.php page. First off, let’s create some code to retrieve the current list of todo items for the user nikko with the password test1234 (this is the user/password combination we used earlier to test the API server).
<?php
session_start();
include_once 'apicaller.php';
$apicaller = new ApiCaller('APP001', '28e336ac6c9423d946ba02d19c6a2632', 'http://localhost/simpletodo_api/');
$todo_items = $apicaller->sendRequest(array(
'controller' => 'todo',
'action' => 'read',
'username' => $_SESSION['username'],
'userpass' => $_SESSION['userpass']
));
echo '';
var_dump($todo_items);
Go to the index.php page, login as nikko/test1234, and you should see a var_dump() of the TODO item we created earlier.
Congratulations, you’ve successfully made an API call to the API server! In this code, we’ve:
- started the session so we have access to the
usernameanduserpassin the$_SESSION - instantiated a new
ApiCallerclass, giving it theAPP ID,APP KEYand the URL of the API server - send a request via the
sendRequest()method
Now, let’s reformat the data so it looks better. Add the following HTML to the todo.php code. Don’t forget to remove the var_dump()!
<!DOCTYPE html>
<html>
<head>
<title>SimpleTODO</title>
<link rel="stylesheet" href="css/reset.css" type="text/css" />
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="css/flick/jquery-ui-1.8.16.custom.css" type="text/css" />
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui-1.8.16.custom.min.js"></script>
<style>
body {
padding-top: 40px;
}
#main {
margin-top: 80px;
}
.textalignright {
text-align: right;
}
.marginbottom10 {
margin-bottom: 10px;
}
#newtodo_window {
text-align: left;
display: none;
}
</style>
<script>
$(document).ready(function() {
$("#todolist").accordion({
collapsible: true
});
$(".datepicker").datepicker();
$('#newtodo_window').dialog({
autoOpen: false,
height: 'auto',
width: 'auto',
modal: true
});
$('#newtodo').click(function() {
$('#newtodo_window').dialog('open');
});
});
</script>
</head>
<body>
<div class="topbar">
<div class="fill">
<div class="container">
<a class="brand" href="index.php">SimpleTODO</a>
</div>
</div>
</div>
<div id="main" class="container">
<div class="textalignright marginbottom10">
<span id="newtodo" class="btn info">Create a new TODO item</span>
<div id="newtodo_window" title="Create a new TODO item">
<form method="POST" action="new_todo.php">
<p>Title:<br /><input type="text" class="title" name="title" placeholder="TODO title" /></p>
<p>Date Due:<br /><input type="text" class="datepicker" name="due_date" placeholder="MM/DD/YYYY" /></p>
<p>Description:<br /><textarea class="description" name="description"></textarea></p>
<div class="actions">
<input type="submit" value="Create" name="new_submit" class="btn primary" />
</div>
</form>
</div>
</div>
<div id="todolist">
<?php foreach($todo_items as $todo): ?>
<h3><a href="#"><?php echo $todo->title; ?></a></h3>
<div>
<form method="POST" action="update_todo.php">
<div class="textalignright">
<a href="delete_todo.php?todo_id=<?php echo $todo->todo_id; ?>">Delete</a>
</div>
<div>
<p>Date Due:<br /><input type="text" id="datepicker_<?php echo $todo->todo_id; ?>" class="datepicker" name="due_date" value="12/09/2011" /></p>
<p>Description:<br /><textarea class="span8" id="description_<?php echo $todo->todo_id; ?>" class="description" name="description"><?php echo $todo->description; ?></textarea></p>
</div>
<div class="textalignright">
<?php if( $todo->is_done == 'false' ): ?>
<input type="hidden" value="false" name="is_done" />
<input type="submit" class="btn" value="Mark as Done?" name="markasdone_button" />
<?php else: ?>
<input type="hidden" value="true" name="is_done" />
<input type="button" class="btn success" value="Done!" name="done_button" />
<?php endif; ?>
<input type="hidden" value="<?php echo $todo->todo_id; ?>" name="todo_id" />
<input type="hidden" value="<?php echo $todo->title; ?>" name="title" />
<input type="submit" class="btn primary" value="Save Changes" name="update_button" />
</div>
</form>
</div>
<?php endforeach; ?>
</div>
</div>
</body>
</html>
It should now look something like this:
Pretty cool huh? But this currently does nothing, so let’s begin adding some functionality. I’ll provide the code for new_todo.php, which will call the todo/create API call to create a new TODO item. Creating the other pages (update_todo.php and delete_todo.php) should be very similar to this one, so I’ll leave it up to you to create those. Open up new_todo.php and add the following code:
<?php
session_start();
include_once 'apicaller.php';
$apicaller = new ApiCaller('APP001', '28e336ac6c9423d946ba02d19c6a2632', 'http://localhost/simpletodo_api/');
$new_item = $apicaller->sendRequest(array(
'controller' => 'todo',
'action' => 'create',
'title' => $_POST['title'],
'due_date' => $_POST['due_date'],
'description' => $_POST['description'],
'username' => $_SESSION['username'],
'userpass' => $_SESSION['userpass']
));
header('Location: todo.php');
exit();
?>
As you can see, the new_todo.php page uses the ApiCaller again to facilitate the sending the todo/create request to the API server. This basically does the same thing as before:
- start a session so it has access to the
$usernameand$userpasssaved in the$_SESSION - instantiate a new
ApiCallerclass, giving it theAPP ID,APP KEYand the URL of the API server - send the request via the
sendRequest()method - redirect back to
todo.php
Congratulations, it works! You’ve successfully created an API-centric application!
Conclusion
There are so many advantages to developing an application that’s built around an API. Want to create an Android application version of SimpleTODO? All the functionality you would need is already in the API server, so all you need to do is just create the client! Want to refactor or optimize some of the classes? No problem — just make sure the output is the same. Need to add more functionality? You can do it wihtout affecting any of the client’s code!
Though there are some disadvantages like longer development times or more complexity, the advantages of developing a web application in this manner greatly outweight the disadvantages. It’s up to us to leverage on this kind of development today so we can reap the benefits later on.
Are you planning to use an API server for your next web application, or have you already used the same technique for a project in the past? Let me know in the comments!
learn, php, rss, tutorials
PHP Tutorials | No Comments »
Create a Scalable Widget Using YUI3: Part 3
Wednesday, December 28th, 2011
In the last part of this series, we looked at the life-cycle methods, automatic methods and the custom methods that our widget requires or can make use of. In this part, we’re going to finish defining the widget’s class by adding the attribute change-handling methods that we attached in the bindUI() life-cycle method.
Let’s get started right away!
Attribute Change Handlers
The attribute change-handling group of methods are called when some of our attributes change values. We’ll start by adding the method that is called when the showTitle attribute changes; add the following code directly after the _uiSetTitle() method:
_afterShowTitleChange: function () {
var contentBox = this.get("contentBox"),
title = contentBox.one(".yui3-tweetsearch-title");
if (title) {
title.remove();
this._titleNode = null;
} else {
this._createTitle();
}
},
We first get a reference to the contentBox, and then use this to select the title node. Remember this is the container in which reside the title and subtitle in the header of the widget.
If the title node already exists, we remove it using YUI’s remove() method. We also set the _titleNode of the widget to null. If the node doesn’t exist, we simple call the _createTitle() method of our widget to generate and display it.
Next we can handle the showUI attribute changing:
_afterShowUIChange: function () {
var contentBox = this.get("contentBox"),
ui = contentBox.one(".yui3-tweetsearch-ui");
if (ui) {
ui.remove();
this._uiNode = null;
} else {
this._createSearchUI();
}
},
This method is almost identical to the last one — all that changes is that we are looking for the change of a different attribute, and either removing or creating a different group of elements. Again, we set the _uiNode property of our widget to null, so that the widget is aware of the latest state of its UI.
Our next method is called after the term attribute changes:
_afterTermChange: function () {
this._viewerNode.empty().hide();
this._loadingNode.show();
this._retrieveTweets();
if (this._titleNode) {
this._uiSetTitle(this.get("term"));
}
},
When the term attribute changes, we first remove any previous search results from the viewer by calling YUI’s (specifically the Node module’s) empty() method followed by the hide() method. We also show our loader node for some visual feedback that something is happening.
We then call our _retrieveTweets() method to initiate a new request to Twitter’s search API. This will trigger a cascade of additional methods to be called, that result ultimately in the viewer being updated with a new set of tweets. Finally, we check whether the widget currently has a _titleNode, and if so we call the _uiSetTitle() method in order to update the subtitle with the new search term.
Our last attribute change-handler is by far the largest and deals with the tweets attribute changes, which will occur as a result of the request to Twitter being made:
_afterTweetsChange: function () {
var x,
results = this.get("tweets").results,
not = this.get("numberOfTweets"),
limit = (not > results.length - 1) ? results.length : not;
if (results.length) {
for (x = 0; x < limit; x++) {
var tweet = results[x],
text = this._formatTweet(tweet.text),
tweetNode = Node.create(Y.substitute(TweetSearch.TWEET_TEMPLATE, {
userurl: "http://twitter.com/" + tweet.from_user, avatar: tweet.profile_image_url,
username: tweet.from_user, text: text
}));
if (this.get("showUI") === false && x === limit - 1) {
tweetNode.addClass("last");
}
this._viewerNode.appendChild(tweetNode);
}
this._loadingNode.hide();
this._viewerNode.show();
} else {
var errorNode = Node.create(Y.substitute(TweetSearch.ERROR_TEMPLATE, {
errorclass: TweetSearch.ERROR_CLASS,
message: this.get("strings").errorMsg
}));
this._viewerNode.appendChild(errorNode);
this._loadingNode.hide();
this._viewerNode.show();
}
},
First up, we set the variables we’ll need within the method including a counter variable for use in the for loop, the results array from the response that is stored in the tweets attribute, the value of the numberOfTweets attribute and the limit, which is either the number of results in the results array, or the configured number of tweets if there are fewer items in the array than the number of tweets.
The remaining code for this method is encased within an if conditional which checks to see if there are actually results, which may not be the case if there were no tweets containing the search term. If there are results in the array, we iterate over each of them using a for loop. On each iteration, we get the current tweet and pass it to a _formatTweet() utility method that will add any links, usernames or hash tags found within the text, and then create a new node for the tweet using the same principles that we looked at in the last part of this tutorial.
When the searchUI is not visible, we should alter the styling of the widget slightly to prevent a double border at the bottom of the widget. We check whether the showUI attribute is set to false, and is the last tweet being processed, and if so add the class name last to the tweet using YUI’s addClass() method. We then add the newly created node to the viewer node to display it in the widget.
After the for loop has completed, we hide the loading node, which will at this point be visible having already been displayed earlier on, and then show the viewer node.
If the results array does not have a length, it means that the search did not return any results. In this case, we create an error node to display to the user and append it to the viewer node, then hide the loading node and show the viewer node as before.
A Final Utility Method
We’ve added all of the methods that support changing attribute values. At this point, we have just one further method to add; the _formatTweet() method that we reference from the within the for loop of the method we just added. This method is as follows:
_formatTweet: function (text) {
var linkExpr = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,
atExpr = /(@[\w]+)/g,
hashExpr = /[#]+[A-Za-z0-9-_]+/g,
string = text.replace(linkExpr, function (match) {
return match.link(match);
});
string = string.replace(atExpr, function (match) {
return match.link("http://twitter.com/" + match.substring(1));
});
string = string.replace(hashExpr, function (match) {
return match.link("http://twitter.com/search?q=" + encodeURI(match));
});
return string;
}
This method accepts a single argument, which is the text from the ‘current’ item of the results array that we want to linkify/atify/hashify. We start by defining three regular expressions, the first will match any links within the text that start with http, https or ftp and contain any characters that are allowed within URLs. The second will match any Twitter usernames (any strings that start with the @ symbol), and the last will match any strings that start with the # symbol.
We then set a variable called string which is used to contain the transformed text. First, we add the links. JavaScript’s replace() function accepts the regular expression for matching links as the first argument and a function as the second argument — the function will be executed each time a match is found and is passed the matching text as an argument. The function then returns the match having converted it to a link element using JavaScript’s link() function. This function accepts a URL that is used for the href of the resulting link. The matching text is used for the href.
We then use the replace() function on the string once again, but this time we pass in the @ matching regular expression as the first argument. This function works in the same way as before, but also adds Twitter’s URL to the start of the href that is used to wrap the matching text. The string variable is then operated on in the same way to match and convert any hashed words, but this time Twitter’s search API URL is used to create the link(s). After the text has been operated on, we return the resulting string.
This brings us to the end of our widget’s class; at this point we should have an almost fully functioning widget (we haven’t yet added the paging, this will be the subject of the next and final instalment in this series). We should be able to run the page and get results:
Styling the Widget
We should provide at least 2 style sheets for our widget; a base style sheet that contains the basic styles that the widget requires in order to display correctly, and a theme style sheet that controls how the widget appears visually. We’ll look at the base style sheet first; add the following code to a new file:
.yui3-tweetsearch-title { padding:1%; }
.yui3-tweetsearch-title h1, .yui3-tweetsearch-title h2 { margin:0; float:left; }
.yui3-tweetsearch-title h1 { padding-left:60px; margin-right:1%; background:url(/img/logo.png) no-repeat 0 50%; }
.yui3-tweetsearch-title h2 { padding-top:5px; float:right; font-size:100%; }
.yui3-tweetsearch-content { margin:1%; }
.yui3-tweetsearch-viewer article, .yui3-tweetsearch-ui { padding:1%; }
.yui3-tweetsearch-viewer img { width:48px; height:48px; margin-right:1%; float:left; }
.yui3-tweetsearch-viewer h1 { margin:0; }
.yui3-tweetsearch-label { margin-right:1%; }
.yui3-tweetsearch-input { padding:0 0 .3%; margin-right:.5%; }
.yui3-tweetsearch-title:after, .yui3-tweetsearch-viewer article:after,
.yui3-tweetsearch-ui:after { content:""; display:block; height:0; visibility:hidden; clear:both; }
Save this style sheet as tweet-search-base.css in the css folder. As you can see, we target all of the elements within the widget using the class names we generated in part one. There may be multiple instances of the widget on a single page and we don’t want our styles to affect any other elements on the page outside of our widget, so using class names in this way is really the only reliable solution.
The styling has been kept as light as possible, using only the barest necessary styles. The widget has no fixed width and uses percentages for things like padding and margins so that it can be put into any sized container by the implementing developer.
Next, we can add the skin file; add the following code in another new file:
.yui3-skin-sam .yui3-tweetsearch-content { border:1px solid #A3A3A3; border-radius:7px; }
.yui3-skin-sam .yui3-tweetsearch-title { border-bottom:1px solid #A3A3A3; border-top:1px solid #fff; background-color:#EDF5FF; }
.yui3-skin-sam .yui3-tweetsearch-title span { color:#EB8C28; }
.yui3-skin-sam .yui3-tweetsearch-loader, .yui3-skin-sam .yui3-tweetsearch-error { padding-top:9%; margin:2% 0; color:#EB8C28; font-weight:bold; text-align:center; background:url(/img/ajax-loader.gif) no-repeat 50% 0; }
.yui3-skin-sam .yui3-tweetsearch-error { background-image:url(/img/error.png); }
.yui3-skin-sam .yui3-tweetsearch article { border-bottom:1px solid #A3A3A3; border-top:2px solid #fff; background:#f9f9f9; background:-moz-linear-gradient(top, #f9f9f9 0%, #f3f3f3 100%, #ffffff 100%); background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f9f9f9), color-stop(100%,#f3f3f3), color-stop(100%,#ffffff)); background:-webkit-linear-gradient(top, #f9f9f9 0%,#f3f3f3 100%,#ffffff 100%); background:-o-linear-gradient(top, #f9f9f9 0%,#f3f3f3 100%,#ffffff 100%); background:-ms-linear-gradient(top, #f9f9f9 0%,#f3f3f3 100%,#ffffff 100%); background:linear-gradient(top, #f9f9f9 0%,#f3f3f3 100%,#ffffff 100%); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#ffffff',GradientType=0); }
.yui3-skin-sam .yui3-tweetsearch article.last { border-bottom:none; }
.yui3-skin-sam .yui3-tweetsearch a { color:#356DE4; }
.yui3-skin-sam .yui3-tweetsearch a:hover { color:#EB8C28; }
.yui3-skin-sam .yui3-tweetsearch-ui { border-top:1px solid #fff; background-color:#EDF5FF; }
Save this file as tweet-search-skin.css in the css folder. Although we also use our generated class names here, each rule is prefixed with the yui3-skin-sam class name so that the rules are only applied when the default Sam theme is in use. This makes it very easy for the overall look of the widget to be changed. This does mean however that the implementing developer will need to add the yui3-skin-sam class name to an element on the page, usually the , but this is likely to be in use already if other modules of the library are being used.
Like before, we’ve added quite light styling, although we do have a little more freedom of expression with a skin file, hence the subtle niceties such as the rounded-corners and css-gradients. We should also recommended that the css-reset, css-fonts and css-base YUI style sheets are also used when implementing our widget, as doing so is part of the reason the custom style sheets used by the widget are nice and small.
Implementing the Widget
Our work as widget builders is complete (for now), but we should spend a little while looking at how the widget is actually used. Create the following HTML page in your text editor:
<!DOCTYPE html>
<html lang="en">
<head>
<title>YUI3 Twitter Search Client</title>
<link rel="stylesheet" href="http://yui.yahooapis.com/combo?3.4.1/build/cssreset/cssreset-min.css&3.4.1/build/cssfonts/cssfonts-min.css&3.4.1/build/cssbase/cssbase-min.css">
<link rel="stylesheet" href="css/tweet-search-base.css" />
<link rel="stylesheet" href="css/tweet-search-skin.css" />
</head>
<body class="yui3-skin-sam">
<div id="ts"></div>
<script src="//yui.yahooapis.com/3.4.1/build/yui/yui-min.js"></script>
<script src="js/tweet-search.js"></script>
<script>
YUI().use("tweet-search", function (Y) {
var myTweetSearch = new Y.DW.TweetSearch({
srcNode: "#ts"
});
myTweetSearch.render();
});
</script>
</body>
</html>
The only YUI script file we need to link to is the YUI seed file which sets up the YUI global object and loads the required modules.
Save this file in the root project directory. First of all we link to the CDN hosted YUI reset, base and fonts combined style sheet, as well as our two custom style sheets that we just created. We also add the yui3-skin-sam class name to the of the page to pick up the theme styling for our widget. On the page, we add a container for our widget and give it an id attribute for easy selecting.
The only YUI script file we need to link to is the YUI seed file; this file sets up the YUI global object and contains the YUI loader which dynamically loads the modules required by the page. We also link to our plugin’s script file, of course.
Within the final script element we instantiate the YUI global object and call the use() method specifying our widget’s name (not the static NAME used internally by our widget, but the name specified in the add() method of our widget’s class wrapper) as the first argument.
Each YUI instance is a self-contained sandbox in which only the named modules are accessible.
The second argument is an anonymous function in which the initialisation code for our widget is added. This function accepts a single argument which refers to the current YUI instance. We can use any number of YUI objects on the page, each with its own modules. Each YUI instance is a self-contained sandbox in which only the named modules (and their dependencies) are accessible. This means we can have any number of self-contained blocks of code, all independent from each other on the same page.
Within the callback function, we create a new instance of our widget stored in a variable. Our widget’s constructor is available via the namespace we specified in the widget’s class, which is attached to the YUI instance as a property. Our widget’s constructor accepts a configuration object as an argument; we use this to specify the container that we want to render our widget into, in this case the empty <div> we added to the page. The specified element will become the contentBox of our widget. Finally, we call the render() method on the variable our widget instance is stored in, which renders the HTML for our widget into the specified container.
In the configuration object, we can override any of the default attributes of our widget, so if we wanted to disable the title of the widget and the search UI, we could pass the following configuration object into our widget’s constructor:
{
srcNode: "#ts",
showTitle: false,
showUI: false
}
I mentioned in an earlier part of the widget that by including all of the text strings used by the widget in an attribute, we could easily enable extremely easy internationalization. To render the widget in Spanish, for example, all we need to do is override the strings attribute, like this:
{
srcNode: "#ts",
strings: {
title: "Twitter Search Widget",
subTitle: "Mostrando resultados de:",
label: "Término de búsqueda",
button: "Búsqueda",
errorMsg: "Lo siento, ese término de búsqueda no ha obtenido ningún resultado. Por favor, intente un término diferente"
}
}
Now when we run the widget, all of the visible text (aside from the tweets of course) for the widget is in Spanish:
Summary
In this part of the tutorial, we completed our widget by adding the attribute change-handling methods and a small utility method for formatting the flat text of each tweet into mark-up. We also looked at the styling required by our widget and how the styles should be categorized, i.e. whether they are base styles or skin styles.
We also saw how easy it is to initialise and configure the widget and how it can easily be converted into display in another language. In the next part of this tutorial, we’ll look at a close relative to the widget – the plugin and add a paging feature to our widget.
learn, php, rss, tutorials
PHP Tutorials | No Comments »
10 New Year’s Resolutions Every Web Developer Should Make
Tuesday, December 27th, 2011
In less than a week, we’ll be in 2012. I know it’s a cliché, but where has the year gone? Naturally, we’re now at the time of year when folks set goals for the new year. While you might have some goals for your “real” life, how about a few resolutions for your developer life?
1 - Learn a New Language, Framework, Or Methodology
We must continue learning about the latest technologies.
About the only constant when it comes to developing for the web is change. Take NodeJS, for example: two or three years ago, it didn’t exist, and there was very little (if any) JavaScript being done on the server. Now, you can’t get away from it. Every web developer wants to stay on top of their game. To do so, we must continue learning about the latest technologies. If you’re a back-end dev, that could mean learning JavaScript and Node.js. It could mean taking up Ruby and Rails. For the front-end developer, that could mean really grokking CSS3, or understanding the new HTML5 APIs. Of course, that doesn’t mean you have to use it regularly; just keep yourself learning.
Along the same lines, now is as good a time as ever to re-evaluate your workflow, and learn better and different tools to get the job done more quickly.
2 - Get Better At What You Know
Set aside some time to also focus on existing languages and software.
Of course, staying sharp means more than learning new things. It also refers to improving in your use of your daily tools. I know I’ve been guilty of sticking with the patterns and methods that I’m comfortable with, and not learning new ones that might be better for a given situation. How knowledgeable are you about JavaScript design patterns? Do you have a solid understanding of object-oriented and functional programming in PHP? Have you used SQL joins? Are there any features your text editor offers that you aren’t using? These aren’t new technologies, but, if you aren’t using them, they’re new to you! Set aside some time to also focus on existing languages and software.
3 - Explore a New Field
This resolution is a different twist on the first one. Learning a new language, framework, or methodology in your own field is great, and might even be useful to your daily practice. But if you’re like me, you’re fascinated with every part of the web. Try exploring new fields. Back-end devs: look into front-end development. Front-ends, explore usability or user experience more than you have before. If you enjoy writing, you might be interested in content strategy, or fostering that design flare. There are dozens of fields on the web; explore!
4 - Engage the Community
Call it engaging, call it networking, call it whatever your want.
The web is a pretty incredible place: I can’t think of any other phenomenon that has ever made such strong friendships between people so far apart. In 2012, why don’t you try to engage this group of amazing people a bit more? Talk to them on Twitter; read their blog posts and comment or write your own articles in response; contribute to their code via Github, or another code-sharing site. Or, go to meet-ups, user groups and conferences. Call it engaging, call it networking, call it whatever your want; but one thing’s for sure: it will (in most cases) benefit both you and the other person. In addition to building great personal relationships, you’ll likely gain new referrals!
5 - Teach Others
The most beneficial comments are the ones that hurt your feelings.
Going hand-in-hand with our previous point, you should resolve to teach others more in 2012. Why? Well, how does it go, “Teaching something is the best way to learn it”? I’ve been writing for Nettuts+ for close to three years, and I can attest that that statement is completely true. Writing down exactly how a concept works forces you to understand it completely; you’ll be surprised how much you’ll learn about your topic when you try to teach it. On top of that, there’s the incredible feeling you get when you know that you’ve helped someone learn a new skill set.
Undoubtedly, you’ll face a few trolls, pointing out legitimate mistakes ( or just making stabby comments). Not to worry (too much); teaching is a learning process, and you’ll improve the more you do it. The most beneficial comments are the ones that hurt your feelings.
6 - Take Better Care Of Yourself
We are the martyrs of the web.
We web developers seem to pride ourselves on our dedication to our craft. We’ll work long hours, hunched over a computer in the dark, so absorbed in our work that we forget to shower or eat. We are the martyrs of the web, suffering to make the internet a better place.
Sounds heroic, but it really isn’t.
At the risk of mommying you, I’m going to suggest that you take care of yourself in 2012. Besides sleeping and eating well, make sure your workplace is ergonomic. It stands to reason that, if you spend a third of your life in your office, it might make sense to make it as comfortable as possible!
7 - Manage Your Time (and Other Resources) Better
Over 1 trillion videos were watched on Youtube this past year.
Perhaps this isn’t specificly related to web developers, but it is, nonetheless, something that almost every “knowledge worker” can afford to get better at. For a lot of us—especially freelancers—what you’re doing with your time could be the difference between feasting and fasting. Remember all those fun, new web technologies I recommended you learn about? Well, don’t let their lure limit your bacon-bringing hours to few and far between. Of coures, the internet at large can be just as much of a distraction. I’m sure you saw this recently; it gave pause when I did:
Assuming that the average YouTube video is 2 – 3 minutes long, we’re looking at something to the tune of one whole day. Something tells me I’m not much better off for it.
Of course, “all work, no play” and all that, right? I’m not suggesting you be a slave to your clients, or an unbearably dull workaholic. I’m merely stating that we would all be wise to track exactly where our hours are going and make an effort to use them a little better.
8 - Use Better Programming Practices
I don’t think you’ll ever have an issue with over-documentation.
No, I’m not repeating resolution two in different words. This time, I’m talking about the practices that surround the actual coding itself. I can’t tell you how many times I’ve eagerly started a new project, and—half an hour later—said, “Hmmm . . . I should create a branch to try this feature. Oh, wait, I forgot to initialize Git when I started . . .” Making sure I remember to use code versioning from the beginning is something I’m going to be working on in 2012; it keeps your project history so much cleaner.
Another meta-coding practice I usually neglect (to my detriment) is commenting. I’ll conjure up a few clever lines of code, and be tickled for the rest of the day. Next week, I’ll return and spend twenty minutes trying to figure out what it does. This plagues you too? Do yourself a favor and leave useful comments to yourself, and others. Documentation is right along the same lines as commenting. When I was recently learning Dojo, I found its in-code documentation to be invaluable. Of course, the level of documentation will depend on the publicity of your project, but I don’t think you’ll ever have an issue with over-documentation.
9 - Generate Passive Income
I’m guessing that most of the Nettuts+ audience performs client work, either as a freelancer or otherwise. Well why not make some passive income on the side? Envato has ten (count `em!) marketplaces where anyone with the right skills can profit. Build a theme for Themeforest, write a script for CodeCanyon, the possibilities are close to endless. Of course, if your skills don’t trade on the Envato marketplaces—or even if they do—there are bunches of other ways to make passive income. If you’re a writer, for example, check out Tuts+ Premium. They’re always looking for new passionate teachers.
The manager of Tuts+ Premium, Skellie, recently opened the Passive Income Author blog, where you’ll find great information on self-publishing.
Selling items on a marketplace or personal website is a brilliant way to passively make some extra cash while still doing exactly what you enjoy.
10 - Take a Break
Put on a completely different hat… sometimes
So far, every resolution has been something you can do to improve your craft as a developer. I’ll close by noting that one of the best things you can do to become a better developer is to not be a developer . . . sometimes. Put on a completely different hat… sometimes. Keep another hobby that’s not even tangentially related to development, and, preferably, doesn’t involve computers. Some play an instrument, some read, some write, some cook. Whatever you do, set aside some get-away time. When you do so, you’ll find that solutions to programming problems often show up on during time off.
Certainly, regular breaks are important, but so are those longer, couple-times-a-year vacation / holiday breaks. Throw a few of those in your annual schedule as well!
Your Resolutions?
Well, that’s my list of ten resolutions all web developers should make. Have any of your own that aren’t on my list? Let’s hear them in the comments!
learn, php, rss, tutorials
PHP Tutorials | No Comments »
Recently in Web Development (December Edition)
Monday, December 26th, 2011
Web development is an industry that’s in a state of constant flux with technologies and jargon changing and mutating in an endless cycle. Not to mention the sheer deluge of information one has to process everyday.
In this series, published monthly, we’ll seek to rectify this by bringing you all the important news, announcements, releases and interesting discussions within the web development industry in a concise package. Join me after the jump!
News and Releases
All of the important news in a single place: releases, announcements, companies bickering, security issues and all related hoopla.

Chrome Overtakes Firefox Globally for First Time
I admit I saw this coming but never so quickly. Chrome has overtaken Firefox in global marketshare. Chrome accounts for 25.69% of the user pie while Firefox is at 25.23%.
Chrome’s number has been increasing lately, overtaking Firefox in the UK, for example. This month, though, sees it leading Firefox for the first time on a global scale. Congrats to the Chrome team!

Facebook Creates HipHop VM to Improve Performance with PHP
It’s no secret that Facebook utilizes PHP on the backend to serve its multi-billion pageviews a month service. PHP’s ease of use has also lead to dismal performance and inability to scale.
In the past, Facebook resorted to optimizing the Zend engine but later went with creating their own PHP interpreter. The new HipHop VM is just another step towards making their PHP codebase run faster.

SOPA Protests Wash Over the Internet
I don’t wish to editorialize the contents and ramifications of SOPA so it’s best you read up on the Wikipedia page linked below.
Internet users and services worldwide, however, have organized widespread protests in opposition of this bill with the backing of internet giants like the Wikimedia foundation and Mozilla. If you live in the US, do write to your local representatives!

Dojo 1.7 Released
Version 1.7 of Dojo got released early this month with substantial improvements including a lot of API changes under the hood.
Make sure to hit the link below for more information. And if you’re looking to gain mastery over Dojo, make sure to check out our session on the topic.

SproutCore 2.0 Gets Renamed. And Renamed Again, For Good Measure
I love Sproutcore and tend to use it in a lot of my experiments. The framework has been moving steadily towards version 2.0 and was renamed to Amber.js in the process. Due to a naming collision, with Smalltalk people no less, SproutCore 2.0 is now officially Ember.js
If you’re curious as to the rationale behind all this renaming, you can find a lot more at the link below.

WordPress 3.3 is Now Live
The WordPress juggernaut rolls on with version 3.3 codenamed ‘Sonny’. The version ships with, to quote the devs themselves, “significant polish around the new user experience, navigation, uploading, and imports”.
WP.Tuts+ has a great overview of the new version, if you’re interested. Also, remember to check out the sweet, short video at the link below.

Sencha Fiddle is Out
Sencha Fiddle is an IDE that lets you start creating mobile applications through your browser. Even though it’s not finished yet, the features already in place are great and work well.

Rails Hits 4.0 Beta
The Rails master branch has officially hit the 4.0 beta mark. Big changes here include dropping support for Ruby 1.8.7. If you’re running the older version of Ruby, stick to the 3.x branch and hang tight for 3.2 to be released!

Arduino 1.0 Released
And to get slightly nerdy, Arduino has finally hit version 1.0. If you’re unsure as to what Arduino is, it’s a microcontroller which you can program through the Arduino environment.
Version 1 brings a lot of changes including API changes, new classes and much more. You can get to the release notes directly here.
New Kids on the Block
As web developers, the sheer amount of resources we can tap into increases exponentially with time. Here is just a quick look at some recently created resources that deserve your attention — everything from new books to scripts and frameworks.

stopcensorship.js
Use this script on your site to protest censorship of the Internet.
After the page is loaded the script randomly censors text on the page by replacing the text with black bars. It also places a black bar at the top of the page with a link to http://americancensorship.org/. Viewers can remove censoring for the current session by clicking on the “Remove this” link.

Sinatra::Synchrony
Sinatra::Synchrony is a small extension for Sinatra that dramatically improves the concurrency of your web application. Powered by EventMachine and EM-Synchrony, it increases the number of clients your application can serve per process when you have a lot of traffic and slow IO calls (like HTTP calls to external APIs).

jQuery Gantt Chart
jQuery Gantt Chart is a simple chart that implements gantt functionality as
a jQuery component. It’s able to page results and read JSON data amongst a ton of other features.

Create
Create, from the Midgard Project is a comprehensive web editing interface for Content Management Systems. It is designed to provide a modern, fully browser-based HTML5 environment for managing content. Create can be adapted to work on almost any content management backend.

Rickshaw
Rickshaw is a JavaScript toolkit for creating interactive time series graphs.

nanoScroller.js
nanoScroller.js is a jQuery plugin that offers a simplistic way of implementing Lion-styled scrollbars for your website. It uses minimal HTML markup and the latest version utilizes native scrolling and works with the iPad, iPhone, and some Android Tablets.

bootbox.js
Enter bootbox.js – alert() and confirm() like behaviour using twitter’s modal dialog boxes.

Broadway
A JavaScript H.264 and VP8/WebM decoder.

gitdocs
Open-source dropbox alternative powered by git. Collaborate on files and tasks without any extra hassle. gitdocs will automatically keep everyone’s repos in sync by pushing and pulling changes. This allows any git repo to be used as a collaborative task list, file share, or wiki for a team. Supports a web front-end allowing each repo to be accessed through your browser.
Best of the Internet
Often, you’re not really looking for a tutorial as much as you’re looking for a rant, an opinion or the musings of a tired developer or just something cool with absolutely zero real world use. This sections contains links to precisely those — interesting and cool stuff from the developer community.

Why HTML5 Media is not Enough
Amos Wenger on why the media elements introduced with the HTML5 spec aren’t evolving fast enough and how he’s countering the issues he’s facing.

What Tools Developers Actually Use
A great inforgraphic charting out the tools that developers use and love. There isn’t too much data here but should give you a quick overview as to what your peers are using.

Backbone.js Fundamentals
Addy Osmani is back again with a great little ebook on working with Backbone.js. The content goes over every aspect of the Backbone framework so if you’re even remotely interested in working with it, this is a great place to start.

Cracks in the Foundation
A clear, concise look at what’s wrong with the PHP platform. If you’re a PHP user, prepare to go in with some denial.
Wrapping Up
Well, that’s about all the major changes that happened in our industry lately.
Do you want us to cover more standard news? A focus on upcoming scripts maybe? Or just more interesting posts and discussions from the community? Let us know in the comments and thank you so much for reading!




