Feeds

100905 items (293 unread) in 22 feeds

CNN CNN
MSNBC MSNBC
PHP PHP
Deals Deals
Tech Tech
Web Development Web Development
CNN Money CNN Money
Frugal Blogs Frugal Blogs

Unread items (250)

 

dealnews - 20 most recent deals.

xpBargains.com

MSNBC.com: U.S. News

xpBargains.com

dealnews - 20 most recent deals.

GottaDeal.com - Why Pay Retail?

xpBargains.com

dealnews - 20 most recent deals.

xpBargains.com

dealnews - 20 most recent deals.

xpBargains.com

dealnews - 20 most recent deals.

xpBargains.com

dealnews - 20 most recent deals.

GottaDeal.com - Why Pay Retail?

MSNBC.com: U.S. News

dealnews - 20 most recent deals.

MSNBC.com: U.S. News

dealnews - 20 most recent deals.

MSNBC.com: U.S. News

dealnews - 20 most recent deals.

The Simple Dollar

GottaDeal.com - Why Pay Retail?

dealnews - 20 most recent deals.

GottaDeal.com - Why Pay Retail?

dealnews - 20 most recent deals.

GottaDeal.com - Why Pay Retail?

dealnews - 20 most recent deals.

Techbargains.com

MSNBC.com: U.S. News

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

MSNBC.com: U.S. News

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

xpBargains.com

Techbargains.com

GottaDeal.com - Why Pay Retail?

xpBargains.com

MSNBC.com: Technology & Science

xpBargains.com

GottaDeal.com - Why Pay Retail?

dealnews - 20 most recent deals.

Techbargains.com

MSNBC.com: Technology & Science

xpBargains.com

Techbargains.com

dealnews - 20 most recent deals.

xpBargains.com

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

MSNBC.com: Technology & Science

Techbargains.com

dealnews - 20 most recent deals.

GottaDeal.com - Why Pay Retail?

Techbargains.com

MSNBC.com: U.S. News

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

MSNBC.com: U.S. News

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

xpBargains.com

Techbargains.com

xpBargains.com

dealnews - 20 most recent deals.

xpBargains.com

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

MSNBC.com: Technology & Science

xpBargains.com

dealnews - 20 most recent deals.

Techbargains.com

xpBargains.com

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

xpBargains.com

Techbargains.com

xpBargains.com

MSNBC.com: Technology & Science

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

The Simple Dollar

dealnews - 20 most recent deals.

xpBargains.com

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

Techbargains.com

dealnews - 20 most recent deals.

xpBargains.com

Techbargains.com

dealnews - 20 most recent deals.

xpBargains.com

dealnews - 20 most recent deals.

MSNBC.com: U.S. News

dealnews - 20 most recent deals.

MSNBC.com: U.S. News

dealnews - 20 most recent deals.

Planet PHP

MSNBC.com: U.S. News

Nettuts+

Techbargains.com

Dev Articles - Programming Help and Tutorials for all development technologies

Nettuts+

Dev Articles - Programming Help and Tutorials for all development technologies

Nettuts+

Dev Articles - Programming Help and Tutorials for all development technologies

Nettuts+

Dev Articles - Programming Help and Tutorials for all development technologies

  • Permalink for 'Overview of JavaScript Variables'

    Overview of JavaScript Variables

    Posted: May 14th, 2012, 10:00pm MDT
    What is a JavaScript Variable? If you are completely new to working with JavaScript, you may find it difficult to understand at first. As with any learning process, you have to start with the basics. This is especially true with programming and the like, because each language can be thought of as its own little universe complete with unique terms, rules, and more. So, when discussing variables in JavaScript, it probably helps to compare them to other parts of life. Before we do that, let us describe what variables are. One of the most basic ways to describe a variable in JavaScript is to...

Nettuts+

  • Permalink for 'Lots Of New Premium Content!'

    Lots Of New Premium Content!

    Posted: May 14th, 2012, 1:57pm MDT by Jeffrey Way

    As Tuts+ Premium continues to sky-rocket, our ability to post better, more frequent, content has improved dramatically as well. This week, we have a variety of fun new things available to members!

    Course – How To Be A Terminal Pro

    In this fifteen-episode course, you’ll learn how to take advantage of that scary app you never touch: Terminal! We’ll begin with the obligatory “hello world” command, and work our way up to advanced usage.

    Course – JavaScript Testing With Jasmine

    Admit it: you say that you test your JavaScript, but, in reality, you…don’t. That’s okay; the idea of testing JavaScript is a relatively new thing. And unfortunately, there aren’t too many “hold your hand” resources for getting up and running. Well, that all changes with this course. We start from scratch, and slowly work our way up the testing chain.

    Along the way, we’ll take advantage of the fantastic Jasmine BDD (Behavior-Driven Development) framework to make our tests as readable as possible. Upon completion of the course, you’ll not only have a robust test suite at your fingertips, but your tests will also make for fantastic documentation!

    eBook - Client Centric Web Design

    Other than Internet Explorer, what is the most challenging part of your job? Did you answer clients? If so, this eBook, by Paul Boag, is for you. Discover how to keep your clients happy, maintain your own sanity and produce the most effective websites you have ever built, resulting in happier clients, better websites, and improved job satisfaction.

    eBook - Building Websites for Return on Investment

    Building Websites For Return on Investment

    ‘Building Websites for Return on Investment’ uncovers the secrets of sites that successfully generate real return on investment. This book will enable you to transform your website from an expense to a measurable source of income.

    Article – Are You Using CoffeeScript?

    For those who haven’t yet had the chance to dig into CoffeeScript, this article will get you up and running in no time!

    Coming Soon to Tuts+ Premium

    Nothing above pique your interest? That’s okay; we have plenty of amazing new content on the near horizon, including the following courses:

    • PHP Fundamentals
    • What’s New in PHP 5.4?
    • Cleaner Code With CoffeeScript
    • Backbone.js Fundamentals
    • The Sublime Text 2 Guide
    • Test-Driven Development in Ruby

    Already a member? What requests do you have? Haven’t signed up yet? Well now’s the perfect time!


  • Permalink for 'How to Convert a Widget into a Joomla Module'

    How to Convert a Widget into a Joomla Module

    Posted: May 11th, 2012, 7:00am MDT by KazKarizmatic

    This tutorial will cover the process of creating a basic Joomla module from an existing widget. We’re going to take a widget from Mixcloud, learn how to convert it into a Joomla module and, finally, distribute the extension to JED (Joomla Extension Directory).

    If you’ve never created a Joomla module before, this article is the best place to start!

    Step 1: Setting up Our Files Basic Files

    For every module created for Joomla, there are two files that absolutely need to be present. One file is a configuration XML file that will hold the module details and parameters and a PHP file that will control our module. For the purpose of this tutorial, we will create a folder called mod_mixcloud_widget and, within it, using your favorite code editor, create mod_mixcloud_widget.php and mod_mixcloud_widget.xml. Before we move on to the next step, create a single HTML file named index.html.The index.html file that was created will be used to hide the contents of the module folder when viewing via a browser.

    Template Files

    Now that you’ve added the core files, it’s time to add the template files. We do this by creating a folder called tmpl. Within that folder, we create default.php and index.html. The file default.php will be the module template that will take generated information and output them into clean HTML format on the page.

    Language Files

    Lastly, while inside our root module folder, we create a new folder called language. This folder will have two files: en-GB.mod_mixcloud_widget.ini and en-GB.mod_mixcloud_widget.sys.ini which will be used to make our module internationable with the option of having different languages.

    Final File Structure

    After following each step, you should have the following file structure

    • language/en-GB.mod_mixcloud_widget.ini
    • language/en-GB.mod_mixcloud_widget.sys.ini
    • tmpl/default.php
    • tmpl/index.html
    • index.html
    • mod_mixcloud_widget.php
    • mod_mixcloud_widget.xml
    Step 2: Setting Up Our XML File

    Each Joomla Extension installed has an XML file, which is referred to as a manifest or Install file. This file contains metadata details, such as author, version, description etc. It is also used as a configuration file for module prameters. For the purpose of this tutorial, we will be creating a manifest file for a Joomla 2.5 module. Add the following snippet to your XML file.

    <?xml version="1.0" encoding="utf-8"?>
    <extension 	type="module"	version="2.5"	client="site"	method="upgrade">
    	<name>MOD_MIXCLOUD_WIDGET</name>
    	<author>B4ucode</author>
    	<creationDate>May 2012</creationDate>
    	<copyright>Copyright (C) 2011 - 2012. All rights reserved.</copyright>
    	<license>GNU General Public License version 2 or later;</license>
    	<authorEmail>info@b4ucode.com</authorEmail>
    	<authorUrl>www.b4ucode.com</authorUrl>
    	<version>1.0.0</version>
    	<description>MOD_MIXCLOUD_WIDGET_XML_DESCRIPTION</description>
    

    The primary tag extension has a few attributes:

    • type: Tells Joomla what type of extension is being installed, in this case module.
    • version: Instructs the installer what version of Joomla we are creating the module for.
    • method: There are two options: new and upgrade. We will be using upgrade, in case of any future updates to the module, it will simply upgrade what is currently there.
    • client: Instructs whether the module is a front-end or back-end module.

    The other set of tags are metadata tags which hold information about the module which will be used during installation and the administration of the module.

    Module Files

    As mentioned before, the manifest file holds information about the files used in the module. During installation, Joomla checks the manifest file for all the files that should be added to the system. If any of the files are missing, then Joomla will give an error explaining the files that are missing. Any files found in the module, that aren’t listed in the XML file are not added to the system with the others. Add the following snippet to your manifest file.

    	<files>
    		<filename module="mod_mixcloud_widget">mod_mixcloud_widget.php</filename>
    		<folder>tmpl</folder>
    		<filename>index.html</filename>
    		<filename>mod_mixcloud_widget.xml</filename>
    	</files>
    

    Instead of writing a line for each file in a folder, we simply use the folder element. This element will instruct the installer to install all the files in this folder.

    Language Files

    This element holds the language files that are to be installed with the module. For the purpose of this tutorial, only one language will be used. When there are more languages, you can simply change the prefix of the files and the tag attribute to the exact language based on the Joomla framework.

    	<languages>
    		<language tag="en-GB">language/en-GB.mod_mixcloud_widget.ini</language>
    		<language tag="en-GB">language/en-GB.mod_mixcloud_widget.sys.ini</language>
    	</languages>
    
    Adding Parameters

    Some extensions don’t work right out of the box, but need certain settings added: these settings are called, parameters, and are defined in the manifest file.

    The first element is config which holds other elements that will be displayed in HTML format. The element called field is the meat of our parameters where you can define what type of form data you wish to display. This element at its basic level is made up of some core attributes:

    • type: Type of form field like text, textarea, checkboxes, radio and calendar.
    • name: The name element of the form field to displayed.
    • default: Default value of the field.
    • label: Text displayed at the beginning of our form field.
    • description: Description that will be shown in a tooltip when hovering on our form field
    • There are different attributes as they vary per form field type like size, filter, exclude, directory and more.

      	<config>
      		<fields name="params">
      			<fieldset name="basic">
      				<field type="text" name="feed" default="" label="MOD_MIXCLOUD_WIDGET_FEED_TITLE" description="MOD_MIXCLOUD_WIDGET_FEED_DESC" />
      				<field name="color" type="color" default="" label="MOD_MIXCLOUD_WIDGET_COLOR_TITLE" description="MOD_MIXCLOUD_WIDGET_COLOR_DESC" />
      				<field name="width" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_WIDTH_TITLE" description="MOD_MIXCLOUD_WIDGET_WIDTH_DESCRIPTION" />
      				<field name="height" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_HEIGHT_TITLE" description="MOD_MIXCLOUD_WIDGET_HEIGHT_DESCRIPTION" />
      			</fieldset>
      			<fieldset
      				name="advanced">
      				<field
      					name="layout"
      					type="modulelayout"
      					label="JFIELD_ALT_LAYOUT_LABEL"
      					description="JFIELD_ALT_module_LAYOUT_DESC" />
      				<field
      					name="moduleclass_sfx"
      					type="text"
      					label="COM_moduleS_FIELD_moduleCLASS_SFX_LABEL"
      					description="COM_moduleS_FIELD_moduleCLASS_SFX_DESC" />
      				<field
      					name="owncache"
      					type="list"
      					default="1"
      					label="COM_moduleS_FIELD_CACHING_LABEL"
      					description="COM_moduleS_FIELD_CACHING_DESC">
      					<option value="1">JGLOBAL_USE_GLOBAL</option>
      					<option	value="0">COM_moduleS_FIELD_VALUE_NOCACHING</option>
      				</field>
      			</fieldset>
      		</fields>
      	</config>
      </extension>
      

      You may notice that we have written labels and description in some uppercase characters like MOD_MIXCLOUD_WIDGET_FEED_TITLE. These are strings that we will make translatable when creating our language files.

      Finished XML File

      If you’ve followed thus far, you should have a completed XML File like following

      <?xml version="1.0" encoding="utf-8"?>
      <extension 	type="module"	version="2.5"	client="site"	method="upgrade">
      	<name>MOD_MIXCLOUD_WIDGET</name>
      	<author>B4ucode</author>
      	<creationDate>May 2012</creationDate>
      	<copyright>Copyright (C) 2011 - 2012 Open Source Matters. All rights reserved.</copyright>
      	<license>GNU General Public License version 2 or later;</license>
      	<authorEmail>info@b4ucode.com</authorEmail>
      	<authorUrl>www.b4ucode.com</authorUrl>
      	<version>1.0.0</version>
      	<description>MOD_MIXCLOUD_WIDGET_XML_DESCRIPTION</description>
      	<files>
      		<filename module="mod_mixcloud_widget">mod_mixcloud_widget.php</filename>
      		<folder>tmpl</folder>
      		<filename>index.html</filename>
      		<filename>mod_mixcloud_widget.xml</filename>
      	</files>
      	<languages>
      		<language tag="en-GB">language/en-GB.mod_mixcloud_widget.ini</language>
      		<language tag="en-GB">language/en-GB.mod_mixcloud_widget.sys.ini</language>
      	</languages>
      	<config>
      		<fields name="params">
      			<fieldset name="basic">
      				<field type="text" name="feed" default="" label="MOD_MIXCLOUD_WIDGET_FEED_TITLE" description="MOD_MIXCLOUD_WIDGET_FEED_DESC" />
      				<field name="color" type="color" default="" label="MOD_MIXCLOUD_WIDGET_COLOR_TITLE" description="MOD_MIXCLOUD_WIDGET_COLOR_DESC" />
      				<field name="width" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_WIDTH_TITLE" description="MOD_MIXCLOUD_WIDGET_WIDTH_DESCRIPTION" />
      				<field name="height" type="text" default="300" size="40" label="MOD_MIXCLOUD_WIDGET_HEIGHT_TITLE" description="MOD_MIXCLOUD_WIDGET_HEIGHT_DESCRIPTION" />
      			</fieldset>
      			<fieldset
      				name="advanced">
      				<field
      					name="layout"
      					type="modulelayout"
      					label="JFIELD_ALT_LAYOUT_LABEL"
      					description="JFIELD_ALT_module_LAYOUT_DESC" />
      				<field
      					name="moduleclass_sfx"
      					type="text"
      					label="COM_moduleS_FIELD_moduleCLASS_SFX_LABEL"
      					description="COM_moduleS_FIELD_moduleCLASS_SFX_DESC" />
      				<field
      					name="owncache"
      					type="list"
      					default="1"
      					label="COM_moduleS_FIELD_CACHING_LABEL"
      					description="COM_moduleS_FIELD_CACHING_DESC">
      					<option value="1">JGLOBAL_USE_GLOBAL</option>
      					<option	value="0">COM_moduleS_FIELD_VALUE_NOCACHING</option>
      				</field>
      			</fieldset>
      		</fields>
      	</config>
      </extension>
      
      Step 3: Creating mod_mixcloud_widget.php

      The first thing you want to with your module is to add your copyright notice. If you intend to submit your module to JED [Joomla Extension Directory], you should add some GPL license information.

      This is one of the checks done before approving a module into the directory. Directly below this, I use the statement defined('_JEXEC') or die; which is used in most PHP files to protect against hackers. This is also another requirement for approval on JED.

      <?php
      /**
       * @package		B4ucode
       * @subpackage	mod_mixcloud_widget
       * @copyright	Copyright (C) 2011 - 2012 B4ucode, Inc. All rights reserved.
       * @license		GNU General Public License version 2 or later;
       */
      // no direct access
      defined('_JEXEC') or die;
      

      Next, we define our paramaters as variables. Developers sometimes define their paramaters as variables in order to have cleaner template files. In order to call a paramaters we use the $params->get() function and get the param name defined in our manifest file. Finally, we call the module Helper function, getLayoutPath, which will render our module template. The first argument of the function takes the module name that we are trying to call, then the second argument looks for the template we intend to render for that module. In this case, we get the parameter layout and in the second argument we set the default layout to be default. This layout is the exact name of the file that we have in our tmpl folder.

      $width = $params->get('width',300);
      $height = $params->get('height',300);
      $feed = $params->get('feed');
      $color = $params->get('color');
      $moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'));
      require JmoduleHelper::getLayoutPath('mod_mixcloud_widget', $params->get('layout', 'default'));
      ?>
      
      Finished File
      	<?php
      /**
       * @package		B4ucode
       * @subpackage	mod_mixcloud_widget
       * @copyright	Copyright (C) 2011 - 2012 B4ucode, Inc. All rights reserved.
       * @license		GNU General Public License version 2 or later;
       */
      // no direct access
      defined('_JEXEC') or die;
          $width = $params->get('width',300);
          $height = $params->get('height',300);
          $feed = $params->get('feed');
          $color = $params->get('color');
          $moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'));
          require JmoduleHelper::getLayoutPath('mod_mixcloud_widget', $params->get('layout', 'default'));
      ?>
      
      Step 4: Creating default.php

      At this point, we have created our manifest file with paramaters, took those same parameters and turned them into variables. In this step, we are going to use those variables in our template file. The template file will render all of our HTML for the module. Edit default.php from your tmpl folder and add the following snippets:

      Copyright Notice and Restricted Access Script
      <?php
        /**
       * @package		B4ucode
       * @subpackage	mod_mixcloud_widget
       * @copyright	Copyright (C) 2011 - 2012 B4ucode, Inc. All rights reserved.
       * @license		GNU General Public License version 2 or later;
       */
       // no direct access
      defined( '_JEXEC' ) or die( 'Restricted access' );
      

      It is recommended that you add the Copyright Notice and Restricted Access line to your PHP files.

      Adding our HTML

      For this tutorial, we will need the embed code from Mixcloud. Here is an example on getting the code . Our module’s purpose is to make the code reusable without having to get the embed each time we want to create or modify a Mixcloud Widget on our site. The default embed code comes with some extra information about the widget content which we don’t need. So for this tutorial, I have stripped it down to just the embed script. Paste this embed code to your default.php file.

      <div><object width="480" height="480"><param name="movie" value=" [www.mixcloud.com] name="allowFullScreen" value="true"></param><param name="wmode" value="opaque"></param><param name="allowscriptaccess" value="always"></param><embed src=" [www.mixcloud.com] type="application/x-shockwave-flash" wmode="opaque" allowscriptaccess="always" allowfullscreen="true" width="480" height="480"></embed></object></div>
      
      Making the Script Configurable

      If we wanted to embed one widget permanently, we could just zip up the module right now. However we don’t, so we are going to replace some of the attributes with our module params . We’re going to change the width, height, color and feed. Paste the following snippet over your embed script.

      	<div><object width="<?php echo $width; ?>" height="<?php echo $height; ?>">
      <param name="movie" value=" [www.mixcloud.com] echo $feed; ?>&amp;embed_uuid=&amp;stylecolor=<?php echo $color; ?>&amp;embed_type=widget_standard"></param><param name="allowFullScreen" value="true"></param><param name="wmode" value="opaque"></param><param name="allowscriptaccess" value="always"></param><embed src=" [www.mixcloud.com] echo $feed; ?>&amp;embed_uuid=&amp;stylecolor=<?php echo $color; ?>&amp;embed_type=widget_standard" type="application/x-shockwave-flash" wmode="opaque" allowscriptaccess="always" allowfullscreen="true" width="<?php echo $width; ?>" height="<?php echo $height; ?>"></embed></object>
      </div>
      

      Take note of how we are just calling the variables from our controller file.

      Step 5: Creating Language Files

      In step one, you might have noticed that we created a folder, called language, with two files. Then, in step two, we added some translatable text. In this section, we are going to translate that text to English. Insert the following snippet to the ini files, en-GB.mod_mixcloud_widget.sys.ini and en-GB.mod_mixcloud_widget.ini.

      ; B4ucode
      ; Copyright (C) 2011 - 2012 B4ucode. All rights reserved.
      ; License GNU General Public License version 2 or later;
      ; Note : All ini files need to be saved as UTF-8 - No BOM
      
      MOD_MIXCLOUD_WIDGET="Mixcloud Widget"
      MOD_MIXCLOUD_WIDGET_XML_DESCRIPTION="This module displays the Mixcloud Widget using feed and other paramaters"
      MOD_MIXCLOUD_WIDGET_ITEMS_LAYOUT_DEFAULT="Default"
      MOD_MIXCLOUD_WIDGET_FEED_TITLE="Feed Url"
      MOD_MIXCLOUD_WIDGET_FEED_DESC="Add the link to single/cloudcast"
      MOD_MIXCLOUD_WIDGET_COLOR_TITLE="Color"
      MOD_MIXCLOUD_WIDGET_COLOR_DESC="Add Style color"
      MOD_MIXCLOUD_WIDGET_WIDTH_TITLE="Width"
      MOD_MIXCLOUD_WIDGET_WIDTH_DESCRIPTION="Width of Widget"
      MOD_MIXCLOUD_WIDGET_HEIGHT_TITLE="Height"
      MOD_MIXCLOUD_WIDGET_HEIGHT_DESCRIPTION="Height of Widget"
      

      If you look closely, you will notice that the text I used for the parameters now have an English translation. You can add other files and create translations in other languages!

      Step 6: Packaging the Module

      After following all the steps thoroughly, your module is now installable, but we’d like to make a checklist of things to do before installation and distribution.

      Add index.html to Folders

      It is recommended that you add a index.html file to each folder. This file, as mentioned previously, stops users from viewing the contents of a module folder directly in a browser. Add the following snippet to your files:

      	<html><body bgcolor="#FFFFFF"></body></html>
      
      Comparing our File Structure to the Manifest File

      At this stage, it is recommended that you look at the files and folder defined in your manifest file, and make sure they exist in your module folder. Any file that does not exist can stop the installer from installing files, or, it may throw an error.

      Packaging

      After our little checklist, we can package the module into a zip file, and install it.

      By navigating to the modules manager, and selecting the module, you can modify the paramaters with your desired width, height, color and song feed.

      Enable the module and check to see if it operates the way that it should.

      Step 7: Submitting to JED Locating the Category

      After registering to JED, one of the main things to note is that you cannot add an extension to multiple sections. So, choosing the appropriate section is very important. Find a suitable section by browsing the site then looking at the top left cornder you will see Submit Extension

      Filling Out the Details

      Once you’ve chosen to submit an extension, there will be a form to fill in all the details about your submission. Review the screenshots below to see the different fields to be filled out, and read the instructions carefully.

      Success Image

      Once all the appropriate fields and files have been submitted, you will see a message like the screenshot above; it will explain how many submissions are in the queue to be checked prior to yours.

      Conclusion

      Now that you’ve learned how to create a Joomla module from a widget, go forth and code. With the basics of this tutorial, the same idea can be applied to Facebook plugins, Twitter widgets, Social bookmarkers, Youtube video embeds, and so much more. Happy Coding!


  • Permalink for 'Aspect-Oriented Programming in PHP'

    Aspect-Oriented Programming in PHP

    Posted: May 10th, 2012, 8:01am MDT by Chris Peters

    There’s a new player in town, and he brought new toys: The PHP World welcomes FLOW3, an enterprise application framework written and backed by the community of the TYPO3 CMS. FLOW3 can be used as standalone full-stack framework for your applications. It’s interesting, because it introduces some concepts of software development that haven’t been adapted to PHP before.

    Among these new concepts is “Aspect Oriented Programming”. We will have a look on the theory of the pattern, and will set up a basic FLOW3 Application and weave in our own aspect!

    Why Should I Care?

    If a new framework hits stable, an excellent question to rise might be: What can it do that the tools that I love can’t?

    PHP already has an armada of excellent frameworks and most of them claim to be written with separation of concerns in mind. So does FLOW3.

    In terms of software development this means, that the classes that are implementing the logic of your application should only care about one thing. For example, a mailer class should send mails. It should not retrieve potential receivers from a database.

    All modern frameworks (including FLOW3) push a lot of patterns into the software stack that do a great job at separating the concerns of your business logic; among them the famous MVC that is separating your logic into different layers.

    However, an application is not only built on business logic alone. As it grows, you may want to implement additional services, features, plugins or plugins of plugins. You surely don’t want this stuff in your business logic! But what are your options?

    Let’s say you want to implement a logging service that writes some stuff to a text file every time a specific set is deleted from the database. Naturally, the logging service is not part of your database layer. But in order to make it work, you have to place some code right there, like this:

    /**
     * Delete a user
     * @param UserModel $user
     * @return void
     */
    public function deleteUser(UserModel $user) {
    $this->loggingService->log('removing user ' . $user->getName());
    $this->users->remove($user);
    }
    

    Horrible, isn’t it? Let’s face it: The logging service adds dirt to your code. You have to touch the original code in order to implement it and you add an additional dependency, in this case an instance of the LoggingService.

    Hence, you’re adding complexity. And you likely will have to add it all over your app (depending on what else you want to log).

    You may come up with an pattern like an event dispatcher or a hook system like it’s implemented in Drupal and WordPress and then have your logger listen for events:

    /**
     * Delete a user
     * @param UserModel $user
     * @return void
     */
    public function deleteUser(UserModel $user) {
    $this->eventDispatcher->dispatch(self::USER_DELETED);
    $this->users->remove($user);
    }
    

    This is better, but it’s still not cool. You’re code is still dependency aware: it has some code with the sole purpose of informing other parties that something happens.

    This has some bad side-effects: What if you want to log something, but there’s not an event dispatched at that time? What if you haven’t written that code because you are writing a plugin? You’d have to change the original code – not once, but every time an update is available.

    Let’s call the logging service an aspect and see how FLOW3 takes care of the problem.

    Aspect Weaving

    Our logging service is only interested in one thing regarding the existing code: It wants to intercept it in some classes at various points (e .g. when something is deleted). With the implementation discussed above, the existing code controls the points of execution.

    Wouldn’t it be nice if the service could define a set of rules at which point it would want to inject itself into the class?

    This is a software development concept named Inversion of control. It decouples classes from another, because there’s no need to change existing code when you’re changing the service. The service takes care of this itself.

    Let’s say we simply want to execute logging on every method in every class that starts with delete, like deleteUser(), deleteEntry() or whatever. A convenient way would be to write a rule into the logging service and let the framework take care of the correct execution of the code. This is remarkably easy in FLOW3:

    /**
     * An aspect that is executed on all methods that start with "delete".
     *
     * @FLOW3\Before("method(.*->delete.*())")
     */
     public function logginMethod() {
    // Do some logging here.
     }
    

    FLOW3 performs some really advanced PHP techniques under the hood.

    The rule is named pointcut in AOP and there are some easy-to-learn ways to define them. The one above tells FLOW3 to inject the logging code in every class before every method that starts with delete.

    It does so by using the method keyword and by adding wildcards (*) for the class and for parts of the method name. If you’re adding this code in an Aspect Class (as we do later), you’re good to go. You will be able to access properties of the class that you are targeting as well. The targeted class itself remains untouched. It may not yet be written – if it’s added to your app in the future, the rule will then match and the code will be injected.

    Maybe you have read the above paragraph twice and are asking yourself: Is this magic? What’s the damn trick? – I sure did, when I was first introduced to AOP!

    Well, AOP has been around for some time in the Java world. FLOW3 is heavily inspired by the AOP implementation of Spring, a Java Framework. The word was on the street, that the pattern can’t be transferred to interpreted languages, because it requires compilation.

    The trick is, that the framework – or some tools like JAspect – intercepts the compilation process (from Java code to bytecode, that can be executed by the Java runtime) and do an analysis of the defined aspects. Whenever a set of rules (aka the pointcut) matches a method, it is weaved directly into the compiled code. Hence, the framework takes care of merging the code parts together:

    FLOW3 did adapt that concept to the world of PHP by introducing an advanced cache. While most frameworks offer caching to increase performance, FLOW3 additionally uses the cache to weave aspects into the original classes.

    If you are running your app, FLOW3 delivers the cached classes instead the ones you’ve written. Hence, your original code remains untouched.

    This sounds complex – and it is: FLOW3 performs some really advanced PHP techniques under the hood, that are well worth to be explored! But: To you as an application developer, it’s not complicated at all. You don’t have to care, if you don’t want to: FLOW3 monitors your files for changes and if you make some, FLOW3 auto-commits them to the cache upon your next request. If an aspect matches to a method, it’s automatically weaved in – no further configuration needed.

    It’s a complex pattern conveniently at your service!

    A Few Words About the Cache

    Every cool feature comes with a downside – so does FLOW3. At the moment, we just scratched the surface of what FLOW3′s caching-mechanism is capable of, but I want to give you an idea.

    Take a look at the following code:

    /**
     * @FLOW3\Inject
     * @var \YourApp\MailerServiceInterface
     */
     protected $mailer;
    /**
     * Sends a mail.
     *
     * @param \YourApp\Model\User $user
     * @param string $message
     */
     protected function sendMail(\YourApp\Model\User $user, $message) {
         // Sends a mail.
     }
    

    The consequence is that PHP is to some degree no longer an interpreted language.

    This may look like some code that is just well documented. But it’s much more.

    The first property annotation (FLOW3\Inject) tells FLOW3 to look for some class in your app that implements the MailerServiceInterface and injects it here (and maybe configure it before). This pattern is known as Dependency Injection.

    The second class defines some type definitions in its comment’s annotations – and FLOW3 uses them. If you’re giving the method some data that can be used to build a User object of your model (for example an array with pure strings from a HTML form), FLOW3 auto-transforms the data safely to a User object and applies some security and validation rules to the second parameter (in this case a string).

    This is (among some other tricks) done by weaving in some code into the cache.

    The consequence is that PHP is to some degree no longer an interpreted language. The process of caching is somewhat similar to compiling and it has the same downsides: You can’t just save & refresh your browser, you have to wait for the cache to be warmed up during development. If you are committing code to your production environment, you have to flush the cache in order to see the changes.

    On top of that, FLOW3 adds some kind of type-validation at runtime: You can’t pass an integer as second argument in the example above – it’ll throw an error. I really like this, because I have a background in strictly typed languages like Java and ActionScript. It also adds a lot of security to your application. But if you’re a PHP purist, this may be something that you don’t want.

    Setting Up Flow3

    Alright, enough with theory. Let’s get our hands dirty.

    Setting up FLOW3 is pretty straightforward, if you already have a PHP-capable server like XAMP or MAMP installed. Just grab a copy of the framework from FLOW3′s download site (or clone from git) and unpack it into your htdocs directory.

    You should already be done now on Windows machines. Unix-based systems like MAC or Linux need to grant the required rights for building the cache. FLOW3 ships with a powerful command line tool, that packs this task into a one-liner:

    # On linux:
    ./flow3 core:setfilepermissions chris www-data www-data
    # On Mac:
    ./flow3 core:setfilepermissions chris _www _www
    

    Please replace chris with your username! This should be enough. However, I’ve installed FLOW3 on
    various machines and have run into some problems. The most common ones are:

    • If you’re on MAC and FLOW3 complains “index.php not found “, open the .htaccess in the webdir and add a # before the line Rewrite Base /“–
    • If you’re on Windows and the command line tool does not work, open Settings.yaml.example in FLOW3′s configuration directory, uncomment and adjust the phpBinaryPathAndFilename variable to the correct path (e.g. C:\xampp\php\php.exe) and save the file as Settings.yaml

    • On some machines, if FLOW3 is very slow, you have to increase the memory limit of PHP in the php.ini

    If you run into problems, that are not listed here, please post them in the comments!

    Now fire up your favorite browser and navigate to [localhost] FLOW3 should welcome you with an introduction screen:

    The first run may take a while, as FLOW3 has to index your code and build all caches.

    This is the Welcome Package. Every application in FLOW3 (and FLOW3 itself) is a package and packages can share code with each other. For example, once the new TYPO3 Version is finished, you can add it as a package and your application will then have an enterprise-ready CMS on top!

    Let’s start our own package. It’s an easy task, because FLOW3′s command line tool will handle most of the work! Type in the following command:

    # On linux / MAC
    ./flow3 kickstart:package Nettuts.AspectDemo
    # On Windows
    flow3 kickstart:package Nettuts.AspectDemo
    

    This will create a ready-to-go package named Nettuts.AspectDemo in FLOW3′s Packages/Application folder. If you review the file structure, you will find many folders that do follow a specific convention.

    The important ones are:

    • Classes: The home of your PHP Code, a first Controller is already created in the Classes/Controller Folder: the StandardController!
    • Resources/Private: The home of all templates that are fired into Fluid, FLOW3′s powerful Templating Engine. It hosts some other stuff like localization files as well.
    • Resources/Public: This has not been created yet, but every file in the Resources/Public folder will be directly accessible from the web. This is a good place for images, CSS, Javascript etc.

    Building a full-featured app is beyond the scope of this tutorial, so we’ll go with the defaults. Please open the following URL: http://localhost/flow3/Web/index.php/Nettuts.AspectDemo

    This is not much, but it’s a start. We want to write something to a logfile, every time this site is called. We do this by weaving in an aspect into the StandardController!

    Writing a First Aspect

    Take a look at the StandardController in theClasses/Controller Folder in your Nettuts.AspectDemo Package.

    It implements a method, named indexAction(). FLOW3 has automatically configured our app in a way, that this method inside the StandardController gets called when we enter the URL above.

    For the moment, we see that this method assigns some strings to the view:

    /**
     * Index action
     *
     * @return void
     */
    public function indexAction() {
    $this->view->assign('foos', array(
    'bar', 'baz'
    ));
    }
    

    If you open the file index.html of this view in Resources/Private/Templates/Standard inside our package, you’ll see how these strings are processed by the templating engine.

    However, our goal is to intercept the code execution before this method gets called.

    At first, create an empty file named Access.log in FLOW3′s Log folder at flow3/Data/Logs. You may save this file wherever you want, but this is a nice place for log files.

    Next, create a folder named Service in your Nettuts.AspectDemo/Classes Folder and inside of it, create another folder, and name it Logging. Then create a PHP file named LoggingAspect.php inside of it. It should have the following content:

    <?php
    namespace Nettuts\AspectDemo\Service\Logging;
    use TYPO3\FLOW3\Annotations as FLOW3;
    /**
     * @FLOW3\Aspect
     */
    class LoggingAspect {
       /**
        * Log a message if this site is called.
        *
        * @param \TYPO3\FLOW3\AOP\JoinPointInterface $joinPoint
        * @FLOW3\Before("method(Nettuts\AspectDemo\Controller\StandardController->indexAction())")
        * @return void
        */
       public function logSiteAccess(\TYPO3\FLOW3\AOP\JoinPointInterface $joinPoint) {
               $filePath = '/home/chris/www/flow3/Data/Logs/Access.log';
         $message = 'The site has been accessed at ' . time() . '.' . PHP_EOL;
         file_put_contents($filePath, $message, FILE_APPEND);
       }
    }
    ?>
    

    This is a very basic class, and if you’d like to have an advanced logger, you may want to separate the logging from the intercepting aspect.

    What’s going on here? At first, we define a namespace, which is your package name and the path to the actual class (without the class folder itself). Next, we import FLOW3′s annotation namespace. Thus, we can use FLOW3′s powerful annotation parser to configure our class.

    That’s exactly what we do in the class comments. We define the class as aspect with the following annotation:

    /**
     * @FLOW3\Aspect
     */
    

    From now on, FLOW3 is aware that this class may define rules for the interception of the code flow and watches our codebase for matches.

    This is the rule:

    @FLOW3\Before("method(Nettuts\AspectDemo\Controller\StandardController->indexAction())")
    

    We could use regular expressions or some other techniques to match multiple methods or classes, but we know exactly where we want to go: Before the indexAction() Method in the StandardController – and that’s exactly what we’re telling FLOW3.

    Note the $jointInterface Parameter of the logSiteAccess() Method, that is provided to us by FLOW3. We don’t use it here, but it contains some useful data about the actual context. For example, if the intercepted method would have arguments, that we may want to use, we could access them like this:

    $argument = $joinPoint->getMethodArgument('argumentName');
    

    The code in our logSiteAccess() method, itself, is fairly simple. Just adjust the path to the Access.log to your environment and you’re good to go!

    Now, again, open http://localhost/flow3/Web/index.php/Nettuts.AspectDemo – nothing should have changed. But when you open the Access.log file, you should see the following entry:

    The site has been accessed at 1335715244.
    

    If you can read this, the aspect has been weaved into the cache. Let’s have a look at the magic!

    FLOW3 stores the cache at flow3/Data/Temporary/Development/Cache/Code/FLOW3_Object_Classes.

    You will find a class named Nettuts_AspectDemo_Controller_StandardController_Original.php. This is the original class from our codebase.

    But there is another class: Nettuts_AspectDemo_Controller_StandardController.php. This class extends our original class and it is build up purely by generated code. Among the many lines you’ll find something like this:

    $this->FLOW3_Aop_Proxy_targetMethodsAndGroupedAdvices = array(
       'indexAction' => array(
          'TYPO3\FLOW3\Aop\Advice\BeforeAdvice' => array(
             new \TYPO3\FLOW3\Aop\Advice\BeforeAdvice(
             'Nettuts\AspectDemo\Service\Logging\LoggingAspect', 'logSiteAccess'
             $objectManager, NULL),
             ),
          ),
    );
    

    This is were FLOW3 initiates the aspect and it’s weaved in directly into your class. The aspect gets executed right where we want it – without touching the original controller.

    The code snippet initiates an instance of the BeforeAdvice class, with our aspect, the respective method and the $objectManager as arguments. The object manager contains the needed information to build the jointInterface, that is passed to the aspect.

    If you’re interested in the details, have a look at the AOP Folder in the FLOW3 package!

    Conclusion

    The aspect oriented approach has many advantages waiting to be discovered.

    The aspect oriented approach has many advantages waiting to be discovered. For example, FLOW3 uses AOP to intercept its own bootstrap to build up a firewall if you choose to use FLOW3′s security framework. Apart from that, we haven’t yet discussed the specific terminology that is commonly used in AOP.

    However, FLOW3 ships with some other unique concepts like Domain-Driven-Design. It has a powerful Doctrine integration and a smart Templating Engine. We have only seen the tip of the iceberg!

    What’s your opinion? Are you eager to learn more about the philosophy behind FLOW3? What’s your impression of AOP? Are you excited to have a robust port for the PHP world or do you think it’s too much overhead for an interpreted language?


  • Permalink for 'Which Tuts+ Site Should We Launch Next?'

    Which Tuts+ Site Should We Launch Next?

    Posted: May 9th, 2012, 7:18am MDT by David Appleyard

    We’re planning our next few Tuts+ sites, and would love your opinion and advice on which topics you think we should cover next! We’d be really grateful if you could take a minute to answer our quick poll and share your thoughts…

    Have Your Say
    Nettuts+ Readers: Which Tuts+ Site Should We Launch Next?

    We’ve been considering lots of different ideas for our next Tuts+ sites over the past few weeks, and wanted to also ask the opinion of our awesome community!

    A selection of different concepts are included in the poll to the right, along with the option for you to submit your own ideas as well.

    The important thing to note is that these are just ideas. Some of these are close to making our final cut, and others aren’t… We’d love to hear what you think, to help guide our decision.

    Thanks for taking the time to offer your suggestion — I can’t wait to see what you have to say!

    Win a 6-Month Tuts+ Premium Membership

    Our poll will be running for the next couple of weeks, and we’ll be choosing one respondent at random to receive a six-month Tuts+ Premium membership!

    To be entered into the giveaway, just leave a comment on this post to go into a bit more detail about your site suggestion. We’ll choose one comment at random to win the Tuts+ Premium membership when the poll ends.

    Best of luck!


  • Permalink for 'Prototypes in JavaScript'

    Prototypes in JavaScript

    Posted: May 9th, 2012, 5:00am MDT by Leigh Kaszick

    When you define a function within JavaScript, it comes with a few pre-defined properties; one of these is the illusive prototype. In this article, I’ll detail what it is, and why you should use it in your projects.

    What is Prototype?

    The prototype property is initially an empty object, and can have members added to it – as you would any other object.

    var myObject = function(name){
        this.name = name;
        return this;
    };
    
    console.log(typeof myObject.prototype); // object
    
    myObject.prototype.getName = function(){
        return this.name;
    };
    

    In the snippet above, we’ve created a function, but if we call myObject(), it will simply return the window object, because it was defined within the global scope. this will therefore return the global object, as it has not yet been instantiated (more on this later).

    console.log(myObject() === window); // true
    The Secret Link

    Every object within JavaScript has a “secret” property.

    Before we continue, I’d like to discuss the “secret” link that makes prototype work the way it does.

    Every object within JavaScript has a “secret” property added to it when it is defined or instantiated, named __proto__; this is how the prototype chain is accessed. However, it is not a good idea to access __proto__ within your application, as it is not available in all browsers.

    The __proto__ property shouldn’t be confused with an object’s prototype, as they are two separate properties; that said, they do go hand in hand. It’s important to make this distinction, as it can be quite confusing at first! What does this mean exactly? Let me explain. When we created the myObject function, we were defining an object of type Function.

    console.log(typeof myObject); // function

    For those unaware, Function is a predefined object in JavaScript, and, as a result, has its own properties (e.g. length and arguments) and methods (e.g. call and apply). And yes, it, too, has its own prototype object, as well as the secret __proto__ link. This means that, somewhere within the JavaScript engine, there is a bit of code that could be similar to the following:

    Function.prototype = {
        arguments: null,
        length: 0,
        call: function(){
            // secret code
        },
        apply: function(){
            // secret code
        }
        ...
    }
    

    In truth, it probably wouldn’t be quite so simplistic; this is merely to illustrate how the prototype chain works.

    So we have defined myObject as a function and given it one argument, name; but we never set any properties, such as length or methods, such as call. So why does the following work?

    console.log(myObject.length); // 1 (being the amount of available arguments)

    This is because, when we defined myObject, it created a __proto__ property and set its value to Function.prototype (illustrated in the code above). So, when we access myObject.length, it looks for a property of myObject called length and doesn’t find one; it then travels up the chain, via the __proto__ link, finds the property and returns it.

    You might be wondering why length is set to 1 and not 0 – or any other number for that fact. This is because myObject is in fact an instance of Function.

    console.log(myObject instanceof Function); // true
    console.log(myObject === Function); // false

    When an instance of an object is created, the __proto__ property is updated to point to the constructor’s prototype, which, in this case, is Function.

    console.log(myObject.__proto__ === Function.prototype) // true

    Additionally, when you create a new Function object, the native code inside the Function constructor will count the number of arguments and update this.length accordingly, which, in this case, is 1.

    If, however, we create a new instance of myObject using the new keyword, __proto__ will point to myObject.prototype as myObject is the constructor of our new instance.

    var myInstance = new myObject(“foo”);
    console.log(myInstance.__proto__ === myObject.prototype); // true

    In addition to having access to the native methods within the Function.prototype, such as call and apply, we now have access to myObject’s method, getName.

    console.log(myInstance.getName()); // foo
    
    var mySecondInstance = new myObject(“bar”);
    
    console.log(mySecondInstance.getName()); // bar
    console.log(myInstance.getName()); // foo
    

    As you can imagine, this is quite handy, as it can be used to blueprint an object, and create as many instances as needed – which leads me onto the next topic!

    Why is Using Prototype Better?

    Say, for instance, that we are developing a canvas game and need several (possibly hundreds of) objects on the screen at once. Each object requires its own properties, such as x and y coordinates, width,height, and many others.

    We might do it as follows:

    var GameObject1 = {
        x: Math.floor((Math.random() * myCanvasWidth) + 1),
        y: Math.floor((Math.random() * myCanvasHeight) + 1),
        width: 10,
        height: 10,
        draw: function(){
            myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
        }
       ...
    };
    
    var GameObject2 = {
        x: Math.floor((Math.random() * myCanvasWidth) + 1),
        y: Math.floor((Math.random() * myCanvasHeight) + 1),
        width: 10,
        height: 10,
        draw: function(){
            myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
        }
        ...
    };
    

    … do this 98 more times …

    What this will do is create all these objects within memory – all with separate definitions for methods, such as draw and whatever other methods may be required. This is certainly not ideal, as the game will bloat the browsers allocated JavaScript memory, and make it run very slowly… or even stop responding.

    While this probably wouldn’t happen with only 100 objects, it still can serve to be quite a performance hit, as it will need to look up one hundred different objects, rather than just the single prototype object.

    How to Use Prototype

    To make the application run faster (and follow best practices), we can (re)define the prototype property of the GameObject; every instance of GameObject will then reference the methods within GameObject.prototype as if they were their own methods.

    // define the GameObject constructor function
    var GameObject = function(width, height) {
        this.x = Math.floor((Math.random() * myCanvasWidth) + 1);
        this.y = Math.floor((Math.random() * myCanvasHeight) + 1);
        this.width = width;
        this.height = height;
        return this;
    };
    
    // (re)define the GameObject prototype object
    GameObject.prototype = {
        x: 0,
        y: 0,
        width: 5,
        width: 5,
        draw: function() {
            myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
        }
    };
    

    We can then instantiate the GameObject 100 times.

    var x = 100,
    arrayOfGameObjects = [];
    
    do {
        arrayOfGameObjects.push(new GameObject(10, 10));
    } while(x--);
    

    Now we have an array of 100 GameObjects, which all share the same prototype and definition of the draw method, which drastically saves memory within the application.

    When we call the draw method, it will reference the exact same function.

    var GameLoop = function() {
        for(gameObject in arrayOfGameObjects) {
            gameObject.draw();
        }
    };
    
    Prototype is a Live Object

    An object’s prototype is a live object, so to speak. This simply means that, if, after we create all our GameObject instances, we decide that, instead of drawing a rectangle, we want to draw a circle, we can update our GameObject.prototype.draw method accordingly.

    GameObject.prototype.draw = function() {
        myCanvasContext.arc(this.x, this.y, this.width, 0, Math.PI*2, true);
    }
    

    And now, all the previous instances of GameObject and any future instances will draw a circle.

    Updating Native Objects Prototypes

    Yes, this is possible. You may be familiar with JavaScript libraries, such as Prototype, which take advantage of this method.

    Let’s use a simple example:

    String.prototype.trim = function() {
        return this.replace(/^\s+|\s+$/g, ‘’);
    };
    

    We can now access this as a method of any string:

    “ foo bar   “.trim(); // “foo bar”

    There is a minor downside to this, however. For example, you may use this in your application; but a year or two down the road, a browser may implement an updated version of JavaScript that includes a native trim method within the String‘s prototype. This means that your definition of trim will override the native version! Yikes! To overcome this, we can add a simple check before defining the function.

    if(!String.prototype.trim) {
        String.prototype.trim = function() {
            return this.replace(/^\s+|\s+$/g, ‘’);
        };
    }
    

    Now, if it exists, it will use the native version of the trim method.

    As a rule of thumb, it’s generally considered a best practice to avoid extending native objects. But, as with anything, rules can be broken, if needed.

    Conclusion

    Hopefully, this article has shed some light on the backbone of JavaScript that is prototype. You should now be on your way to creating more efficient applications.

    If you have any questions regarding prototype, let me know in the comments, and I’ll do my best to answer them.


  • Permalink for '14 Reason Why Nobody Used Your jQuery Plugin'

    14 Reason Why Nobody Used Your jQuery Plugin

    Posted: May 7th, 2012, 4:45am MDT by Jonathan Cutrell

    With so many folks developing jQuery plugins, it’s not uncommon to come across one that just plain – for lack of better words – sucks. There’s no examples or documentation, the plugin doesn’t follow best practices, etc. But you’re one of the lucky ones: this article will detail the pitfalls that you must avoid.

    jQuery is no stranger to those of you frequent Nettuts+. Jeffrey Way’s awesome 30 Days to Learn jQuery (and various other tutorials here and elsewhere) have led us all down the path to Sizzle-powered awesomesauce. In all the hype (and a lot of leaps in JavaScript adoption by developers and browser vendors), plenty of plugins have come onto the scene. This is partially why jQuery has become the most popular JavaScript library available! The only problem is that many of them aren’t too great.

    In this article, we’ll focus less on the JavaScript specifically, and more on best practices for plugin delivery.

    1 – You Aren’t Making a jQuery Plugin

    There are some patterns that are, more or less, universally accepted as “The Right Way” to create jQuery plugins. If you aren’t following these conventions, your plugin may… suck! Consider one of the most common patterns:

    (function($, window, undefined){
    $.fn.myPlugin = function(opts) {
    	var defaults = {
    		// setting your default values for options
    	}
    
      // extend the options from defaults with user's options
      var options = $.extend(defaults, opts || {});
    
    	return this.each(function(){ // jQuery chainability
    	  // do plugin stuff
    	});
    })(jQuery, window);
    

    First, we are creating a self-invoking anonymous function to shield ourselves from using global variables. We pass in $, window, and undefined. The arguments the self invoking function is called with are jQuery and window; nothing is passed in for undefined, so that if we decide to use the undefined keyword within the plugin, “undefined” actually will be undefined.

    This shields from other scripts potentially assigning a malicious value to undefined, such as true!

    $ is passed as jQuery; we do it this way to ensure that, outside of the anonymous function, $ can still refer to something else entirely, such as Prototype.

    Passing the variable for the globally accessible window object allows for more compressed code through the minification processes (which you should be doing, as well).

    Next, we are using the jQuery plugin pattern, $.fn.PluginName. This is a way of registering your plugin to be used with the $(selector).method() format. It simply extends jQuery’s prototype with your new method. If you want to instead create a plugin that defines a function on the jQuery object, add it directly, like so:

    $.PluginName = function(options){
    	// extend options, do plugin stuff
    }
    

    This type of plugin won’t be chainable, as functions that are defined as properties of the jQuery object typically don’t return the jQuery object. For instance, consider the following code:

    $.splitInHalf = function(stringToSplit){
    	var length = stringToSplit.length;
    	var stringArray = stringToSplit.split(stringToSplit[Math.floor(length/2)]);
    	return stringArray;
    }
    

    Here, we are returning an array of strings. It makes sense to simply return this as an array, as this is likely what users will want to use (and they can easily wrap it in the jQuery object if they wish). In contrast, consider the following contrived example:

    $.getOddEls = function(jQcollection){ //
    	return jQcollection.filter(function(index){
    		var i = index+1;
    		return (index % 2 != 0);
    	});
    }
    

    In this case, the user is probably expecting the jQuery object to return from $.getOddEls; so, we return the filter method, which returns the jQuery collection defined by the function that is passed. A good rule of thumb is to wrap returned elements in the jQuery function, especially if they can be chained; if you are returning arrays, strings, numbers, functions, or other data types, leave them unwrapped.

    2 - You Aren’t Documenting Your Code (Correctly)

    Arguably, the most important thing you can do when publishing your code is add the necessary documentation. The gap between what you explain to developers and what the code actually does or can do is the time that users don’t want to waste figuring out the ins and outs of your code.

    Documentation is a practice that doesn’t have any hard-fast rules; however, it is generally accepted that the more (well organized) documentation you have, the better.

    This process should be both an internal practice (within/interspersed throughout your code) as well as an external practice (explaining every public method, option, and multiple use cases thoroughly in a wiki or readme).

    3 – You Aren’t Providing Enough Flexibility or Customizability

    The most popular plugins offer full access to variables (what most plugins refer to as “options” objects) that a user may want to control. They also may offer many different configurations of the plugin so that it is reusable in many different contexts. For instance, let’s consider a simple slider plugin. Options that the user might wish to control include the speed, type, and delay of the animation.

    It’s good practice to also give the user access to classnames/ID names which are added to the DOM elements inserted or manipulated by the plugin. But beyond this, they may also want to have access to a callback function every time the slide transitions, or perhaps when the slide transitions back to the beginning (one full “cycle”).

    It’s your job to think of all possible uses and needs for the plugin.

    Let’s consider another example: a plugin that makes a call to an API should provide access to the API’s returned object. Take the following example of a simple plugin concep:.

    $.fn.getFlickr = function(opts) {
    	return this.each(function(){ // jQuery chainability
    		var defaults = { // setting your default options
    			cb : function(data){},
    			flickrUrl : // some default value for an API call
    		}
    	    // extend the options from defaults with user's options
    	    var options = $.extend(defaults, opts || {});
    
    	    // call the async function and then call the callback
    	    // passing in the api object that was returned
    	    $.ajax(flickrUrl, function(dataReturned){
    			options.cb.call(this, dataReturned);
    		});
    	});
    }
    

    This allows us to do something along the lines of:

    	$(selector).getFlickr(function(fdata){ // flickr data is in the fdata object });
    

    Another way of publicizing this is to offer “hooks” as options. As of jQuery 1.7.1 and up, we can use .on(eventName, function(){}) after our plugin call to separate the behaviors into their own functions. For instance, with the plugin above, we could change the code to look like this:

    $.fn.getFlickr = function(opts) {
    	return this.each(function(i,el){
    		var $this = el;
    		var defaults = { // setting your default options
    			flickrUrl : " [someurl.com"] // some default value for an API call
    		}
    	    var options = $.extend(defaults, opts || {});
    
    	    // call the async function and then call the callback
    	    // passing in the api object that was returned
    	    $.ajax(flickrUrl, function(dataReturned){
    	    	// do some stuff
    			$this.trigger("callback", dataReturned);
    		}).error(function(){
    				$this.trigger("error", dataReturned);
    			});
    	});
    }
    

    This allows us to call the getFlickr plugin and chain other behavior handlers.

    $(selector).getFlickr(opts).on("callback", function(data){ // do stuff }).on("error", function(){ // handle an error });
    

    You can see that offering this kind of flexibility is absolutely important; the more complex actions your plugins have, the more complex the control that should be available.

    4 – You’re Requiring Too Much Configuration

    Ok, so tip number three suggested that the more complex actions your plugins have, the more complex control that should be available. A big mistake, however, is making too many options required for plugin functionality. For instance, it is ideal for UI based plugins to have a no-arguments default behavior.

    $(selector).myPlugin();
    

    Certainly, sometimes this isn’t realistic (as users may be fetching a specific feed, for instance). In this case, you should do some of the heavy lifting for them. Have multiple ways of passing options to the plugin. For instance, let’s say we have a simple Tweet fetcher plugin. There should be a default behavior of that Tweet fetcher with a single required option (the username you want to fetch from).

    $(selector).fetchTweets("jcutrell");
    

    The default may, for instance, grab a single tweet, wrap it in a paragraph tag, and fill the selector element with that html. This is the kind of behavior that most developers expect and appreciate. The granular options should be just that: options.

    5 – You’re Mixing External CSS Rules and Inline CSS Rules

    It’s inevitable, depending upon the type of plugin, of course, that you will have to include a CSS file if it is highly based on UI manipulations. This is an acceptable solution to the problem, generally speaking; most plugins come bundled with images and CSS. But don’t forget tip number two – documentation should also include how to use/reference the stylesheet(s) and images. Developers won’t want to waste time looking through your source code to figure these things out.

    Things should just…work.

    With that said, it is definitely a best practice to use either injected styles (that are highly accessible via plugin options) or class/ID based styling. These IDs and classes should also be accessible, via options as previously mentioned. Inline styles override external CSS rules, however; the mixing of the two is discouraged, as it may take a developer a long time to figure out why their CSS rules aren’t being respected by elements created by your plugin. Use your best judgment in these cases.

    As a rule of thumb, inline CSS is bad – unless it’s so minimal to the point that it doesn’t warrant its own external stylesheet.

    6 – You Don’t Offer Examples

    The proof is in the pudding: if you can’t provide a practical example of what your plugin does with accompanying code, people will quickly be turned off to using your plugin. Simple as that. Don’t be lazy.

    A good template for examples:

    • A “hello world” example – usually the plugin call with the minimum configuration/options passed, and it’s accompanying html/css
    • A few more involved examples – usually with examples of full functionality of multiple options
    • An integration example – if someone might use another plugin with your plugin, here is where you can show how to do that. (This gets you bonus points in the open-source development world, too. Kudos.)
    7 – Your Code Doesn’t Match Their jQuery Version

    jQuery, like any good code library, grows with every release. Most methods are kept even after support is deprecated. However, new methods are added on; a perfect example of this is the .on() method, which is jQuery’s new all-in-one solution for event delegation. If you write a plugin that uses .on(), people using jQuery 1.6 or earlier will be out of luck. Now I’m not suggesting that you code for the lowest common denominator, but, in your documentation, be sure to explain which version of jQuery your plugin supports. If you introduce a plugin with support for jQuery 1.7, you should strongly consider maintaining support for 1.7 even once 1.8 comes out. You should also consider taking advantage of new/better/faster features in jQuery as they come out.

    Encourage developers to upgrade, but don’t break your plugin too often! One option is to offer a “legacy” deprecated, non-supported versions of your plugin.

    8 - Where’s the Changelog?

    It’s time to bite the bullet if you haven’t learned how to use version control yet.

    Along with keeping your jQuery version support/compatibility a part of your documentation, you should also be working in version control. Version control (specifically, via GitHub) is largely the home of social coding. If you are developing a plugin for jQuery that you want to eventually publish in the official repository, it must be stored in a GitHub repository anyway; it’s time to bite the bullet if you haven’t learned how to use version control. There are countless benefits to version control, all of which are beyond the scope of this article. But one of the core benefits is that it allows people to view the changes, improvements, and compatibility fixes you make, and when you make them. This also opens the floor for contribution and customization/extension of the plugins you write.

    Additional Resources 9 – Nobody Needs Your Plugin

    The world doesn’t need another slider plugin.

    Ok, we’ve ignored it long enough here: some “plugins” are useless or too shallow to warrant being called a plugin. The world doesn’t need another slider plugin! It should be noted, however, that internal teams may develop their own plugins for their own uses, which is perfectly fine. However, if you’re hoping to push your plugin into the social coding sphere, find a reason to write more code. As the saying goes, there’s no reason to reinvent the wheel. Instead, take someone else’s wheel, and build a racecar. Of course, sometimes there are new and better ways of doing the same things that have already been done. For instance, you very well might write a new slider plugin if you are using faster or new technology.

    10 – You Aren’t Providing a Minified Version

    This one is fairly simple: offer a minified version of your code. This makes it smaller and faster. It also ensures that your Javascript is error free when compiled. When you minify your code, don’t forget to offer the uncompressed version as well, so that your peers can review the underlying code. Free and cheap tools exist for front-end developers of all levels of experience.

    Refer to tip number thirteen for an automated solution.

    11 – Your Code is Too Clever

    When you write a plugin, it is meant to be used by others, right? For this reason, the most effective source code is highly readable. If you’re writing countless clever one-liner lambda style functions, or your variable names aren’t semantic, it will be difficult to debug errors when they inevitably occur. Instead of writing short variable names to save space, follow the advice in tip number nine (minify!). This is another part of good documentation; decent developers should be able to review your code and understand what it does without having to expend too much energy.

    If you find yourself calling variables “a” or “x“, you’re doing it wrong.

    Additionally, if you find yourself consulting documentation to remember what your own strange looking code is doing, you also likely need to be less concise and more explanatory. Restrict the number of lines in each function to as few as possible; if they stretch for thirty or more lines, there might be a code smell.

    11.You Don’t Need jQuery

    As much as we all love using jQuery, it is important to understand that it is a library, and that comes with a small cost. In general, you don’t need to worry too much about things like jQuery selector performance. Don’t be obnoxious, and you’ll be just fine. jQuery is highly optimized. That said, if the sole reason why you need jQuery (or a plugin) is to perform a few queries on the DOM, you might consider removing the abstraction entirely, and, instead, sticking with vanilla JavaScript, or Zepto.

    Note: if you decide to stick with vanilla JavaScript, ensure that you’re using methods that are cross-browser. You might potentially need a small polyfill for the newer APIs.

    13 – You’re Not Automating the Process

    Use Grunt. Period.

    Grunt is a “task-based command line build tool for JavaScript projects”, which was covered in detail recently here on Nettuts+. It allows you to do things like this:

    grunt init:jquery
    

    This line (executed in the command line) will prompt you with a set of questions, such as the title, description, version, git repository, licenses, etcetera. These pieces of information help to automate the process of setting up your documentation, licensing, etc.

    Grunt does far more than just make some customized boilerplate code for you; it also offers built in tools, like the code linter JSHint, and it can automate QUnit tests for you as long as you have PhantomJS installed (which Grunt takes care of). This way, you can streamline your workflow, as tests run instantly in the terminal on save.

    14 – You’re Not Testing

    Oh, by the way – you do test your code, right? If not, how can you ensure/declare that your code works as expected? Manual testing has its place, but, if you find yourself refreshing the browser countless times every hour, you’re doing it wrong. Consider using tools, such as QUnit, Jasmine, or even Mocha.

    Testing is particularly useful when merging in pull requests on GitHub. You can require that all requests provide tests to ensure that the new/modified code does not break your existing plugin.

    If the concept of testing jQuery plugins is brand new to you, consider watching our Premium-exclusive screencast, Techniques For Test-Driving jQuery Plugins. Additionally, we’re launching a new “JavaScript Testing With Jasmine” course later this week on the site!

    Some Helpful Resources

    We wouldn’t be doing you any favors by just telling you what you’re doing wrong. Here are some links that will help get you back on the right path!

    Closing Thoughts

    If you are writing a jQuery plugin, it is vital that you stray away from the pitfalls listed above. Did I miss any key signs of a poorly executed plugin?


  • Permalink for 'Best of Tuts+ in April 2012'

    Best of Tuts+ in April 2012

    Posted: May 6th, 2012, 6:20pm MDT by David Appleyard

    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!

    We’ve Been in Kuala Lumpur!

    This month we’ve been attending an Envato company meet-up in Malaysia. We’ve had a fun time working together as a team, made lots of exciting plans for the future of Tuts+, and also had the chance to meet up with lots of our readers! Thanks to everyone who took the time to attend our community meet-up and, if you’re interested, you can find out a bit more about our trip here (and see a few photos!)

    Psdtuts+ — Photoshop Tutorials
    • Use Photoshop CS6 to Create a Micro Machines Inspired Scene Use Photoshop CS6 to Create a Micro Machines Inspired Scene

      Photoshop CS6 is packed with new features and effects that you can use in your work. In this tutorial we will utilize Photoshop’s new 3D capabilities as well as its new content aware features to create a Micro Machines inspired composition. Let’s get started!

      Visit Article

    • Create a Snowy Landscape From Desert Photography in Photoshop – Tuts+ Premium Tutorial Create a Snowy Landscape From Desert Photography in Photoshop – Tuts+ Premium Tutorial

      Photoshop is a great tool because it allows us to be creative and produce imagery that would be impossible to create otherwise. In this Tuts+ Premium tutorial, author Tony Aubé will create a snowy landscape from desert photography and photos of sand. This tutorial is available exclusively to Tuts+ Premium Members. If you are looking to take your photo manipulation skills to the next level then Log in or Join Now to get started!

      Visit Article

    • Create a Light Bulb Inspired Text Effect in Photoshop Create a Light Bulb Inspired Text Effect in Photoshop

      Layer styles are a powerful and time saving feature that can help you apply amazing effects to your designs. In this tutorial we will use layer styles to create a light bulb inspired text effect in Photoshop. Let’s get started!

      Visit Article

    • Nettuts+ — Web Development Tutorials
    • The Build Tool for JavaScript Meet Grunt: The Build Tool for JavaScript

      If you’re working on a large project, you’ll no doubt have a build script or a bunch of task scripts to help with some of the repetitive parts of the process. You might use Ant or Rake, depending on the language the project is written in.

      Visit Article

    • Borders CSS Refreshers: Borders

      Sure, we’re all familiar with borders. Is there anything new that could possibly be introduced? Well, I bet there’s quite a few things in this article that you never knew about!

      Visit Article

    • Lightning Fast Folder and File Creation in Sublime Text 2 Lightning Fast Folder and File Creation in Sublime Text 2

      I’m frequently asked about how I’m able to create new directory structures and files so quickly in Sublime Text 2. Well the answer is that this functionality is not offered natively; instead, I use a helpful plugin. I’ll demonstrate it in this video.

      Visit Article

    • Vectortuts+ — Illustrator Tutorials
    • The Line of Action, Make Your Character Poses More Dynamic! Quick Tip: The Line of Action, Make Your Character Poses More Dynamic!

      The line of action is a key ingredient to making your character’s poses look more dynamic. In this guide, we will explore what the line of action is and how it can be used to make your character poses come alive.

      Visit Article

    • 200+ Free Vector Grunge Graphics for Designers and Illustrators Free Vector Grunge Graphics for Designers and Illustrators

      If you’re looking for free vector grunge graphics, such as distressed backgrounds, worn textures, dirty paint splatter, and more, then you’ve found a compilation worth downloading. We’ve collected an assortment of vector grunge illustrations, free vector grunge textures, and wickedly worn graphics available for free download. Jump in and grab these free grunge vectors now and start making grunge vector art for your next project.

      Visit Article

    • Creating a Retro Flyer Design Vintage Vector Design Workflow: Creating a Retro Flyer Design

      This tutorial will cover the process of creating a vintage inspired retro flyer design. There are four main areas of concentration to achieve this look and feel: color, type, character and texture. We’ll review a complete vintage vector design workflow to create this retro flyer design. Let’s get started.

      Visit Article

    • Webdesigntuts+ — Web Design Tutorials
    • Speed Up Your Workflow With Photoshop Actions Quick Tip: Speed Up Your Workflow With Photoshop Actions

      Avoiding repetitive tasks is always going to speed up your workflow. In today’s Quick Tip we’ll do just that, by utilizing Photoshop’s actions panel and combining it with hotkeys. Watch this quick screencast and I guarantee you’ll save tons of time next time you’re designing!

      Visit Article

    • Finishing Off Building a Responsive Layout With Skeleton: Finishing Off

      During previous screencasts in this series we’ve covered a lot of ground, building our responsive (or adaptive) layout with the Skeleton boilerplate. It’s now time to finish all the final details; arguably the most time-consuming part of any website build!

      Visit Article

    • Improvements for Web and UI Designers Adobe Photoshop CS6: Improvements for Web and UI Designers

      Photoshop CS6 has been hailed as a huge improvement for web and UI designers. Im going to share with you some of the features that Photoshop CS6 Beta has to offer and demonstrate how they can help you in your web or UI design workflow.

      Visit Article

    • Phototuts+ — Photography Tutorials
    • A How-To Guide to Getting Started in Real Estate Photography A How-To Guide to Getting Started in Real Estate Photography

      Real estate is one of the world’s most competitive industries. Dominated by ambitious agents looking for the next big sale, selling real estate is all about setting yourself apart from the competition. What better way to catch a buyer’s eye than the perfect photo of the perfect home? In today’s article, we’re taking a look at the exciting world of real estate photography.

      Visit Article

    • The 18% Gray Card A Simple Solution to White Balance and Exposure: The 18% Gray Card

      An 18% gray card is a handy accessory that every serious photographer should keep in their bag. It doesn’t cost much and it barely takes up any space. If you encounter a situation where you have mixed lights, this unassuming piece of plastic helps you determine the white balance. It can also be used to determine the correct exposure.

      Visit Article

    • An Expert Guide to Matting and Framing a Photo An Expert Guide to Matting and Framing a Photo

      The final printed image is the culmination of my journey in creating a piece of artwork that represents my view of the world around me. As photographers in the digital age we spend far too much time staring at our photographs on our computer screens and very little time holding them in our hands. I still take great pride in every print I produce. There are a myriad of options for printing your work today, from canvas wraps to Metal prints, however for me there is something timeless and classic about a finely Matted and Framed print.

      Visit Article

    • Cgtuts+ — Computer Graphics Tutorials
    • Rigging A Voodoo Doll Character In Maya Using Setup Machine & Face Machine Rigging A Voodoo Doll Character In Maya Using Setup Machine & Face Machine

      In this tutorial you’ll learn how to create a complete character rig for a voodoo doll character in Maya using the Setup Machine and Face Machine plugins from Anzovin studios. You’ll learn how these plugins can save you valuable time during rigging by allowing you to utilize pre-built body and face rigs which can then be customized to fit you and your character’s specific needs.

      Visit Article

    • Creating A Stylish 3D Countdown Animation In Cinema 4D Creating A Stylish 3D Countdown Animation In Cinema 4D

      In this tutorial we’re going to create a smooth, stylish countdown animation. You can use words, letters, logos or whatever you want to make this type of animation. As you can see it’s easy to set up and looks very stylish and attractive.

      Visit Article

    • Create a 3D Micro Robotic Insect in ZBrush Create a 3D Micro Robotic Insect in ZBrush

      This week, Cgtuts+ has teamed up with our sister site Psdtuts+ to bring you this amazing two part, in-depth tutorial from Nacho Riesco. In this tutorial we are going to sculpt a Micro Bionic Insect with chemical war purposes using simple hard-surface modelling techniques with the Clipping Brush, Masking and much more. Head over to Psdtuts+ for the conclusion of this project where we’ll composite our render passes from Zbrush, and create the final image in Photoshop!

      Visit Article

    • Aetuts+ — After Effects Tutorials
    • Make Your Own Durable Light Dimmers For Less Than $30 Make Your Own Durable Light Dimmers For Less Than $30

      In today’s tutorial we’re going to take you step by step through everything you need to know to build your own rugged light dimmers. We use these exact dimmers on all our studio and on location shoots. Besides being extremely durable, these little devices provide a wider range of lighting options and are surprisingly valuable when you have to light a scene in a tight location.

      Visit Article

    • Is Working On Stills Easier in After Effects or Photoshop? Is Working On Stills Easier in After Effects or Photoshop?

      We always tend to go to Photoshop for working with still images, but today I’d like to bring up a few thoughts about why working in After Effects might be a better solution for your next project.

      Visit Article

    • Show A Motion Path With The StroMotion Effect Show A Motion Path With The StroMotion Effect

      In this tutorial we will track freeze frames into a hand-held scene utilizing The Foundry’s CameraTracker to achieve an effect that is often referred to as “StroMotion”. We’ll be talking about different methods of how to remove the subject from the background and how to line everything up. Enjoy! )

      Visit Article

    • Audiotuts+ — Audio & Production Tutorials
    • 30+ Sites That Serve Up Great Loops and Samples Sites That Serve Up Great Loops and Samples

      Loops can form the foundation of a track, and are useful for quickly putting some ideas together when sketching out an arrangement. Samples provide us with sounds and colors to create our music with. But where can you download great loops and samples? Here are 30+ great places to start.

      Every music producer worth his salt is in the process of building up a useful collection of useable sounds.

      Visit Article

    • Morphing in Pro Tools Morphing in Pro Tools

      We’ve all seen how you can morph one face into another in the graphical world. In this screencast Rishabh Rajan shows us how to achieve the same thing with audio using Pro Tools.

      Visit Article

    • Mastering, The Final Chapter (Part 1) D Mixing Part 7: Mastering, The Final Chapter (Part 1)

      Although this is a series on mixing, it feels incomplete not to get into at least a brief discussion on master bus options and to discuss what exactly goes on when you print all your hard work to a single and final stereo file. Due to the depth of this topic, I am splitting it into two parts.

      Visit Article

    • Activetuts+ — Flash, Flex & ActionScript Tutorials
    • What Is Dart, and Why Should You Care? What Is Dart, and Why Should You Care?

      In this tutorial, I’ll introduce you to Google’s new web programming language, Dart, and explain why you should like it and what you need to know about it. Learn about this new language and form some opinions about it – will it really replace JavaScript?

      Visit Article

    • Accessing the Same Saved Data With Separate Flash and JavaScript Apps Accessing the Same Saved Data With Separate Flash and JavaScript Apps

      In this tutorial I will show you how to access the same saved data in separate Flash and JavaScript apps, by storing it in HTML5 LocalStorage and using ExternalInterface to reach it with AS3. We will create the same app in both JavaScript and Flash to demonstrate that it is platform agnostic.

      Visit Article

    • Introduction An ImpactJS Overview: Introduction

      Impact is an incredibly powerful HTML5 game framework which takes advantage of modern browser’s canvas element and can also run on mobile or be compile into a native iOS app. In this video I will go over the framework, how to set up a project, some background into how to create classes in it and finally go over the core classes that make up the framework. This is a high level overview which will give you a general sense for how things work.

      Visit Article

    • Wptuts+ — WordPress Tutorials
    • Mini Guide to Contact Form 7 Mini Guide to Contact Form 7

      Usually a website needs a contact form to communicate with the site owner. One of our favorites is Contact Form 7. Let’s see what it can do!

      Visit Article

    • Custom Post Type Helper Class Custom Post Type Helper Class

      For a lot of WordPress projects these days we use custom post types. The WordPress development team created some handy methods to integrate them into your projects. But when you use custom post types, taxonomies and meta boxes frequently, it’s quite probable that you’re going to repeat yourself. That’s why we are going to use the power of these WordPress functions to build a more powerful class, which we can use to quickly register post types, taxonomies and meta boxes.

      Visit Article

    • Using WordPress as an Intranet Using WordPress as an Intranet

      When we talk about WordPress we usually associate it with either being a blogging platform or just another content management system, but what about as an Intranet? This tutorial will show you how you can turn your basic installation of WordPress into a robust Intranet for your business.

      Visit Article

    • Mobiletuts+ — Mobile Development Tutorials
    • Create an Awesome Carousel, Version 2.0 Create an Awesome Carousel, Version 2.0

      Engage your users with stunning carousels! We’ll look at how easy and clean it can be to implement scrollable, interactive carousels in your iOS applications. With high configurability, you can have 3D, flat, rotating, and endless scrolling arrays for data, images, and buttons.

      Visit Article

    • Create an Alphabet Soup Game Corona SDK: Create an Alphabet Soup Game

      In this tutorial series, you will learn how to create a minimalistic Alphabet Soup game. The goal of this game is to allow the player to pick words out from a jumbled set of letters. Read on!

      Visit Article

    • Interacting with Web Services iOS Quick Tip: Interacting with Web Services

      At some point in your iOS development career, you will have the need to interact with a web service from within your app. You may need to access remote data, parse a social network feed, or even download some assets into your application. This quick tip will teach you to do so without using third party libraries!

      Visit Article


  • Permalink for 'Reshaping Our Perception of Success'

    Reshaping Our Perception of Success

    Posted: May 4th, 2012, 8:02pm MDT by Jeffrey Way

    Over the course of these last two weeks, I had the pleasure of attending an Envato meetup/conference in Malaysia. As you might expect, Envato is composed of ridiculously smart and talented folks…folks so smart that it quickly becomes intimidating!

    But I’m not here to talk about the conference specifically; instead, I’d prefer to ramble a bit on one of my largest takeaways from the event.

    The Old-Fashioned “Path” The Path

    One day during the conference, I had a chat with Envato’s current (temporary) lead development manager, Pete, about the traditional concept of advancement in a company. In many ways, we’re designed/brainwashed from an early age to follow a very specific path:

    • Begin at the bottom.
    • Slowly work your way up to your target position (meaning the job in which you are most content and fullfilled).
    • Finally, despite your instincts advising you otherwise, you disregard your current contentment, and instead continue once again up the stairs… to management.

    That’s a good thing, right? Well, in our industry, specifically, maybe not.

    Management can be a bit of a scary word. It indicates Excel, not code. It indicates… management, not development.

    Our life-long training tells us that this is what’s supposed to happen.

    But, nonetheless, it’s still a higher level (hopefully higher paying) job. Our life-long training tells us that this is what’s supposed to happen, if we desire to be successful. You’ve worked hard; now you get to manage others (and maybe drink scotch). This is the path.

    For creatives, though, does this sort of role make us happy?

    • Is this what kept us up late at night learning how to code?
    • Are we selling our souls (to be dramatic) for slightly more money?
    • Are we addicted to some silly notion of control or power or respect?

    Sure, we may have a bit more input into the direction of the business, but does it make us happier? For the last year or so, I’ve struggled with this very thing. I adore my current job: I’m able to help shape the future of education in the creative fields (more on that later this year), and spend all of my spare/free time learning how to be a more efficient developer. What could be better than that?

    Still, though, that lingering feeling always rested in the back of my mind: I’m only “advancing” in the world if my job title/rank increases sporadically. I had (and have) no desire to change my current involvement/role in the company (Envato), but, nevertheless, felt that I should reach for these more traditional managerial roles.

    This old-fashioned notion of advancement is a silly metric for success.

    The Lesson

    Pete taught me that this old-fashioned notion of advancement is a silly metric for success. Instead, we have to reshape our perception of what both success and fulfillment are. Remember when I noted that Pete was the development manager at Envato? Well, technically, at his own choosing, he’s the temporary manager, while we search for a new development manager. Despite the fact that he’s certainly qualified for the job, he doesn’t want it – which I find incredibly admirable. Instead, his skills/desires rest firmly in things like software architecture. In his own words, that is where he is able to contribute most effectively to the company. So, a bit oddly, perhaps, he is currently in the position of finding and hiring his future manager.

    Closing Thoughts

    It’s interesting how the older I get, the more and more I come back to this one word: “contentment.” It’s not about job titles, or vanity, or even money (to some extent); it’s simply about contentment. Do what you love, and forget those old-fashioned job titles and notions of success. Or…

    Figure out where you’re most effective in your company, and do…that. Period.


Dev Articles - Programming Help and Tutorials for all development technologies

  • Permalink for 'The Top HTML5 Audio Players'

    The Top HTML5 Audio Players

    Posted: May 2nd, 2012, 9:00am MDT
    HTML5 has certainly made a name for itself and has managed to overshadow the previously ubiquitous technology known as Flash. While you usually hear about HTML5's impressive capabilities when it comes to video, it has solid audio capabilities as well. To show you how those capabilities have been put to use, this article will list some of the top HTML5 audio players around. As you search on your own you will likely find more audio players, but this list will give you a sneak peek as to what is out there. MediaElement.js MediaElement.js offers both audio and video playing capability via pure...

Nettuts+

  • Permalink for 'Why Wine and Macbooks Don’t Mix…and How to Handle the Aftermath'

    Why Wine and Macbooks Don’t Mix…and How to Handle the Aftermath

    Posted: May 1st, 2012, 4:18pm MDT by Jeffrey Way

    Ready for a revelation? A concept that you’ve never considered before? Well here it is: never ever, ever pour a glass of wine into your Macbook keyboard. Or, more practically put, be extremely careful when there’s a drink of any kind near your laptop. If a spill occurs, and you don’t act quickly enough, you’ll find yourself staring at a massive bill for a new logic board, hard-drive, battery, and anything in between.

    Accidents do happen — so plan on it. What’s more important is that you learn exactly what to do when these spills inevitably occur.

    July, 2010 Step 1. Don’t Freeze. Unplug! Macbook Wine Spill

    Ahhhh! The wife (meaning, you) accidentally spilled wine all over your keyboard. From personal experience, I can assure you that, for some odd reason, your first instinct with a massive computer spill is to freeze for five seconds or so, in shock. Don’t do this! Luckily Apple laptops are pretty helpful about automatically shutting down to prevent as many issues as possible before they happen. The more recent laptops even have liquid detection…though I’m certain that Apple is more interested in voiding your warranty than protecting you. For those uninformed, most laptop warranties do not cover spills.

    Nonetheless, don’t waste a single second. Quickly unplug the computer, and shut it down.

    The walls and carpet may have liquid on them as well, but ignore that. The computer is far more important right now.

    Step 2. Flip that Sucka Turn the laptop over to let the liquid drain

    The next step, which should occur within seconds of beginning Step 1, is to flip the laptop upside down, into an L-shape. Gravity will then force as much liquid to drain out of the keyboard as possible. Make sure that you lay it on a towel so that it can soak up the liquid.

    Let gravity do its job. Immediately flip the laptop into an L-shape.

    Step 3. Open the Back Unscrew the laptop to reveal the insides

    Using a tiny screw driver, unscrew the back-side of your laptop. This will, of course, vary, depending upon which model you’re using. I’m sure you can figure it out.

    Particularly on Macs, not all of the screws are the same size. Make a note of which screw goes where.

    Step 4. Remove the Battery and Hard Drive Remove the Macbook Pro battery

    Before progressing, ensure your livelihood and touch some metal objects nearby to remove any potential static electricity from your body.

    Needless to say, batteries and liquids — especially sugary, acidic liquids — don’t play nice together. Wherever yours is located on your laptop, remove it as quickly as possible. Next, get the hard drive out as well. We don’t want to risk any liquid seeping in, and corrupting your file system!

    And now that you know how easy it is to remove a hard drive, don’t ever again pay a person to upgrade your hard drive. It only takes a moment to do yourself. ;)

    Step 5. Dry the Insides Clean the insides of the computer after a drink spill

    With a paper towel of some sort, begin cleaning the insides of your computer. Depending upon how much liquid was spilled, this may either be a quick or lengthy process. For yours truly, it took around ten minutes to clean everything.

    Some people prefer to use a hair dryer to clean the insides. This one is up to you; however, I’d encourage you to not do so. Play it safe and use a towel. We don’t want to risk frying the insides.

    Step 6. Rubbing Alcohol and Cotton Clean the insides with a cotton swab

    Next, we need to continue removing as much sugar and acid as possible from the logic board. Otherwise, over time, it can begin to corrode the wiring. Yeah, this isn’t good!

    Using rubbing alcohol and a cotton swab, begin dabbing any stained areas — but be gentle. If you have access to the backside of your keyboard, clean that area as well. Unfortunately, on the newer Macbook Pro models, it’s extremely difficult to access this section. With past models, it was quite easy to remove the keyboard entirely, for cleaning purposes. Unfortunately, that’s no longer the case.

    Rubbing alcohol will help dissolve any remaining acid or sugar on the logic board.

    Step 7. Leave it Alone Leave the computer off for 3-5 days after a spill

    Anxiety is a dangerous thing. Resist the urge to determine whether or not you’ve destroyed your laptop, and keep it off for a minimum of 72-120 hours (3-5 days). This will allow any remaining liquid to dry/evaporate first. Make sure that, while its drying, you keep the battery outside of the computer. This is mostly a precaution.

    Keep the computer off for 3-5 days — no questions asked. Do not turn it on during this window.

    Step 8. Cross Your Fingers Cross your fingers

    After 72-120 hours, reconnect the battery, screw everything back in, cross your fingers, say a prayer, and turn on the computer. Particularly if you’re using a newer Macbook Pro (2010+ models), you’ve done everything you can do. With hope, and more often than not, it’ll chime, and start-up like a charm. However, if the battery is dead, or the hard drive is corrupted, you’re next best option is to take it in for official repair. Of course, this will somewhat depend upon how skilled you are, when working under the hood.

    About the Author

    Jeffrey Way — me…yes, I’m speaking in third person — once committed a Cardinal Sin, and caused a massive wine spill into his Macbook Pro. Had he not followed these exact steps, he’d be forking over another life savings for a new Mac. Luckily, that was not the case.

    Thanks for reading. Should the same ever happen to you, I hope this guide will help a bit!


  • Permalink for 'Recently in Web Development (April ’12 Edition)'

    Recently in Web Development (April ’12 Edition)

    Posted: April 30th, 2012, 2:04pm MDT by Siddharth

    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.

    Nettuts image The Infamous Semi-Colon Debate

    Ahh, JavaScript. I think it has caused more conflict than thatHelen. This time around there’s been a flurry of activity around a single, missing comma. I don’t want to take you away from the drama so check out the Github discussion below, after grabbing some popcorn.

    Personally, if you’re not CoffeeScript-ing, just add that darn semi-colon and call it a day.

    Click here for internet drama

    Nettuts image Django Moves to Github, Finally

    Most Pythonistas know Django. For those of you who don’t, Django is a high level Python framework that helps you out with web development. While Django has had a repo on Github for a long time now, it was in a state of desolation. You’d often see that the repo only held versions that were a lot behind the curve.

    Well, no more of that. Django has finally moved to Github and the repo seems to be active. If you’re interested, Subversion was what was used to manage Django earlier, since 2005.

    Github repo

    Nettuts image Meteor, a New Way to Build Apps

    Tired of the current frameworks and technologies, a group of devs has created a full stack, JavaScript only framework.

    Meteor is a set of new technologies for building top-quality web apps in a fraction of the time, whether you’re an expert developer or just getting started. I’m sure people are already tired of reading about JavaScript and the sheer number of frameworks sprouting out each day but this is really worth a look.

    Read more

    Nettuts image SPDY Gains More Traction With Firefox Beta

    SPDY, developed by Google, is a networking protocol aimed at improving web page load times as well as web security.

    As with anything web related, it takes eons to get anything standardized and browsers have already started implementing experimental versions of the technology. The latest Firefox beta adds support for the protocol, switching it on by default. It’s not the only browser to do — Chrome already includes support for SPDY while Opera does the same with its preview of version 12.

    Release Notes

    Nettuts image Microsoft Announces the Metro jQuery Mobile Theme

    Microsoft, in order to increase awareness of its spectacularly clean Metro interface, has open sourced a Metro themed design for jQuery mobile. The theme includes a large number of Metro themed widgets and interactions and seems to work really well.

    Read more

    Nettuts image Firefox is Now At Version 12

    Another month, another Firefox update. To be fair, the updates are now rather substantial this time around though.

    This version introduces a ton of developer tools and improvements along with a far more streamlined update process. The list of developer related updates, the ones we really care about, makes for a rather interesting read so make sure to hit the link below.

    Read more

    Nettuts image CoffeeScript, Now With JavaScript’s Strict Mode, Updates to Version 1.3

    Developers either love or hate CoffeeScript. I personally love it which is why you’re seeing this here. The latest version enforces the strict more at compile time helping you weed out those annoying, niggling issues.

    Version 1.3 also brings you improvements to the REPL as well as a bunch of tweaks and improvements.

    Change log

    Nettuts image Rails Updates in Light of Recent Security Issues

    With the havoc caused by the mass assignment issue last month, the Rails team has reconsidered their stance on this issue and has pushed out version 3.2.3 which changes the value of config.active_record.whitelist_attributes . There are also various, assorted fixes and improvements bundled into this version.

    Release Notes

    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.

    Smooth.js

    Smooth.js takes an array of numbers or vectors and returns a parametric function that continuously interpolates that array. Smooth.js supports several interpolation methods, and flexible options for boundary behavior.

    Github Repo

    Scroll Path

    jQuery Scroll Path is a plugin that lets you define your own custom scroll path. What this means exactly is best understood by checking out the demo. The plugin uses canvas flavored syntax for drawing paths, using the methods moveTo, lineTo and arc. To help with getting the path right, a canvas overlay with the path can be enabled when initializing the plugin.

    Github Repo

    keymaster.js

    Keymaster is a simple (100 LoC or so) micro-library for defining and dispatching keyboard shortcuts. It has no dependencies.

    Github Repo

    Ham

    PHP Microframework for use with whatever you like. Basically just a fast router with nice syntax, and a cache singleton. Will add more things as I go, like perhaps an extension system, autoloader and some other stuff to make developing in PHP less irritating than it currently is.

    Github Repo

    mailcheck.js

    The jQuery plugin that suggests a right domain when your users misspell it in an email address.

    Github Repo

    Hammer.js

    Hammer.js is a javascript library that can be used to control gestures on touch devices.

    Github Repo

    Monorail.js

    Monorail.js will never force you, and uses only what you need. Monorail.js will never force you to install anything not needed for your project. The goal is to use what you need. Anything other than creating a project will always be optional.

    Github Repo

    Rainbow

    Rainbow is a code syntax highlighting library written in Javascript. It was designed to be lightweight (1.4kb), easy to use, and extendable.

    Github Repo

    Timeline

    There are lots of timeline tools on the web but they are almost all either hard on the eyes or hard to use. Create timelines that are at the same time beautiful and intuitive for users. Timeline is great for pulling in media from different sources. Just throw in a link from Twitter, YouTube, Flickr, Vimeo, Google Maps or SoundCloud and Timeline will format it to fit perfectly. More media types will be supported in the future.

    Github Repo

    FakeS3

    FakeS3 is a lightweight server that responds to the same calls Amazon S3 responds to.
    It is extremely useful for testing of S3 in a sandbox environment without actually making calls to Amazon, which not only require network, but also cost you precious dollars.

    Github Repo

    retina.js

    retina.js makes it easy to serve high-resolution images to devices with retina displays. When your users load a page, retina.js checks each image on the page to see if there is a high-resolution version of that image on your server. If a high-resolution variant exists, the script will swap in that image in-place.

    Github Repo

    Rucksack

    Rucksack is a jquery plugin to arrange elements that can fit in the given width. It relies on the knapsack algorithm.

    Github Repo

    jQuery PopBox

    jQuery PopBox is a simple balloon UI element inspired by 37Signals Highrise CRM.

    Github Repo

    html2canvas

    This script allows you to take “screenshots” of webpages or parts of it, directly on the users browser. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.

    Github Repo

    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.

    Nettuts image PHP: a fractal of bad design

    A detailed look at why most people, when given a gun with two bullets and asked to shoot Hitler or PHP, want to shoot PHP twice. As much of a PHP lover I am, I can’t help but agree with a lot of this article.

    Read more

    Nettuts image PHP Sucks! But I Like It!

    A really well written counter point to the earlier article, backed by a lot of reasoned thinking.

    Read more

    Nettuts image The infernal semicolon

    Brendan Eich chimes in with his stance on the entire JavaScript semi-colon issue.

    Read more

    Nettuts image How to be a successful programmer without a CS degree

    A wonderfully detailed answer on StackOverflow that outlines how to be a kickass programmer without an expensive CS degree.

    Read more

    Nettuts image Zero downtime deploys for Rails apps

    A very informative presentation that outlines how you should go on about running and upgrading your Rails apps.

    Read more

    Nettuts image On being “Senior”

    A nice little read about the software industry and the rat race around titles.

    Read more

    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!


  • Permalink for 'The Essentials of Zepto.js'

    The Essentials of Zepto.js

    Posted: April 28th, 2012, 2:13am MDT by Siddharth

    Modern JavaScript libraries are quite the behemoths — just take a look at jQuery. When you’re creating a mobile app, or even just targeting modern browsers, a library that’s much more svelte and nimble becomes a tastier proposition.

    Today, we’re going to look at one such library, named Zepto.

    The Issue With Mixing Desktop Libraries and Mobile Devices

    One thing that has snuck past most radars has been the rise of mobile devices.

    See, the internet, and the technology that powers it, has grown in leaps and bounds over the past years. We moved from static sites to web applications to dynamic web applications and then to real time, hyper responsive, thingamabob apps of today. One thing that has snuck past most radars has been the rise of mobile devices.

    Think about it: a lot of us use smart phones and use it for browsing on a constant basis. Even at home, a non-trivial portion of my circle has adopted a tablet device for casual surfing and email. While this influx of devices is good from an exposure point of view, it isn’t without its caveats.

    Instead of thinking of these devices as display constrained like consumers do, we, as developers, need to think of them in terms of resources and bandwidth. Not all them sport a hyper quad gajillion Ghz CPU or come with oodles of memory. And let’s not even get started with the bandwidth. A big portion of the browsing population is still stuck on these infernal excuses for a mobile internet connection.

    I think you see where I’m going with this. Big, monolithic libraries like jQuery or Prototype definitely have their place but for this mobile era, I think there’s a place for something that’s a lot more nimble. And a lot of developers seem to agree with me.

    All the Code to Make a Library Work Across Browsers Adds Up

    Another big issue that I failed to mention is that contemporary libraries do a lot of cross browser stuff. In fact, a big draw of jQuery, initially, was how it abstracted away a lot of the cross browser quirkiness that front end developers had to work around. Even now, jQuery does a lot of heavy lifting under the hood to make sure nothing breaks in different browsers.

    But if you’re a developer looking to cater to only contemporary devices, do you really need all this, dare I say, cruft? The short answer is no. By cutting out unnecessary code, you both:

    • eke out more performance since there’s fewer lines of code for the browser to parse and
    • make your file smaller in size, which helps with the bandwidth constrained mobile devices.

    Think that this issue is overblown? Here’s a random blob of code from jQuery’s source:

    isPlainObject: function( obj ) {
    		// Must be an Object.
    		// Because of IE, we also have to check the presence of the constructor property.
    		// Make sure that DOM nodes and window objects don't pass through, as well
    		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
    			return false;
    		}
    ....
    

    Or something a little more esoteric:

    // Perform a simple check to determine if the browser is capable of
    // converting a NodeList to an array using builtin methods.
    // Also verifies that the returned array holds DOM nodes
    // (which is not the case in the Blackberry browser)
    try {
    	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
    
    // Provide a fallback method if it does not work
    } catch( e ) {
    	// The intended fallback
    }
    ....
    

    This may look fairly trivial but keep in mind this tends to adds up. If you’re only going to target modern browsers, either on desktops or mobiles, then there is no real need for all these additional checks and hacks. By cutting down your intended browsers, you win on both bandwidth and performance!

    So What’s Zepto’s Deal?

    I hear you guys saying “Enough buildup! Tell us about the darn library already!”. So let’s get to it.

    Zepto, as the title spoiled it for you, is a mobile JavaScript framework that rectifies both of the issues mentioned above. It has a very small code base and is feather weight at around 8kb.

    It manages to be so svelte by mostly cutting out the cross browser stuff. When it was created, the main focus was to support Webkit only. The mobile version of Webkit to be exact. Now, it’s been expanded to work with desktop browsers too — but only modern ones. No more klutzing around to make things work this IE6!

    Zepto’s API is jQuery compatible. If you use jQuery, you already know how to use Zepto.

    Another area where Zepto manages to be small is how it manages to avoid feature bloat. The core library doesn’t seem to include any extraneous functionality. Even the AJAX and animation functionality are available as separate modules, should the need arise. For users that primarily use libraries for DOM traversal and manipulation, this is an utter god send.

    And, oh, did I mention Zepto’s main party piece? Zepto’s API is jQuery compatible. If you use jQuery, you already know how to use Zepto.

    Are Zepto and jQuery Interchangeable?

    Yes and no. Depends is a more apt answer.

    Yes because Zepto’s core API mimics jQuery to a large extent. In order to make it easy to use and dramatically reduce the learning curve, Zepto emulates jQuery’s API. Most of the oft used methods, like DOM manipulation, are named pretty much the same and have the same parameters in the same order. The method signatures are the same, for the engineers out there.

    Let’s look at a small example:

    $('#element').html("Hey! Are you on the GW2 beta?");
    

    Looks familiar? It should. This is the exact same code you’d use with jQuery to change the HTML of an element. As I mentioned, this isn’t limited to just this method. Most DOM operations are built the same way along with your utilities, like AJAX.

    On the flip side, the API isn’t a 100% match. Zepto forgoes some methods present in jQuery that’s liable to break your code. And just as importantly, since Zepto is a subset of jQuery, you’ll probably miss out on specific functionalities that are built in — Deferred is a fine example. You simply can’t swap out jQuery with Zepto and expect everything to work.

    And for me, the biggest hurdle are the methods that have been copied from jQuery but have a different signature and feature set. It becomes a little frustrating when you think you’re using a method right but you aren’t. The clone method’s ability to copy event handlers is a good example. Without looking at the source, I really wouldn’t have found this out.

    Exploring the Core API

    If you’ve worked with jQuery before, everything below should be a snooze fest.

    Enough chit chat, let’s dive into some code now. As with a lot of modern libraries, DOM traversal and manipulation is a core feature that everyone wants to perfect. Since the API and overall functionality is very similar to jQuery, I think you can safely assume everything is top notch.

    Let’s take a look at some common DOM related functionality.

    Modifying the HTML contents of a container

    This is the bread and butter of DOM operations: reading or changing the HTML contents of an element. With Zepto, it’s as simple as calling the html method on the container, and passing in the new HTML, if needed.

    For example, this obtains the HTML of an element and stores it in a variable.

    var containerText = $('#element').html();
    

    Or if you want to change it to something else:

    $('#element').html("Hola there!");
    

    Pretty simple, right?

    Prepend/Append an Element to a Container

    As with jQuery, Zepto makes use of the append and prepend methods. And the invokation remains the same as well.

    $('#element').append("<p>This is the appended element.</p>");
    
    // or
    
    $('#element').prepend("<p>This is the appended element.</p>");
    
    Events

    Events are the backbone of any modern application and Zepto provides you with a bunch of easy to use methods to get your job done. The bulk of the work is done through the on method.

    $('#element').on('click', function(e){
       // Your code here
    });
    

    Easy to read and easy to parse. If you’re feeling old school and feel like using bind, delegate or live methods, don’t. Just like with jQuery, they’re deprecated here.

    AJAX

    Any modern low level library needs to provide an easy to use wrapper around AJAX and Zepto doesn’t let you down here. Here is an example of a super simple AJAX request.

    
    $.ajax({
      type: 'POST',
      url: '/project',
      data: { name: 'Super Volcano Lair' },
      dataType: 'json',
      success: function(data){
        // Do some nice stuff here
      },
      error: function(xhr, type){
        alert('Y U NO WORK?')
      }
    });
    

    Things might look a little complicated but what we’re doing can be boiled down to:

    • Creating the AJAX object and passing it options.
    • In the options, specifiy that we’d like to do a POST request. The default is GET, I imagine.
    • Specify the URL to POST to.
    • Specify the data that needs to be sent to the server. As you can see, I’m laughing maniacally and trying to create my own super villain lair.
    • Specify methods that will be triggered when the request succeeds or fails. This way, we can update the UI whatever happens.

    As with jQuery, there are separate method for a GET or POST request or ones to merely load up some web content.

    Animations

    What will the world come to without a few animations? Zepto exposes the almighty animate method that should handle most of your animating needs.

    $('#element').animate({
      opacity: 0.50, top: '30px', color: '#656565'
    }, 0.5)
    

    We’re basically selecting the element to be animated, invoking the animate method and specify the properties to be animated as well as the time it should take to finish animating. Zepto does the rest.

    Or if you just need to show and hide an element, the toggle should work just fine.

    I think you get the point here — Zepto’s DOM, animation and events API emulates that of jQuery to a large extent. And as we all know, jQuery is darn good with those things. If you’ve worked with jQuery before, you shouldn’t face too much trouble here.

    A Look at the Touch Events and Other Niceties

    Zepto does provide you with a few touch specific events that you can leverage in your apps. These include:

    • swipe — Handles your typical swipe motion. There are also separate events for different directions, like swipeLeft.
    • tap — Triggered in response to a generic tap action.
    • doubleTap — Obviously, this handles double taps.
    • longTap — It’s triggered when an element is tapped on for more than 750ms. There doesn’t seem to be a straightforward to change this delay though.

    Here’s a quick example, delightfully swiped from Zepto’s documentation.

    <ul id=items>
      <li>List item 1 <span class=delete>DELETE</span></li>
      <li>List item 2 <span class=delete>DELETE</span></li>
    </ul>
    
    <script>
    // show delete buttons on swipe
    $('#items li').swipe(function(){
      $('.delete').hide()
      $('.delete', this).show()
    })
    
    // delete row on tapping delete button
    $('.delete').tap(function(){
      $(this).parent('li').remove()
    })
    </script>
    

    When a list item is swept, every other list element’s delete button is hidden and only the current’s is displayed. Tapping a delete button removes that button’s parent li item to be removed from the DOM.

    This should be fairly similar to how you generally handle events, except you’ve binding your handlers to different events, that’s all.

    Wrapping Up

    Considering what and whom I develop for, this is perfect for me; but as it always is, your mileage may vary.

    Well, that’s about almost all there is to Zepto. At it’s core, it was meant to be a lean, cruft free version of jQuery that could be used on mobile devices. Over time, it has morphed into a lean library that does away with supporting archaic browsers.

    Considering what and whom I develop for, this is perfect for me; but as it always is, your mileage may vary. You may be locked into using jQuery plugins that require non-trivial modifications to make it work under Zepto or just have more faith in jQuery.

    Either way, you really need to give Zepto a try to see how it fits in with your workflow before writing it off. I did and I love it!

    Well, that’s all from me today. Let me know what you think in the comments below and thank you so much for reading!


  • Permalink for 'Closures: Front to Back'

    Closures: Front to Back

    Posted: April 26th, 2012, 8:05pm MDT by Brian Scaturro

    Closures are often viewed as an arcane art in the land of JavaScript. Once mastered, they allow you to write some truly amazing JavaScript. This article will get you up to speed on the magic of JavaScript closures.

    What Is A Closure?

    One of the key truths of JavaScript is that everything is an object. This, of course, includes functions.

    A closure is nothing more than a function object with a related scope in which the function’s variables are resolved.

    Closures get their name because of the way they close over their contents. Consider the following bit of JavaScript:

    topping = "anchovi";
    function pizzaParty(numSlices) {
    	var topping = "pepperoni",
    
    	innerFunction = function() {
    		var topping = "ham";
    		console.log(" .....But put " + topping + " on " + numSlices + " slices");
    	};
    
    	console.log("This pizza is all about the " + topping);
    
    	innerFunction();
    }
    pizzaParty(3);
    

    If you open up your favorite console and run that bad boy, you will be greeted with a delicious message to the effect of “This pizza is all about the pepperoni ….. But put ham on 3 slices.” This example illustrates some key concepts of JavaScript that are crucial to getting a hold on closures.

    A Closure is a Function Object

    How many function objects are in the above code? Well… we have our pizzaParty function, and nested in that function is innerFunction. Math hasn’t always been my strong suit, but 1 + 1 = 2 in my book. Each function object has its own set of variables, which are resolved in each function’s scope.

    A Closure Has its Own Scope

    Closures can’t be fully understood without a firm grounding in scope. JavaScript’s scope mechanism is what allows each function to have its own topping variable, and without it we might have too much pepperoni, too little ham, or *gasp* … some anchovies at our pizza party. Let’s use a quick illustration to better illustrate this idea.

    Functions are executed using the scope that was in effect when the function was defined. It has nothing to do with the scope in effect when the function is called.

    Variable Accessibility Works Outside-In

    The green arrows show that accessibility works from the outside in. Variables defined in the scope outside of a function are accessibile from within it.

    If we were to omit the topping variable from inside the pizzaParty function, then we would get a message like “This pizza is all about the anchovi”, but since pizzaParty has a topping variable within its own scope; those salty suckers will never get near our pizza party.

    Likewise, the numSlices parameter can be accessed from within innerFunction because it is defined in the scope above – in this case the scope of pizzaParty.

    Variable Accessibility Does Not Work Inside-Out

    The red arrows show that variables in scope for a function are never accessible outside of that function. This is the case only when a variable meets one of the following conditions:

    1. The var keyword is being used.
    2. The variable is a parameter to the function or an outer function.
    3. The variable is a nested function.

    Omitting the var keyword when setting a variable will cause JavaScript to set the closest named variable in outer functions all the way up to the global scope. So, using our example, the ham topping in innerFunction cannot be accessed from pizzaParty, and the pepperoni topping in pizzaParty cannot be accessed out in the global scope where the anchovi dwells.

    JavaScript Uses Lexical Scoping

    Lexical scope means functions are executed using the variable scope in effect when the function was defined. It has nothing to do with the scope in effect when the function is called. This fact is crucial to unlocking the power of closures.

    Now that we understand what a closure is, and what scope means for closures, let’s dive into some classic use cases.

    Using Closures For Privacy

    Closures are the way to conceal your code from the public eye. With closures, you can easily have private members that are shielded from the outside world:

    (function(exports){
    
    	function myPrivateMultiplyFunction(num,num2) {
    		return num * num2;
    	}
    
    	//equivalent to window.multiply = function(num1,num2) { ...
    	exports.multiply = function(num1,num2) {
    		console.log(myPrivateMultiplyFunction(num1,num2));
    	}
    
    })(window);
    

    With closures, you can easily have private members that are shielded from the outside world.

    Let’s break it down. Our top level function object is an anonymous function:

    (function(exports){
    
    })(window);
    

    We invoke this anonymous function right away. We pass it the global context (window in this case) so we can “export” one public function, but hide everything else. Because the function myPrivateMultiplyFunction is a nested function, it exists only within the scope of our closure; so we can use it anywhere inside this scope, and only in this scope.

    JavaScript will hold a reference to our private function for use inside the multiply function, but myPrivateMultiplyFunction cannot be accessed outside of the closure. Let’s try this out:

    multiply(2,6) // => 12
    myPrivateMultiplyFunction(2,6) // => ReferenceError: myPrivateMultiplyFunction is not defined
    

    The closure has allowed us to define a function for private use, while still allowing us to control what the rest of the world sees. What else can closures do?

    Using Closures For Meta-Programming

    Closures are quite handy when it comes to generating code. Tired of remembering all those pesky key codes for keyboard events? A common technique is to use a key map:

    var KeyMap = {
    	"Enter":13,
    	"Shift":16,
    	"Tab":9,
    	"LeftArrow":37
    };
    

    Then, in our keyboard event, we want to check if a certain key was pressed:

    var txtInput = document.getElementById('myTextInput');
    txtInput.onkeypress = function(e) {
    	var code = e.keyCode || e.which //usual fare for getting the pressed key
    	if (code === KeyMap.Enter) {
    	    console.log(txtInput.value);
    	}
    }
    
    Capturing A Moment In Time

    The above example isn’t the worst, but we can use meta-programming and closures to make an even better solution. Using our existing KeyMap object, we can generate some useful functions:

    for (var key in KeyMap) {
    
    	//access object with array accessor to set "dyanamic" function name
    	KeyMap["is" + key] = (function(compare) {
    		return function(ev) {
    			var code = ev.keyCode || ev.which;
    			return code === compare;
    		}
    	})(KeyMap[key]);
    
    }
    

    Closures are so powerful because they can capture the local variable and parameter bindings of the function in which they are defined.

    This loop generates an is function for every key in KeyMap, and our txtInput.onkeypress function becomes a bit more readable:

    var txtInput = document.getElementById('myTextInput');
    txtInput.onkeypress = function(e) {
    	if(KeyMap.isEnter(e)) {
    		console.log(txtInput.value);
    	}
    }
    

    The magic starts here:

    KeyMap["is" + key] = (function(compare){
    
    })(KeyMap[key]); //invoke immediately and pass the current value at KeyMap[key]
    

    As we loop over the keys in KeyMap, we pass the value referenced by that key to the anonymous outer function and invoke it immediately. This binds that value to the compare parameter of this function.

    The closure we are interested in is the one we are returning from inside the anonymous function:

    return function(ev) {
    	var code = ev.keyCode || ev.which;
    	return code === compare;
    }
    

    Remember, functions are executed with the scope that was in place when they were defined. The compare parameter is bound to the KeyMap value that was in place during a loop iteration, and so our nested closure is able to capture it. We take a snapshot in time of the scope that was in a effect at that moment.

    The functions we created allow us to skip setting up the code variable everytime we want to check the key code, and we now have convenient, readable functions to use.

    Using Closures To Extend The Language

    At this point, it should be relatively easy to see that closures are vital to writing top notch JavaScript. Let’s apply what we know about closures to augmenting one of JavaScript’s native types (gasp!). With our focus on function objects, let’s augment the native Function type:

    Function.prototype.cached = function() {
    	var self = this, //"this" refers to the original function
    		cache = {}; //our local, lexically scoped cache storage
    	return function(args) {
    		if(args in cache) return cache[args];
    		return cache[args] = self(args);
    	};
    };
    

    This little gem allows any and every function to create a cached version of itself. You can see the function returns a function itself, so this enhancement can be applied and used like so:

    Math.sin = Math.sin.cached();
    Math.sin(1) // => 0.8414709848078965
    Math.sin(1) // => 0.8414709848078965 this time pulled from cache
    

    Notice the closure skills that come into play. We have a local cache variable that is kept private and shielded from the outside world. This will prevent any tampering that might invalidate our cache.

    The closure being returned has access to the outer function’s bindings, and that means we are able to return a function with full access to the cache inside, as well as the original function! This small function can do wonders for performance. This particular extension is set up to handle one argument, but I would love to see your stab at a multiple argument cache function.

    Closures in the Wild

    As an added bonus, let’s take a look at a couple uses of closures in the wild.

    jQuery

    Sometimes, the famous jQuery $ factory is not available (think WordPress), and we want to use it in the way we typically do. Rather than reach for jQuery.noConflict, we can use a closure to allow functions inside to have access to our $ parameter binding.

    (function($){
    	$(document).ready(function(){
    		//business as usual....
    	});
    })(jQuery);
    
    Backbone.js

    On large Backbone.js projects, it might be favorable to have your application models private, and then expose one public API on your main application view. Using a closure, you can easily acheive this privacy.

    (function(exports){
    
    var Product = Backbone.Model.extend({
        urlRoot: '/products',
    });
    
    var ProductList = Backbone.Collection.extend({
        url: '/products',
        model: Product
    });
    
    var Products = new ProductList;
    
    var ShoppingCartView = Backbone.View.extend({
    
        addProduct: function (product, opts) {
            return CartItems.create(product, opts);
        },
    
        removeProduct: function (product, opts) {
            Products.remove(product, opts);
        },
    
        getProduct: function (productId) {
            return Products.get(productId);
        },
    
        getProducts: function () {
            return Products.models;
        }
    });
    
    //export the main application view only
    exports.ShoppingCart = new ShoppingCartView;
    
    })(window);
    
    Conclusion

    A quick recap of what we learned:

    • A closure is nothing more than a function object with a scope.
    • Closures get their name by the way they “close” over their contents.
    • Closures cash in big time on JavaScript’s lexical scope.
    • Closures are the way to achieve privacy in JavaScript.
    • Closures are able to capture the local variable and parameter bindings of an outer function.
    • JavaScript can be powerfully extended with some closure magic.
    • Closures can be used with many of your favorite libraries to make them even cooler!

    Thanks so much for reading! Feel free to ask any questions. Now let’s enjoy the pizza party!


  • Permalink for 'Meeting Grunt, the Build Tool for JavaScript'

    Meeting Grunt, the Build Tool for JavaScript

    Posted: April 25th, 2012, 1:05pm MDT by Andrew Burgess

    If you’re working on a large project, you’ll no doubt have a build script or a bunch of task scripts to help with some of the repetitive parts of the process. You might use Ant or Rake, depending on the language the project is written in.

    But what do you use if the project is primarily JavaScript? That’s the problem Ben Alman set out to solve when he created Grunt.

    What is Grunt, Anyway?

    What exactly is Grunt? Well, the README on Github says

    Grunt is a task-based command line build tool for JavaScript projects.

    Here’s the idea: when working on a JavaScript project, there are a bunch of things you’ll want to do regularly. Like what, you ask? Well, like concatenating given files, running JSHint on your code, running tests, or minifying your scripts. If you’re pasting your JavaScript into JSHint online, you probably realize that there’s a better way to do it; even if you’re using cat to concatenate files or a command line minifier, it would be nice to have a single, unified set of commands for all those extra tasks, that worked for every single JavaScript project, right?

    That’s what Grunt aims to be. It has a bunch of built-in tasks that will get you pretty far, with the ability to build your own plugins and scripts that extend the basic functionality.

    For more Grunt intro goodness, see Ben’s post on his personal blog and the Bocoup blog.

    How Do I Install Grunt?

    Grunt is built on Node.js, and it’s available as a package via the Node package manager (npm). You’ll want to install it globally, so use this command:

    npm install -g grunt

    You’ll notice it installs quite a few dependencies; there are other npm packages that Grunt uses. Once that’s done, you’re all set to go!

    How Do I Use Grunt?

    As you know, Grunt is a command line tool; therefore, I’ll assume you have a terminal window open for the rest of this tutorial.

    Let’s start by creating a sample project directory; we’re not actually going to be building a project here, but we’ll be seeing how Grunt works in this directory. Once you’re within that directory, run the grunt command (according to the documentation, if you’re on Windows, you might have to run grunt.cmd). You’ll probably see something like this:

    <FATAL> Unable to find 'grunt.js' config file. Do you need any --help? </FATAL>

    Before you can really leverage Grunt to its fullest potential, you’re going to need a grunt.js file in the project directory. Thankfully, Grunt can auto-generate a grunt.js file—and some other project skeleton material—with the init task, which can run without a grunt.js file in place. But grunt init still isn’t enough to get your project started, as you’ll see if you run it. You need to choose a type of project to generate. Running grunt init will give you a list of project types to choose from:

    • jquery: A jQuery plugin
    • node: A Node module
    • commonjs: A CommonJS module
    • gruntplugin: A Grunt plugin
    • gruntfile: A Gruntfile (grunt.js)

    If your project doesn’t really match any of the first four project types, you can use the final one: gruntfile: it just creates a basic grunt.js that you can fill in. So, let’s give this a try, with the jQuery plugin template. Run grunt init:jquery in your terminal.

    You’ll notice a lot of initial output. If you take the time to read the template notes, you’ll see that we’re going to have to fill in a few values, like project name and project title. In fact, after that note, you’ll see something like this:

    Please answer the following:
    [?] Project name (jquery.demo) 

    Whenever you initialize a project, Grunt will ask you a series of questions, so it can fill in a few options. That value in the parentheses? That’s the default suggestion, based on the project type and the name of the project directory. If you want to change it, write your own project name at the end of the line and hit ‘enter’; otherwise, just hit ‘enter’ to use the default name.

    Keep going and fill in the rest of the fields. For a jQuery plugin project, here’s what else you’ll need to give it:

    • Project title
    • Description
    • Version
    • Project git repository
    • Project homepage
    • Project issues tracker
    • Licenses
    • Author name
    • Author email
    • Author url
    • Required jQuery version

    A lot of these have default values; if you want to use the default value, just hit enter for that line; to leave the field blank, you can just type “none.” Once you’ve gone through all the options, you’ll see that Grunt is creating some basic project files. Like what? Like this:

    LICENSE-GPL
    LICENSE-MIT
    README.md
    grunt.js
    libs
    |-- jquery
    |    |-- jquery.js
    |-- qunit
         |-- qunit.css
         |-- qunit.js
    package.json
    src
    |-- jquery.demo.js
    test
    |-- jquery.demo.html
    |-- jquery.demo_test.js

    As you can see, this gives us a good start: not only do we have our plugin file (src/jquery.demo.js), we also have Qunit tests (test/jquery.demo_test.js). And these aren’t empty files, either. They’ve got some initial content, with a so-super-basic jQuery plugin and unit tests. Go ahead and check out the contents of these files, you’ll see what I mean.

    Grunt does more than set up the project for you.

    Of course, Grunt does more than set up the project for you. Notably, our project now has grunt.js: a project-specific configuration file; because of the options it sets, we’re now able to use Grunt’s other built-in tasks. Soon we’ll crack it open and make some adjustments, but for now let’s run some tasks.

    If you run grunt with no options now, we’ll run the default task, if one has been set. In the case of a jQuery plugin project, that’s equivalent to running these four commands:

    • grunt lint: checks your JavaScript against JSHint
    • grunt qunit: runs your Qunit tests
    • grunt concat: concatenates your project files together and puts the new file in a dist folder
    • grunt min: minifies the file concat put out.

    I should note something about the Qunit tests here: Qunit tests are meant to run in the browser by default; just open tests/jquery.demo.html (or your equivalent) in the browser. However, the grunt qunit test wants to run them on the terminal, which means you need to have PhantomJS installed. It’s not difficult: just head over to phantomjs.org and download and install the latest version. If Grunt can find that in your path, it will be able to run the Qunit tests from the terminal.

    So, running grunt should give you output to similar to this:

    Grunt Output

    As you can see, each of our four tasks have run. If any of them were to fail, the rest of the tasks would be cancelled (unless you call Grunt with the --force flag).

    How Do I Customize My Tasks?

    Already, we’ve gotten a lot of great functionality out of Grunt, using it just as it comes. However, let’s crack open that grunt.js file and do some configuring.

    Inside grunt.js, you’ll see that all configuring is done by passing an object literal to grunt.initConfig(). Let’s look at a few of the properties of our config object.

    pkg

    This property points to the package.json file that Grunt created in our project directory. Having a package.json file is part of the CommonJS Packages spec; it’s a single place where most of the metadata about the project (name, version, homepage, repository link … many of the values you set when initializing the project) can be stored. However, this pkg property does more than point to the package file: notice the syntax: '<json:package.json>'. That’s one of Grunt’s built-in directives: it actually loads the JSON file, so Grunt (or you) can access all the properties in the package.json file from the pkg property.

    meta

    The meta property is an object with only a single property: a banner. This banner is the comment that goes at the top of concatenated or minified project files. As you can see, it’s a string with some template tags (<%= %>); in most cases, the tags surround a call to a property on the pkg property, such as pkg.title. However, you can also execute functions from inside those tags: the use of grunt.template.today() and _.pluck() shows us that.

    concat / min / qunit / lint / watch

    I’ve grouped the next five properties together because they’re very similar. They all set options for specific tasks, the tasks they’re named after. When configuring these tasks, it’s important to note that Grunt distinguished between two types of tasks: regular tasks, and multitasks. Basically, the difference is that regular tasks have only a single set of configuration options, whereas multitasks can have multiple sets of instructions (called targets). Of the five tasks I listed in the header of this section, the only one that isn’t a multitask is watch.

    Notice that in our config object, the qunit and lint properties are both objects with the files property. files is a single target for this task. In both cases, they’re an array of files to be used when executing this task. Let’s say I want to be able to lint only the files in src sub-directory. I could add another target so that the lint property would look like this:

    lint: {
    	files: ['grunt.js', 'src/**/*.js', 'test/**/*.js'],
    	src: ['src/**/*.js']
    },

    Now, to lint only the files in src, I run grunt lint:src: I pass the target name after a colon. If I run only grunt lint, both targets will be run.

    In the case of the concat and min tasks, the targets are more complicated: they are objects with source (src) and destination (dest) properties. Of course, this tells Grunt where to get the files and where to put them when it is done processing them, respectively. If you add other files to your project, you’ll want to add them in the right place to make sure they are concatenated and minified correctly. So, if I added a src/utils.js file that my jQuery plugin depended on, I’d change concat.dist.src to this:

    src: ['<banner:meta.banner>', 'src/utils.js', '<file_strip_banner:src/<%= pkg.name %>.js>'], 

    Looking at some of these tasks more closely, you’ll notice a few other directives: the most important is probably the directive. This allows you to access the properties of other tasks for reuse. You’ll notice that the configuration for the watch task uses , so that it operates on the same list of files that we gave to the lint task. You can learn more about the other directives in the Grunt docs.

    Speaking of the watch task, what exactly does it do? Very simple: it runs the tasks in the tasks property when a file in that list of files is changed. By default, the lint and qunit tasks are run.

    jshint

    This property simply configures what “bad parts” JSHint looks for in your JavaScript. The complete list of options can be found on the JSHint website’s options pages.

    At the very bottom of our grunt.js file, you’ll see this line:

    grunt.registerTask('default', 'lint qunit concat min');

    This is what creates our default task; you know, the one that runs when we run just grunt. It’s actually creating an alias task, and you can create as many alias tasks as you want:

    grunt.registerTask('src', 'lint:src qunit:src concat:src min:src');

    Assuming you created src targets for each of those tasks, you can now call grunt src and do exactly what you want.

    How Do I Use Third-Party Tasks?

    While the tasks that come with Grunt will get your pretty far, you can probably think of other things that you’d love to be able to automate. Not to worry: Grunt comes with an API that allows anyone to create Grunt tasks and plugins. While we won’t be creating any Grunt tasks in this tutorial, if you’re interested in doing so, you should start with the Grunt plugin template (run grunt init:gruntplugin), and then read through the API docs. Once you’ve written your task, you can load it into a project by adding this line inside your project’s grunt.js file:

    grunt.loadTasks(PATH_TO_TASKS_FOLDER);

    Note that the parameter isn’t the path to the task file itself, it’s the path to the folder the task file is in.

    However, other Grunt plugins are starting to appear, and some are available on NPM. After you install them via npm install, you’ll load them into your project with this line:

    grunt.loadNpmTasks(PLUGIN_NAME);

    Of course, you’ll want to check the plugin documentation to see what you should add to your configuration object.

    What Grunt plugins are available? Well, since Grunt is so new (less than an month old as I write this), there aren’t too many yet. I’ve found two:

    If you’ve found others, I’d love to hear about them; post ‘em in the comments!

    Conclusion

    While Grunt is a very new project, it’s hardly incomplete; as we’ve seen, it comes with pretty much everything you’ll need to use it on a large project, and can be extended as much as you want.

    I’m hoping Grunt will become a community standard, and that we’ll see lots of tasks, plugins, and init templates popping up in the near future. How do you feel about it?


Dev Articles - Programming Help and Tutorials for all development technologies

  • Permalink for 'More of the Top jQuery Social Plugins'

    More of the Top jQuery Social Plugins

    Posted: April 24th, 2012, 10:00pm MDT
    This is not the first time we have discussed the top jQuery plugins that can help you maximize your site's presence through the omnipresent power of social networking. Like jQuery plugins in other areas, there are many of the social networking variety that currently reside on the Web. To give you even more to choose from, here are more of the top jQuery social plugins. Hovercard Hovercard is a lightweight jQuery plugin that stresses simplicity and a clean look. It does this by displaying information once a visitor hovers their cursor over a label, link, or other HTML element. This plugin w...

Nettuts+

  • Permalink for 'Are You Our Next Awesome Writer?'

    Are You Our Next Awesome Writer?

    Posted: April 24th, 2012, 12:07pm MDT by Siddharth

    We’re in need of a kick-ass, talented author to help out on Nettuts+ on a regular basis, a Bieber fan preferably.

    We’re not sticklers but we’d optimally like to see weekly and bi-weekly submissions from you. Do you have what it takes? This is a paid gig, so read on!

    What You Need
    • A Ninja grasp of the subject matter: Nettuts+ is one of the biggest, most trusted web development blogs out there and this is built on quality content. You, as our author, will need to possess rock solid comprehension of what you’d like to write about.
    • Writing chops: You must be comfortable with the English language. We can proof your content but we can’t rewrite everything for you. If you struggle when deciding whether to write fewer or less, this might not be the gig for you.
    • Ability to stick to a schedule: We expect you to keep the schedule we’ve agreed upon. Be professional.
    What You’ll Get
    • $150 per tutorial for the first month.
    • $200 per from the second month onwards, with a pay review after a year.
    • Option to submit to our premium program which pays significantly more.

    So, assuming you submit an article a week, and one Premium tut/screencast per month, you can expect to make between $1100 – $1400 each month.

    Excellent! Where Do I Sign Up?

    We’ll need the following information from you:

    • Name.
    • A few sentences about yourselves.
    • A single link to an article that you’ve written, helped with or like. This is compulsory.
    • Two ideas for tutorials you’d like to write for us.
    • Emails with an optional tutorial as attachment will get more attention from us since this means you’re serious about the gig.
    • Preferential treatment (and higher pay) given to those who can record professional quality screencasts.

    Please email this information to net[at]tutsplus.com.

    We get a ton of single line emails. Don’t be that person. Emails without the requisite information will be discarded.

    If you can’t manage a weekly/bi-weekly schedule, get in touch either way. I’m sure we can work something out!

    Get cracking, ladies and gents! Looking forward to hearing from all of you.


Dev Articles - Programming Help and Tutorials for all development technologies

  • Permalink for 'Top CSS3 Button Tutorials'

    Top CSS3 Button Tutorials

    Posted: April 22nd, 2012, 10:00pm MDT
    No matter what site you are on, you will probably see some type of button on it. Buttons are integral parts of website navigation that help customers submit data, move from place to place, and more. While buttons can be simple in appearance, you can use CSS3 to make them stand out and give your visitors a more visually stimulating experience. After all, if you can figure out how to maximize the appearance of your site's buttons, why not do it? Of course, that is where the trouble may come in for some that are new to CSS3. Luckily, there are several tutorials available on the Web that focus...

Nettuts+

  • Permalink for 'Create an Animated 3D Bar Chart/Graph'

    Create an Animated 3D Bar Chart/Graph

    Posted: April 22nd, 2012, 9:53pm MDT by Kendra Schaefer and Ken Breeden

    The Truematter team was recently tasked with creating a fun, sexy web app that presents numerical data in an engaging way. After putting our heads together, we came up with a bar chart that responds interactively to user input without, heaven forbid, reloading any pages. We’re very pleased to be able to share that with the coding community. There are some CSS tricks involved, a dose of jQuery, and some graphic magic, but when we’re done with this tutorial, we’ll have a beautifully interactive chart that you can customize to your heart’s content.

    Prepping the Graphics

    The graphic elements and the way those elements are chopped up and compiled is what really gives this chart some wow-factor.  There are only three graphic elements needed for this project, but, since we’re essentially creating an illusion using CSS and images, those graphics need to be crafted with precision.

    The chart itself is composed of three separate PNGs stacked on top of each other using CSS, two of which are stationary (the front and back “glassy” chart casing pieces), and one of which is animated using jQuery (the green bar piece in the middle).

    These are the graphical elements that make up the final presentation. Graphic Element 1: Back of the Chart This is the back panel graphic used in the 3D animated graph.

    The background piece is comprised of the bottom of the chart (which we only see when the bar is empty at 0%), the back left and back right panels. On this bottommost layer, we include all of the faces of the graph casing that need to become “covered” when the graph is full or partially full. This is the layer that really gives the 3D illusion some depth.

    Graphic Element 2: The Bar Graph The is the middle layer and bar graph of the 3D animated jQuery tutorial

    The animated center portion of this graph is simple to create. We suggest using very basic 3D extrude functions in Illustrator, or you can also just draw a three-panel shape in Photoshop and call it a day.  Color your graph very brightly, oversaturating it as much as possible. Why? Because in the final chart, it will be shown beneath a semi-transparent casing, so the color will be muted by the layer that covers it.

    It’s super important that the top and bottom edges of this piece remain transparent, so be sure to save it as a PNG.

    Also just as important: make this piece exactly the same height as the graph casing pieces. In our pictures here, the middle layer looks shorter than the casing – when you create your central piece, make the central bar exactly as tall as the casing. If you make it too short, your graph will never be able to fill up to 100% properly. If you make it too tall, the graph can shoot out of the casing container when it’s animated.

    Graphic Element 3: The Top Casing The top casing to complete the 3D animated graph/chart using jQuery and CSS

    Here’s where we get to the real visual trickery, which happens along the bottom edge of this third and final piece. While the top left and right edges retain transparency, the bottom left and right edges should be filled in solid with the same color as the background the graph will be sitting on.

    For example, if your website background is black, the bottom two edges of this piece need to be filled in with solid black. In our example above, the site background is white, so we’ve filled in the bottom edges with white. This solid-color area effectively hides any overspill from the middle bar-chart piece (graphic element 2). Without this piece and its opaque bottom edge, we lose the 3D effect entirely. Here’s the graph without it:

    Image illustrating no correctly producing graphics for the 3D animated graph/chart using jQuery and CSS The HTML

    Okay! We’ve got all of our graphic pieces complete and we’re ready to jump right into the code. The HTML itself is pretty straightforward. You’re looking at a few basic form select fields and a few divs for the bar graph.

    First, let’s look at the complete code, then we’ll take it piece by piece (no pun intended!). Note that the bar graph div elements are included within the form tag.

    <noscript><h3>You must enable JavaScript to view this demo!</h3></noscript>
    
    <form id="form1" action="#" onsubmit="return false;">
    <!-- container for the form elements -->
    <div id="formcontainer">
    How much money do you want to contribute to savings each month?
    <select id="savings" onchange="calculate();">
    	<option selected="selected" value="0">- select an amount -</option>
    	<option value="100">100 dollars</option>
    	<option value="200">200 dollars</option>
    	<option value="300">300 dollars</option>
    	<option value="400">400 dollars</option>
    	<option value="500">500 dollars</option>
    	<option value="1000">1000 dollars</option>
    	<option value="2000">2000 dollars</option>
    	<option value="3000">3000 dollars</option>
    	<option value="4000">4000 dollars</option>
    	<option value="5000">5000 dollars</option>
    </select>
    
    What is your monthly income?
    <select id="income" onchange="calculate();">
    	<option selected="selected" value="0">- select an amount -</option>
    	<option value="1000">1000 dollars</option>
    	<option value="2000">2000 dollars</option>
    	<option value="3000">3000 dollars</option>
    	<option value="4000">4000 dollars</option>
    	<option value="5000">5000 dollars</option>
    </select>
    </div>
    
    <div id="grapharea">
    <h4>Percentage of Monthly Salary Saved</h4>
    <div id="p25">25%</div>
    <div id="p50">50%</div>
    <div id="p75">75%</div>
    <div id="p100">100%</div>
    <div id="graphcontainer">
    	<img id="graphbackground" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    	<img id="graphbar" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    	<img id="graphforeground" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    </div>
    </div>
    </form>
    
    The Breakdown

    Since this chart depends on javascript, we first check to make sure it’s enabled in the browser:

    		<noscript><h3>You must enable JavaScript to view this demo!</h3></noscript>
    		

    Now we begin the form. For the purposes of this demo, we’ve used two simple dropdowns, but you could just as easily modify this code to use text fields, radio buttons, or any other type of input. The select onchange attribute is given the function “calculate();”, which we’ll cover in the jQuery section below.

    		<div id="formcontainer">
    			How much money do you want to contribute to savings each month?
    			<select id="savings" onchange="calculate();">
    				<option selected="selected" value="0">- select an amount -</option>
    				<option value="100">100 dollars</option>
    				<option value="200">200 dollars</option>
    				<option value="300">300 dollars</option>
    				<option value="400">400 dollars</option>
    				<option value="500">500 dollars</option>
    				<option value="1000">1000 dollars</option>
    				<option value="2000">2000 dollars</option>
    				<option value="3000">3000 dollars</option>
    				<option value="4000">4000 dollars</option>
    				<option value="5000">5000 dollars</option>
    			</select>
    
    			What is your monthly income?
    			<select id="income" onchange="calculate();">
    				<option selected="selected" value="0">- select an amount -</option>
    				<option value="1000">1000 dollars</option>
    				<option value="2000">2000 dollars</option>
    				<option value="3000">3000 dollars</option>
    				<option value="4000">4000 dollars</option>
    				<option value="5000">5000 dollars</option>
    			</select>
    
    		</div>
    		

    And finally, included within the form tag, the graphic elements:

    		<div id="grapharea">
    			<h4>Percentage of Monthly Salary Saved</h4>
    			<div id="p25">25%</div>
    			<div id="p50">50%</div>
    			<div id="p75">75%</div>
    			<div id="p100">100%</div>
    			<div id="graphcontainer">
    				<img id="graphbackground" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    				<img id="graphbar" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    				<img id="graphforeground" src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="" width="262" height="430" />
    			</div>
    		</div>
    		
    The CSS
    		#formcontainer { float: left; }
    		#grapharea { position: relative; float: left; margin-left: 4em; }
    		#graphcontainer {
    			position: relative;
    			width: 262px;
    			height: 430px;
    			overflow: hidden;
    		}
    		#graphbackground, #graphforeground { position: absolute; }
    		#graphbar { position: absolute; top: 430px; }
    
    		.graphlabel { position: absolute; left: 270px; }
    		#p25 { top: 365px; }
    		#p50 { top: 278px; }
    		#p75 { top: 191px; }
    		#p100 { top: 105px; }
    		

    Probably the most crucial thing that should catch your eye here is the #graphbar div. Notice that our #graphbar div starts out at 430px – the total height of the bar chart. This height declaration is the number that is manipulated via jQuery to make the graph animate. If you have created your own graphic elements which are taller or shorter than 430px, you’ll need to adjust that number to match your own graphics.

    Likewise, you’ll also need to adjust the px of #p25, #p50, #p75, and #p100. These top declarations set the position of the 25%, 50%, 75% and 100% markers on the right side of the graph.

    Also, take a close look at the #graphcontainer styles:

    		#graphcontainer {
    			position: relative;
    			width: 262px;
    			height: 430px;
    			overflow: hidden;
    		}
    		

    Putting a position:relative;declaration on this outer wrapper lets us use absolute positioning on the three divs within #graphcontainer, so we can stack them on top of each other using CSS offsets. Setting a height and a width are also vital here – the height and width of this div should perfectly match the height and width of graphic elements 1 and 3. And overflow: hidden; hides the animated graphic, element 2, when it extends outside the bounds of the wrapping div.

    The Code

    Ah, now for the jQuery! It ties all pieces together and adds in the animation. A quick review of the full jQuery:

    		<script>
    		 function calculate() {
    			var ZEROPOS = 355;
    			var salary = $("#income").val();
    			var savings = $("#savings").val();
    			var percent = savings / salary; 	
    
    			if (parseInt(savings) >  0 &amp;&amp; parseInt(salary) > 0)
    			{
    				if (parseInt(savings) > parseInt(salary))
    					alert("You cannot save more than you earn - please change your selections accordingly.");
    				else
    				{
    					val = (percent == 0) ? ZEROPOS : ZEROPOS - (percent * ZEROPOS);
    					$("#graphbar").animate({ top: val + "px" }, 1500);
    				}
    			}
    		}
    		</script>
    		
    The Final Breakdown

    First, create a constant to use in the calculations. ZEROPOS is the pixel value of where the central graphic element (graphic 2, the movable piece) should be positioned to represent 0%.

    var ZEROPOS = 355;

    Next, find the values selected by the user using the select boxes – salary and savings. Then calculate the percentage value – percent.

    		var salary = $("#income").val();
    		var savings = $("#savings").val();
    		var percent = savings / salary;
    		

    The next step is a validation check to make sure the user has actually selected values from both select boxes. If they have, we continue with the script. Otherwise, we do nothing.

    if (parseInt(savings) >  0 &amp;&amp; parseInt(salary) > 0)

    If the user has entered the appropriate values, we then make sure that they have selected a salary that is higher than the amount they want to contribute to savings. If they have, we continue with the script. Otherwise we prompt the user to change their selections.

    		if (parseInt(savings) > parseInt(salary))
    		alert("You cannot save more than you earn - please change your selections accordingly.");
    		

    Now we are finally to the meat of the script – calculating the position to which we will move the graph bar and then firing off the jQuery animate functionality to make it happen.

    		val = (percent == 0) ? ZEROPOS : ZEROPOS - (percent * ZEROPOS);
    		$("#graphbar").animate({ top: val + "px" }, 1500);
    		

    So, in calculating the value for the graph bar position – val –  first determine if the percentage is zero. If so, set value equal to the ZEROPOS constant. Otherwise, calculate the new bar position by subtracting the percentage value multiplied by the zero position value from the zero position value. This formula is used because we are animating the bar from the zero position at the bottom of the chart up towards the top.

    Once the pixel value is calculated, we know where we’re heading, so simply call the animate method in jQuery on the graphbar object passing in the new CSS value for the top position with an animation rate of 1500 (the speed of the animation in milliseconds). Then jQuery does the magic for us and moves the bar within the chart accordingly. Violà!

    Hope you enjoyed this tutorial!


  • Permalink for 'Lightning Fast Folder and File Creation in Sublime Text 2'

    Lightning Fast Folder and File Creation in Sublime Text 2

    Posted: April 19th, 2012, 12:48pm MDT by Jeffrey Way

    I’m frequently asked about how I’m able to create new directory structures and files so quickly in Sublime Text 2. Well the answer is that this functionality is not offered natively; instead, I use a helpful plugin. I’ll demonstrate it in this video.

    Choose 720p for the clearest video. Closing Thoughts

    It’s worth mentioning that, toward the end of the video, I assign a custom key-binding: n-n. Please note that this binding assumes that you’re working in Vintage (Vim) mode. To trigger it, you’d exit to command mode – by pressing Esc – and then type n-n.

    If you’re not a Vintage user, you can stick with the default key-binding that comes with the plugin.

    Show Links


  • Permalink for 'Top 10 Pitfalls When Switching to Vim'

    Top 10 Pitfalls When Switching to Vim

    Posted: April 18th, 2012, 9:16pm MDT by Jeffrey Way

    Admit it: every time you see a person using Vim, you consider the possibility that they know something you don’t. Why else would they be using an editor that, in your mind, is dated, open-source junk? Think what you wish, but there’s a reason why top developers swear by Vim.

    February 2011

    Until you’ve spent at least a month working every day with the editor, you’ll undoubtedly hate it! This is specifically why the majority of newcomers will play around with Vim for a day, become disgusted, and never touch it again. What’s unfortunate is that, if these developers could get beyond the pitfalls, they’d be introduced to incredible speed and flexibility.

    1. There’s Too Many Modes

    It’s true: Vim is not your standard code editor (it’s better). Transitioning from, say, TextMate to Vim is going to be an entirely different process than switching from TextMate to Espresso. Always keep that in mind when you find yourself tearing our your hair because Vim seemingly refuses to enter text when you type.

    Though there are multiple modes in Vim, we’ll focus on the three most important. But before we continue, note that each key serves a different function, dependent upon which mode you’re currently in. Even more confusing — at first — a capital letter triggers a different action than a lowercase.

    In command mode, pressing the lowercase “i” will trigger “Insert Mode.” However, an uppercase “I” will move the cursor to the beginning of the line. This might sound confusing, but it provides you will incredible power!

    • Command: By default, Vim should rest in command mode. Think of this mode as the “getting around” mode. While, in a traditional editor, you might be accustomed to using the mouse or the arrow keys to traverse your document, Vim’s command mode makes the process quicker and “mouse-less.”
    • Insert: Pressing the lowercase “i” in command mode will switch you into “Insert Mode.” Newcomers to Vim will find this mode to be familiar. As a result, though, they often remain in this mode far longer than they should (I know I did). As a rule of thumb, insert mode should purely be used for the sole purpose of inserting text. When finished, immediately return to command mode.
    • Visual: Think of visual mode as “selection” mode. Need to select the next five lines and delete them? With a normal code editor, you could use the mouse to visually select five lines, and then press the backspace key. With Vim, on the other hand, you’d press capital V to switch to Visual mode, and then type 5j to select five lines down. Finally, you’d press d, for delete.

    I know this sounds incredibly confusing at first. You might think to yourself, “All that work just to delete five lines?” The truth is, though, this method is significantly faster.

    2. Ancient Editor

    Why would you turn your nose up at over three decades of development?

    You might hear your friends say, “Isn’t Vim an ancient code editor?” Well, you could say that; it’s been around for over thirty years. Though honestly, why would you turn your nose up at over three decades of development? That’s longer than I’ve been alive! Better yet, even to this day, Vim is under active development. The most recent release, 7.3, was made available in August, 2010.

    Secondly, it’s important to keep in mind that Vim is not Vi. If your only experience is with the latter, take some time to download the latest release and toy around with the new features. You’ll be pleasantly surprised!

    3. I Love TextMate Snippets

    If Vim can’t natively do it, you can bet that there’s a plugin available somewhere!

    You’ll quickly find that, if Vim can’t perform a particular task, then it’s likely that a plugin has developed to provide that functionality. For instance, consider TextMate’s excellent snippets feature. While Vim doesn’t support this natively, you can download the snipMate plugin, which should make the experience virtually identical to what you’re used to.

    Learn More About Switching to Vim From TextMate 4. I Can’t Use the Arrow Keys

    The less movement, the better.

    Firstly, this isn’t true. It might have been the case with Vi, but you’re free to use how Vim in the way that feels most comfortable to you. So use the arrow keys to your heart’s content — though keep in mind that there’s a reason why most Vim users don’t.

    The h,j,k,l keys mapping to left, down, up, and right, respectively, serve two purposes:

    • No Choice: Back in the day, machines didn’t have those helpful arrow keys. As such, they had little choice but to choose the best alternative.
    • Less Movement: If your hands generally rest along the second row of the keyboard, it makes little sense to repeatedly move your hand to the lower-right portion of the keyboard every time you want to move the cursor. The less movement, the better. With this arrangement, you can traverse your documents without moving an inch.

    When all is said and done, you are the person using the editor. If, at first, you feel more comfortable using the arrow keys, then by all means do!

    5. I’m a Designer, Dude

    That’s okay! Vim is not for everybody. As a person who at least attempts to do design work from time to time, I can fully attest that Vim may not be the best fit for designers.

    Developers are not designers; it’s only natural that this fact will be reflected in their choice of editors.

    If you find that the bulk of your days are spent working with HTML and CSS, then maybe Vim is not for you. Now, that’s not to say that you shouldn’t give it a shot; but it’s certainly understandable, should you decide to stick with a more designer-friendly editor, such as Coda.

    6. Vim Offers Nothing My Current Editor Doesn’t Already Do

    Plain and simple, that’s rubbish. Certainly, every editor does have its strong points, but you’ll find that Vim is incredibly powerful, and, more importantly, flexible. There are hundreds upon hundreds of plugins available (for free) that will provide support for virtually any kind of functionality that you require.

    Many newcomers often cite the built-in “Change Inner” command as a huge selling point. It certainly was for me! Let’s say that you have the following piece of code:

    var joe = 'plumber';
    

    Assuming that the cursor is at the beginning of that line, and you wish to change the value “plumber” to “black,” traditionally, you might use the arrow keys or the mouse to select and change the text. With Vim, the process is hugely simplified. Simply type: ci'. This stands for “Change Inner Quotes,” or, find the next set of single quotes, and change the value inside.

    Kick-Ass Plugins
    • snipMate: Allows you to, for instance, type + tab, and have a full div element expanded. It’s tremendously helpful.
    • Surround: Wrap portions of text with parens, tags, braces, etc.
    • NerdTree: Explore your filesystem and to open files and directories. It presents the filesystem to you in the form of a tree which you manipulate with the keyboard and/or mouse. It also allows you to perform simple filesystem operations.
    • TComment: Easily and quickly comment certain lines of your code.
    • Sparkup: Similar to ZenCoding, but provide more support for applying values to elements as well, such as: ul > li { My list item text. }.
    7. My Vimrc File is Blank

    This was an initial gripe that I had with Vim, as well. When first launching, say, MacVim, you’re thrown into the wolf-pack! No code highlighting, no formatting, no smart indenting… no nothing! Particularly if you’re using a custom Vim editor, there should at least be a base vimrc file to get you started. It can be an intimidating experience trying to figure out how to apply your custom preferences.

    For those unfamiliar with a vimrc file, it’s essentially a file that allows you to specify your editor preferences.

    Use this as a starter (click the Expand button below):

    " .vimrc File
    " Maintained by: Jeffrey Way
    " jeffrey@jeffrey-way.com
    " [net.tutsplus.com] "
    
    "Forget compatibility with Vi. Who cares.
    set nocompatible
    
    "Enable filetypes
    filetype on
    filetype plugin on
    filetype indent on
    syntax on
    
    "Write the old file out when switching between files.
    set autowrite
    
    "Display current cursor position in lower right corner.
    set ruler
    
    "Want a different map leader than \
    "set mapleader = ",";
    
    "Ever notice a slight lag after typing the leader key + command? This lowers
    "the timeout.
    set timeoutlen=500
    
    "Switch between buffers without saving
    set hidden
    
    "Set the color scheme. Change this to your preference.
    "Here's 100 to choose from: [www.vim.org] colorscheme twilight
    
    "Set font type and size. Depends on the resolution. Larger screens, prefer h20
    set guifont=Menlo:h14
    
    "Tab stuff
    set tabstop=3
    set shiftwidth=3
    set softtabstop=3
    set expandtab
    
    "Show command in bottom right portion of the screen
    set showcmd
    
    "Show lines numbers
    set number
    
    "Prefer relative line numbering?
    "set relativenumber"
    
    "Indent stuff
    set smartindent
    set autoindent
    
    "Always show the status line
    set laststatus=2
    
    "Prefer a slightly higher line height
    set linespace=3
    
    "Better line wrapping
    set wrap
    set textwidth=79
    set formatoptions=qrn1
    
    "Set incremental searching"
    set incsearch
    
    "Highlight searching
    set hlsearch
    
    " case insensitive search
    set ignorecase
    set smartcase
    
    "Hide MacVim toolbar by default
    set go-=T
    
    "Hard-wrap paragraphs of text
    nnoremap <leader>q gqip
    
    "Enable code folding
    set foldenable
    
    "Hide mouse when typing
    set mousehide
    
    "Shortcut to fold tags with leader (usually \) + ft
    nnoremap <leader>ft Vatzf
    
    " Create dictionary for custom expansions
    set dictionary+=/Users/jeff_way/.vim/dict.txt
    
    "Opens a vertical split and switches over (\v)
    nnoremap <leader>v <C-w>v<C-w>l
    
    "Split windows below the current window.
    set splitbelow              
    
    " session settings
    set sessionoptions=resize,winpos,winsize,buffers,tabpages,folds,curdir,help
    
    "Set up an HTML5 template for all new .html files
    "autocmd BufNewFile * silent! 0r $VIMHOME/templates/%:e.tpl
    
    "Load the current buffer in Firefox - Mac specific.
    abbrev ff :! open -a firefox.app %:p<cr>
    
    "Map a change directory to the desktop - Mac specific
    nmap <leader>d :cd ~/Desktop<cr>:e.<cr>
    
    "Shortcut for editing  vimrc file in a new tab
    nmap <leader>ev :tabedit $MYVIMRC<cr>
    
    "Change zen coding plugin expansion key to shift + e
    let g:user_zen_expandabbr_key = '<C-e>'
    
    "Faster shortcut for commenting. Requires T-Comment plugin
    map <leader>c <c-_><c-_>
    
    "Saves time; maps the spacebar to colon
    nmap <space> :
    
    "Automatically change current directory to that of the file in the buffer
    autocmd BufEnter * cd %:p:h
    
    "Map code completion to , + tab
    imap <leader><tab> <C-x><C-o>
    
    " More useful command-line completion
    set wildmenu
    
    "Auto-completion menu
    set wildmode=list:longest
    
    "http://vim.wikia.com/wiki/Make_Vim_completion_popup_menu_work_just_like_in_an_IDE
    set completeopt=longest,menuone
    inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
    inoremap <expr> <C-n> pumvisible() ? '<C-n>' :
      \ '<C-n><C-r>=pumvisible() ? "\<lt>Down>" : ""<CR>'
    inoremap <expr> <M-,> pumvisible() ? '<C-n>' :
      \ '<C-x><C-o><C-n><C-p><C-r>=pumvisible() ? "\<lt>Down>" : ""<CR>'
    
    "Map escape key to jj -- much faster
    imap jj <esc>
    
    "Delete all buffers (via Derek Wyatt)
    nmap <silent> ,da :exec "1," . bufnr('$') . "bd"<cr>
    
    "Bubble single lines (kicks butt)
    "http://vimcasts.org/episodes/bubbling-text/
    nmap <C-Up> ddkP
    nmap <C-Down> ddp
    
    "Bubble multiple lines
    vmap <C-Up> xkP`[V`]
    vmap <C-Down> xp`[V`]
    
    " Source the vimrc file after saving it. This way, you don't have to reload Vim to see the changes.
    if has("autocmd")
     augroup myvimrchooks
      au!
      autocmd bufwritepost .vimrc source ~/.vimrc
     augroup END
    endif
    
    " easier window navigation
    nmap <C-h> <C-w>h
    nmap <C-j> <C-w>j
    nmap <C-k> <C-w>k
    nmap <C-l> <C-w>l
    
    "------------------------"
    "NERDTREE PLUGIN SETTINGS
    "------------------------"
    "Shortcut for NERDTreeToggle
    nmap <leader>nt :NERDTreeToggle <CR>
    
    "Show hidden files in NerdTree
    let NERDTreeShowHidden=1
    
    "autopen NERDTree and focus cursor in new document
    autocmd VimEnter * NERDTree
    autocmd VimEnter * wincmd p
    
    "Helpeful abbreviations
    iab lorem Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    iab llorem Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
    
    "Spelling corrects. Just for example. Add yours below.
    iab teh the
    iab Teh The
    
    " Get to home dir easier
    " <leader>hm is easier to type than :cd ~
    nmap <leader>hm :cd ~/ <CR>
    
    " Alphabetically sort CSS properties in file with :SortCSS
    :command! SortCSS :g#\({\n\)\@<=#.,/}/sort
    
    " Shortcut to opening a virtual split to right of current pane
    " Makes more sense than opening to the left
    nmap <leader>bv :bel vsp
    
    " Saves file when Vim window loses focus
    au FocusLost * :wa
    
    " Backups
    set backupdir=~/.vim/tmp/backup// " backups
    set directory=~/.vim/tmp/swap// " swap files
    set backup " enable backup
    
    " No more stretching for navigating files
    "noremap h ;
    "noremap j h
    "noremap k gj
    "noremap l gk
    "noremap ; l
    
    set showmatch " show matching brackets
    
    " print empty <a> tag
    map! ;h <a href=""></a><ESC>5hi
    
    8. I Don’t Want to Use the Terminal

    Me neither — at least not more than I have too — there are a variety of dedicated Vim editors which provide a more Windows/Mac GUI-like experience.

    These editors will provide support for the sorts of keystrokes that are ingrained into your body, such as “Command + F” to search, or “Command + W” to close the current window.

    9. Too Difficult to Learn Without a Teacher Venturing into Vim

    Well I suppose that depends on if you’re more of a visual learner. However, if that’s the case — promo alert — you might consider checking out our “Venturing into Vim” 4-week course. What’s unique about this series is that I recorded each episode in real-time, as I was learning Vim for the first time. The advantage to this is that you’ll get a far more practical overview of Vim. What confused me at first will undoubtedly confuse you as well!

    You can purchase it on the Tuts+ marketplace for $19.

    Remember how, in school, sometimes, the student sitting next to you was able to explain and help you understand some difficult concept more than the teacher? The reason is because, once you’re mastered a craft, it’s difficult to recall what personally gave you the most trouble. From September to October, I embarked on a four-week challenge, which I call “Venturing into Vim.” After hearing countless extremely talented developers praise this seemingly decade-old code editor, I decided that it was worth a month of my time to figure out why so many people consider Vim to be the best editor on the planet.

    10. I Can’t Edit Files on My Server

    Of course you can, though, admittedly, it’s not quite as user-friendly as, say, Coda’s remote server feature. Speaking of Panic, if you’re a Transmit user, you might consider installing the Transmit FTP plugin.

    “This script allows you to upload the current file via Transmit directly from Vim. For it to work, you need to be working on a file that’s tied to a Transmit connection, and this connection must have “DockSend” enabled.”

    With this plugin, when editing a file that has a Transmit connection (open file via Transmit), you only need to press Control + U to push those updates back to your remote server. It’s a cinch!

    Truthfully, though, you should try to adopt a better build/deployment process. This way, rather than using FTP, you can simply git push.

    Sure – there are a handful of reasons not to use Vim. It has a steep learning curve, and requires a complete rethinking of how a code editor should function. That said, there are hundreds of reason why you should use Vim. The only question is: why aren’t you?


Dev Articles - Programming Help and Tutorials for all development technologies

  • Permalink for 'The Top jQuery Social Plugins'

    The Top jQuery Social Plugins

    Posted: April 17th, 2012, 10:00pm MDT
    Whether in the online or real world, it seems as if social networking is everywhere now. Sites like Facebook and Twitter have become insanely popular with the masses and have even made their way into mainstream media. As is the case, social networking is an extremely powerful tool that you cannot ignore. If you have a new or pre-existing site, you can increase your presence by using social networking to your advantage. One way to do this is through the use of some nifty jQuery plugins that have been developed to make things easier for you. This list will feature some of the top jQuery so...

Nettuts+

  • Permalink for 'Creattica Redesign: Introducing UI Elements'

    Creattica Redesign: Introducing UI Elements

    Posted: April 17th, 2012, 10:50am MDT by Collis Ta'eed

    It’s a month of new beginnings over at our design and inspiration gallery Creattica. April has seen the site undergo a complete redesign with a whole new streamlined grid-style layout for its over 50 different categories. On top of that, Creattica now has better navigation, a new UI Elements section and a growing Freebies area of now over 700 items. All this and over 14,000 featured works from some 100,000 members. It’s quite the site!

    But that’s not all, let’s first take a look at some of Creattica’s top UI work – and then stay tuned for some exciting news at the conclusion!

    1. Hi 2. User Login 3. Simple Breadcrumb 4. WIP – Calendar App 5. Minimal Login User Interface 6. Switch 7. the One Club Video Player 8. the Creative Finder 9. Pagination 10. Pricing Tables The Future of Creattica

    When we started Creattica (originally Faveup) back in 2007, we wanted it to be one on the top inspiration galleries on the web. And as the site has grown and changed over the years, we find ourselves with what has become one of the biggest, broadest and most in-depth galleries of design out there. So I guess we can say – mission accomplished!

    Over these past few months, Envato has really started working on focusing on our core products of Marketplaces and Tuts+ sites. So while we love Creattica, we find ourselves in the regrettable position of having to put the site up for sale soon. We really want it to go to an awesome home, so if anyone would like to express interest in the sale or get more details, please contact us here.

    I’m certain we’ll find some new owners who can keep Creattica growing and evolving on into the future. And in the meantime I hope you enjoy the new design and all the gorgeous work as much as I do!


  • Permalink for 'Advanced CodeIgniter Profiling With XHProf'

    Advanced CodeIgniter Profiling With XHProf

    Posted: April 17th, 2012, 7:16am MDT by James Constable

    There are a number of ways to profile and monitor the performance of PHP code in a development environment, but once it’s been let loose on a production server its extremely difficult to know what’s going on when your app is getting accessed by your users.

    In March 2009, Facebook released XHProf, a function level profiler that allows you to identify bottlenecks in your application. And it runs on a production server with little overhead.

    XHProf will provide you with a hierarchical profile of the functions your application calls, allowing you to follow the chain of events that lead up to resource intensive code running. You’ll be able to see exactly how much wall time (the actual time elapsed), CPU time and memory your application uses.

    This tutorial will help you get XHProf installed on your server, and integrated with your CodeIgniter application via hooks so that you can start profiling your application, in a production environment, straight away. Everything you see here was written for Ubuntu 10.04 – the latest LTS release at the time of writing.

    Installation

    Installation of XHProf can be done via PECL – that said, I’ve never been able to get the PECL version installed on Ubuntu easily so its easier to install from source. Start off by downloading the latest revision from the XHProf GitHub account.

      	wget [https:] -O xhprof.tar.gz
    

    Extract the tarball and switch into the extracted folder – this will change depending on the latest revision available from GitHub.

    	tar -xvf xhprof.tar.gz
    	cd facebook-xhprof-bc8ef04/extension
    

    Then install as normal.

    	phpize
    	./configure
    	make
    	sudo make install
    

    Finally, we need to tell PHP to load the extension. Create a config file for it – I do this for cleanliness but you can always drop it at the end of your main php.ini.

    	sudo nano /etc/php5/conf.d/xhprof.ini
    

    And paste in the following:

    	extension=xhprof.so
    	xhprof.output_dir="/var/tmp/xhprof"
    

    This tells XHProf to use the directory at /var/tmp/xhprof to save its run data.

    You can check whether XHProf is installed correctly by entering php -m at the command line and checking that the module is available. Remember to restart Apache so that it gets picked up in your PHP web applications as well.

    If you want to render the callgraph images you’ll also need the graphviz package. This can be obtained from apt.

    	sudo apt-get install graphviz
    
    Integration With CodeIgniter

    XHProf can be used on an ad-hoc basis to evaluate small pieces of code, but it’s at its most useful when you let it profile the full page. First of all, you’ll need to move the XHProf code into your web applications root so that it has access to the appropriate classes.

    	sudo mv ~/facebook-xhprof-bc8ef04  /var/www/xhprof
    

    CodeIgniter has an excellent mechanism for injecting custom code into the execution of a page called ‘Hooks’. This is what we’ll use to integrate XHProf with your application. Enable hooks in your application/config/config.php file.

    	$config['enable_hooks'] = true;
    

    Then specify your hooks in application/config/hooks.php

    	$hook['pre_controller'] = array(
    	  'class'  => 'XHProf',
    	  'function' => 'XHProf_Start',
    	  'filename' => 'xhprof.php',
    	  'filepath' => 'hooks',
    	  'params' => array()
    	);
    
    	$hook['post_controller'] = array(
    		'class'  => 'XHProf',
    		'function' => 'XHProf_End',
    		'filename' => 'xhprof.php',
    		'filepath' => 'hooks',
    		'params' => array()
    	);
    

    Then create the hook that will load XHProf into your application at application/hooks/xhprof.php. This class will provide the necessary minimum to get XHProf collecting data from your application.

    	class XHProf {
    
    		private $XHProfPath = 'xhprof/';
    		private $applicationName = 'my_application';
    		private $sampleSize = 1;
    		private static $enabled = false;
    
    		public function XHProf_Start() {
    			if (mt_rand(1, $this->sampleSize) == 1) {
    				include_once $this->XHProfPath . 'xhprof_lib/utils/xhprof_lib.php';
    				include_once $this->XHProfPath . 'xhprof_lib/utils/xhprof_runs.php';
    				xhprof_enable(XHPROF_FLAGS_NO_BUILTINS);
    
    				self::$enabled = true;
    			}
    		}
    
    		public function XHProf_End() {
    			if (self::$enabled) {
    				$XHProfData = xhprof_disable();
    
    				$XHProfRuns = new XHProfRuns_Default();
    				$XHProfRuns->save_run($XHProfData, $this->applicationName);
    			}
    		}
    
    	}
    

    There’s a few thing to point out in this code sample.

    • The $XHProfPath variable should point to the directory you installed XHProf in. In our example, we put it in the root of the web application, but you might be storing it somewhere central and symlinking it to multiple applications.
    • The $applicationName variable lets you specify the name of the application using XHProf. This could be especially important in an environment where you’re running multiple applications on the same server.
    • The $sampleSize variable lets you specify a factor for how often XHProf profiles a run. In a production environment where you’re receiving thousands of hits, it’s probably not worth storing every single run. You can increase this variable to get a random sample of runs. Changing it to 10, for example, will give you a report from one in every 10 visits to your application.

    The xhprof_enable() function can accept any combination of 3 constants.

    • XHPROF_FLAGS_NO_BUILTINS – skip all internal php functions. Adding this means you’ll only see time spent in functions that you have written (or are part of CodeIgniter)
    • XHPROF_FLAGS_CPU – add additional CPU profiling information
    • XHPROF_FLAGS_MEMORY – add additional memory profiling information

    Combine them using +. eg. xhprof_enable(XHPROF_FLAGS_NO_BUILTINS + XHPROF_FLAGS_MEMORY);

    After running through your application a couple of times, point your browser at the XHProf application directory http://localhost/xhprof/xhprof_html/index.php – adjusting for the address of your development server – and you’ll see a list of your last application runs with the newest at the top. Select one of the runs to see it’s profiling information.

    Evaluating the Results

    Storing all this profiling information is all very well and good but knowing how to evaluate it is the key to optimising your application.

    The ‘Overall Summary’ is a good place to start – it’ll show you:

    • Total inclusive wall time – how long (in microseconds) it took for you page to be generated
    • Total memory use – the total memory used by this run of your application
    • Total peak memory use – the maximum amount of memory that was used by your application
    • Number of function calls – the number of functions that were called by your application
    Run summary

    These number should give you an overall base to start from and provide headline numbers to compare against when you start optimisation.

    Below the summary is the detailed run report The bottlenecks in your application should be fairly obvious – they’re the function calls at the top of the report.

    Wall report

    The most resource intensive things you’re likely to come across will be those that make calls to external services or your database. By default, the results are sorted by ‘inclusive wall time’. This shows the functions that took the longest to run by the cumulative total of them and the functions they call. Ordering by ‘exclusive wall time’ allows you to see the specific functions that are using the most amount of resource.

    Clicking a function allows you to drill down into more detail about that function and the functions it called. From there, it’ll be easier to see exactly what your long running function was doing and spot any issues.

    When debugging your CodeIgniter application, one of the best places to start is the controller being called for your page – Welcome::index in the example. From there you can easily see the breakdown of where the controller spent most of it’s time.

    Controller summary Callgraph

    XHProf can generate a call graph view that provides a visual clue to the main path of your application. The main bottlenecks are highlighted in red to show where most your resources are being spent.

    Callgraph Comparing Runs

    XHProf provides a mechanism for comparing multiple runs – this will allow you to make a number of optimisations and then see how they’ve affected your application.

    http://localhost/xhprof/xhprof_html/index.php?run1=run_id_1>&run2=run_id_2&source=applicationName

    Note: run_id_1 and run_id_2 should be the ids from some of your previous runs and applicationName should be the name you specified when setting up the hook earlier.

    This will provide the same information you see in a regular report but provide percentage statistics on any changes since the first run, allowing you to easily see if your optimisations are moving your performance in the right direction.

    Aggregating Runs

    Sometimes a single run might not be enough to evaluate exactly what’s going on. Pages my work slightly differently depending on the query string or user input or there might be differences in caching mechanisms.

    Aggregating a number of runs allows you to combine a number of runs and receive an average of the resources consumed.

    http://localhost/xhprof/xhprof_html/index.php?run=run_id,run_id,run_id&source=applicationName

    Note: run_id should be the ids from some of your previous runs and applicationName should be the name you specified when setting up the hook earlier.

    Summary

    You should now have XHProf up and running in your CodeIgniter application and be able to see exactly where your code is spending most of it’s time. Optimisation can be a difficult task. Sometimes it’s not as simple as reimplementing a function, or adding a layer of caching. Thinking about why you’re doing something and what the exact effect that is having on your application is just as important.

    So let me know if you have any questions in the comments below. Thank you so much for reading!


  • Permalink for 'The Essentials of AMD and RequireJS: New on Tuts+ Premium'

    The Essentials of AMD and RequireJS: New on Tuts+ Premium

    Posted: April 16th, 2012, 9:37am MDT by Jeffrey Way

    In this Tuts+ Premium screencast, we’ll review RequireJS, an asynchronous module loader and dependency manager, and AMD, which defines the mechanism and guidelines for declaring and importing modules.

    Become a Premium member to view this screencast, as well as hundreds of other advanced tutorials and screencasts from the Tuts+ network.

    You’ll Learn:
    • What is AMD? Why is it helpful?
    • How to use RequireJS, which implements the AMD spec.
    • How to create, store, and reference modules.
    • How to integrate the use plugin.
    • How to import scripts, which do not register themselves as AMD modules.
    • A lightning-fast run-through of importing and working with Backbone.js.
    Tuts+ Premium

    The recently re-launched Tuts+ Premium is a service that provides top-tier training in a variety of creative fields. Whether you prefer books, visual training, or in depth tutorials, we have you covered. While we unfortunately can’t afford to provide the service for free, it’s only $19 a month – less than you’d spend on dinner.

    I hope you’ll consider checking it out! In addition to learning a huge variety of new skills, it’s also a fantastic way to say thank you to Nettuts+.


  • Permalink for 'Optimize Your CSS With RequireJS'

    Optimize Your CSS With RequireJS

    Posted: April 16th, 2012, 9:21am MDT by Jeffrey Way

    In this lesson, we’ll review the awesome RequireJS optimizer to handle the process of merging and compressing our stylesheets. While preprocessors continue to become increasingly popular, there are still plenty of folks who stick with regular CSS. In these cases, a solid build tool/process is vital.

    Choose 720p for the clearest video. Closing Thoughts

    If you don’t like the idea of using Require.js, alternatively you might consider Grunt (along with the Grunt-CSS plugin), or Jake.


Dev Articles - Programming Help and Tutorials for all development technologies

  • Permalink for 'Top HTML5 Video Tutorials'

    Top HTML5 Video Tutorials

    Posted: April 16th, 2012, 6:00am MDT
    Many believe that HTML5 is the wave of the future. Its ability to simplify the development of web applications and increase interoperability has allowed HTML5 to gain a widespread presence across the Web. If you are new to HTML5 or have yet to jump into the technology, you are probably wondering where to begin. After all, learning an entirely new topic is no easy task. Luckily, there are tons of tutorials across the Web that cover various areas of HTML5 development. Many are in text format, but some are in video. For the purpose of this list, we are only including HTML5 tutorials that c...

Nettuts+

  • Permalink for 'Nettuts+ Quiz #12: Quirky HTML Tags'

    Nettuts+ Quiz #12: Quirky HTML Tags

    Posted: April 13th, 2012, 2:29pm MDT by Siddharth

    Taking a break from the relatively technical focus of the past few quizzes, we’re going to do something very offbeat today. Yes, Offbeat with a capital O. Be it front end or back end programming, I’m sure you’re working with HTML tags every day. But as the saying goes, can you ‘catch ‘em all?’ Or rather, can you figure out what these rarely used HTML tags do?

    I can already hear you chuckling with mirth, grasshopper. I’ve added a few deprecated tags just to keep you on your toes. Get everything right and prove that your HTML-fu is strong!


    $(document).ready(function(){ $('#quiz-container').jquizzy({ questions: init.questions, resultComments: init.resultComments, twitterStatus: 'Woo! I scored {score} on the Nettuts quiz on quirky HTML tags. Give it a shot!', twitterImage: 'http://d2o0t5hpnwv4c1.cloudfront.net/jquizzy-1.0/img/share.png', twitterUsername: 'envatowebdev', splashImage: 'http://d2o0t5hpnwv4c1.cloudfront.net/1152_quiz12/nettuts.png', }); });


  • Permalink for 'Toying With the HTML5 FileSystem API'

    Toying With the HTML5 FileSystem API

    Posted: April 11th, 2012, 10:11am MDT by Ivaylo Gerchev

    HTML5 provides us with a whole crop of new possibilities, such as drawing with canvas, implementing multimedia with the audio and video APIs, and so on. One of these tools, which is still relatively new, is the File System API. It gives us access to a sandboxed section of the user’s local file system, thus filling the gap between desktop and web applications even further! In today’s tutorial, we’ll go through the basics of this new and exciting API, exploring the most common filesystem tasks. Let’s get started!

    Introduction

    No longer do we need to download and install a given piece of software in order to use it. Simply a web browser and an internet connection gives us the ability to use any web application, anytime, anywhere, and on any platform.

    In short, web apps are cool; but, compared to desktop apps, they still have one significant weakness: they don’t have a way to interact and organize data into a structured hierarchy of folders – a real filesystem. Fortunately, with the new Filesystem API, this can be changed. This API gives web applications controlled access to a private local filesystem “sandbox,” in which they can write and read files, create and list directories, and so on. Although at the time of this writing only Google’s Chrome browser supports the “full” implementation of the Filesystem API, it still deserves to be studied as a powerful and convenient form of local storage.

    Can I Use Support}

    The Filesystem API comes in two different versions. The asynchronous API, which is useful for normal applications, and the synchronous API, reserved for use with web workers. For the purposes of this tutorial, we will exclusively explore the asynchronous version of the API.

    Step 1 – Getting Started

    Your first step is to obtain access to the HTML5 Filesystem by requesting a LocalFile System object, using the window.requestFileSystem() global method:

    window.requestFileSystem(type, size, successCallback, opt_errorCallback)

    There’s no way for a web application to “break out” beyond the local root directory.

    As the first two parameters, you specify the lifetime and size of the filesystem you want. A PERSISTENT filesystem is suitable for web apps that want to store user data permanently. The browser won’t delete it, except at the user’s explicit request. A TEMPORARY filesystem is appropriate for web apps that want to cache data, but can still operate if the web browser deletes the filesystem. The size of the filesystem is specified in bytes and should be a reasonable upper bound on the amount of data you need to store.

    The third parameter is a callback function that is triggered when the user agent successfully provides a filesystem. Its argument is a FileSystem object. And, lastly, we can add an optional callback function, which is called when an error occurs, or the request for a filesystem is denied. Its argument is a FileError object. Although this parameter is optional, it’s always a good idea to catch errors for users, as there are a number of places where things can go wrong.

    The filesystem obtained with these functions depends on the origin of the containing document. All documents or web apps from the same origin (host, port, and protocol) share a filesystem. Two documents or applications from different origins have completely distinct and disjoint filesystems. A filesystem is restricted to a single application and cannot access another application’s stored data. It’s also isolated from the rest of the files on the user’s hard drive, which is a good thing: there’s no way for a web application to “break out” beyond the local root directory or otherwise access arbitrary files.

    Let’s review an example:

    window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;
    
    window.requestFileSystem(window.TEMPORARY, 5*1024*1024, initFS, errorHandler);
    
    function initFS(fs){
      alert("Welcome to Filesystem! It's showtime :)"); // Just to check if everything is OK :)
      // place the functions you will learn bellow here
    }
    
    function errorHandler(){
      console.log('An error occured');
    }
    

    This creates a temporary filesystem with 5MB of storage. It then provides a success callback function, which we will use to operate our filesystem. And, of course, an error handler is also added – just in case something goes wrong. Here, the errorHandler() function is too generic. So if you want, you can create a slightly optimized version, which gives the reader a more descriptive error message:

    function errorHandler(err){
     var msg = 'An error occured: ';
    
      switch (err.code) {
        case FileError.NOT_FOUND_ERR:
          msg += 'File or directory not found';
          break;
    
        case FileError.NOT_READABLE_ERR:
          msg += 'File or directory not readable';
          break;
    
        case FileError.PATH_EXISTS_ERR:
          msg += 'File or directory already exists';
          break;
    
        case FileError.TYPE_MISMATCH_ERR:
          msg += 'Invalid filetype';
          break;
    
        default:
          msg += 'Unknown Error';
          break;
      };
    
     console.log(msg);
    };

    The filesystem object you obtain has a name (a unique name for the filesystem, assigned by the browser) and root property that refers to the root directory of the filesystem. This is a DirectoryEntry object, and it may have nested directories that are themselves represented by DirectoryEntry objects. Each directory in the file system may contain files, represented by FileEntry objects. The DirectoryEntry object defines methods for obtaining DirectoryEntry and FileEntry objects by pathname (they will optionally create new directories or files if you specify a name that doesn’t exist). DirectoryEntry also defines a createReader() factory method that returns a DirectoryReader object for listing the contents of a directory. The FileEntry class defines a method for obtaining the File object (a Blob) that represents the contents of a file. You can then use a FileReader object to read the file. FileEntry defines another method to return a FileWriter object that you can use to write content into a file.

    Phhew…sounds complicated? Don’t worry. Everything will become clearer as we progress through the examples below.

    Step 2 – Working With Directories

    Obviously, the first thing you need to create in a filesystem is some buckets, or directories. Although the root directory already exists, you don’t want to place all of your files there. Directories are created by the DirectoryEntry object. In the following example, we create a directory, called Documents, within the root directory:

    fs.root.getDirectory('Documents', {create: true}, function(dirEntry) {
      alert('You have just created the ' + dirEntry.name + ' directory.');
    }, errorHandler);

    The getDirectory() method is used both to read and create directories. As the first parameter, you can pass either a name or path as the directory to look up or create. We set the second argument to true, because we’re attempting to create a directory – not read an existing one. And at the end, we add an error callback.

    So far, so good. We have a directory; let’s now add a subdirectory. The function is exactly the same with one difference: we change the first argument from ‘Documents’ to ‘Documents/Music’. Easy enough; but what if you want to create a subfolder, Sky, with two parent folders, Images and Nature, inside the Documents folder? If you type ‘Documents/Images/Nature/Sky‘ for the path argument, you will receive an error, because you can’t create a directory, when its immediate parent does not exist. A solution for this is to create each folder one by one: Images inside Documents, Nature inside Images, and then Sky inside Nature. But this is a very slow and inconvenient process. There is a better solution: to create a function which will create all necessary folders automatically.

    function createDir(rootDir, folders) {
      rootDir.getDirectory(folders[0], {create: true}, function(dirEntry) {
        if (folders.length) {
          createDir(dirEntry, folders.slice(1));
        }
      }, errorHandler);
    };
    
    createDir(fs.root, 'Documents/Images/Nature/Sky/'.split('/'));
    

    With this little trick, all we need to do is provide a full path representing the folders which we want to create. Now, the Sky directory is successfully created, and you can create other files or directories within it.

    Now it’s time to check what we have in our filesystem. We’ll create a DirectoryReader object, and use the readEntries() method to read the content of the directory.

    fs.root.getDirectory('Documents', {}, function(dirEntry){<br>
      var dirReader = dirEntry.createReader();
      dirReader.readEntries(function(entries) {<br>
        for(var i = 0; i < entries.length; i++) {
          var entry = entries[i];
          if (entry.isDirectory){
            console.log('Directory: ' + entry.fullPath);
          }
          else if (entry.isFile){
            console.log('File: ' + entry.fullPath);
          }
        }
    
      }, errorHandler);
    }, errorHandler);
    

    In the code above, the isDirectory and isFile properties are used in order to obtain a different output for directories and files, respectively. Additionally, we use the fullPath property in order to get the full path of the entry, instead of its name only.

    There are two ways to remove a DirectoryEntry from the filesystem: remove() and removeRecursively(). The first one removes a given directory only if it is empty. Otherwise, you’ll receive an error.

    fs.root.getDirectory('Documents/Music', {}, function(dirEntry) {
      dirEntry.remove(function(){
        console.log('Directory successfully removed.');
      }, errorHandler);
    }, errorHandler);

    If the Music folder has files within it, then you need to use the second method, which recursively deletes the directory and all of its contents.

    fs.root.getDirectory('Documents/Music', {}, function(dirEntry) {
      dirEntry.removeRecursively(function(){
        console.log('Directory successufully removed.');
      }, errorHandler);
    }, errorHandler);
    Step 3 – Working With Files

    Now that we know how to create directories, it’s time to populate them with files!

    The following example creates an empty test.txt in the root directory:

    fs.root.getFile('test.txt', {create: true, exclusive: true}, function(fileEntry) {
      alert('A file ' + fileEntry.name + ' was created successfully.');
    }, errorHandler);

    The first argument to getFile() can be an absolute or relative path, but it must be valid. For instance, it is an error to attempt to create a file, when its immediate parent does not exist. The second argument is an object literal, describing the function’s behavior if the file does not exist. In this example, create: true creates the file if it doesn’t exist and throws an error if it does (exclusive: true). Otherwise, if create: false, the file is simply fetched and returned.

    Having an empty file is not very useful, though; so let’s add some content inside. We can use the FileWriter object for this.

    fs.root.getFile('test.txt', {create: false}, function(fileEntry) {
      fileEntry.createWriter(function(fileWriter) {
        window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
        var bb = new BlobBuilder();
        bb.append('Filesystem API is awesome!');
        fileWriter.write(bb.getBlob('text/plain'));
      }, errorHandler);
    }, errorHandler);
    

    Above, we retrieve the test.txt file, and create a FileWriter object for it. We then append content to it by creating a new BlobBuilder object and using the write() method of FileWriter.

    Calling getFile() only retrieves a FileEntry. It does not return the contents of the file. So, if we want to read the content of the file, we need to use the File object and the FileReader object.

    fs.root.getFile('test.txt', {}, function(fileEntry) {
      fileEntry.file(function(file) {
        var reader = new FileReader();
        reader.onloadend = function(e) {
          alert(this.result);
        };
        reader.readAsText(file);
      }, errorHandler);
    }, errorHandler);

    We have written some content to our file, but what if desire to add more at a later date? To append data to an existing file, the FileWriter is used once again. We can reposition the writer to the end of the file, using the seek() method. seek accepts a byte offset as an argument, and sets the file writer’s position to that offset.

    fs.root.getFile('test.txt', {create: false}, function(fileEntry) {
      fileEntry.createWriter(function(fileWriter) {
        fileWriter.seek(fileWriter.length);
        window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
        var bb = new BlobBuilder();
        bb.append('Yes, it is!');
        fileWriter.write(bb.getBlob('text/plain'));
      }, errorHandler);
    }, errorHandler);
    

    To remove a file from the filesystem, simply call entry.remove(). The first argument to this method is a zero-parameter callback function, which is called when the file is successfully deleted. The second is an optional error callback if any errors occur.

    fs.root.getFile('test.txt', {create: false}, function(fileEntry) {
      fileEntry.remove(function() {
        console.log('File successufully removed.');
      }, errorHandler);
    }, errorHandler);
    
    Step 4 – Manipulating Files and Directories

    FileEntry and DirectoryEntry share the same API methods for copying, moving and renaming entries. There are two methods you can use for these operations: copyTo() and moveTo(). They both accept the exact same parameters:

    copyTo(parentDirEntry, opt_newName, opt_successCallback, opt_errorCallback);
    
    moveTo(parentDirEntry, opt_newName, opt_successCallback, opt_errorCallback);
    

    The first parameter is the parent folder to move/copy the entry into. The second is an optional new name to give the moved/copied entry, which is actually required when you copy an entry in the same folder; otherwise you will get an error. The third and fourth parameters were explained previously.

    Let’s review some simple examples. In the following one, we copy the file test.txt from the root to the Documents directory.

    function copy(currDir, srcEntry, destDir) {
      currDir.getFile(srcEntry, {}, function(fileEntry) {
        currDir.getDirectory(destDir, {}, function(dirEntry) {
          fileEntry.copyTo(dirEntry);
        }, errorHandler);
      }, errorHandler);
    }
    
    copy(fs.root, 'test.txt', 'Documents/');

    This next example moves test.txt to Documents, instead of copying it:

    function move(currDir, srcEntry, dirName) {
      currDir.getFile(srcEntry, {}, function(fileEntry) {
        currDir.getDirectory(dirName, {}, function(dirEntry) {
          fileEntry.moveTo(dirEntry);
        }, errorHandler);
      }, errorHandler);
    }
    
    move(fs.root, 'test.txt', 'Documents/');

    The following example renames test.txt to text.txt:

    function rename(currDir, srcEntry, newName) {
      currDir.getFile(srcEntry, {}, function(fileEntry) {
        fileEntry.moveTo(currDir, newName);
      }, errorHandler);
    }
    
    rename(fs.root, 'test.txt', 'text.txt');
    Learn More

    In this introductory tutorial, we’ve only scratched the surface of the different filesystem interfaces. If you want to learn more and dig deeper into Filesystem API, you should refer to the W3C specifications specifications:

    Now that you have a basic understanding of what the Filesystem API is, and how it can be used, it should be considerably easier to understand the API documentation, which can be a bit confusing at first sight.

    Conclusion

    The Filesystem API is a powerful and easy to use technology, which provides web developers with a whole crop of new possibilities when building web applications. Admittedly, it’s still quite new and not widely supported by all major browsers, but this will certainly change in the future. You might as well get a head start!


Dev Articles - Programming Help and Tutorials for all development technologies

  • Permalink for 'More Top CSS3 Tutorials for Animation and Images'

    More Top CSS3 Tutorials for Animation and Images

    Posted: April 11th, 2012, 6:00am MDT
    A Master Class in CSS Animations As you can tell from the title of this tutorial, what you have here is a comprehensive look at CSS animations. It does not teach you one specific CSS technique. Instead, you get a nice overview that is very informative and covers several key topics. Since the tutorial covers multiple topics in the realm of CSS animations, it does take a longer time to complete. Still, if you have one to two hours of free time, use them wisely with a visit here. Only a basic knowledge of HTML and CSS is needed. The tutorial begins with a brief look at previous CSS limitati...

Nettuts+

  • Permalink for 'Unveiling the All-New Tuts+ Hub'

    Unveiling the All-New Tuts+ Hub

    Posted: April 10th, 2012, 2:05pm MDT by David Appleyard

    Over the past few weeks, we’ve been working hard behind the scenes to create a central place for our Tuts+ readers to call “home”. Somewhere that shows you the latest content from across all our sites, allows you to filter only those tutorials that interest you, and shares a few statistics about the Tuts+ network.

    Today, we’re very excited to introduce the Tuts+ Hub — read on to find out more about it!

    All Our Latest Tutorials in One Place

    The Tuts+ Hub is a new way to see all the latest content across our whole network. Any new tutorials that have been published since your last visit will be given a “New” banner, and you can quickly filter out the sites that don’t interest you — just toggle the checkboxes at the top of the screen to show/hide content for each site.

    Tuts+ Hub

    We’re also showcasing all our new Tuts+ Premium tutorials — these are shown with a yellow border, so it’s worth keeping an eye out for these if you’re one of our awesome Tuts+ Premium members!

    A Handful of Statistics

    We also thought it would be fun to share a few of our statistics with you. Did you know we’ve published over 11,500 tutorials? Or that we’re approaching half a million comments across the network? It’s a fun way to keep an eye on how Tuts+ is growing (and these stats are updated every day).

    Tuts+ Hub What Do You Think?

    I’d love to hear your feedback on Tuts+ Hub, and any thoughts or comments on what works well/what you’d like to see improved. We’re really happy with how the project turned out and I think you’re going to love it!

    Thanks for being one of our readers and, if you’ve somehow resisted all the way down to this point, head over and check out the Tuts+ Hub!


  • Permalink for 'Techniques for Test-Driving Your JavaScript: New on Premium'

    Techniques for Test-Driving Your JavaScript: New on Premium

    Posted: April 9th, 2012, 2:23pm MDT by Jeffrey Way

    In this hands-on Premium screencast, from scratch, we’ll use test-driven development to build a jQuery plugin. Along the way, we’ll take advantage of Grunt, QUnit, and GitHub to build, test, and distribute our plugin, respectively. If the idea of testing in JavaScript is still foreign to you, you won’t find a better introduction!

    Become a Tuts+ Premium member to watch this 45 minute screencast, as well as hundreds of other advanced videos, tutorials, and courses.

    You’ll Learn How to:
    • Use Ben Alman’s Grunt build tool to expedite the process of generating and building new plugins
    • Take a test-driven approach to creating jQuery plugins – using QUnit
    • Distribute code in seconds with GitHub

    Of course, you’re likely to pick up a variety of other neat tips and tricks along the way!

    Tuts+ Premium

    The recently re-launched Tuts+ Premium is a service that provides top-tier training in a variety of creative fields. Whether you prefer books, visual training, or in depth tutorials, we have you covered. While we unfortunately can’t afford to provide the service for free, it’s only $19 a month – less than you’d spend on dinner.

    I hope you’ll consider checking it out! In addition to learning a huge variety of new skills, it’s also a fantastic way to say thank you to Nettuts+.


  • Permalink for 'Better CoffeeScript Testing With Mocha'

    Better CoffeeScript Testing With Mocha

    Posted: April 9th, 2012, 1:54pm MDT by Andrew Burgess

    Recently, I’ve been doing a considerable amount of CoffeeScript work. One problem I ran into early-on was testing: I didn’t want to have to manually convert my CoffeeScript to JavaScript before I could test it. Instead, I wanted to test from CoffeeScript directly. How’d I end up doing it? Read on to find out!

    You’ll need to have Node.js and Node Package Manager installed.

    Before we continue on, I’ll point out that you need to have a decent knowledge of CoffeeScript for this tutorial; I won’t be explaining the bits and pieces here. If you’re interested in CoffeeScript, you should check out the CoffeeScript tuts available here on Nettuts+, or the CoffeeScript documentation.

    Additionally, you’ll need to have Node.js and the Node Package Manager (npm) installed for this tutorial. If you don’t have ‘em installed, no worries: head over to nodejs.org and download the installer for your platform; then, well, install it!

    Meeting Mocha and Chai

    We’ll be building the beginnings of a todo list application (cliché, I know). These will be CoffeeScript classes. Then, we’ll write some tests with Mocha and Chai to test that functionality.

    Why both Mocha and Chai? Well, Mocha is a testing framework, but it doesn’t include the actual assertions component. That might sound strange: after all, there isn’t much more to a testing library, is there? Well, there is, in Mocha’s case. The features that brought me to the library are two-fold: the ability to run tests from the command line (instead of having an HTML page to run them in the browser), and the ability to run test in CoffeeScripts, without having to convert that code to JavaScript (as least manually: Mocha does it behind the scenes). There are other features, too, that I won’t be talking about here, including:

    • You can easily test asynchronous code.
    • You can watch for especially slow tests.
    • You can output the results in a number of different formats.

    And on, and on. See more at the Mocha home page. To install Mocha simply run npm install -g mocha, and you’re set.

    As for Chai: it’s a great assertion library that offers interfaces for doing both BDD and TDD; you can use it both in the browser or on the command line via node, which is how we’ll use it today. Install it for Node, via npm install -g chai.

    Now that we have our libraries installed, let’s start writing some code.

    Setting Up Our Project

    Let’s begin by setting up a mini project. Create a project folder. Then, create two more folders in that one: src, and test. Our CoffeeScript code will go in the src folder, and our tests will go in, you guessed it, the tests folder. Mocha looks for a test folder by default, so by doing this, we’ll save ourselves some typing later.

    Mocha looks for a test folder by default.

    We’re going to create two CoffeeScript classes: Task, which will be a todo item, and TaskList, which will be a list of todo items (yes, it’s more than an array). We’ll put them both in the src/task.coffee file. Then, the tests for this will be in test/taskTest.coffee. Of course, we could split ‘em into their own files, but we’re just not going to do that today.

    We have to start by importing the Chai library and enabling the BDD syntax. Here’s how:

    chai = require 'chai'
    chai.should()

    By calling the chai.should method, we’re actually adding a should property to Object.prototype. This allows us to write tests that read like this:

    task.name.should.equal "some string"

    If you prefer the TDD syntax, you can do this:

    expect = chai.expect

    … which allows you to write tests like this:

    expect(task.name).to.equal "some string"

    We’ll actually have to use both of these, as you’ll see; however, we’ll use the BDD syntax as much as possible.

    Now we’ll need to import our Task and TaskList classes:

    {TaskList, List} = require '../src/task'

    If you aren’t familiar with this syntax, that’s CoffeeScript’s destructured assignment at work, as well as some of its object literal sugar. Basically, our require call returns an object with two properties, which are our classes. This line pulls them out of that object and gives us two variables named Task and TaskList, each of which points to the respective class.

    Writing Our First Tests

    Great! Now, how about a test? The beauty of the Mocha syntax is that its blocks (describe and it) are identical to Jasmine’s (both being very similar to RSpec). Here’s our first test:

    describe 'Task instance', ->
    	task1 = task2 = null
    	it 'should have a name', ->
    		task1 = new Task 'feed the cat'
    		task1.name.should.equal 'feed the cat'

    We start with a describe call: all these tests are for a Test instance. By setting test1 = test2 = null outside our individual tests, we can use those values for multiple tests.

    Then, in our first test, we’re simply creating a task and checking to see that its name property has the correct value. Before writing the code for this, let’s add two more tests:

    it 'should be initially incomplete', ->
    	task1.status.should.equal 'incomplete'
    it 'should be able to be completed', ->
    	task1.complete().should.be.true
    	task1.status.should.equal 'complete'

    Ok, let’s run these tests to make sure they’re failing. To do this, let’s open a command prompt and cd to your project folder. Then, run this command:

    mocha --compilers coffee:coffee-script

    Mocha doesn’t check for CoffeeScript by default, so we have to use the --compilers flag to tell Mocha what compiler to use if it finds a file with the coffee file extension. You should get errors that look like this:

    If, instead of seeing that, you get the error Cannot find module '../src/task', it’s because your src/task.coffee file doesn’t exist yet. Make said file, and you should get said error.

    Coding Our First Features

    Well, now that we have failing tests, it’s time to write the code, correct? Open that src/task.coffee file and let’s get cracking.

    class Task
    	constructor: (@name) ->

    Just this is enough to get our first test passing. If you aren’t familiar with that parameter syntax, that just sets whatever value was passed to new Task to the @name (or this.name) property. However, let’s add another line to that constructor:

    @status = 'incomplete'

    That’s good. Now, head back to the terminal and re-run our tests. You’ll find that—wait a second, nothing’s changed! Why aren’t our first two tests passing?

    A simple problem, actually. Because the CoffeeScript compiler wraps the code in each file in a IIFE (or, a self-invoking anonymous function), we need to “export” anything we want to be accessible from other files. In the browser, you’d do something like window.Whatever = Whatever. For Node, you can use either global or exports. We’ll be using exports, since 1) that’s considered best practice, and 2) that’s what we prepared for when setting up our tests (remember our require call?). Therefore, at the end of our task.coffee file, add this:

    root = exports ? window
    root.Task = Task

    With that in place, you should find that two of our three tests are now passing:

    To get the last test to pass, we’ll have to add a complete method. Try this:

    complete: ->
    	@status = 'complete'
    	true

    Now, all tests pass:

    Now’s a good time to mention that Mocha has a number of different reports: these are just different ways to output the test results. You can run mocha --reporters to see your options:

    By default, Mocha uses the dot reporter. However, I prefer the spec reporter, so I tack -R spec on the end of command (-R is the reporter-setting flag).

    Adding a Feature

    Let’s add a feature to our Task class: we’ll let tasks be dependent on other tasks. If the “parent” task isn’t completed, the “child” task can’t be done. We’ll keep this feature simple and allow tasks to have only one sub-task. We also won’t check for recursiveness, so while it will be possible to set two tasks to be the parent and child of each other, it will render both tasks incomplete-able.

    Tests first!

    it 'should be able to be dependent on another task', ->
    	task1 = new Task 'wash dishes'
    	task2 = new Task 'dry dishes'
    
    	task2.dependsOn task1
    
    	task2.status.should.equal 'dependent'
    	task2.parent.should.equal task1
    	task1.child.should.equal task2
    
    it 'should refuse completion it is dependent on an uncompleted task', ->
    	(-> task2.complete()).should.throw "Dependent task 'wash dishes' is not completed."

    Task instances are going to have a dependsOn method, which tasks the task that will become their parent. Tasks that have a parent task should have a status of “dependent.” Also, both tasks get either a parent or child property that points to the appropriate task instance.

    In the second test there, we say that a task with an incomplete parent task should throw an error when its complete method is called. Notice how test syntax works: we need to call should off of a function, and not the result of the function: therefore, we wrap the function in parentheses. This way, the test library can call the function itself and check for the error.

    Run those tests and you’ll see that both fail. Coding time!

    dependsOn: (@parent) ->
    	@parent.child = @
    	@status = 'dependent'

    Again, very simple: we just set the task parameter to the parent task, and give it a child property which points to this task instance. Then, we set the status of this task to be “dependent.”

    If you run this now, you’ll see that one of our tests is passing, but the second isn’t: that’s because our complete method doesn’t check for an uncompleted parent task. Let’s change that.

    complete: ->
    	if @parent? and @parent.status isnt 'completed'
    		throw "Dependent task '#{@parent.name}' is not completed."
    	@status = 'complete'
    	true

    Here’s the completed complete method: if there’s a parent task, and it isn’t completed, we throw an error. Otherwise, we complete the task. Now, all tests should pass.

    Building the TaskList

    Next, we’ll build the TaskList class. Again, we’ll start with a test:

    describe 'TaskList', ->
        taskList = null
        it 'should start with no tasks', ->
            taskList = new TaskList
            taskList.tasks.length.should.equal 0
            taskList.length.should.equal 0

    This is old-hat to you by now: we’re creating a TaskList object and checking its tasks and length properties to makes sure their both at zero. As you might guess, tasks is an array that holds the tasks, while length is just a handy property that we’ll update when adding or removing tasks; it just saves us from having to write list.tasks.length.

    To make this test pass, we’ll make this constructor:

    class TaskList
    	constructor: () ->
    		@tasks = []
    		@length = 0

    Good start, and that gets our test passing.

    We’ll want to be able to add tasks to a task list, right? We’ll have an add method that can take either a Task instance, or a string which it will convert to a Task instance.

    Our tests:

    it 'should accept new tasks as tasks', ->
        task = new Task 'buy milk'
        taskList.add task
        taskList.tasks[0].name.should.equal 'buy milk'
        taskList.length.should.equal 1
    it 'should accept new tasks as string', ->
        taskList.add 'take out garbage'
        taskList.tasks[1].name.should.equal 'take out garbage'
        taskList.length.should.equal 2

    First, we add an actual Task object, and check the taskList.tasks array to verify that it’s been added. Then, we add a string, and make sure that a Task object with the right name was added to the tasks array. In both cases, we check the length of taskList as well, to make sure that it’s being property updated.

    And the function:

    add: (task) ->
        if typeof task is 'string'
            @tasks.push new Task task
        else
            @tasks.push task
        @length = @tasks.length

    Pretty self-explanatory, I think. And now our tests pass:

    Of course, we might want to remove tasks from our list, right?

    it 'should remove tasks', ->
    	i = taskList.length - 1
    	taskList.remove taskList.tasks[i]
    	expect(taskList.tasks[i]).to.not.be.ok

    First, we call the remove method (yet to be written, of course), passing it the last task currently in the list. Sure, we could just hardcode the index 1, but I’ve done it this way because that makes this test flexible: if we changed our previous tests or added more tests above this one, that might have to change. Of course, we have to remove the last one because otherwise, the task after it will take its place and there’ll be something at that index when we’re expecting there to be nothing.

    And speaking of expecting, notice that we’re using the expect function and syntax here instead of our usual should. This is because taskList.tasks[i] will be undefined, which doesn’t inherit from Object.prototype, and therefore we can’t use should.

    Oh, yeah, we still need to write that remove function:

    remove: (task) ->
        i = @tasks.indexOf task
        @tasks = @tasks[0...i].concat @tasks[i+1..] if i > -1
        @length = @tasks.length

    Some fancy array footwork combined with CoffeeScript’s ranges and array splicing shorthand closes this deal for us. We’re simply splitting off all the items before the one to remove and all the items after it; the we concat those two arrays together. Of course, we’ll update @length accordingly. Can you say “passing tests”?

    Let’s do one more thing. We want to print our a (relatively) nice-looking list of the current tasks. This will be our most complex (or at least, our longest) test yet:

        it 'should print out the list', ->
            taskList = new TaskList
            task0 = new Task 'buy milk'
            task1 = new Task 'go to store'
            task2 = new Task 'another task'
            task3 = new Task 'sub-task'
            task4 = new Task 'sub-sub-task'
    
            taskList.add task0
            taskList.add task1
            taskList.add task2
            taskList.add task3
            taskList.add task4
    
            task0.dependsOn task1
            task4.dependsOn task3
            task3.dependsOn task2
    
            task1.complete()
    
            desiredOutput = """Tasks
    
    - buy milk (depends on 'go to store')
    - go to store (completed)
    - another task
    - sub-task (depends on 'another task')
    - sub-sub-task (depends on 'sub-task')
    
    """
    		taskList.print().should.equal desiredOutput

    What’s going on here? First, we’re creating a new TaskList object so that we start from scratch. Then, we create five tasks and add them to taskList. Next, we set up a few dependencies. Finally we complete one of our tasks.

    We’re using CoffeeScript’s heredoc syntax to create a multi-line string. As you can see, we’re keeping it pretty simple. If a task has a parent task, it’s mentioned in parentheses after the task name. If a task is completed, we put that, too.

    Ready to write the function?

    print: ->
        str = "Tasks\n\n"
        for task in @tasks
            str += "- #{task.name}"
            str += " (depends on '#{task.parent.name}')" if task.parent?
            str += ' (complete)' if task.status is 'complete'
            str += "\n"
        str

    It’s actually pretty straightforward: we just look over the @tasks array and add ‘em to a string. If they have a parent, we add that, and if they’re complete, we add that too. Notice that we’re using the modifier form of the if statement, to tighten up our code. Then, we return the string.

    Now, all our tests should pass:

    Wrapping Up

    Try adding a few features to get the hang of it all.

    That’s the extent of our little project today. You can download the code from the top of this page; in fact, why don’t you try adding a few features to get the hang of it all? Here are a few ideas:

    • Prevent Task instances from being able to depend on each other (recursive dependencies).
    • Make the TaskList::add method throw an error if it receives something other than a string or a Task object.

    These days, I’m finding CoffeeScript more and more attractive, but the biggest downside to it is that it must be compiled to JavaScript before it’s useful. I’m grateful for anything that negates some of that workflow breaker, and Mocha definitely does that. Of course, it’s not perfect (since it’s compiling to JS before running the code, line numbers in errors don’t match up with your CoffeeScript line numbers), but it’s a step in the right direction for me!

    How about you? If you’re using CoffeeScript, how have you been doing testing? Let me know in the comments.


Dev Articles - Programming Help and Tutorials for all development technologies

  • Permalink for 'HTML5: Reasons to Learn and Use It'

    HTML5: Reasons to Learn and Use It

    Posted: April 9th, 2012, 6:00am MDT
    If you are a developer that has not yet jumped on the HTML5 bandwagon, you may want to seriously consider doing so. HTML5 has become the technology of choice over the basically defunct Flash, and its future looks extremely bright. Support for HTML5 has grown, and even tech giant Apple has praised it, so you know there must be something special that makes it so appealing. Even Adobe has conceded defeat to HTML5 and has started building new products around the language to help with the transition away from Flash. Many top websites have taken a liking to HTML5 as well, and others are sure to ...

Nettuts+

  • Permalink for 'CSS Refreshers: Borders'

    CSS Refreshers: Borders

    Posted: April 6th, 2012, 7:56am MDT by Jeffrey Way

    Sure, we’re all familiar with borders. Is there anything new that could possibly be introduced? Well, I bet there’s quite a few things in this article that you never knew about!

    Not only can CSS3 be used to create rounded corners, but plain-ole’ CSS can also be wrestled into displaying custom shapes. That’s right; in the past, before these techniques were discovered, we might have resorted to using absolutely positioned background images to display circles or arrows. Thankfully – as we gleefully take one more step away from Photoshop – this is no longer the case.

    The Basics

    You’re likely familiar with the most basic use of borders.

    border: 1px solid black;
    

    The above code will apply a 1px border to an element. Plain and simple; but we can also modify the syntax a bit.

    border-width: thick;
    border-style: solid;
    border-color: black;
    

    In addition to passing a specific value to border-width, three keywords may alternatively be used: thin, medium, and thick.

    image

    While it might initially seem unnecessary to ever make use of the long-hand form, there are a handful of cases when it’s advantageous, such as when you need to update some aspect of a border when a designated event occurs.

    Perhaps you need to change the color of a border when the user hovers over a specific element. Using the shorthand form would require that you repeat the pixel values.

    .box {
        border: 1px solid red;
    }
    
    .box:hover {
        border: 1px solid green;
    }
    

    A more elegant and DRY approach would be to specifically update the border-color property.

    .box {
        border: 1px solid red;
    }
    
    .box:hover {
        border-color: green;
    }
    

    Additionally, as you’ll find shortly, this long-hand technique is helpful when creating custom shapes with CSS.

    Border-Radius

    border-radius is the golden child of CSS3 – the first new property to gain widespread use in the community. What this translates to is that, excluding Internet Explorer 8 and below, all browsers can display rounded corners.

    Previously, it was necessary to use vendor prefixes for both Webkit and Mozilla, in order for the styling to be correctly applied.

    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
    

    These days, however, we can slice off the vendor versions without worry, and simply stick with the official form: border-radius.

    image

    As one might expect, we can also specify custom values for each side of a box.

    image
    border-top-left-radius: 20px;
    border-top-right-radius: 0;
    border-bottom-right-radius: 30px;
    border-bottom-left-radius: 0;
    

    In the code above, setting border-top-right-radius and border-bottom-left-radius to zero would be superfluous, unless the element is inheriting values which need to be reset.

    Much like margin or padding, these settings can be condensed into a single property, if necessary.

    /* top left, top right, bottom right, bottom left */
    border-radius: 20px 0 30px 0;
    

    As an example (and as web designers do so often), the shape of a lemon can be reproduced with CSS and the border-radius property, like so:

    .lemon {
       width: 200px; height: 200px; 
    
       background: #F5F240;
       border: 1px solid #F0D900;
       border-radius: 10px 150px 30px 150px;
    }
    
    image Beyond the Basics

    Many designers happily stick with the knowledge outlined thus far in this chapter; however, there’s a few ways we can push it further!

    Multiple Borders

    There’s a variety of techniques that we can refer to, when tasked with applying multiple borders to an element.

    Border-Style

    While solid, dashed, and dotted are the most frequent values for the border-style property, there’s also a few others that we can make use of, including groove and ridge.

    border: 20px groove #e3e3e3;
    

    Or, with the long-hand form:

    border-color: #e3e3e3;
    border-width: 20px;
    border-style: groove;
    
    image

    While this is certainly helpful, a ridge or groove effect isn’t really multiple borders.

    Outline

    The most popular technique for creating two borders is to take advantage of the outline property.

    .box {
       border: 5px solid #292929;
       outline: 5px solid #e3e3e3;
    }
    
    image

    This method works wonderfully, however, it’s limited to two borders. Should you need to create a layered, gradient-esque, effect, a different approach will be necessary.

    Pseudo Elements

    When the outline technique doesn’t suffice, an alternate approach is to take advantage of the :before and :after pseudo elements, and apply any necessary additional borders to the generated content.

    .box {
      width: 200px; height: 200px;
      background: #e3e3e3;
      position: relative;
    
      border: 10px solid green;
    }
    
    /* Create two boxes with the same width of the container */
    .box:after, .box:before {
      content: '';
      position: absolute;
      top: 0; left: 0; bottom: 0; right: 0;
    }
    
    .box:after {
      border: 5px solid red;
      outline: 5px solid yellow;
    }
    
    .box:before {
      border: 10px solid blue;
    }
    
    image

    This perhaps isn’t the most elegant approach, but it certainly gets the job. One caveat is that it’s easy to confuse the order in which the border colors will be applied. A certain level of “guess and check” is often required to apply the correct sequence.

    Box-Shadow

    The cool kids way to create an infinite number of borders is to take advantage of the spread parameter in the box-shadow CSS3 property.

    .box {
        border: 5px solid red;
         box-shadow:
           0 0 0 5px green,
           0 0 0 10px yellow,
           0 0 0 15px orange;
    }
    
    image

    In this case, we’re being clever and are using box-shadow in a way that might not necessarily have been intended when the specification was originally written.

    By setting the x, y, and blur components to 0, we can instead use the spread value to create solid borders at the desired locations. Because box-shadows can be stacked, through the use of a comma, the number of possible levels is infinite.

    This technique gracefully degrades quite nicely. In older browsers, which do not recognize the box-shadow property, this will simply render the single red 5px border.

    Remember: designs needn’t be identical in all browsers. Write your CSS for the most modern of browsers, and then provide suitable fallbacks, accordingly.

    Modifying Angles

    In addition to passing a single value to border-radius, we can alternatively provide two – separated by a / – to specify unique values for both the horizontal and vertical radii.

    For example…

    border-radius: 50px / 100px; /* horizontal radius, vertical radius */
    

    …is equivalent to:

    border-top-left-radius: 50px 100px;
    border-top-right-radius: 50px 100px;
    border-bottom-right-radius: 50px 100px;
    border-bottom-left-radius: 50px 100px;
    

    This technique is particularly helpful when you need to mimic a subtle, lengthy curve, rather than a generic rounded corner. For instance, the following code allows us to slightly break away from a square shape, resulting in more of a curled, paper-like effect.

    .box {
        width: 200px; height: 200px;
        background: #666;
    
        border-top-left-radius: 15em 1em;
        border-bottom-right-radius: 15em 1em;
    
    }
    
    image CSS Shapes

    Perhaps the neatest use of borders is when they’re cleverly applied to elements, which have a zero width and height. Confusing, huh? Let’s see a demonstration.

    For the next several examples, assume the following markup…

    <div class="box"></div>
    

    …and the following base styling:

    .box {
       width: 200px;
       height: 200px;
       background: black;
    }
    

    The most frequently referenced example, when demonstrating how CSS shapes might be used in a project, is to create the obligatory arrow.

    The key to understanding how an arrow might be formed with CSS is to set a unique border-color to each side, and then reduce both the width and height values for the container to 0.

    Assuming a div with a class of arrow as the container:

    .arrow {
      width: 0; height: 0;
    
      border-top: 100px solid red;
      border-right: 100px solid green;
      border-bottom: 100px solid blue;
      border-left: 100px solid yellow;
    }
    

    As demonstrated at the beginning of this chapter, a cleaner syntax would be to not use the all-encompassing short-hand version:

    .arrow {
      width: 0; height: 0;
    
      border: 100px solid;
      border-top-color: red;
      border-right-color: green;
      border-bottom-color: blue;
      border-left-color: yellow;
    }
    

    We can even reduce this further, by grouping the color values.

    .arrow {
      width: 0; height: 0;
    
      border: 100px solid;
      border-color: red green blue yellow;
    }
    
    image

    Interesting, right? It makes perfect sense, though, when we take a step back. That’s the only possible way that the colors could align, assuming a width and height of zero for the container. Now, what if we set all of the border-colors to transparent, except for the blue side?

    .arrow {
      width: 0; height: 0;
    
      border: 100px solid;
      border-bottom-color: blue;
    }
    
    image

    Excellent! But it doesn’t seem too semantic to create an .arrow div, all for the purpose of adding an arrow to the page. Instead, pseudo elements can be used to apply the arrow after or before the associated element.

    Creating a Speech Bubble

    To create a 100% CSS speech bubble, we begin with the markup.

    <div class="speech-bubble">Hi there!</div>
    

    Next, some base styling should be applied.

    .speech-bubble {
        position: relative;
        background-color: #292929;
    
        width: 200px;
        height: 150px;
        line-height: 150px; /* vertically center */
    
        color: white;
        text-align: center;
    }
    
    image

    The arrow will be applied using the after psuedo-element.

    .speech-bubble:after {
        content: '';
    }
    

    The :before and :after psuedo elements can be used to insert generated content either before or after an element’s content.

    At this point, it’s simply a matter of reproducing the arrow, and positioning it in the proper location. We start by absolutely positioning the content, resetting the width and height, and applying the border colors.

    .speech-bubble:after {
      content: '';
      position: absolute;
    
      width: 0;
      height: 0;
    
      border: 10px solid;
      border-color: red green blue yellow;
    }
    
    image

    Because we know that we want the arrow to point downward, the image above demonstrates that all but the red (or top) border should either be omitted, or set to transparent.

    .speech-bubble:after {
      content: '';
      position: absolute;
    
      width: 0;
      height: 0;
    
      border: 10px solid;
      border-top-color: red;
    }
    
    image

    When creating CSS shapes, because we can’t use the width property to specify how wide the arrow should be, the border-width property should be used instead. In this case, the arrow should be slightly larger; so the border-width can be increased to 15px. We’ll also position the arrow at the bottom and center of the container, by using the top and left properties, respectively.

    .speech-bubble:after {
      content: '';
      position: absolute;
    
      width: 0;
      height: 0;
    
      border: 15px solid;
      border-top-color: red;
    
      top: 100%;
      left: 50%;
    }
    
    image

    Almost there; the final step is to update the color of the arrow to be the same as the container’s background. The positioning also needs to be modified to account for the width of the borders (15px). While we’re here, we’ll also apply a subtle border-radius to make the container appear to be more bubble-like.

    .speech-bubble {
       /* … other styles */
       border-radius: 10px;
    }
    
    .speech-bubble:after {
      content: '';
      position: absolute;
    
      width: 0;
      height: 0;
    
      border: 15px solid;
      border-top-color: #292929;
    
      top: 100%;
      left: 50%;
      margin-left: -15px; /* adjust for border width */
    }
    
    image

    Not bad, ay? Abstract this code away to a few reusable classes, and you’re good to go for all future projects.

    /*
       Speech Bubbles
       Usage: Apply a class of .speech-bubble and .speech-bubble-DIRECTION
       <div class="speech-bubble speech-bubble-top">Hi there</div>
    */
    
    .speech-bubble {
      position: relative;
      background-color: #292929;
    
      width: 200px;
      height: 150px;
      line-height: 150px; /* vertically center */
    
      color: white;
      text-align: center;
      border-radius: 10px;
    
      font-family: sans-serif;
    }
    
    .speech-bubble:after {
      content: '';
      position: absolute;
    
      width: 0;
      height: 0;
    
      border: 15px solid;
    }
    
    /* Position the Arrow */
    
    .speech-bubble-top:after {
      border-bottom-color: #292929;
    
      left: 50%;
      bottom: 100%;
      margin-left: -15px;
    }
    .speech-bubble-right:after {
      border-left-color: #292929;
    
      left: 100%;
      top: 50%;
      margin-top: -15px;
    }
    
    .speech-bubble-bottom:after {
      border-top-color: #292929;
    
      top: 100%;
      left: 50%;
      margin-left: -15px;
    }
    
    .speech-bubble-left:after {
      border-right-color: #292929;
    
      top: 50%;
      right: 100%;
      margin-top: -15px;
    }
    
    image Bonus: Better Vertical Centering

    One downside to using line-height to vertically center text is that you’re limited to a single line. Should the text require two or more lines, each line height will be far too large. A clever solution is to set a display of table to the speech bubble, and a display of table-cell to the paragraph that wraps the text. This then allows us to align the text to the middle, accordingly.

    <div class="speech-bubble speech-bubble-top">
        <p>Text goes here.</p>
    </div>
    

    Next, the modified CSS.

    .speech-bubble {
     /* other styles */
    
      display: table;
    }
    
    .speech-bubble p {
      display: table-cell;
      vertical-align: middle;
    }
    
    image

    If references to display: table bring back terrible memories of old-fashioned, table-based layouts, don’t worry. These properties merely refer to the style in which an element should display.

    We’re not limited to triangles; CSS is capable of producing all sorts of shapes – even hearts and biohazard signs!

    image
    .biohazard {
      width: 0; height: 0;
    
      border: 60px solid;
      border-radius: 50%;
    
      border-top-color: black;
      border-bottom-color: black;
      border-left-color: yellow;
      border-right-color: yellow;
    }
    
    Summary

    Though it’s true that the simple border: 1px solid black syntax goes a long way, if we’re clever, we can create a variety of helpful effects, icons, and shapes. Who would have thought that borders could be so powerful? The key is to remember that the styling for common shapes or speech bubbles should only be created once, and then abstracted away to utility classes for future usage.


  • Permalink for 'JavaScript Fundamentals: New Premium Course'

    JavaScript Fundamentals: New Premium Course

    Posted: April 5th, 2012, 1:42pm MDT by Jeremy McPeak

    I’m pleased to announce that Jeremy McPeak’s latest course, JavaScript Fundamentals, is now available on Tuts+ Premium! As the author of countless books, including JavaScript: 24 Hour Trainer and Professional AJAX, Jeremy is the perfect person to show you the ropes!

    JavaScript Fundamentals

    With over five hours of content, you’ll learn everything from the absolute basics, all the way up to event delegation. And, with Jeremy’s teaching style, nobody gets left behind.

    Take the final course quiz to ensure that you’ve mastered the skills in each lesson. Tuts+ Premium

    The recently re-launched Tuts+ Premium is a service that provides top-tier training in a variety of creative fields. Whether you prefer books, visual training, or in depth tutorials, we have you covered.

    While we unfortunately can’t afford to provide the service for free, it’s only $19 a month – less than you’d spend on dinner.

    But the best part is that, every month, we’re adding as many as five new in depth courses on the skills that you want to learn. What’s on the near horizon? JavaScript Testing with Jasmine, Professional Screencasting, Cleaner Code With CoffeeScript, Test-Driven Development in Rails, and countless more.

    I hope you’ll consider checking it out! In addition to learning a huge variety of new skills, it’s also a fantastic way to say thank you to Nettuts+.


  • Permalink for 'Build a Contacts Manager Using Backbone.js: Part 5'

    Build a Contacts Manager Using Backbone.js: Part 5

    Posted: April 5th, 2012, 10:47am MDT by Dan Wellman

    Welcome back to the Building a content viewer with Backbone series. Over the first four parts, we looked at almost every major component that ships with the latest version of Backbone including models, controllers, views and routers.

    In this part of the tutorial, we’re going to hook our application up to a web server so that we can store our contacts in a database. We won’t be looking at LocalStorage; this is a popular means of persisting the data that Backbone apps use, but the fact is there are already a number of excellent tutorials available on this subject.

    Getting Started

    We’ll need a webserver and a database for this part of the tutorial. I use Microsoft’s VWD as an editor, which ships with a built-in web server and works well with MSSQL server, so this is what we’ll be using. In truth, it doesn’t really matter which stack you decide to go with.

    Installing and configuring either of these technologies (VWD and MSSQL server) is beyond the scope of this tutorial, but it’s relatively straight-forward to do and there are plenty of good guides out there.

    Once installed, you’ll want to set up a new database containing a table to store the data in. The table columns should mirror the different properties our models use, so there should be a name column, an address column, etc. The table can be populated with the example data we’ve used throughout the series so far.

    One column that should appear in our new table, but which we haven’t used in our local test data is an id, which should be unique to each row in the table. For ease of use, you probably want to set this to auto-increment when the data is added to the table.

    Backbone Sync

    In order to communicate with the server, Backbone gives us the Sync module; this is the only major module that we haven’t used yet and so understanding it will complete our knowledge of the fundamentals of the framework.

    Calling the sync() method results in a request being made to the server; by default, it assumes either jQuery or Zepto is in use and delegates the request to whichever of them is present to actually perform. It also assumes a RESTful interface is awaiting on the back-end so by default makes use of POST, PUT, GET, DELETE HTTP methods. As we’ve seen, Backbone can be configured to fall back to old-school GET and POST methods with additional headers which specify the intended action.

    As well as being able to call sync() directly, models and collections also have methods that can be used to communicate with the server; models have the destroy(), fetch(), parse() and save() methods, and collections have fetch() and parse(). The destroy() fetch() and sync() methods all defer to sync() whether being used with models or collections. The parse() method, called automatically whenever data is returned by the server, is by default a simple no-op which just returns the response from the server, but can be overridden if we wish to pre-process the response before consuming it.

    Page Load Caveat

    The way model data is bootstrapped into the page will vary depending on the back-end technology being used.

    The Backbone documentation for the fetch() method (of a collection) states that this method should not be used on the initial page load to request the required models from the server. It goes on to elaborate in the FAQ section that a page should have the required modules already available to the page on load to avoid the initial AJAX request.

    This is a great idea and while we don’t explicitly have to follow the advice, doing so will make our application just a little bit snappier, and that can only be a good thing.

    The way model data is bootstrapped into the page will vary depending on the back-end technology being used. We’re going to be using .net in this example, so one way of doing this would be to dynamically create a <script> element containing the required model data, and inject it into the page. To do this we’ll need to convert our index.html file to index.aspx instead (we’ll also need an index.aspx.cs code-behind or class file too). But doing this raises a new issue.

    Using Underscore Microtemplates in an ASPX Page

    We can lift the ‘Mustache-style’ example straight off of the Underscore documentation page.

    The problem with Underscore templates is that they use <%= to specify placeholders in the template that are replaced with actual data when the template is consumed. This is the same syntax that ASPX pages use to run dynamic .Net code within HTML tags. The Underscore templates that we’ve used in this example so far prevent the ASPX page from running correctly and instead it displays a server error.

    Fortunately there are several ways around this problem, the simplest way being to change the syntax used to specify the placeholders used in the templates. Underscore exposes the templateSettings property for this very purpose, allowing us to easy specify a regular expression used to match the symbols we wish to use. We can lift the ‘Mustache-style’ example straight off of the Underscore documentation page in fact; at the start of our app.js file (within the very outer function) we can just add the following code:

    _.templateSettings = {
        interpolate: /\{\{(.+?)\}\}/g
    };

    All this does is supply a new regular expression to the interpolate method, which allows us to use the alternative syntax {{ property }} instead of <%= property %>. We should also at this point go through the templates and change all of the original template tags to use the new syntax.

    Although this is not something we’ve used in our templates so far, there are also additional symbols that Underscore can use. We can evaluate JavaScript using <% and can escape data using <%-. If we wish to use these in our templates and have replaced the interpolate property, we should also configure the evaluate and escape Underscore properties as well.

    Bootstrapping the Model Data

    We can now think about delivering the model data that is stored in a database to our page when the page is initially rendered. We can easily do this be adding a simple method to the class file for our ASPX page that reads the records from the database and creates a list of objects where each object represents a single contact. We can then serialise the list into a JavaScript array and inject it into the page. As long as the array has the same format as the dummy array we used in the first four parts of this tutorial, we won’t have to change our front-end code.

    As a placeholder for the array, we can just add a new <script> element to the body of the page, directly before the reference to app.js, which calls the method in the code-behind:

    <script>
        var contacts = <%= getData() %>
    </script>

    The actual logic in the code-behind that performs the database read and list serialisation could vary wildly depending on the implementation, and is somewhat beyond the scope of this tutorial – we’re more interested in getting that initial payload on the page than we are about how we actually get it. Feel free to check out the class file in the accompanying code download for probably the quickest and easiest, but by no means the best, way to do it.

    At this point, we should be able to remove the contacts array that held our dummy data from app.js, run the page (through the built-in WVD webserver, or IIS) and see exactly the same page, with almost the same functionality, as we saw at the end of part 4. Yay!

    Syncing Our App With the Server

    In this example, I’ve used a .net 4.0 ASMX file to handle the requests from the front-end. In order for the back-end to see the data sent to it, we should configure the emulateHTTP and emulateJSON Backbone properties. Add the following lines of code directly after where we changed Underscore’s template syntax:

    Backbone.emulateHTTP = true;
    Backbone.emulateJSON = true;

    Whether or not you’ll need to configure these properties when building a Backbone app for real depends entirely on the back-end technology you choose to work with.

    So, our application could modify the data in several ways; it could change the attributes of a contact that already exists, it could add an entirely new contact, or it could delete a contact that already exists.

    The logic to do all of these things on the front-end already exists, but now that a server is involved, the behaviour of the page has already changed. Although the page will render as it did before, if we try to delete a contact, Backbone will throw an error complaining that a url has not been defined. The reason for this is because we used the destroy() method in the deleteContact() method of our ContactView class.

    Let’s look at how to restore the delete functionality. The first thing we should do then is define a url attribute for our models. Add the property to the Contact class that defines an individual model:

    url: function () {
        return "/ContactManager.asmx/ManageContact?id=" + this.get("id");
    }

    We specify a function as the value of the url property, which returns the URL that should be used to make the requests to. In this example, we can use an asmx web service file to handle the requests. We also add the name of our web method (ManageContact) and add the id of the model as a query string parameter.

    Now if we delete one of the contacts when we run the page a POST request is made to the web service. An X [HTTP-Method-Override] header is added to the request which specifies that the intended HTTP method was DELETE. We can use this in our web service logic to determine what action to take on the database.

    Next we can update the saveEdits() method of the ContactView class so that it notifies the web service when a contact is edited; change the line of code that uses the set() method so that it appears like this:

    this.model.set(formData).save();

    All we do is chain the save() method on to the set() method. The save() method delegates to the sync() method which makes a POST request to the server. As before the id of the model is sent as a query string and an X [HTTP-Method-Override] is used to specify the intended PUT method. This time however, the Content-Type header is set to application/x-www-form-urlencoded (if we didn’t configure the emulateJSON property it would be application/json) and the model data is sent as a form data, which we can use to make whatever changes are necessary.

    All that is left to do on the front-end is to update the addContact() method of the DirectoryView class. Previously in this method we had an if statement that checked the type of the model being added to see if the select menu needed to be updated. We should now change that if statement so that it appears as follows:

    if (_.indexOf(this.getTypes(), formData.type) === -1) {
        this.$el.find("#filter").find("select").remove().end().append(this.createSelect());
    }
    
    this.collection.create(formData);

    We’ve trimmed the if statement down to remove the else condition, making the code a bit tidier. We’ve also removed the add() method and added the create() method in its place. The create() method will actually add the new model to the collection automatically without us manually creating a new instance of our model’s class, and it will also make a request to the server, once again delegating to sync().

    This time the X [HTTP-Method-Override] header does not need to be set, because POST is the method that we would use were the request being made to a RESTful interface anyway. As with the save() method, the model data passed to the create() method is delivered to the server as form data.

    As with the server-side code used at the start of this part of the tutorial to bootstrap the initial model data into our app, the code used to process and handle the requests made by Backbone is beyond the scope of the tutorial. We’re interested only in the front-end here. As before, the Web service used for this demo is included in the code archive and is fully commented, so check it out if you’re interested. I’ve also included a database backup, which you should be able to restore in order to get going with the demo data.

    Summary

    In this part of the tutorial, we looked at some of the methods we can use which delegate to Backbone’s sync() method in order to communicate with a back-end that can persist the changes made using the front-end of the application.

    We saw how Backbone by default makes RESTful requests to a specified URL and how we can configure it in order to work with legacy servers that do not operate on REST principles. We also looked at some of the methods that delegate to sync() in order to communicate with the server. Specifically, we covered the remove(), save() and create() methods and looked at what is sent to the server and how.

    We also looked at how easy it is to change the symbols that Underscore uses in order to interpolate data into a template. This now concludes the Contact Manager tutorial; while there are many more features we could add to the application, we have now covered the basics of what it takes to build a fully-functional application using the excellent Backbone.js. Thanks for reading.


  • Permalink for 'Best of Tuts+ in March 2012'

    Best of Tuts+ in March 2012

    Posted: April 4th, 2012, 4:27pm MDT by David Appleyard

    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
    • Our First Look at Photoshop CS6 – Now Available in Beta Our First Look at Photoshop CS6 – Now Available in Beta

      Today, Adobe announced some big news. Photoshop CS6 is now available for download in Beta. For the last several months, we have been speculating about what features we can expect to see in Photoshop CS6. This speculation was fueled by the Photoshop team’s release of several sneak peek videos that revealed some exciting new features. Now that the speculation is over and Photoshop CS6 Beta is available for us to download and try, we have been able to make a careful examination of some of its new features.

      Visit Article

    • Create a Royal Gold Text Effect in Photoshop Using Layer Styles Quick Tip: Create a Royal Gold Text Effect in Photoshop Using Layer Styles

      In this quick tutorial we will show you how to create a royal gold text effect using layer styles in Photoshop. Let’s get started!

      Visit Article

    • Create a Clean Twitter App Interface in Photoshop Create a Clean Twitter App Interface in Photoshop

      In this tutorial we will create a clean Twitter app interface in Photoshop using layer styles and basic vector shapes. Let’s get started!

      Visit Article

    • Nettuts+ — Web Development Tutorials
    • Sass vs. LESS vs. Stylus: Preprocessor Shootout Sass vs. LESS vs. Stylus: Preprocessor Shootout

      Wielding the true power of a CSS preprocessor is an adventure. There are countless languages, syntaxes, and features, all ready for use right now.

      Visit Article

    • Sexy Code Snippet Management With Gists Sexy Code Snippet Management With Gists

      I’ve always struggled to find the perfect code snippet management tool…until now (and it’s free). I’ll show you my preferred workflow, using GitHub Gists and Sublime Text 2.

      Visit Article

    • Create Instagram Filters With PHP Create Instagram Filters With PHP

      In this tutorial, I’ll demonstrate how to create vintage (just like Instagram does) photos with PHP and ImageMagick. Wait? What? Yes, you can do this very thing with PHP and ImageMagick, and that’s just scratching the surface!

      Visit Article

    • Vectortuts+ — Illustrator Tutorials
    • Create a Psychedelic, Funky Line Art Portrait Create a Psychedelic, Funky Line Art Portrait

      In today’s Illustrator tutorial, I’m going to show you how I created a retro, psychedelic, funky, 70s inspired portrait using link art, bold colors and the handy Swirl Tool.

      Visit Article

    • Brainstorming Head Design, a Focus on the Eye Line Quick Tip: Brainstorming Head Design, a Focus on the Eye Line

      Varying the horizontal axis line (the eyeline) and adjusting the spacing of the eyes are two excellent methods used to brainstorm new character designs. In this tutorial, we look at a few simple, but effective, techniques you can employ to give your characters personality while making them both fresh and visually interesting.

      Visit Article

    • 15+ InDesign Tutorials for Magazine and Layout Design InDesign Tutorials for Magazine and Layout Design

      Do you want to learn to how to design a magazine in InDesign? Discover industry standard workflows for print design professionals, magazine layout design tips, and follow how to design a magazine cover layout that attracts attention. These are just a few of the topics you’ll find in this roundup of best InDesign magazine and layout tutorials.

      Visit Article

    • Webdesigntuts+ — Web Design Tutorials
    • The Benefits and Pitfalls of Gamification The Benefits and Pitfalls of Gamification

      Gamification is becoming a hot commodity around the web, but what is it? Is it being used correctly? Let’s have a look at various aspects of gamification and how they can be used and misused.

      Visit Article

    • Starting Out Building a Responsive Layout With Skeleton: Starting Out

      Dave Gamache’s Skeleton Boilerplate provides the perfect foundations upon which to build responsive websites rapidly and reliably. We’re going to use Skeleton and build a responsive page based on the Magazine design featured on Webdesigntuts+ recently. We’ll be looking at everything from multiple background images, through to media queries, flexible media and mobile-friendly navigation. Let’s get started!

      Visit Article

    • Stitch up Your Layout Quick Tip: Stitch up Your Layout

      In this Quick Tip we’re going to create a cool stitching effect in Photoshop. We won’t be using brushes, we won’t be relying on patterns – we’re going to use a really simple and fast alternative.

      Visit Article

    • Phototuts+ — Photography Tutorials
    • How to Photograph Birds of Prey in White How to Photograph Birds of Prey in White

      The first thing people say when they see my Birds of Prey Portrait Sessions is “nice Photoshop cutout work”. In fact, it’s not a cutout, the birds are photographed against a white background. Let me show you how.

      Visit Article

    • Camera Exposure Modes Explained Camera Exposure Modes Explained

      If you’re just getting started with photography, the letters on your camera’s dial might feel like hieroglyphics. With a variety of modes, it can be hard to pick what’s right for the current shooting situation. Today, we’re going to explain common camera modes so that you can pick the right one for any situation and grow out of using auto mode.

      Visit Article

    • A Photographer’s Guide to Visiting Nepal A Photographer’s Guide to Visiting Nepal

      Nepal is a country wrapping in mystique for many. The home of the highest mountain in the world and a civilization known for living in the harsh conditions of the Himalayas, Nepal has much to offer the photographic traveler. Lush jungles cover areas of Southern Nepal which is the location of the birth place of Buddha, founder of one of the oldest religions in the world still practiced today. To the East travel becomes more rugged as compared to the more arid regions of the West.

      Visit Article

    • Cgtuts+ — Computer Graphics Tutorials
    • Creating The Always Popular “Invisibility” Effect With Maya & After Effects Creating The Always Popular “Invisibility” Effect With Maya & After Effects

      In this tutorial from James Whiffin you’ll learn how to create a truly awesome invisibility effect using Maya and After Effects. James will cover creating a fractal material in Maya to use as a transition for the cloaking effect, and how to composite displacement maps inside of After Effects, using the luma values of ambient occlusion and depth map layers to achieve this popular effect in our shot.

      Visit Article

    • The Complete Workflow Creating An Animated Fish Swarm In Blender Using Particles: The Complete Workflow

      In this new two part tutorial from Frederik Steinmetz, you’ll learn how to create a truly unique fish swarm animation using Blender. Frederik will guide you through the entire process of Modeling, Texturing, Rigging and Animating a realistic school of mackerels. You’ll then learn how to create a spiraling, tornado like effect for the swarm using particles.

      Visit Article

    • An Introduction To UVMapping In 3d Studio Max Using The Unwrap UVW Modifier An Introduction To UVMapping In 3d Studio Max Using The Unwrap UVW Modifier

      So UVMapping… you hate it, I hate it. But unfortunately it’s a necessary step in the process of completing most cg projects. In this tutorial we’ll look at creating uvs using the ‘Unwrap UVW’ modifier in 3D Studio Max, and discuss what uv mapping is, why it’s necessary and some ways to approach it.

      Visit Article

    • Aetuts+ — After Effects Tutorials
    • The Naked Truth About 3D Rotations The Naked Truth About 3D Rotations

      Third of the series: “Naked Truth About…” In this video I am showing issues with rotations in 3D space and ways to deal with them. Have you ever wondered what is the difference between Rotation and Orientation? We set two keyframes for rotations and the layer rotates strangely. Has it ever happened to you? Those problems are NOT After Effects specific. This video explains the way rotations in 3D space work. Once you understand the concept – it will be easier for you to tame rotations not only in After Effects, but also in other applications. Have fun.

      Visit Article

    • Quick Tip – Implementing Droplets and Watch Folders Quick Tip – Implementing Droplets and Watch Folders

      When working with video files on a daily basis, alot of time is spent converting videos into different formats, whether for web, archive, or editing purposes. Add onto that the interruption of opening and closing programs to convert your files and you’ll end up spending less time being creative and more on technical chores. In this quick tip tutorial, we look at two simple ways to save you time by automating the process of conversion using droplets and watch folders.

      Visit Article

    • Helpful Tips For Improving Promotional Documentary Video Helpful Tips For Improving Promotional Documentary Video

      Promotional video content for the web is a powerful way to communicate a message and it is used by many companies and organizations. It allows communication in a variety of forms including spoken word and visual imagery but it also facilitates a connection with the audience on a more subconscious level. A promotional video containing a product, message or guidance must look professional – but before you spend your annual marketing budget employing a production company, ask yourself if you can achieve appropriate results by applying the hints and tips below.

      Visit Article

    • Audiotuts+ — Audio & Production Tutorials
    • A Guide to Producing an Epic Orchestral Track A Guide to Producing an Epic Orchestral Track

      Although I’m not a huge fan of epic productions, they are definitely the thing that producers/directors/game developers search for nowadays. Now, as a whole, epic orchestral tracks can be heard on movies, TV, commercials, video games, trailers. They always support tension, battle, chase – all of these extremely dynamic moments that always catch the attention of the customer. This tutorial is a guide that I do hope will help you create your own epic orchestral track. Let’s get started!

      Visit Article

    • How to Minimize Noise In Your Mixes How to Minimize Noise In Your Mixes

      Home recordings are infamous for having noise. Background noise from outside and indoor noises from the air conditioning and people shuffling around in the next room. Home recording studios are usually never sound isolated enough. Even though you might have a great sounding room, with acoustic treatment carefully placed all over, you’re still going to run into sound isolation issues.

      The biggest issue is noise, and in the following tutorial I’ll run through a couple of ways you can minimize the amount of annoying hiss and noise from your home recordings.

      Visit Article

    • Making An Electro/Dubstep Bass Patch In FM8 Making An Electro/Dubstep Bass Patch In FM8

      If you fancy a bit of departure form virtual analog, subtractive synths you could try dabbling in FM (Frequency Modulation) synthesis. Native Instruments FM8 is the perfect way to get involved with this edgy sound creation method. Lets take a look at how to create a typical roughed up bass patch that you could use for Electro house or Dubstep.

      Visit Article

    • Activetuts+ — Flash, Flex & ActionScript Tutorials
    • Build a Stage3D Shoot-’Em-Up: Sprite Test Build a Stage3D Shoot-’Em-Up: Sprite Test

      In this tutorial series (part free, part Premium) we’ll create a high-performance 2D shoot-em-up using the new hardware-accelerated Stage3D rendering engine. We will be taking advantage of several hardcore optimization techniques to achieve great 2D sprite rendering performance. In this part, we’ll build a high-performance demo that draws hundreds of moving sprites on-screen at once.

      Visit Article

    • A jQuery- and Flash-Style Library for HTML5 Canvas oCanvas: A jQuery- and Flash-Style Library for HTML5 Canvas

      With the advent of tools like Adobe Edge and libraries like EaselJS, more resources are becoming available for developers looking to create interactive HTML5 content. Many of these tools are being geared specifically for Flash developers to make the transition from ActionScript to HTML5 canvas a smooth one. This article will overview oCanvas, an HTML5 library that developers might not only find invaluable but also very easy to use.

      Visit Article

    • How to Build a Python Bot That Can Play Web Games How to Build a Python Bot That Can Play Web Games

      In this tutorial we’ll explore the ins and outs of building a Computer Vision-based game bot in Python, which will be able to to play the popular Flash game Sushi Go Round. You can use the techniques taught in this tutorial to create bots for automatically testing your own web games.

      Visit Article

    • Wptuts+ — WordPress Tutorials
    • Using Custom Image Sizes in Your Theme and Resizing Existing Images to the New Sizes Using Custom Image Sizes in Your Theme and Resizing Existing Images to the New Sizes

      In this tutorial you will learn how to generate custom sized images for you to use in your WordPress theme. Why use custom image sizes? So you won’t have to edit every image you upload to the Media Library. This way every image uploaded will get all the custom defined image sizes generated automatically. It can be inserted into the post or page using the Media Gallery or from the loop. Continue reading to find out how.

      Visit Article

    • The Complete Guide To The WordPress Settings API, Part 4: On Theme Options The Complete Guide To The WordPress Settings API, Part 4: On Theme Options

      In the last article, we took a deep dive into the various types of menus that are supported by the WordPress API. Although they aren’t necessarily part of the Settings API, they play a key part in development especially when working on more advanced plugins and themes.

      Visit Article

    • The header.php – What Needs to Go in It and What Doesn’t The header.php – What Needs to Go in It and What Doesn’t

      In this tutorial, let’s talk about the header.php, an essential file for any WordPress theme. I’ll show you a nice header file example and give tips about what needs to go in it and what doesn’t.

      Visit Article

    • Mobiletuts+ — Mobile Development Tutorials
    • Project Overview D Game Development with ShiVa3D Suite: Project Overview

      Curious about 3D game development? Now is the time to learn! This five-part tutorial series will demonstrate how to build a simple game with ShiVa3D Suite, a cross-platform 3D game engine and development tool. This series was originally intended for Tuts+ Premium members only, but will instead be given away to the community for free with each portion published back-to-back over the next 5 days. Read on to begin your journey into 3D programming!

      Visit Article

    • Creating Android-Compliant Libraries Android Essentials: Creating Android-Compliant Libraries

      Android libraries can be packaged and reused in other Android applications using the new Android Library feature of the Android SDK. In this quick tutorial, you will learn how to create simple Android library files that can be reused in multiple projects and increase developer efficiency.

      Visit Article

    • Enabling Google Analytics to Gather App Statistics Enabling Google Analytics to Gather App Statistics

      Google Analytics is a service provided by Google that makes it easy to track what users do. The Google Analytics team released an Analytics SDKs for mobile platforms including Android, iOS (Apple), and mobile websites. In this tutorial, learn how to include and enable this technology within your Android projects to gather important information about how users are using your applications.

      Visit Article


Dev Articles - Programming Help and Tutorials for all development technologies

  • Permalink for 'More of the Top jQuery Slider Plugins'

    More of the Top jQuery Slider Plugins

    Posted: April 3rd, 2012, 10:00pm MDT
    RoyalSlider - Touch-Enabled jQuery Image Gallery RoyalSlider is a jQuery slider plugin that is ideal for the plethora of mobile devices with touch-screens that seem to be so popular nowadays. Its list of feature is huge and is highlighted by its touch gesture support for Android, iOS, and other touch devices. Moving on, here is a sampling of some of the features you can look forward to with RoyalSlider: a resizable layout, smart lazy loading, animated captions, a plethora of customizable settings, SEO optimized, move or fade transition for slides, smooth transitions that work well with a w...

Nettuts+

  • Permalink for 'Persisting a Todo List With MongoDB and Geddy'

    Persisting a Todo List With MongoDB and Geddy

    Posted: April 3rd, 2012, 8:06am MDT by Daniel Erickson

    In this three part tutorial, we’ll be diving deep into creating a to do list management app in Node.js and Geddy. This is the last entry in the series, where we’ll be persisting our todo items to MongoDB.

    As a quick refresher, last time, we created our todo resource and made a working to do list application, but the data only existed in memory. In this tutorial, we’ll fix that!

    Intro to MongoDB

    MongoDB is a NoSQL document store database created by the folks over at 10gen. It’s a great database for Node apps because it stores its data in a JSON-like format already, and its queries are written in JavaScript. We’ll be using it for our app, so let’s get it set up.

    Installing MongoDB

    Go to [www.mongodb.org] and download the latest version for your OS. Follow the instructions in the readme from there. Make sure that you can start mongod (and go ahead and leave it running for the duration of this tutorial)

    It’s worth noting that you’ll need to have mongo running any time you want your app running. Most people set this up to start up with their server using an upstart script or something like it.

    Done? alright, let’s move on.

    MongoDB-Wrapper

    For our app, we’ll be using a module that wraps the mongodb-native database driver. This greatly simplifies the code that we’ll be producing, so let’s get it installed. cd into your app and run this command:

    npm install mongodb-wrapper

    If all goes well you should have a mongodb-wrapper directory in your node_modules directory now.

    Setting up Your Database

    Mongo is a really easy DB to work with; you don’t have to worry about setting up tables, columns, or databases. Simply by connecting to a database, you create one! And just by adding to a collection, you make one. So let’s set this up for our app.

    Editing your init.js file

    We’re going to need access to our DB app-wide, so let’s setup our code in config/init.js. Open it up; it should look like this:

    // Add uncaught-exception handler in prod-like environments
    if (geddy.config.environment != 'development') {
      process.addListener('uncaughtException', function (err) {
        geddy.log.error(JSON.stringify(err));
      });
    }
    geddy.todos = [];
    geddy.model.adapter = {};
    geddy.model.adapter.Todo = require(process.cwd() + '/lib/model_adapters/todo').Todo;
    

    Let’s add in our db code at the very top (and remove the geddy.todos array while we’re at it):

    var mongo = require('mongodb-wrapper');
    
    geddy.db = mongo.db('localhost', 27017, 'todo');
    geddy.db.collection('todos');
    
    // Add uncaught-exception handler in prod-like environments
    if (geddy.config.environment != 'development') {
      process.addListener('uncaughtException', function (err) {
        geddy.log.error(JSON.stringify(err));
      });
    }
    geddy.model.adapter = {};
    geddy.model.adapter.Todo = require(process.cwd() + '/lib/model_adapters/todo').Todo;

    First, we require the mongodb-wrapper module. Then, we set up our database, and add a collection to it. Hardly any set up at all.

    Rewriting Your Model-Adapter

    Geddy doesn’t really care what data backend you use, as long as you’ve got a model-adapter written for it. This means that the only code that you’ll have to change in your app to get your todos into a database is in the model-adapter. That said, this will be a complete rewrite of the adapter, so if you want to keep your old in-memory app around, you’ll want to copy the code to another directory.

    Editing Your Save Method

    Open up your model-adapter (lib/model_adapters/todo.js) and find the save method. It should look something like this:

    this.save = function (todo, opts, callback) {
      if (typeof callback != 'function') {
        callback = function(){};
      }
      var todoErrors = null;
      for (var i in geddy.todos) {
        // if it's already there, save it
        if (geddy.todos[i].id == todo.id) {
          geddy.todos[i] = todo;
          todoErrors = geddy.model.Todo.create(todo).errors;
          return callback(todoErrors, todo);
        }
      }
      todo.saved = true;
      geddy.todos.push(todo);
      return callback(null, todo);
    }

    Make it look like this:

    this.save = function (todo, opts, callback) {
      // sometimes we won't need to pass a callback
      if (typeof callback != 'function') {
        callback = function(){};
      }
      // Mongo doesn't like it when you send functions to it
      // so let's make sure we're only using the properties
      cleanTodo = {
        id: todo.id
      , saved: todo.saved
      , title: todo.title
      , status: todo.status
      };
      // Double check to see if this thing is valid
      todo = geddy.model.Todo.create(cleanTodo);
      if (!todo.isValid()) {
        return callback(todo.errors, null);
      }
      // Check to see if we have this to do item already
      geddy.db.todos.findOne({id: todo.id}, function(err, doc){
        if (err) {
          return callback(err, null);
        }
        // if we already have the to do item, update it with the new values
        if (doc) {
          geddy.db.todos.update({id: todo.id}, cleanTodo, function(err, docs){
            return callback(todo.errors, todo);
          });
        }
        // if we don't already have the to do item, save a new one
        else {
          todo.saved = true;
          geddy.db.todos.save(todo, function(err, docs){
            return callback(err, docs);
          });
        }
      });
    }

    Don’t be too daunted by this one; we started with the most complex one first. Remember that our save method has to account for both new todos and updating old todos. So let’s walk through this code step by step.

    We use the same callback code as we did before – if we don’t have a callback passed to us, just use an empty function.

    Then we sanitize our todo item. We have to do this because our todo object has JavaScript methods on it (like save), and Mongo doesn’t like it when you pass it objects with methods on them. So we just create a new object with just the properties that we care about on it.

    Then, we check to see if the todo is valid. If it’s not, we call the callback with the validation errors. If it is, we continue on.

    In case we already have this todo item in the db, we check the db to see if a todo exists. This is where we start to use the mongodb-wrapper module. It gives us a clean API to work with our db. Here we’re using the db.todos.findOne() method to find a single document that statisfies our query. Our query is a simple js object – we’re looking for a document whose id is the same as our todos id. If we find one and there isn’t an error, we use the db.todos.update() method to update the document with the new data. If we don’t find one, we use the db.todos.save() method to save a new document with the todo item’s data.

    In all cases, we call a callback when we’re done, with any errors that we got and the docs that the db returned to us being passed to it.

    Editing the all method

    Take a look at the all method, it should look like this:

    this.all = function (callback) {
      callback(null, geddy.todos);
    }

    Let’s make it look like this:

    this.all = function (callback) {
      var todos = [];
      geddy.db.todos.find().sort({status: -1, title: 1}).toArray(function(err, docs){
        // if there's an error, return early
        if (err) {
          return callback(err, null);
        }
        // iterate through the docs and create models out of them
        for (var i in docs) {
          todos.push( geddy.model.Todo.create(docs[i]) )
        }
        return callback(null, todos);
      });
    }

    Much simpler than the save method, don’t you think? We use the db.todos.find() method to get all the items in the todos collection. We’re using monogdb-wrapper’s api to sort the results by status (in decending alphabetical order) and by title (in ascending alphabetical order). Then we send that to an array, which triggers the query to start. Once we get our data back, we check to see if there are any errors, if there are, we call the callback with the error. If there aren’t any errors we continue on.

    Then, we loop through all the docs (the documents that mongo gave back to us), create new todo model instances for each of them, and push them to a todos array. When we’re done there, we call the callback, passing in the todos.

    Editing the load method

    Take a look at the ‘load’ method, it should look something like this:

     this.load = function (id, callback) {
      for (var i in geddy.todos) {
        if (geddy.todos[i].id == id) {
          return callback(null, geddy.todos[i]);
        }
      }
      callback({message: "To Do not found"}, null);
    };

    Let’s make it look like this:

    this.load = function (id, callback) {
      var todo;
      // find a todo in the db
      geddy.db.todos.findOne({id: id}, function(err, doc){
        // if there's an error, return early
        if (err) {
          return callback(err, null);
        }
        // if there's a doc, create a model out of it
        if (doc) {
          todo = geddy.model.Todo.create(doc);
        }
        return callback(null, todo);
      });
    };

    This one is even simpler. We use the db.todos.findOne() method again. This time, that’s all we have to use though. If we have an error, we call the callback with it, if not, we continue on (seeing a pattern here yet?). If we have a doc, we create a new instance of the todo model and call the callback with it. That’s it for that one.

    Editing the remove method

    Take a look at the remove method now, it should look like this:

    this.remove = function(id, callback) {
      if (typeof callback != 'function') {
        callback = function(){};
      }
      for (var i in geddy.todos) {
        if (geddy.todos[i].id == id) {
          geddy.todos.splice(i, 1);
          return callback(null);
        }
      }
      return callback({message: "To Do not found"});
    };

    Let’s make it look like this:

    this.remove = function(id, callback) {
      if (typeof callback != 'function') {
        callback = function(){};
      }
      geddy.db.todos.remove({id: id}, function(err, res){
        callback(err);
      });
    }

    The remove method is even shorter than it used to be. We use the db.todos.remove() method to remove any documents with the passed in id and call the callback with an error (if any).

    Time for the Magic

    Let’s go test our app: cd into your project’s directory and start up the server with geddy. Create a new todo. Try editing it, have it fail some validations, and try removing it. It all works!

    Conclusion

    I hope you’ve enjoyed learning about Node.js, MongoDB and especially Geddy. I’m sure by now you’ve got a million ideas for what you could build with it, and I’d love to hear about them. As always, if you have any questions, leave a comment here or open up an issue on github.