Posts Tagged ‘learn’

Happy Holidays from Tuts+!

Sunday, December 25th, 2011

The holidays are upon us, and we’re feeling festive at Tuts+ this weekend! We’d like to take this opportunity to say a huge Christmas thank you to all our readers, and wish you a very Happy Holiday. Read on for a video message from the HQ team, and a few freebies from around the Tuts+ and Envato network!


A Message from Envato HQ

Although the Tuts+ team is spread over the globe, Envato HQ is where much of the Tuts+ magic happens! It isn’t looking traditionally Christmassy in Melbourne at the moment, but we have a special holiday message from everyone at head office:

From everyone at Envato we want to wish you a Happy Holidays and look forward to seeing you all refreshed and ready for another big year in 2012! From Envato HQ to the community, we’ve created a little video to share the holiday cheer. Enjoy!

Music is Kids Holiday Theme by AudioJungle Author CraigHall


Gift Guides & Freebies!

Wondering what to buy your fellow geek this Christmas? Never fear! You may have left it it a little late, but our holiday gift guides can still come in handy. Here are a few great places to start:

We also have a couple of exclusive freebies and discounts, just in time for the holidays:


The Christmas Freelance Freedom Comic

The “holiday jingle” comic encapsulates everything that we love and hate about freelancing. Don’t forget to sing along to the “Jungle Bells” theme music as you read it…!

You can also enjoy the whole back catalog of Freelance Freedom comics over at FreelanceSwitch.


AppStorm Giveaways

We have two fantastic competitions running over at the AppStorm network over the holiday period, and there’s still time to get your entry in to stand a chance of winning:

  1. Business Productivity Bundle Giveaway —Each bundle includes a license to Daylite and Billings Pro – it’s the perfect combination for getting your business organised and making money!
  2. The AppStorm Holiday ’11 Video Game Giveaway — In the spirit of this season we’ve hand picked a few critically acclaimed, and award-winning, games released over this year to give away to our readers!

Merry Christmas, and Happy New Year!

All that’s left is to wish you a very happy holiday on behalf of everyone at Tuts+! We hope you’ve enjoyed everything that we’ve had to share this year, and look forward to publishing thousands more top-quality tutorials, articles, freebies, and resources in 2012.

Here’s to another exciting year at Tuts+, and thank you for joining us on the journey!


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

Object-Oriented PHP for Beginners

Friday, December 23rd, 2011

Twice a month, we revisit some of our readers’ favorite posts from through out the history of Nettuts+. This tutorial was first published in July, 2010.

For many PHP programmers, object-oriented programming is a frightening concept, full of complicated syntax and other roadblocks. As detailed in my book, Pro PHP and jQuery, you’ll learn the concepts behind object-oriented programming (OOP), a style of coding in which related actions are grouped into classes to aid in creating more-compact, effective code.


Understanding Object-Oriented Programming

Object-oriented programming is a style of coding that allows developers to group similar tasks into classes. This helps keep code following the tenet “don’t repeat yourself” (DRY) and easy-to-maintain.

“Object-oriented programming is a style of coding that allows developers to group similar tasks into classes.”

One of the major benefits of DRY programming is that, if a piece of information changes in your program, usually only one change is required to update the code. One of the biggest nightmares for developers is maintaining code where data is declared over and over again, meaning any changes to the program become an infinitely more frustrating game of Where’s Waldo? as they hunt for duplicated data and functionality.

OOP is intimidating to a lot of developers because it introduces new syntax and, at a glance, appears to be far more complex than simple procedural, or inline, code. However, upon closer inspection, OOP is actually a very straightforward and ultimately simpler approach to programming.


Understanding Objects and Classes

Before you can get too deep into the finer points of OOP, a basic understanding of the differences between objects and classes is necessary. This section will go over the building blocks of classes, their different capabilities, and some of their uses.

Recognizing the Differences Between Objects and Classes

“Developers start talking about objects and classes, and they appear to be interchangeable terms. This is not the case, however.”

Right off the bat, there’s confusion in OOP: seasoned developers start talking about objects and classes, and they appear to be interchangeable terms. This is not the case, however, though the difference can be tough to wrap your head around at first.

A class, for example, is like a blueprint for a house. It defines the shape of the house on paper, with relationships between the different parts of the house clearly defined and planned out, even though the house doesn’t exist.

An object, then, is like the actual house built according to that blueprint. The data stored in the object is like the wood, wires, and concrete that compose the house: without being assembled according to the blueprint, it’s just a pile of stuff. However, when it all comes together, it becomes an organized, useful house.

Classes form the structure of data and actions and use that information to build objects. More than one object can be built from the same class at the same time, each one independent of the others. Continuing with our construction analogy, it’s similar to the way an entire subdivision can be built from the same blueprint: 150 different houses that all look the same but have different
families and decorations inside.

Structuring Classes

The syntax to create a class is pretty straightforward: declare a class using the class keyword, followed by the name of the class and a set of curly braces ({}):

<?php

class MyClass
{
    // Class properties and methods go here
}

?>

After creating the class, a new class can be instantiated and stored in a variable using the new keyword:

$obj = new MyClass;

To see the contents of the class, use var_dump():

var_dump($obj);

Try out this process by putting all the preceding code in a new file called test.php in [your local] testing folder:

<?php

class MyClass
{
	// Class properties and methods go here
}

$obj = new MyClass;

var_dump($obj);

?>

Load the page in your browser at http://localhost/test.php and the following should display:

object(MyClass)#1 (0) { }

In its simplest form, you’ve just completed your first OOP script.


Defining Class Properties

To add data to a class, properties, or class-specific variables, are used. These work exactly like regular variables, except they’re bound to the object and therefore can only be accessed using the object.

To add a property to MyClass, add the following code to your script:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";
}

$obj = new MyClass;

var_dump($obj);

?>

The keyword public determines the visibility of the property, which you’ll learn about a little later in this chapter. Next, the property is named using standard variable syntax, and a value is assigned (though class properties do not need an initial value).

To read this property and output it to the browser, reference the object from which to read and the property to be read:

echo $obj->prop1;

Because multiple instances of a class can exist, if the individual object is not referenced, the script would be unable to determine which object to read from. The use of the arrow (->) is an OOP construct that accesses the contained properties and methods of a given object.

Modify the script in test.php to read out the property rather than dumping the whole class by modifying the code as shown:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";
}

$obj = new MyClass;

echo $obj->prop1; // Output the property

?>

Reloading your browser now outputs the following:

I'm a class property!

Defining Class Methods

Methods are class-specific functions. Individual actions that an object will be able to perform are defined within the class as methods.

For instance, to create methods that would set and get the value of the class property $prop1, add the following to your code:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

$obj = new MyClass;

echo $obj->prop1;

?>

Note — OOP allows objects to reference themselves using $this. When working within a method, use $this in the same way you would use the object name outside the class.

To use these methods, call them just like regular functions, but first, reference the object they belong to. Read the property from MyClass, change its value, and read it out again by making the modifications below:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

$obj = new MyClass;

echo $obj->getProperty(); // Get the property value

$obj->setProperty("I'm a new property value!"); // Set a new one

echo $obj->getProperty(); // Read it out again to show the change

?>

Reload your browser, and you’ll see the following:

I'm a class property!
I'm a new property value!

“The power of OOP becomes apparent when using multiple instances of the
same class.”

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

// Create two objects
$obj = new MyClass;
$obj2 = new MyClass;

// Get the value of $prop1 from both objects
echo $obj->getProperty();
echo $obj2->getProperty();

// Set new values for both objects
$obj->setProperty("I'm a new property value!");
$obj2->setProperty("I belong to the second instance!");

// Output both objects' $prop1 value
echo $obj->getProperty();
echo $obj2->getProperty();

?>

When you load the results in your browser, they read as follows:

I'm a class property!
I'm a class property!
I'm a new property value!
I belong to the second instance!

As you can see, OOP keeps objects as separate entities, which makes for easy separation of different pieces of code into small, related bundles.


Magic Methods in OOP

To make the use of objects easier, PHP also provides a number of magic methods, or special methods that are called when certain common actions occur within objects. This allows developers to perform a number of useful tasks with relative ease.

Using Constructors and Destructors

When an object is instantiated, it’s often desirable to set a few things right off the bat. To handle this, PHP provides the magic method __construct(), which is called automatically whenever a new object is
created.

For the purpose of illustrating the concept of constructors, add a constructor to MyClass that will output a message whenever a new instance of the class is created:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

// Create a new object
$obj = new MyClass;

// Get the value of $prop1
echo $obj->getProperty();

// Output a message at the end of the file
echo "End of file.<br />";

?>

Note__CLASS__ returns the name of the class in which it is called; this is what is known as a magic constant. There are several available magic constants, which you can read more about in the PHP manual.

Reloading the file in your browser will produce the following result:

The class "MyClass" was initiated!
I'm a class property!
End of file.

To call a function when the object is destroyed, the __destruct() magic method is available. This is useful for class cleanup (closing a database connection, for instance).

Output a message when the object is destroyed by defining the magic method
__destruct() in MyClass:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function __destruct()
    {
        echo 'The class "', __CLASS__, '" was destroyed.<br />';
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

// Create a new object
$obj = new MyClass;

// Get the value of $prop1
echo $obj->getProperty();

// Output a message at the end of the file
echo "End of file.<br />";

?>

With a destructor defined, reloading the test file results in the following output:

The class "MyClass" was initiated!
I'm a class property!
End of file.
The class "MyClass" was destroyed.

“When the end of a file is reached, PHP automatically releases all resources.”

To explicitly trigger the destructor, you can destroy the object using the
function unset():

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function __destruct()
    {
        echo 'The class "', __CLASS__, '" was destroyed.<br />';
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

// Create a new object
$obj = new MyClass;

// Get the value of $prop1
echo $obj->getProperty();

// Destroy the object
unset($obj);

// Output a message at the end of the file
echo "End of file.<br />";

?>

Now the result changes to the following when loaded in your browser:

The class "MyClass" was initiated!
I'm a class property!
The class "MyClass" was destroyed.
End of file.

Converting to a String

To avoid an error if a script attempts to output MyClass as a string, another magic method is used called __toString().

Without __toString(), attempting to output the object as a string results in a fatal error. Attempt to use echo to output the object without a magic method in place:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function __destruct()
    {
        echo 'The class "', __CLASS__, '" was destroyed.<br />';
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

// Create a new object
$obj = new MyClass;

// Output the object as a string
echo $obj;

// Destroy the object
unset($obj);

// Output a message at the end of the file
echo "End of file.<br />";

?>

This results in the following:

The class "MyClass" was initiated!

Catchable fatal error: Object of class MyClass could not be converted to string in /Applications/XAMPP/xamppfiles/htdocs/testing/test.php on line 40

To avoid this error, add a __toString() method:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function __destruct()
    {
        echo 'The class "', __CLASS__, '" was destroyed.<br />';
    }

    public function __toString()
    {
        echo "Using the toString method: ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

// Create a new object
$obj = new MyClass;

// Output the object as a string
echo $obj;

// Destroy the object
unset($obj);

// Output a message at the end of the file
echo "End of file.<br />";

?>

In this case, attempting to convert the object to a string results in a call to the getProperty() method. Load the test script in your browser to see the result:

The class "MyClass" was initiated!
Using the toString method: I'm a class property!
The class "MyClass" was destroyed.
End of file.

Tip — In addition to the magic methods discussed in this section, several others are available. For a complete list of magic methods, see the PHP manual page.


Using Class Inheritance

Classes can inherit the methods and properties of another class using the extends keyword. For instance, to create a second class that extends MyClass and adds a method, you would add the following to your test file:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function __destruct()
    {
        echo 'The class "', __CLASS__, '" was destroyed.<br />';
    }

    public function __toString()
    {
        echo "Using the toString method: ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

class MyOtherClass extends MyClass
{
    public function newMethod()
    {
        echo "From a new method in " . __CLASS__ . ".<br />";
    }
}

// Create a new object
$newobj = new MyOtherClass;

// Output the object as a string
echo $newobj->newMethod();

// Use a method from the parent class
echo $newobj->getProperty();

?>

Upon reloading the test file in your browser, the following is output:

The class "MyClass" was initiated!
From a new method in MyOtherClass.
I'm a class property!
The class "MyClass" was destroyed.

Overwriting Inherited Properties and Methods

To change the behavior of an existing property or method in the new class, you can simply overwrite it by declaring it again in the new class:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function __destruct()
    {
        echo 'The class "', __CLASS__, '" was destroyed.<br />';
    }

    public function __toString()
    {
        echo "Using the toString method: ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

class MyOtherClass extends MyClass
{
    public function __construct()
    {
        echo "A new constructor in " . __CLASS__ . ".<br />";
    }

    public function newMethod()
    {
        echo "From a new method in " . __CLASS__ . ".<br />";
    }
}

// Create a new object
$newobj = new MyOtherClass;

// Output the object as a string
echo $newobj->newMethod();

// Use a method from the parent class
echo $newobj->getProperty();

?>

This changes the output in the browser to:

A new constructor in MyOtherClass.
From a new method in MyOtherClass.
I'm a class property!
The class "MyClass" was destroyed.

Preserving Original Method Functionality While Overwriting Methods

To add new functionality to an inherited method while keeping the original method intact, use the parent keyword with the scope resolution operator (::):

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function __destruct()
    {
        echo 'The class "', __CLASS__, '" was destroyed.<br />';
    }

    public function __toString()
    {
        echo "Using the toString method: ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

class MyOtherClass extends MyClass
{
    public function __construct()
    {
        parent::__construct(); // Call the parent class's constructor
        echo "A new constructor in " . __CLASS__ . ".<br />";
    }

    public function newMethod()
    {
        echo "From a new method in " . __CLASS__ . ".<br />";
    }
}

// Create a new object
$newobj = new MyOtherClass;

// Output the object as a string
echo $newobj->newMethod();

// Use a method from the parent class
echo $newobj->getProperty();

?>

This outputs the result of both the parent constructor and the new class’s constructor:

The class "MyClass" was initiated!
A new constructor in MyOtherClass.
From a new method in MyOtherClass.
I'm a class property!
The class "MyClass" was destroyed.

Assigning the Visibility of Properties and Methods

For added control over objects, methods and properties are assigned visibility. This controls how and from where properties and methods can be accessed. There are three visibility keywords: public, protected, and private. In addition to its visibility, a method or property can be declared as static, which allows them to be accessed without an instantiation of the class.

“For added control over objects, methods and properties are assigned visibility.”

Note — Visibility is a new feature as of PHP 5. For information on OOP compatibility with PHP 4, see the PHP manual page.

Public Properties and Methods

All the methods and properties you’ve used so far have been public. This means that they can be accessed anywhere, both within the class and externally.

Protected Properties and Methods

When a property or method is declared protected, it can only be accessed within the class itself or in descendant classes (classes that extend the class containing the protected method).

Declare the getProperty() method as protected in MyClass and try to access it directly from outside the class:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function __destruct()
    {
        echo 'The class "', __CLASS__, '" was destroyed.<br />';
    }

    public function __toString()
    {
        echo "Using the toString method: ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    protected function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

class MyOtherClass extends MyClass
{
    public function __construct()
    {
        parent::__construct();
		echo "A new constructor in " . __CLASS__ . ".<br />";
    }

    public function newMethod()
    {
        echo "From a new method in " . __CLASS__ . ".<br />";
    }
}

// Create a new object
$newobj = new MyOtherClass;

// Attempt to call a protected method
echo $newobj->getProperty();

?>

Upon attempting to run this script, the following error shows up:

The class "MyClass" was initiated!
A new constructor in MyOtherClass.

Fatal error: Call to protected method MyClass::getProperty() from context '' in /Applications/XAMPP/xamppfiles/htdocs/testing/test.php on line 55

Now, create a new method in MyOtherClass to call the getProperty() method:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function __destruct()
    {
        echo 'The class "', __CLASS__, '" was destroyed.<br />';
    }

    public function __toString()
    {
        echo "Using the toString method: ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    protected function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

class MyOtherClass extends MyClass
{
    public function __construct()
    {
        parent::__construct();
		echo "A new constructor in " . __CLASS__ . ".<br />";
    }

    public function newMethod()
    {
        echo "From a new method in " . __CLASS__ . ".<br />";
    }

    public function callProtected()
    {
        return $this->getProperty();
    }
}

// Create a new object
$newobj = new MyOtherClass;

// Call the protected method from within a public method
echo $newobj->callProtected();

?>

This generates the desired result:

The class "MyClass" was initiated!
A new constructor in MyOtherClass.
I'm a class property!
The class "MyClass" was destroyed.

Private Properties and Methods

A property or method declared private is accessible only from within the class that defines it. This means that even if a new class extends the class that defines a private property, that property or method will not be available at all within the child class.

To demonstrate this, declare getProperty() as private in MyClass, and attempt to call callProtected() from
MyOtherClass:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function __destruct()
    {
        echo 'The class "', __CLASS__, '" was destroyed.<br />';
    }

    public function __toString()
    {
        echo "Using the toString method: ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    private function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

class MyOtherClass extends MyClass
{
    public function __construct()
    {
        parent::__construct();
        echo "A new constructor in " . __CLASS__ . ".<br />";
    }

    public function newMethod()
    {
        echo "From a new method in " . __CLASS__ . ".<br />";
    }

    public function callProtected()
    {
        return $this->getProperty();
    }
}

// Create a new object
$newobj = new MyOtherClass;

// Use a method from the parent class
echo $newobj->callProtected();

?>

Reload your browser, and the following error appears:

The class "MyClass" was initiated!
A new constructor in MyOtherClass.

Fatal error: Call to private method MyClass::getProperty() from context 'MyOtherClass' in /Applications/XAMPP/xamppfiles/htdocs/testing/test.php on line 49

Static Properties and Methods

A method or property declared static can be accessed without first instantiating the class; you simply supply the class name, scope resolution operator, and the property or method name.

“One of the major benefits to using static properties is that they keep their stored values for the duration of the script.”

To demonstrate this, add a static property called $count and a static method called plusOne() to MyClass. Then set up a do...while loop to output the incremented value of $count as long as the value is less than 10:

<?php

class MyClass
{
    public $prop1 = "I'm a class property!";

    public static $count = 0;

    public function __construct()
    {
        echo 'The class "', __CLASS__, '" was initiated!<br />';
    }

    public function __destruct()
    {
        echo 'The class "', __CLASS__, '" was destroyed.<br />';
    }

    public function __toString()
    {
        echo "Using the toString method: ";
        return $this->getProperty();
    }

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    private function getProperty()
    {
        return $this->prop1 . "<br />";
    }

    public static function plusOne()
    {
        return "The count is " . ++self::$count . ".<br />";
    }
}

class MyOtherClass extends MyClass
{
    public function __construct()
    {
        parent::__construct();
        echo "A new constructor in " . __CLASS__ . ".<br />";
    }

    public function newMethod()
    {
        echo "From a new method in " . __CLASS__ . ".<br />";
    }

    public function callProtected()
    {
        return $this->getProperty();
    }
}

do
{
    // Call plusOne without instantiating MyClass
    echo MyClass::plusOne();
} while ( MyClass::$count < 10 );

?>

Note — When accessing static properties, the dollar sign
($) comes after the scope resolution operator.

When you load this script in your browser, the following is output:

The count is 1.
The count is 2.
The count is 3.
The count is 4.
The count is 5.
The count is 6.
The count is 7.
The count is 8.
The count is 9.
The count is 10.

Commenting with DocBlocks

“The DocBlock commenting style is a widely
accepted method of documenting classes.”

While not an official part of OOP, the DocBlock commenting style is a widely accepted method of documenting classes. Aside from providing a standard for
developers to use when writing code, it has also been adopted by many of the most popular software development kits (SDKs), such as Eclipse and NetBeans, and will be used to generate code hints.

A DocBlock is defined by using a block comment that starts with an additional asterisk:

/**
 * This is a very basic DocBlock
 */

The real power of DocBlocks comes with the ability to use tags, which start with an at symbol (@) immediately followed by the tag name and the value of the tag. DocBlock tags allow developers to define authors of a file, the license for a class, the property or method information, and other useful information.

The most common tags used follow:

A sample class commented with DocBlocks might look like this:

<?php

/**
 * A simple class
 *
 * This is the long description for this class,
 * which can span as many lines as needed. It is
 * not required, whereas the short description is
 * necessary.
 *
 * It can also span multiple paragraphs if the
 * description merits that much verbiage.
 *
 * @author Jason Lengstorf <jason.lengstorf@ennuidesign.com>
 * @copyright 2010 Ennui Design
 * @license http://www.php.net/license/3_01.txt PHP License 3.01
 */
class SimpleClass
{
    /**
     * A public variable
     *
     * @var string stores data for the class
     */
    public $foo;

    /**
     * Sets $foo to a new value upon class instantiation
     *
     * @param string $val a value required for the class
     * @return void
     */
    public function __construct($val)
    {
        $this->foo = $val;
    }

    /**
     * Multiplies two integers
     *
     * Accepts a pair of integers and returns the
     * product of the two.
     *
     * @param int $bat a number to be multiplied
     * @param int $baz a number to be multiplied
     * @return int the product of the two parameters
     */
    public function bar($bat, $baz)
    {
        return $bat * $baz;
    }
}

?>

Once you scan the preceding class, the benefits of DocBlock are apparent: everything is clearly defined so that the next developer can pick up the code and never have to wonder what a snippet of code does or what it should contain.


Comparing Object-Oriented and Procedural Code

There’s not really a right and wrong way to write code. That being said, this section outlines a strong argument for adopting an object-oriented approach in software development, especially in large applications.


Reason 1: Ease of Implementation

“While it may be daunting at first, OOP actually provides an easier approach to dealing with data.”

While it may be daunting at first, OOP actually provides an easier approach to dealing with data. Because an object can store data internally, variables don’t need to be passed from function to function to work properly.

Also, because multiple instances of the same class can exist simultaneously, dealing with large data sets is infinitely easier. For instance, imagine you have two people’s information being processed in a file. They need names, occupations, and ages.

The Procedural Approach

Here’s the procedural approach to our example:

<?php

function changeJob($person, $newjob)
{
    $person['job'] = $newjob; // Change the person's job
    return $person;
}

function happyBirthday($person)
{
    ++$person['age']; // Add 1 to the person's age
    return $person;
}

$person1 = array(
    'name' => 'Tom',
    'job' => 'Button-Pusher',
    'age' => 34
);

$person2 = array(
    'name' => 'John',
    'job' => 'Lever-Puller',
    'age' => 41
);

// Output the starting values for the people
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>";
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>";

// Tom got a promotion and had a birthday
$person1 = changeJob($person1, 'Box-Mover');
$person1 = happyBirthday($person1);

// John just had a birthday
$person2 = happyBirthday($person2);

// Output the new values for the people
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>";
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>";

?>

When executed, the code outputs the following:

Person 1: Array
(
    [name] => Tom
    [job] => Button-Pusher
    [age] => 34
)
Person 2: Array
(
    [name] => John
    [job] => Lever-Puller
    [age] => 41
)
Person 1: Array
(
    [name] => Tom
    [job] => Box-Mover
    [age] => 35
)
Person 2: Array
(
    [name] => John
    [job] => Lever-Puller
    [age] => 42
)

While this code isn’t necessarily bad, there’s a lot to keep in mind while coding. The array of the affected person’s attributes must be passed and returned from each function call, which leaves margin for error.

To clean up this example, it would be desirable to leave as few things up to the developer as possible. Only absolutely essential information for the current operation should need to be passed to the functions.

This is where OOP steps in and helps you clean things up.

The OOP Approach

Here’s the OOP approach to our example:

<?php

class Person
{
    private $_name;
    private $_job;
    private $_age;

    public function __construct($name, $job, $age)
    {
        $this->_name = $name;
        $this->_job = $job;
        $this->_age = $age;
    }

    public function changeJob($newjob)
    {
        $this->_job = $newjob;
    }

    public function happyBirthday()
    {
        ++$this->_age;
    }
}

// Create two new people
$person1 = new Person("Tom", "Button-Pusher", 34);
$person2 = new Person("John", "Lever Puller", 41);

// Output their starting point
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>";
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>";

// Give Tom a promotion and a birthday
$person1->changeJob("Box-Mover");
$person1->happyBirthday();

// John just gets a year older
$person2->happyBirthday();

// Output the ending values
echo "<pre>Person 1: ", print_r($person1, TRUE), "</pre>";
echo "<pre>Person 2: ", print_r($person2, TRUE), "</pre>";

?>

This outputs the following in the browser:

Person 1: Person Object
(
    [_name:private] => Tom
    [_job:private] => Button-Pusher
    [_age:private] => 34
)

Person 2: Person Object
(
    [_name:private] => John
    [_job:private] => Lever Puller
    [_age:private] => 41
)

Person 1: Person Object
(
    [_name:private] => Tom
    [_job:private] => Box-Mover
    [_age:private] => 35
)

Person 2: Person Object
(
    [_name:private] => John
    [_job:private] => Lever Puller
    [_age:private] => 42
)

There’s a little bit more setup involved to make the approach object oriented, but after the class is defined, creating and modifying people is a breeze; a person’s information does not need to be passed or returned from methods, and only absolutely essential information is passed to each method.

“OOP will significantly reduce your workload if implemented properly.”

On the small scale, this difference may not seem like much, but as your applications grow in size, OOP will significantly reduce your workload if implemented properly.

TipNot everything needs to be object oriented. A quick function that handles something small in one place inside the application does not necessarily need to be wrapped in a class. Use your best judgment when deciding between object-oriented and procedural approaches.


Reason 2: Better Organization

Another benefit of OOP is how well it lends itself to being easily packaged and cataloged. Each class can generally be kept in its own separate file, and if a uniform naming convention is used, accessing the classes is extremely simple.

Assume you’ve got an application with 150 classes that are called dynamically through a controller file at the root of your application filesystem. All 150 classes follow the naming convention class.classname.inc.php and reside in the inc folder of your application.

The controller can implement PHP’s __autoload() function to dynamically pull in only the classes it needs as they are called, rather than including all 150 in the controller file just in case or coming up with some clever way of including the files in your own code:

<?php
    function __autoload($class_name)
    {
        include_once 'inc/class.' . $class_name . '.inc.php';
    }
?>

Having each class in a separate file also makes code more portable and easier to reuse in new applications without a bunch of copying and pasting.


Reason 3: Easier Maintenance

Due to the more compact nature of OOP when done correctly, changes in the code are usually much easier to spot and make than in a long spaghetti code procedural implementation.

If a particular array of information gains a new attribute, a procedural piece of software may require (in a worst-case scenario) that the new attribute be added to each function that uses the array.

An OOP application could potentially be updated as easily adding the new property and then adding the methods that deal with said property.

A lot of the benefits covered in this section are the product of OOP in combination with DRY programming practices. It is definitely possible to create easy-to-maintain procedural code that doesn’t cause nightmares, and it is equally possible to create awful object-oriented code. [Pro PHP and jQuery] will attempt to demonstrate a combination of good coding habits in conjunction with OOP to generate clean code that’s easy to read and maintain.


Summary

At this point, you should feel comfortable with the object-oriented programming style. Learning OOP is a great way to take your programming to that next level. When implemented properly, OOP will help you produce easy-to-read, easy-to-maintain, portable code that will save you (and the developers who work with you) hours of extra work. Are you stuck on something that wasn’t covered in this article? Are you already using OOP and have some tips for beginners? Share them in the comments!

Author’s Note — This tutorial was an excerpt from Pro PHP and jQuery (Apress, 2010).


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

Say Hello to Webkit Filters

Thursday, December 22nd, 2011

Earlier this month, a new specification, Filter Effects 1.0, was released. It presents some exciting new Photoshop-like effects that we can use in the browser. Even better, Webkit has already landed support (in the nightlies)!


According to the Spec…

“A filter effect is a graphical operation that is applied to an element as it is drawn into the document. It is an image-based effect, in that it takes zero or more images as input, a number of parameters specific to the effect, and then produces an image as output.”

Now, at least at this point, I wouldn’t presume to be able to show you everything that’s possible with these new filters. I’m still learning them myself! That said, I’ll show you a handful of the new filters, how we can use them in our projects, and then, hopefully, we can all brainstorm and learn from each other within the comments. Let’s get started.

Filters are typically associated with images (though they can also be applied to video). As such, for the handful of demos below, we’ll be using the Nettuts+ logo as input.

 Nettuts+ Logo
Nettuts+ Logo

Remember: these effects aren’t yet available in the public releases of Webkit browsers. For now, download Canary when testing these demos.


hue-rotate

Ever played around with the Hue/Saturation panel in Photoshop? Well now you can play around with it in the browser.

img {
   -webkit-filter: hue-rotate(50deg);
}

If specifying this value in degrees seems confusing, just imagine a color wheel. The number of degrees you specify determines where that wheel stops. This means, that 0deg won’t do a thing, while 50deg will turn the dial, accordingly.

In this case, the Nettuts+ logo will take on a blu-ish hue.

Or, let’s say that you want your image to continuously change colors. Likely, in a real-world project, the color transitions will be far more subtle, but for this demo, we’ll be a bit obnoxious.

img {
   -webkit-animation: adjustHue 1s alternate infinite;
}

@-webkit-keyframes adjustHue {
   0% { -webkit-filter: hue-rotate(30deg); }
   50% { -webkit-filter: hue-rotate(60deg); }
   100% { -webkit-filter: hue-rotate(90deg); }
}

Simple enough. View Demo


grayscale

We’ve used a variety of hacks in the past to transition an image from black and white to color in the browser. One technique calls for two images stacked on top of one another. Another option is to use canvas. Or… we can use the grayscale filter.

img {
   -webkit-filter: grayscale(100%);
}

When applying a percentage to the grayscale function, just think to yourself, “On a scale of 0 to 100%, how gray do I want this image to be?

When used in tandem with CSS3 transitions, we can apply a nice and clean hover effect.

img {
  -webkit-transition: -webkit-filter 1s;
}
img:hover {
    -webkit-filter: grayscale(100%);
}

In the future, you’ll want to provide prefixes for the other browsers, however, it’s not necessary at this point. No need in applying Mozilla transitions to accomodate for a filter that’s only implemented in Webkit (so far).

View Demo


sepia

Enjoy the sepia-flavored Instagram effect? Let’s see what Nettuts+ looked like in the old west.

img {
      -webkit-filter: sepia(100%);
}

Typically, though, this effect is applied to photos. Let’s see how the greatest artist who ever lived looks in sepia.

Excellent.


blur

By passing a radius, we can blur an image in the browser with ease.

img {
      -webkit-filter: blur(2px);
}

Or by upping the blur radius to 50px.


brightness

We use the brightness filter to specify…wait for it…how bright the input image should appear.

img {
      -webkit-filter: brightness(15%);
}

Think of 100% as home base. brightness(100%) keeps the image unchanged. As we reduce this percentage, however, the image will continue to darken.

Don’t forget: you can combine all of these filters.

img {
      -webkit-filter: brightness(60%) sepia(100%);
}

contrast

We can now adjust the contrast of an image quite easily.

img {
      -webkit-filter: contrast(200%);
}

Once again, think of 100% as resting position. We can then reduce or increase this value to adjust the contrast of the image. According to the spec, applying a value of 0% should make the image 100% black, similar to what you might expect from -webkit-filter: brightness(0%);. However, I’m seeing more of a dark gray.

img {
      -webkit-filter: contrast(0%);
}

Now if we up the percentage considerably, to 2000%:

img {
      -webkit-filter: contrast(2000%);
}

Just for fun, let’s create a throbbing Matrix version of the Nettuts+ logo. We’ll combine CSS3 animations and filters.

img {
    -webkit-animation: bluePill 1s alternate infinite;
}

@-webkit-keyframes bluePill {
   0% { -webkit-filter: contrast(2000%); }
   100% { -webkit-filter: contrast(100%); }
}

View Demo


invert

Mac users: press Control + Option + Command + 8. Notice how it inverts your screen (of course you noticed). I use this trick late at night when I’m reading on the computer, and my eyes are sore.

By applying a percentage of 100 to the new invert filter, we can achieve the exact same effect.

img {
      -webkit-filter: invert(100%);
}

Note that 0% will leave the image unchanged.

Now, you could technically apply this to, say, the body of your website, and it would work. However, you’ll notice considerable slow down, and lose the ability to scroll the page. AKA – Don’t do it, except for fun.


saturate

In addition to setting grayscale(100%), we could also achieve a similar effect by desaturating the image entirely.

In this case, 100% is the unchanged state, at which point you can either decrease or increase this value. As such, reducing this value to 0% should remove all color from the image.

img {
      -webkit-filter: saturate(0%);
}

Or, by upping the value to 700%:


That’s All For Now

Stay tuned to this article over the course of the next week. As these techniques are still super new, we all need time to figure out how to use them. I’ll update this article as I learn more!


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

From Idea to Market: How We Built Gradient

Wednesday, December 21st, 2011

Retracing the steps you’ve taken is a helpful way to understand how well you’ve executed your vision – whatever that might be. What could you have done better? What should have been avoided? Today, I’ll share what we’ve learned (and are still learning) while crafting Gradient. It’s an experience that has changed everything for us.

First Sketch

Building a product, be it a native app, web app, or service, is always a challenging task. However, once we convinced ourselves to follow a few pieces of advice, we managed to ship something we believed in. And this is what I’d like to talk about.


It All Starts with a Simple Idea

For as long as I can remember, I’ve always felt that great products needed unreachably smart ideas to be built. I was exceptionally pleased to find that this is not necessarily true.

More often than not, if you find a simple way to solve a problem that you personally have, you’re probably going to make other people’s life easier as well.

Turning that solution into something you end up selling or giving away for free (that really depends on your vision, which I’ll talk about later) is the most logical following step.

In our specific case, we were building our own website, which is rich with linear gradients, and I found myself complaining loudly about the tedious process of writing lines and lines of CSS code – all for the purpose of making every browser agree on the fact that you’re actually writing something they can understand.

“What if”, I asked Yari (@yariok, the developer), “we had a native app that took care of it?”


Your Vision Will Lead the Way

Once you have your idea, however simple it might be, you get to decide what goals you’re setting for yourself (or your team).

Every choice will be influenced by what you want your path to be.

The investments differ dramatically. Maybe you dream of turning this project into the only revenue source you have and finally get rid of client or office work. Whichever the case might be, stick to that. Every choice will be influenced by what you want your path to be and you will have a much easier time when facing a fork if your vision is strong since the beginning.

Our Choice

Here’s more or less what we decided for Gradient:

As with anything, there were also a few bonus goals. It would be nice if people I learned CSS from used my app. Also, what if this app created new possibilities with people around the world?

Once all this was set, we did everything we could to make the app a reality.


Have a Plan Before Writing a Single Line of Code

It’s quite simple, actually. If you have a good plan laid out, you can have a measure of how much work is going to be required to develop your project. This means that you can start marking dates on your calendar. This also means that you can begin creating expectations for those dates. Ultimately, this helps if you plan to create some hype among users and the media.

These trivial tasks will undoubtedly turn into huge time sinks.

Many times, especially if you’re not used to promoting or communicating your work, when laying down the plan, you will forget about some apparently trivial aspects. Of course, you’re focused on getting your “creature” just perfect for the launch or beta, and you think the rest will be taken care of in no more than a couple of hours. These trivial tasks will undoubtedly turn into huge time sinks.

For instance, you’re not used to marketing lingo… or you haven’t thought of everything that might happen when your product finally reaches your potential first users…or you forgot about a banner…or the mail you will be sending to your beta testers. Countless little things like this will add up quickly!


A Note on Focus

Often, when you’re excited about what you’re creating, new ideas, beta tester suggestions, and nice-to-have features will come to you during your sleep.

These ideas have the potential to deter you from your planned path.

It happens all the time – and certainly did to us. Take time to consider thoroughly if these new ideas are truly worth the diversion. In most cases, stick to the plan.


Prototype Like There’s no Tomorrow

There’s nothing quite as valuable as building something usable quickly. Weaknesses in the UX design of your product are so much easier to spot when you’re actually using what you’ve built. There’s not much theory here, really. I think this is the most straightforward step.

A couple of hours after my initial complaint, we had the first rough incarnation of the app. It had HEX input and the output was messy code, but the idea was definitely in front of us.

First Incarnation

We added from there, building what we decided was the very basic array of features our first version needed to have, and then refining the usage patterns in order to streamline the user experience as much as we possibly could. We wanted it to be the fastest solution for that problem. We were and are aware of free and well established competition and our focus went on refining those features our competition couldn’t have.


Don’t Be Afraid of Talking to Strangers

In fact, they’re your best friends. There’s no room for introversion, if you plan on creating your own application or service. You absolutely must get in touch with other people, such as opinion leaders and those who you admire (or even intimidated by). But beyond these folks, also connect with lots of geeks like you! You definitely want people to talk about your project and the only way to let them know is to speak to them directly.

Once you do so, expect one of the following reactions:

Seek publicly available email addresses, reach out on Twitter, use every instrument you think might be relevant to your target audience (Dribbble, Facebook, you name it), listen to what the others are saying, and engage people in relevant conversations. It’s time consuming but it will make a huge difference.

If executed correct, the pieces quickly fall into place.

For us, this engagement pattern led us from less than 300 followers on Twitter at the beginning of September, when we began our closed beta, to 1000 and counting on launch day in November and a growth in actual amplification that went from no more than 5 retweets on the first beta announcement, to more than 70 retweets and many other support messages from the entire community in November – including many of our heroes. Visits to the website and registration increased exponentially.

Additionally, this led to new interesting business opportunities, connections we could only dream of just a couple of months ago, a lot more visibility and also some new good friends. If executed correct, the pieces quickly fall into place.


There’s a Price

It’s tricky, though – especially for people like us who prefer creating things over pricing them. Again, your vision will help you with this, providing you with at least a range of options.

Studying your market of choice, especially in contexts like the App Store, where the data is mostly kept secret, is difficult and takes time, but, again, rational thought comes in handy. Here are the questions we answered when coming to our decision:

As a reasonable indicator of how things are going, we’re right now evaluating user feedback. Unless what you build is free, there will always be someone screaming at you because your product costs money. However, if some of these buyers reply to you, explaining why the price is reasonable in their eyes, you’ve likely hit a sweet spot. (And you have awesome users.)


Hit the Shelves or the Screens

Building your own product is both a challenge and the most rewarding adventure in our industry.

It’s a wonderful experience; building your own product is both a challenge and the most rewarding adventure in our industry. Ironically, the things you learn in the process serve to be the best prize at the end of your path. The connections you build along the way are extremely valuable. You gain respect, because you demonstrate you’re able to ship. You transition from an idea, to execution.

Once your product reaches the public, a new journey begins, and many new interaction possibilities open up. Still, though, the same rules that you’ve followed still apply. Don’t stray from the path.

We’re sticking to our plan. So far, things are going exactly according to plan!


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

Create a Scalable Widget Using YUI3: Part 2

Tuesday, December 20th, 2011

In part one of this series, we reviewed some of the necessary constructs to use when creating a widget with YUI3. We looked at the static properties we needed to set, the class constructor and namespacing, and briefly looked at the extend() method.

In this part of the tutorial, we’ll review the prototype methods we can override or create in order to make our widget function.

Before we begin, let’s just remind ourselves of the method now, as this method houses all the code below:

TweetSearch = Y.extend(TweetSearch, Y.Widget, {

});

The third argument is what we are interested in, in this part of the tutorial. All of the functionality we add that is specific to our widget will be within functions that are added as values to different properties of the object passed to the extend() method. Some of these methods are added automatically for us –we just need to override them with custom functionality. We’ll look at these methods first.


Lifecycle Methods

Several methods executed at different points in the widget instances life cycle. The first of these is an initializer method (remember to add this code within the extend() method shown above):

initializer: function () {
    this._retrieveTweets();
},

The underscore convention to indicate the method should be treated as private, and not called directly by any implementing developer.

The initializer method is provided to allow us to do any tasks that are required as soon as the widget is initialized. Within any prototype methods we attach to our widget, whether inherited or created ourselves, the value of this is set to the widget instance.

All our widget needs to do at this point is retrieve the search results from Twitter. We package this up as a separate function (which we’ll look at in more detail a little later), instead of just retrieving the results directly within initializer so that we can reuse the functionality and retrieve search results any time we wish. The _retrieveTweets() method uses the underscore convention to indicate the method should be treated as private, and not called directly by any implementing developer. It can be called directly of course, but may result in weirdness.

The next life-cycle method inherited from Widget is renderUI(), which we can use to perform any necessary setup, the creation and insertion of new elements, etc, our widget requires. Add this code directly after that shown above:

renderUI: function () {
    var contentBox = this.get("contentBox"),
        strings = this.get("strings"),
        viewer = Node.create(Y.substitute(TweetSearch.VIEWER_TEMPLATE, { viewerclass: TweetSearch.VIEWER_CLASS })),
        loadingNode = Node.create(Y.substitute(TweetSearch.LOADER_TEMPLATE, { loaderclass: TweetSearch.LOADER_CLASS }));

    if (this.get("showTitle")) {
        this._createTitle();
    }
    this._loadingNode = contentBox.appendChild(loadingNode);
    this._viewerNode = contentBox.appendChild(viewer);

    if (this.get("showUI")) {
        this._createSearchUI();
    }

    contentBox.addClass("yui3-widget-content");
},

When a widget is initialised, YUI will automatically create a wrapper element for the element that was passed to the constructor.

Within the renderUI() method, we first store a reference to the contentBox attribute of the widget. The contentBox represents the inner container of the widget and is one of the attributes automatically inherited from Widget, like the srcNode attribute that we saw briefly in part 1. When a widget is initialised, YUI will automatically create a wrapper element for the element that was passed to the constructor, with the inner element becoming the contentBox. The wrapper is known as the bounding box (available as the boundingBox attribute).

We also get a reference to the strings attribute that contains the localizable strings used by elements created by the widget. We then create two new elements; the viewer which will be used to contain the list of tweets returned by Twitter’s search API, and a loading element that will be displayed while the request is in progress.

We use the create() method of the YUI Node module to create our new elements. This element can accept the string representation of an element, which it will then create. Instead of passing it a string directly however, we use YUI’s substitute() method to replace the tokenised templates that we created in part one of this tutorial.

The substitute() method takes two arguments;

The values of each property are swapped into the string, so for example, our viewer template will be stored like this:

"<div class={viewerclass}></div>"

The object passed as the second argument to the substitute() method used to create the viewer node contains a key called viewerclass, so the value of this key will be swapped with the matching token in the source string. In this case, we use the stored class name as the substitution, so the viewer will be given the class name yui3-tweetsearch-viewer (the class names were all created and stored on our widget instance in part one).

We then check whether the showTitle attribute of our widget is set to true, which it is by default, but may be disabled by the implementing developer. If the attribute is set to true we call the custom (i.e. not inherited) _createTitle() method. The reason we package this up as a separate unit of code, instead of just creating the widget is because the showTitle attribute may be set at any time by someone implementing our widget, so it can’t just reside within a life-cycle method. We will look at our custom methods in detail after looking at the inherited life-cycle methods.

After we do or do not (depending on configuration) create the title node, we then insert the new elements into the DOM by adding them as child nodes of the contentBox. Note that we also store the new elements on the widget instance so that we can easily refer to them later on.

We then check whether the showUI attribute is enabled (again, it is by default, but it could be changed in the configuration), and if so call the _createSearchUI() method. This is a separate method for the same reason as last time – so that it can be reused throughout the widget instance’s life.

Finally, we add the class name yui3-widget-content to the contentBox. This isn’t strictly necessary, as the implementing developer may not be using any of the YUI’s style sheets (base, fonts, reset, etc), but as the class name isn’t added for us automatically, we should include in case the developer does wish to pick up some of the styling provided by the library.

The final life-cycle method we are going to use is bindUI(), which allows us to hook up any handlers that should be called when an attribute changes value, or an event occurs. Add the following code directly after the renderUI() method:

bindUI: function () {
    if (this.get("showUI")) {

        Y.on("click", Y.bind(this._setTerm, this), this._buttonNode);
        this.after("termChange", this._afterTermChange);
    }

    this.after("showTitleChange", this._afterShowTitleChange);
    this.after("showUIChange", this._afterShowUIChange);
    this.after("tweetsChange", this._afterTweetsChange);
},

The first thing we do is check whether the showUI attribute is enabled; if it has been disabled we don’t need to worry about adding event handlers for it. If it is enabled, we use YUI’s on() method to add a click-handler bound to the custom _setTerm() method. We ensure the widget instance remains bound to the this keyword within the event handler by passing this (which at this point refers to the widget instance) as the second argument to the bind() method.

We also use the after() method that is automatically attached to our widget instance by the library to add a listener that reacts to the term attribute changing. A listener can be bound to any of our custom attributes by simply suffixing After to any attribute name. The term attribute will only change if the search UI is enabled. We then add listeners for each of the other attributes we need to monitor; showTitle, showUI and tweets, hooking these up with the relevant handlers.

Note: There is another life cycle method provided by the Widget class, but in this particular example we don’t need to make use of it. This method is the destructor, which will be called just before the widget is destroyed. It is used to tidy up after the widget, but only needs to be used if elements are added to the DOM outside of the boundingBox (the outer wrapper) of the widget.


Automated Prototype Methods

Remember the validator we specified as part of the ATTRS object in the first part of this tutorial? The method that we set as the value of this property will be called automatically whenever an attempt is made to update the attribute. Let’s take a look at it now; add the following code directly after bindUI():

_validateTerm: function (val) {
    return val !== this.get("term");
},

The method must return true or false and automatically receives the new value (that is, the value that may become the new value if it passes validation) as the first argument; if true is returned, the attribute is updated with the new value, if false is returned the attribute is not updated.

The logic we supply is pretty simple in this example – we simply check that the new value is not the same as the old value. There’s no point after all in making another AJAX call only to receive exactly the same set of results.


Non-Inherited Prototype Methods

Next we can start adding our custom methods that will add more functionality to our widget. The first function we referenced within the initializer method was _retrieveTweets(), so we’ll look at that first:

_retrieveTweets: function () {
    var that = this,
        url = [this.get("baseURL"), "&q=", encodeURI(this.get("term")), "&rpp=", this.get("numberOfTweets")].join(""),
        handler = function (data) {
        that.set("tweets", data);
    },
    request = new Y.JSONPRequest(url, handler);

    request.send();
},

We first set a few variables; the this keyword will no longer point to our widget instance inside the success callback that we’ll specify when we make the request to Twitter, so we store a reference to this in a variable called that, as convention dictates.

We also create the request URL; we retrieve the baseURL, the term and the numberOfTweets attributes, storing each as an item in an array and then using JavaScript’s join() function to concatenate them all into a string. Using an array and the join() method is way faster than concatenating strings with the + operator.

Next we define our success callback; all this simple function needs to do is set the widget’s tweets attribute to the response received from the request. The response will be automatically passed to the callback function.

The last variable we define is for the request itself, which is initialised using YUI’s JSONPRequest() method. This method accepts two arguments; the first is the URL to make the request to and the second is the callback function to invoke on success. Finally, to initiate the request we simply call the send() method.

Our next custom method is _createTitle(), which we call from the renderUI() method:

_createTitle: function () {
    var strings = this.get("strings"),
        titleNode = Node.create(Y.substitute(TweetSearch.TITLE_TEMPLATE, {
	        titleclass: TweetSearch.TITLE_CLASS,
            title: strings.title,
            subtitle: strings.subTitle,
            term: this.get("term")
        }));

    this._titleNode = this.get("contentBox").prepend(titleNode);
},

We also store a reference to the strings attribute for use within the function. A title is created using the same principles as before, although this time we have a few more tokens to replace in our substitute() method. This method is only called if the showTitle attribute is set to true. Note that the get() method is chainable, so we can call the prepend() method to insert the title directly after it.

The code here is very similar to what has been used before, as is the case for our next method, _createSearchUI():

_createSearchUI: function () {

        var contentBox = this.get("contentBox"),
            strings = this.get("strings"),
            ui = Node.create(Y.substitute(TweetSearch.UI_TEMPLATE, { uiclass: TweetSearch.UI_CLASS })),
            label = Node.create(Y.substitute(TweetSearch.LABEL_TEMPLATE, { labelclass: TweetSearch.LABEL_CLASS, labeltext: strings.label })),
            input = Node.create(Y.substitute(TweetSearch.INPUT_TEMPLATE, { inputclass: TweetSearch.INPUT_CLASS })),
            button = Node.create(Y.substitute(TweetSearch.BUTTON_TEMPLATE, { buttonclass: TweetSearch.BUTTON_CLASS, buttontext: strings.button }));

        this._uiNode = ui;

        this._labelNode = this._uiNode.appendChild(label);
        this._inputNode = this._uiNode.appendChild(input);
        this._buttonNode = this._uiNode.appendChild(button);

        this._uiNode.appendTo(contentBox);
    },

Again, very similar to what we have seen before. Remember, the only reason this is in a separate function is so that the UI can be switched on or off at any point during the widget’s life-cycle. This method is only called if the showUI attribute is set to true.

Next up is the _setTerm() method, which is called by the event listener attached to the _buttonNode when the button is clicked:

_setTerm: function () {
        this.set("term", this._inputNode.get("value"));
    },

In this simple method, we just try to set the term attribute to the string entered into the <input>. In trying to set the attribute, our validator will be called and will only update the attribute if the value is different to the attribute’s current value.

The last of our custom methods is another simple method used to update the subtitle in the header of the widget to the new search term; add the following code:

_uiSetTitle: function (val) {
        this._titleNode.one("h2 span").setContent(val);
        },

This method will receive the new value as an argument (we’ll call this method manually from an attribute change-handling method that we’ll look at in the next part of this series). We call YUI’s one() method on our title node to select the <span> within the subtitle, and then use the setContent() method to update its inner-text.


Summary

In this part of the tutorial, we first looked at the life-cycle methods that we get as a result of extending the Widget superclass. These methods are called automatically for us by the library at different points in the widget’s life-cycle.

Although the methods that we’ve added all look similar in structure, there are distinctions between the two; for example, the life-cycle methods receive more ‘protection’ than those methods we add ourselves, hence why these methods are not prefixed with an underscore. These methods, unlike our custom ones, can’t be called directly by the implementing developer.

We also took a look at a validator method; these methods will also be called by the library automatically when appropriate which makes them incredibly useful for ensuring data is in a particular format, or meets a particular requirement before an attribute is updated.

Lastly, we looked at the custom prototype methods that we need in order to make our widget function. We saw that we can easily use the built-in get() and set() methods to get and set attributes, and that within each method the this keyword Is helpfully set to our widget’s instance, so that we can easily obtain and manipulate different aspects of the widget.

In the next part of this tutorial, we’ll look at the attribute change-handling methods that need to be added in order to make our widget respond to user interaction or changes in the page’s state. We can also look at the CSS we need to provide for our widget, and how the widget is initialized and used.

If you have any questions, please let me know in the comments section below. Thank you so much for reading!


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

The Official 2011 Nettuts+ Holiday Gift Guide

Monday, December 19th, 2011

I needn’t remind you that Christmas is almost upon us. If you still haven’t bought gifts for your loved ones, this is the perfect time to start panicking. If your loved one is a developer though, we have an easy way out for you: pick a few from the list below and you’ll be off the hook!

In this mini gift guide, we’ll take a look at what we, as developers, want our stockings to be filled with. Hopefully, Santa hasn’t figured out that we’ve been feigning innocence all year!


Subscriptions and Software

Subscriptions are the gifts that keep on giving. Depending on whether you want to gift something for work or pleasure, you’ll find something here.


Nettuts+ Holiday 2011 Gift Guide

Netflix

Let’s face it — we’re busy people and can’t always catch a show at the right time. Heck, we’re the ones missing dinners with our special ones, right? And DVRing things can get pretty messy pretty quickly. This is where Netflix comes in. Unlimited movies and TV episodes over the internet? Yes please. Gift this to the geek in your life and watch him light up.

Get it here

Nettuts+ Holiday 2011 Gift Guide

Linode / Other VPS

Show your cutting edge web developer a shared hosting plan and he’d balk. Get them a yearly subscription to a virtual private server and watch as he formulates all the sheer uses he’d eke out of it. While there are plenty of options out there, I’ve personally used Linode for a few years now and gets my recommendation.

Get it here

Nettuts+ Holiday 2011 Gift Guide

Heroku / Platform as a Service

Or you could be a bit more forward and present them with a subscription to a PaaS [platform as a service]. Unlike a VPS, most of the sys-admin grunt work is taken care for you, including load management, letting you focus on just the code. Again, there are lots of options here but Heroku gets my vote for being so darn good.

Get it here

Nettuts+ Holiday 2011 Gift Guide

Litmus / Browser Testing

Browser compatibility testing still remains a scourge on the workflow of a modern developer but it really doesn’t need to be. Get them, or yourself, a subscription to the Litmus service and forget about having gazillion browser windows and versions open to test things out.

Get it here

Nettuts+ Holiday 2011 Gift Guide

Magazine

People have been harking on about the death of the print medium for years now but they’ve still been chugging on. I don’t have a specific recommendation since these tend to be intensely personal so take your pick. As opposed to gaming and tech magazines, I think people like me would appreciate something related to business, travel, lifestyle, or let’s go crazy for a second here, fashion.

Nettuts+ Holiday 2011 Gift Guide

Evernote

Evernote is awesome. There, I said it. It basically focuses on getting all your mental threads together and then syncs it all across any of your devices. If it sounds simple and you let yourself believe that, smack yourselves on the head — it’s much more complicated than that.

Evernote goes above and beyond the call and provides a ton of nifty features including extracting data from images. While the free version is more than serviceable, the premium version ships with just a few more enticing features.

Get it here

Nettuts+ Holiday 2011 Gift Guide

Tuts+ Premium

Not to toot our own horn but our Tuts+ premium program offers one of the best ways to learn new technologies and skill sets or hone existing ones. In addition to a massive 700+ exclusive tutorial roster, you also get access to nearly 30 top selling ebooks. At $180 for an entire year of learning, you can’t do better than this!

Get it here

Nettuts+ Holiday 2011 Gift Guide

Sublime Text

And finally, don’t forget a good text editor or an IDE. They are the heart and soul of a developer’s workflow and an informed gift here will definitely elevate you in a developer’s eyes.

A lot of people will go with the Coda/Textmate hoopla but, for a change, try SublimeText. It’s cross platform, feature laden, stable and cheap for a software of such stature.

Get it here


Gadgets

The Venn diagram of web developers and tech enthusiasts is primarily largely intersecting. Be it the new all mighty smartphone or an innocuous desk toy, gadgets make for excellent gifts.


Nettuts+ Holiday 2011 Gift Guide

Tablets

Tablets have been the all the rage recently and I can certainly see why: they make for excellent consumption devices. Checking your all important work email or catching up on your silly kitten videos? Do it from the comfort of your couch and through an intuitive interface. Couple this with the abundance of games and other apps and you have a bonafide winner on your hands.

Which tablet to get is an argument in itself. The iPad’s software lineup is a definite advantage but don’t discount its Android brethren either. The Transformer Prime looks incredible.

Get it here

Nettuts+ Holiday 2011 Gift Guide

E-reader

Or if you’re feeling a little bit old school, get them an e-reader. These feature e-ink technology, making reading a lot less strenuous on your eyes [as opposed to gazing at an incandescent light bulb that is a tablet's screen] and provide an experience that’s as close to a real book as possible whilst providing superior battery life.

I personally like the Kindle but there are tons of options available in this segment.

Get it here

Nettuts+ Holiday 2011 Gift Guide

USB Coffee Warmer

It’s a well known fact that web developers account for roughly 97% of the world’s caffeine intake. And a vast majority of that is ingested in front of a monitor whilst mulling over some arcane piece of code that just refuses to work. Get him, or her, this magical coffee warmer that conveniently works over USB and win over their goodwill for the rest of your natural life.

Get it here

Nettuts+ Holiday 2011 Gift Guide

IronKey USB Drive

You can never really be too secure — specially in this digital age. Data gets swiped, accounts get hacked and passwords get broken on a daily basis.

The IronKey USB drive provides you with a plethora of features including military grade encryption, hardware level authentication, anti-keystroke logger amongst a ton of others. It’s a little pricey compared to your run of the mill USB drive but the features definitely make it worth it.

Get it here

Nettuts+ Holiday 2011 Gift Guide

Universal Remote

The sheer number of remotes in a modern home is staggering. You need to have one for your television, receiver, speaker, settop box, DVD/BluRay and a lot more whamathingies. Not fun at all.

While universal remotes have been around for a while now, the recent ones have really started kicking it up a notch. The Logitech Harmony series deserves a special mention since they feature great build quality, support a staggering number of devices and are quite easy to set up. There are also touch screen versions if you’re into that sort of thing.

Get it here

Nettuts+ Holiday 2011 Gift Guide

MiFi

Your mobile phone probably has access to a decently quick internet connection but you’ll mostly be limited to tethering it to your laptop or, worse, no tethering support at all. What happens if you’re a technophile and travel with a tablet and maybe a handheld gaming device that you’d like to get online?

The MiFi range of devices are custom made for these specific scenarios. These connect to your carrier and provide internet access to the devices of your choice. It only supports upto 5 devices but hey, that should cover 99% of y’all.

Get it here

Nettuts+ Holiday 2011 Gift Guide

Nerdy Desk Toys

I’m sure you can’t count the sheer number of times you’ve given up on a piece of code and sat staring at a random dent on my desk wondering where it all went wrong. Let’s get this out of the way: I can’t fix your code for you and I really can’t fix the dent on your desk. However, completely unbiased, unquestionable studies from the toy making companies state that staring at a worthwhile nerdy toy on your desk should get your creative and analytical juices flowing.

I’m pretty partial to physics based items but you can find a ton more options at the link below.

Get it here


Hardware

Moving away from gadgets and toys, here are additions to your workstation and your workplace that are worth considering. Often overlooked, these are very obvious additions that can directly improve how you work.


Nettuts+ Holiday 2011 Gift Guide

A Second [or Third] Display

Yes, it’s that simple — get them, or yourself, another display. It doesn’t matter whether it’s a 15″ TN panel or a 30″ IPS panel. A second monitor can vastly improve one’s workflow, and thus, productivity since there is no need to juggle around windows. Just keep your debugging window on the other display and you can be on your way. Having a video run on the other display is fun too!

Get it here

Nettuts+ Holiday 2011 Gift Guide

An Ergonomic Chair

Developers, like most people with white collar jobs, tend to sit for a large portion of their working day. Discounting the issues caused by being static for such long stretches, a major issue is how one tends to pick up lumbar issues quite quickly.

Ensure their safety by buying them a lumbar supportive, height adjustable, comfortable chair. I’m partial to Aaron chairs but there are plenty of options out there.

Get it here

Nettuts+ Holiday 2011 Gift Guide

Input Peripherals

The input peripherals are how you to interact with your workstation and there is no need to be flimsy here. Be it a spiffy tactile keyboard or a touch gizmo to replace your mouse, just make sure it’s ergonomic. As someone who used to have carpal tunnel issues in the past, I can assure you it’s not fun.

I like keyboard with low travel and illumination so I’m pretty partial towards the Logitech Illuminated keyboard.

Get it here

Nettuts+ Holiday 2011 Gift Guide

Earbuds or Headphones

I’m one of those people who tends to have music running constantly. Probably not the heart pounding, whumpa-whumpa sounding things that young people tend to listen to though. Ahh, I digress.

A good quality headset is critical to your sanity as a developer. Not to mention coexisting with the people around you. Tried working when someone blares ‘Friday’ around you?

I prefer a proper circumaural pair since it tends to be the most comfortable for me, big head and all.

Get it here

Nettuts+ Holiday 2011 Gift Guide

MOAR Storage

You can’t have enough storage space — it’s a fact of life. Chalk it upto cameras that record in much higher resolutions or faster internet speeds, or aliens, the fact remains that we’re constantly filling up our hard drives.

Cloud solutions are nice but not always optimal. In these cases, get yourself a big hunk of storage that’s network attached and call it a day. I’ve used a Drobo in the past and it’s fairly good at what it does. It’s a little on the expensive side though. Or if you do have a higher budget, get them a nice, fast SSD and watch everything load up quickly.

Get it here


Assorted Fun

If you’re looking for something generic, but fun, this is the place to be!


Nettuts+ Holiday 2011 Gift Guide

Skyrim

Yes, Skyrim. There’s a very good chance this gift will make the giftee lose his job, relationship and house but goshdarnit, he’ll be a Dovahkiin!

If that’s not an option, this year had an incredible amount of AAA releases — Assassin’s Creed: Revelations, Arkham City, Battlefield 3, Deus Ex: Human Revolution, Witcher 2, Portal 2, Modern Warfare 3. Phew. Take your pick and gift away.

And promise to throat punch any whiners on online services and you’ll have their eternal gratitude.

Get it here

Nettuts+ Holiday 2011 Gift Guide

Books

Books make for excellent gifts. They’re fairly cheap, don’t require power, can carry it around at will and you won’t get hassled during a flight.

Choosing which book to get is an incredibly intimate thing though. The best seller list at Amazon is a great place to start but don’t let it constrain you — there are tons of incredible books out there. If you’re fresh out of ideas, may I suggest the recent Steve Jobs biography? Whether you love or hate him, there’s enough material in there for you.

Get it here

Nettuts+ Holiday 2011 Gift Guide

30 Rock

Shows pop up all the time and it comes down to personal preference. That being said, if you can watch this video and not be interested in this show, I’m going to silently weep for humanity and start plotting something fierce.

Or if you’re looking for something a bit more serious, the debut season of Game of Thrones is incredibly well made and deserves a look. Be warned though — it’s made for an adult audience.

Get the first season here

Nettuts+ Holiday 2011 Gift Guide

T- Shirts

Tees makes for low profile, high humor gifts. Just choose something that the receiver will appreciate and you should be golden. Extra points if the tee’s contents contains subtle puns or jargon that no one else can understand. There are lots of places to get such clothing — I’ve linked a few of my recommendations below.

Get it here


Work Related Books

…. or you could take the easy way out and present them with one of the books below. Yes, they’ll be glad that you bought them something that would truly enrich their lives but the next time the developer in your life is late to a movie or dinner, you’ll know you have yourself to blame!


Professional JavaScript for Web Developers

Professional JavaScript for Web Developers

Author: Nicholas Zakas

“Starting at the beginning, the book explores how JavaScript originated and evolved into what it is today. A detailed discussion of the components that make up a JavaScript implementation follows, with specific focus on standards such as ECMAScript and the Document Object Model (DOM).”


JavaScript - The Good Parts

JavaScript – The Good Parts

Author: Douglas Crockford

“Most programming languages contain good and bad parts, but JavaScript has more than its share of the bad, having been developed and released in a hurry before it could be refined. This authoritative book scrapes away these bad features to reveal a subset of JavaScript that’s more reliable, readable, and maintainable than the language as a whole-a subset you can use to create truly extensible and efficient code.”


Nettuts image

Pro JavaScript Techniques

Author: John Resig

“This book addresses all the points above in detail – modern browser support (including information on Internet Explorer 7), Object-Oriented JavaScript, testing and debugging, Unobtrusive JavaScript techniques using DOM Scripting, Ajax, creating and using blocks of reusable code, and looking towards the future of JavaScript.”


Nettuts image

jQuery Enlightenment

Author: Cody Lindley

“jQuery Enlightenment was written to express, in short-order, the concepts essential to intermediate and advanced jQuery development. Its purpose is to instill in you, the reader, practices that jQuery developers take as common knowledge. Each chapter contains concepts essential to becoming a seasoned jQuery developer.”


Nettuts image

Introducing HTML5

Author: Bruce Lawson

“Written by developers who have been using the new language for the past year in their work, this book shows you how to start adapting the language now to realize its benefits on today’s browsers. Rather than being just an academic investigation, it concentrates on the practical—the problems HTML5 can solve for you right away.”


Nettuts image

Professional WordPress Plugin Development

Author: Brad Williams, Justin Tadlock, Ozh Richard

“As one of the most popular open source content management systems available today, WordPress boasts a framework that allows you to easily customize and extend it through plugins. This comprehensive book shows you how plugins work, reviews the tools and APIs available in WordPress, and demonstrates how to extend the functionality of WordPress with plugins.”


Wrapping Up

I’m sure I’m missing a ridiculous number of gifts here so holler over at the comments section below. Or if you’ve already bought a gift for the developer in your life, let us know what you bought. Thanks for stopping by!


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

Introducing Nettuts+ Builder – Version 2

Saturday, December 17th, 2011

We’re pleased to announce the release of Version 2 of Nettuts+ Builder, a Mac app that handles the process of concatenating and compressing your assets, optimizing your CSS by running it through Prefixr.com, and uploading to your FTP server.


What Exactly Does it Do?

Intended for small projects and demos, all you need to do is drag your project folder onto Builder’s icon in the menu bar. Once you do so, it will:


See it in Action


Availability

Nettuts+ Builder V2 is currently available free to all Tuts+ Premium members.


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

Dig into Dojo: Dijit

Thursday, December 15th, 2011

Maybe you saw that tweet: “jQuery is a gateway drug. It leads to full-on JavaScript usage.” Part of that addiction, I contend, is learning other JavaScript frameworks. And that’s what this four-part series on the incredible Dojo Toolkit is all about: taking you to the next level of your JavaScript addiction. In this episode, we’ll take a tour of Dijit, Dojo’s UI library.


What is Dijit?

So, what exactly is Dijit? According to the docs, “Dijit is Dojo’s UI Library.” It builds on what we’ve seen in Dojo Core and it’s very extensive: pretty much every UI widget you can think of is available. And, if you want to build your own, specialized widget, that’s certainly possible. If you’re following along with the Premium screencast, we’ll be building a Tuts+ widget. So, if you’re not a Premium member, now’s a good time to sign up.

Dijit is Dojo’s UI Library

For terminology’s sake, remember that Dijit is the namespace under which Dojo’s UI widgets live.

Here’s how this is going to go down: just showing you how to use a bunch of Dijits would be akin to showing you how to use a bunch of jQuery plugins. Of course, Dijits aren’t really comparable to jQuery plugins, but the point stands: once you’ve used one, you’ve used ‘em all (caveats aside). So, we’ll be talking about the diverse and sundry ways to create and use Dijits. Then, we’ll take a brief look at some specific Dijits, just to whet your appetite.

Of course, we’ll need to use some Dijits as examples while we learn. We’ll keep it basic and use a plain button widget.


Why Should I Use Dijit?

After you learn how to use widgets, you might think it’s a lot easier to not use many of them; after all, why not just use the <button> element, instead of the button widget? There are a couple of reasons to consider here:

So, now that you know the benefits of using Dijit, let’s learn how to use it.


How do I Use Dijit?

There are two ways to instantiate widgets: the programmatic way, and the declarative way.

Dijit widgets are actually just Dojo classes that inherit from Dijit._Widget, and often Dijit._Templated. I know we haven’t discussed Dojo’s object-oriented side, and we won’t be able to in this session (you’ll learn some in the Premium screencast), but just know that Dojo can make JavaScript classes. Of course, they aren’t really classes, they’re JavaScript constructor functions; however, you can flex some serious OO muscle with Dojo’s methods.

So, back to widgets. There are two ways to instantiate widgets: the programmatic way, and the declarative way. If you’ve used UI widgets in other libraries, you’re probably familiar with the programmatic method: put some widget markup up in your HTML, and interact with it from the JavaScript. Let’s try it!

I’ll assume you’ve set up a working page, loading Dojo from a CDN, as we have before. So, let’s make a Dijit button.

Before we start, you’ll definitely want to make sure you have a theme loaded; otherwise, your widgets will stick out like nobody’s business.

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dijit/themes/claro/claro.css" />

That’s the Claro theme; you can replace both instances of “claro” with “tundra,” “soria,” or “nihilo.” to try the other bundled themes. To use the loaded theme, you’ll have to add the theme’s name as a class on your <body> (technically, it doesn’t have to be the <body>, but some element that is a parent of any widgets that should be themed.)

Now that our theme is loaded, let’s programmatically create a button. First, we’ll add the button markup to our document:

 <button id="btn" type="submit">Click Me!</button>

Now, let’s instantiate this in our JavaScript.

dojo.require("dijit.form.Button");

dojo.ready(function () {
  var btn = new dijit.form.Button({ onClick: handleClick}, "btn");
});

function handleClick () {
  alert("clicked");
}

The dijit.form namespace includes any form widgets you might need.

We have to load the file containing the widget class before we can use; then, we can instantiate the button with new dijit.form.Button. Notice that the “class” (constructor function) is stored at the same “path” we required. While this isn’t forced technically, it’s very much the standard way to do it. The exception to that is when a single file loads multiple classes: this “dojo.form.Button” file is a great example: it loads dijit.form.Button, dijit.form.ComboButton, dijit.form.DropDownButton, and dijit.form.ToggleButton.

Let’s look a little more closely at the parameters we’ve passed to dijit.form.Button. In this case, we’ve passed an object, and a string, which is the id of the widget node in our DOM; we could instead have passed a reference to the node itself, if we wanted to. Of course, any widget options can be set in that first parameter object; here, we’re setting the click handler via the onClick option.

You’ve probably figured this out by now, but know that the dijit.form namespace includes any form widgets you might need.

Now, load up the page and you should see something like this:

The Button

Behold, a programmatically-created, Claro-themed, Dijit button. That wasn’t too hard, now, was it?

Now, open your browser console and check out the DOM; specifically, look at that <button> node. You’ll see that our instantiation have removed our node and replaced it with a <span> with child <span>s, all with many attributes. This is part of how Dijit widgets work: more often than not, they replace the nodes you have with a template of their own. In fact, if we left out the second parameter (the id string or DOM node reference), the new nodes would be made, but just not injected into the DOM. Then, we could place it ourselves:

var btn = new dijit.form.Button({ label: "Hello" });
dojo.place(btn.domNode, dojo.body());

Notice that we give the button a label (otherwise, it would be blank); then, our dijit.form.Button instance has a domNode property that reference the nodes it created for itself.

So, if we can do it this way, and Dijit gets rid of our initial nodes anyway, why not always do it this way? Well, don’t forget that you want your app to work without JavaScript. If you have the nodes in the DOM, you have a basic experience for people with JavaScript turned off. Then, Dojo will replace that with the better experience if it can. Of course, the other benefit is that using hard-coded DOM nodes does fill a lot of the default parameters, depending on widget class, of course. As we saw, when we didn’t use a node, we have to define a label property to get text in the button.

All this seems pretty natural, right? If you’ve used UI widgets in other libraries, this seems pretty run-of-the-mill. However, Dojo ups the ante by allowing you to put all the properties for the widget in your HTML. This is that declarative way of which I spoke.

Here’s how you do it. Remove the JavaScript we’d written previously, leaving only this:

dojo.require("dijit.form.Button");

function handleClick () {
  alert("clicked");
}

Now, fix up our <button> element so that it looks like this:

<button id="btn" type="submit" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: handleClick" data-dojo-id="my.btn">Click Me!</button>

We’ve added HTML5 data-* attributes to our <button>: data-dojo-type and data-dojo-props. I think you’re starting to see how these are related: the type is the widget class “path”; the props are the properties, in key-colon-value-comma format. What does this do? It instantiates our widget for us. Since we aren’t creating it in our JS, the data-dojo-id attribute gives us a change to create a variable that points to the widget instance. Notice, it can be as a property of an object, if you want.

Not so fast though. Dojo isn’t magic after all, so we do have to let it know that we want it to parse out any widgets declared in our HTML when the library loads. Of course, it will only find widgets whose class we have dojo.required. The most common way to do this is to set parseOnLoad: true in your djConfig.

Let’s take a quick detour and talk about djConfig. This objects sets a few configuration options for Dojo; besides parseOnLoad, there are a number of debugging, localization, and resource-finding settings. There are three ways of settings djConfig. First, you can make a custom build of Dojo, which is beyond the scope of this session. Second, you can create a global djConfig object; if you do this, you have to be sure that it appears before the Dojo base file is loaded.

<script>djConfig = { parseOnLoad: true };</script>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js.uncompressed.js"></script>

The other way, which is much more common, is to use the data-dojo-config property on the script node that loads Dojo Base:

<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js.uncompressed.js" data-dojo-config="parseOnLoad: true"></script>

So djConfig: it’s the most common way to parse declared widgets. The other way is to manually call the method that parseOnLoad calls: dojo.parser.parse(). This will parse your HTML, find the widgets and create them.

We’re just about done with our general overview of how Dijit widgets are used, so I want to wrap up a few loose ends. First, note that all the HTML5 data-* goodness ain’t always been so. Dojo used to use plain, non-standard attributes, and will still accept them. So, instead of data-dojo-type, you would use dojoType. Instead of data-dojo-config, you’d use djConfig. Instead of data-dojo-id, you’ve got jsid. And data-dojo-props was split into individual properties. So, using our button example, this:

<button id="btn" type="submit" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: handleClick, iconClass: 'dijitIconCopy'" data-dojo-id="my.btn">Click Me!</button>

Would be, with old, non-standard attributes, this:

 <button id="btn" type="submit" dojoType="dijit.form.Button" onClick="handleClick" iconClass="dijitIconCopy" jsid="my.btn">Click Me!</button>

Notice how onClick and iconClass are two separate properties in old-style.

Both these styles work, but I’ll be sticking with the HTML5 attributes.

Second, I’ll note that if you don’t set a property when you create a widget, you can do so with the widget instance’s set method:

var btn = new dijit.form.Button({});
btn.set("label", "Click here!");
btn.set("onClick', function () { alert("clicked!"); });

There’s also a get method, so retrieve your properties; of course, this works with those read-only properties, too.

And the watch method is pretty cool: pass it the property you want to watch, and then a function: if that property is changed, your function will get called:

var btn = new dijit.form.Button({}, "btn");
btn.set("onClick", function () { this.set("label", "clicked") });
btn.watch("label", function (property, oldValue, newValue) {
  alert("Property " + property + " was changed from " + oldValue + " to " + newValue + ".");
});

I sure was caught off guard by declaratively creating widgets and I’m still not exactly sure how I feel about it.

Of course, there are other methods and properties that widgets have in common, as well as widget-specific ones; we can’t cover them all here, of course, but skip to the end if you can’t wait for some tips on learning about the specific widgets of your choice.

Finally, what do you think of this declarative way of creating widgets? I sure was caught off guard when I first saw it, and I’m still not exactly sure how I feel about it. With the programmatic way—the way every other library I’ve seen does it—you have to either match up HTML and JavaScript (which requires work in two places) or place new nodes from the JavaScript (which isn’t no-JS-friendly).

The benefit of the declarative method is that all the information about a widget is in one place; the UI and the logic. However, is that what you want? I’ve done a bit of desktop programming, but from what I’ve seen on both Windows and Mac, UI and logic are separated, in different files even. So it’s not like this is a throwback to anything. In any case, you’ve got the power to do it however you want. Choose wisely . . .


A Dijit Amuse-boche

Let’s wrap this tutorial up by looking at a couple of Dijit widgets, and then talk about how you can learn to use ‘em practically. Remember, however I show you the widgets, they can be created in declaratively or programmatically.

dijit.ColorPalette

Exactly what it says, this is a simple little colour picker.

<div id="colors"></div>
<p>The selected colour is <span id="selectedColor"></span>.</p>
dojo.require("dijit.ColorPalette");

dojo.ready(function () {
  var selectedColorEl = dojo.byId("selectedColor"),
      colors = new dijit.ColorPalette({
        onChange : function () {
          selectedColorEl.innerHTML = this.value;
        }
      }, "colors");
});
Color Palette widget

This is a good example of a widget that takes very little information from a DOM node, unless you give it the Dojo attributes. It’s also a good example of how you can work with widgets that accept / set some kind of value (like a dijit.form.FilteringSelct and dijit.form.verticalSlider).

dijit.Editor

A rich text editor: this is a good example of how easy Dijit makes creating complex UI pieces a breeze.

<div id="editor" data-dojo-type="dijit.Editor" data-dojo-id="editor" data-dojo-props="
	plugins: ['bold','italic','underline','|','cut', 'copy','paste']"></div>

<button data-dojo-type="dijit.form.Button" data-dojo-id="btn" data-dojo-props="onClick: handleEditor"> Get Text </button>
dojo.require("dijit.Editor");
dojo.require("dijit.form.Button");

dojo.parser.parse();

function handleEditor () {
  dojo.create("div", { innerHTML: editor.value }, dojo.byId("main"), "last");
  editor.set("value", ""); // editor.value = "" doesn't clear the text
}
Dijit Editor

Note, I probably wouldn’t ever connect an event handler via an attribute in real life; however, it’s a good example of Dojo’s flexibility.

dijit.ProgressBar

A handy progress bar, useful when doing lengthy AJAX stuff or heavy calculating action:

<div id="progbar"></div>
dojo.require("dijit.ProgressBar");

dojo.ready(function () {
  var progbar = new dijit.ProgressBar( { maximum: 150 }, "progbar");

  function updateProgressBar() {
    progbar.set("value", parseInt(progbar.get("value")) + 1);
    if (progbar.get("value") === 150) {
    progbar.set("label", "Complete!");
    } else {
    setTimeout(updateProgressBar, 100);
    }
  }
  updateProgressBar();
});
Progress Bar

Learning More

For the most part, you’ll learn by osmosis butwhen you’re ready to dive deeper, you’ll want to check out the API docs.

Of course there are a ton of Dijits; I can’t teach you to use them all. So, let’s close up by looking at how you can learn to use the widgets your hankering after.

For the most part, you’ll learn by osmosis (isn’t that the way most dev work is, though?). For example, while reading the reference guide page for dijit.ColorPalette, I learned that most widgets that set some value have an onChange event. In fact, the reference guides are the first of the two best places to get documentation for Dijits. If you head over to the Dojo documentation page, you’ll see three links: Tutorials, Reference Guides, and API Documentation. The tutorials are listed on that page, and they’re great, but we’re interested in the reference guides and API docs.

So, click Reference Guides, and then Dijit on the right sidebar. Here’s a great place to start when you’re trying to figure out how to use a widget; most articles give you examples of both programmatic and declarative creation, as well as common properties.

If you’re ready to dive deeper, though, you’ll want to check out the API docs. This neat web app is Dojo Documentation: The Complete Series. Navigate the namespaces on the left, and you’ll get all the details on the right. This can be somewhat cryptic when you’re starting, though, so certainly default to the reference guides.

Of course, Googling “Dijit <widget-name> tutorial” often serves up something tasty.


Conclusion

And that’s a wrap for this third episode of Dig into Dojo. If you’re interested in creating a widget of your own, you’ll want to check out the premium screencast that goes with this tutorial.

Otherwise, I’ll see you in the final episode of Dig into Dojo, where we’ll discuss Dojox.


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

Should You Learn CoffeeScript?

Wednesday, December 14th, 2011

I’d imagine that I represent a large portion of the web development community. I’m very intrigued by CoffeeScript; I’ve even learned the syntax and used it in a few demos. However, I haven’t yet taken the plunge and used it in a real project. It comes down to this one question for me: is CoffeeScript something that is truly worth investing time and effort into learning?

I wasn’t sure, so I compiled a list of frequently asked questions (along with a few of my own), and asked some masters in the industry – on both sides of the fence – for their advice.

The Panel


1 – Perhaps the most common question: if I’m a reasonably solid JavaScript developer, is there any real incentive for me to learn CoffeeScript?

Jeremy Ashkenas

Yes. CoffeeScript is not an entirely new and strange language. It exists to allow “reasonably solid” JavaScript developers to write the same code they were going to write in the first place, in a more readable and fluent way. The basic idea is to write what you mean, instead of writing within the limits of historical accident. For example, if I want to loop over every item in a list, in CoffeeScript, I can write what I mean:

    for item in list
      process item

Whereas in JavaScript, I partially obscure my intention, by writing:

    for (var i = 0, l = list.length; i < l; i++) {
      var item = list[i];
      process(item);
    }

CoffeeScript allows “reasonably solid” JavaScript developers to accomplish the latter by simply writing the former.

Other Incentives Include

James Padolsey

If you’re comfortable in JavaScript, and are able to create expressive APIs that suit you well, then I don’t feel there is a sufficient incentive for learning CoffeeScript. Widening horizons and learning new programming paradigms and patterns is always good, but if you’re learning CoffeeScript so it can eventually replace your need for JavaScript then there are other things to consider.

John-David Dalton

If you’re great with JS, I don’t think there is any real incentive to learn CoffeeScript. Things like accidental leaked globals, switch statement fall-throughs, and other potential JS gotchas can be handled by JS linters/text-editors and don’t require a compile step / Node.js. Class sugar is so basic any JS developer can, if needed, simulate it in a handful of lines. I happen to like double equals ==, and switch statement fall-throughs, and know how best to write my JS.

Having to conform to someone else’s rules of what they feel is appropriate doesn’t mesh well with me.

Also, don’t forget CoffeeScript isn’t without its own warts.

Dave Ward

Continually exposing yourself to new perspectives and technologies is a critical part of keeping yourself relevant in our field.

Absolutely. Continually exposing yourself to new perspectives and technologies is a critical part of keeping yourself relevant in our field, and CoffeeScript is certainly a great candidate for that in the JavaScript space. Even if you ultimately decide that CoffeeScript doesn’t appeal to you, being able to write a bit of CoffeeScript should be a prerequisite to making an informed decision either way.

Nathan Smith

I have been using CoffeeScript for a few months now, as part of my job as a front-end dev on a Rails team. I don’t know if I would say there’s “incentive” to learning CoffeeScript if you already know JavaScript. I’m not sure there would be an incredible speed boost to be gained, because really there is no “best” tool for a job, only one you’re most familiar with to accomplish a given task.

Though I enjoy the comfy feel of JavaScript (like a well broken-in pair of shoes), there is also a lot to like in CoffeeScript — the “unless” syntax, for example. I would liken using CoffeeScript to having a conversation with a friend who majored in English, correcting your grammar all the while. It’s great if you want that guidance, but sometimes I just want to “keep it casual” and speak slang, without worrying about what that’s going to translate into.

Note: I suspended judgment until after reading Trevor Burnham’s book on CoffeeScript. Now that I know more about it, I’m fine using CS when I am on a team that already uses it, but I still tend to prefer JS for my own projects.

Ryan Florence

Absolutely. CoffeeScript is influencing TC-39′s decisions (like paren-free, class syntax, arrow syntax, etc.). The future versions of JavaScript will likely look a lot like CoffeeScript. I decided to learn it after listening to Brendan mentioning its influence during his talk at TXJS.

If there is anything to learn about CoffeeScript is that it’s _Just JavaScript™_. I consider it a part of our community and have really enjoyed learning it and using it. It doesn’t feel like a different language when you use it.

Brendan Eich

(Limiting my response to responding to Ryan Florence’s comments about TC39, except in my final paragraph.)

The influence of CoffeeScript on TC39 in practice is mostly me writing and proposing strawmen. None has yet stuck. I’m going to retool paren-free to be more like CoffeeScript in that newlines will be more significant in statement heads (this solves some nasty hard cases Waldemar Horwat identified, see es-discuss). But no indentation-based block structure.

Arrow function syntax was worth doing but it’s not going to make it. Block lambdas are in better shape but not yet “in”. As Jeremy said, “For the record, I too favor [block lambdas] if arrows in JS will need curlies to delimit blocks. Curlies or arrows, not both.”

That JS and CoffeeScript are formally co-expressive — have the same semantics — is huge. Yes, this means you could have just written JS. But productivity and beauty (in the eyes of some beholders) matter; syntax matters.

Oscar Godson

In short, no. The incentives to CoffeeScript are incentives, in my opinion, that are for developers who don’t fully understand the language. For example, for…in loops and leaking globals and not understanding “this” fully. If you understand those things you don’t make those mistakes in the first place, and if you do, you know what the problem is right away and know how to fix them. Having an entire transpiled language to fix common mistakes seems like overkill.

Marco Chomut

Out of professional curiosity, you should always be exploring new languages, technologies, libraries, and frameworks.

There are a few different approaches to answering this question. First and foremost, out of professional curiosity, you should always be exploring new languages, technologies, libraries, and frameworks. The worst thing that can happen to you as a developer is to become stuck in a rut. If the first language you learned was COBOL, ColdFusion, or PHP, and that’s still the breadth of your knowledge five years later, you’re just asking to become obsolete. Then again, it’s equally worse to jump ship onto the new flavor-of-the-month every time something mildly interesting appears in your news reader or Twitter feed. Have a healthy curiosity while maintaining reasonable skepticism.

Arriving back on topic, if you and your co-workers are already well-versed in restricting yourselves to the “good parts” of JavaScript, and are painfully aware of its idiosyncrasies, than CoffeeScript probably won’t offer you much. It’s a more Ruby or Python-like approach to syntax for the language that does everything it can to prevent you or your team from shooting themselves in the foot. But it’s not for everyone.

Trevor Burnham

Obviously I have a financial stake in this question (my book was released by PragProg in May), so you can take my words with a grain of salt. But yes, I think that learning CoffeeScript is worth the time. It doesn’t take much effort to learn; CoffeeScript is basically the sum of a few dozen syntactic sugars on top of JavaScript. And the reward is that you get to write more beautiful code, when you want it. For instance, some JavaScripters use CoffeeScript just for their unit tests.

Some folks complain about having to use a compiler on top of JavaScript, but some of JavaScript’s flaws—like automatic global creation when the var keyword is omitted (see here)—more or less necessitate the use of other tools, or strict mode. CoffeeScript is one such tool, and is easily among the most popular.

Alex MacCaw

My CoffeeScript programs end up as being about half the length of the equivalent source written in JavaScript.

Absolutely; in fact I’d say there was even more of an incentive to learn CoffeeScript if you’re a solid JavaScript developer. CoffeeScript certainly requires some JavaScript profiency, there’s no getting away from it. JavaScript knowledge is a pre-requisite, especially when it comes to debugging.

However, for good JavaScript developers, CoffeeScript offers a lot of advantages, such as fixing common bugs concerning global variables, semicolons and equality comparisons. Frankly, even the best JavaScript developers make these sort of simple mistakes from time to time.

The other major advantage CoffeeScript offers me over JavaScript is syntactical sugar such as shorter function declarations, comprehensions and a simple class abstraction. My CoffeeScript programs end up as being about half the length of the equivalent source written in JavaScript, with twice the clarity.


2 – Is CoffeeScript targeted at JavaScript developers? Or, is it for devs who prefer other languages, like Ruby, and haven’t yet learned the ins and outs of JS?

Jeremy Ashkenas

The core idea with CoffeeScript is to express JavaScript semantics in as readable and minimal a syntax as we can find.

CoffeeScript is targeted at JavaScript developers. It certainly borrows ideas from other dynamic languages, including Python, Ruby and Perl. But ultimately, the core idea with CoffeeScript is to express JavaScript semantics in as readable and minimal a syntax as we can find.

John-David Dalton

It seems to me developers who prefer languages like Ruby gravitate more towards CoffeeScript than those that don’t. Although, it’s common to find developers having love / hate opinions about it in any group.

Nathan Smith

I think CoffeeScript is targeted at people that understand JavaScript, but for whom it isn’t their language of choice. Otherwise, (obviously) they would prefer to just be writing JS. Whether one knows the ins and outs of JS when starting with CS, it is essential if one is to get the most out of using CS.

Oscar Godson

I work at Yammer with a lot of senior JavaScript engineers; none use it. I noticed that the friends who do use it and are extremely happy about it are Rails people. For example, at Posterous, they use it but don’t have any real JavaScript engineers. We have Rails people here, but they only do Rails – not JavaScript.

Ryan Florence

I’d have to defer to Jeremy for that one, but I do think it appeals mostly to Rubyists who are finding they spend most of their day in JavaScript. CoffeeScript knowledge is not a substitute for JavaScript knowledge. Scope is kind of different; other than that, it’s just a cleaner syntax.

Marco Chomut

I’d definitely say that it’s targeting both existing JavaScript developers and those coming from other dynamic languages who are somewhat new to the front-end web world. I personally discovered it after already having a decent amount of “raw” JS experience, and it was refreshing to work with what I imagine a modern-day client-side language would look like. While it’s just my personal approach to learning things, I don’t think I would have dove straight into CoffeeScript without any prior knowledge of the language it was built upon.

It’s important to always have at least a rudimentary understanding of whatever “black boxes” of abstraction exist in your toolkit.

Trevor Burnham

If you’re someone who likes JavaScript but wants to write more expressive code, CoffeeScript is going to be the obvious choice.

CoffeeScript’s goal is to stay as close as possible to the underlying JavaScript while improving on the language’s syntax. That makes it very different from, say, Dart, or GWT, or something that reorders code like TameJS. So I think that if you’re someone who likes JavaScript but wants to write more expressive code, CoffeeScript is going to be the obvious choice.

Obviously it’s disproportionately popular in the Ruby world, since it’s borrowed many Ruby-isms like postfix if/unless and has an extremely prominent evangelist in dhh, but it’s also quite popular in the Node.js world, which says a lot.

Alex MacCaw

I’ve used JavaScript for years, and wrote the O’Reilly book on JavaScript web applications. I think you could say I’ve learnt the ‘ins and outs’ of the language. That said, I personally plan to never write plain JavaScript again, not because I don’t like the language, but because I love writing CoffeeScript so much.

CoffeeScript is for people who deeply understand and respect JavaScript.


3 – When Dart was announced, it was met with immediate slander by much of the JS community. Though not an entirely different language, the same is partially true for CoffeeScript. Are some developers simply afraid of learning yet another new thing, or are their criticisms justified?

Jeremy Ashkenas

With the release of Dart, the web development community was faced with the peril of Google forcing a new, nonstandard language into a shipping web browser.

Dart is a different story. With the release of Dart, the web development community was faced with the peril of Google forcing a new, nonstandard language into a shipping web browser. As we know well from the web — once you ship something in a browser, it tends to be there forever. In addition, Dart retreats from the dynamism of JavaScript, and instead exists as a somewhat static language, where types can be checked at compile time, but are erased at runtime. The JavaScript community perceived this as a cynical gesture to make Java developers feel more at home in Dart, being able to write types that appear similar to Java types, even though they’re treated as comments when the program runs. It’s not just JavaScript developers being wary of the Dart push, browser implementors are wary as well.

Now, let’s take the CoffeeScript case. CoffeeScript has felt threatening to a surprising number of JavaScript developers, in a way that other languages have not. You don’t hear JS programmers worrying about other new languages like Clojure or Scala, or even compile-to-JS languages like GWT or Objective-J in anything approaching the same volume.

Note that I’m not talking about people who simply choose to continue to use JavaScript — I continue to use JavaScript for many projects as well. I’m talking about the fearful rhetoric of “I won’t use your library because you wrote it in CoffeeScript”, or “CoffeeScript makes you forget how to write JavaScript.”

CoffeeScript feels threatening to JavaScript developers precisely because it’s so close to JavaScript.

Because the semantics are the same, every CoffeeScript program is fully interoperable with JavaScript, and vice-versa. You may already be using a library written in CoffeeScript without even knowing it (like Zombie.js, Riak-JS, or xml2js). In addition, CoffeeScript is actually being used — it’s currently the 13th most popular language on GitHub.

As as JavaScript developer, confronting this situation — where there’s a fully compatible alternative to JavaScript, with the same performance profile — forces you to answer the question: “why haven’t you tried CoffeeScript yet?” Many of the posts that we’re seeing are developers justifying their answer to that question for themselves. If I hadn’t tried CoffeeScript yet, I’d probably be writing the same kind of posts.

James Padolsey

The real battle is creating clean, intuitive and maintainable APIs.

Dart’s slightly different. One, it’s from Google! i.e. that massive monopoly that we’re supposed to be wary of. Beyond the various political issues, Dart doesn’t seem to bring anything to the table other than a more Java-esque syntax, which many developers aren’t too fond of, myself included. I prefer to stick to the most expressive API/languages I have at my disposal. When it comes to CoffeeScript, though, I am cautious because really, it’s just JavaScript, but with a completely different syntax. JavaScript’s malleable enough for me to create the APIs and functionality that I need. I don’t much care for convenience sugar unless it really enhances my ability to write good code. Some of CoffeeScript’s features, like destructuring assignment and the existential operator, are really quite awesome, but to be honest, they’re just minor sweetness, and similar functionality can be gained in JavaScript (see JS 1.7 for destructuring assignment too!), although with a little more verbosity. The real battle is creating clean, intuitive and maintainable APIs. CoffeeScript isn’t going to help you a great deal there. Like I said, it’s sugar.

John-David Dalton

I don’t think it’s being afraid of something new. For me at least, it’s more about not wanting to over-engineer and having more control over my JS.

Dave Ward

It’s difficult to speak for others, but I don’t get the impression that many JavaScript developers are avoiding CoffeeScript because they avoid new things. If anything, I think most developers who are aware of CoffeeScript at all are probably on the early adopter’s end of the curve.

In particular, I believe that reluctance toward adding CoffeeScript’s compilation step into client-side development is objectively justified, not related to any previous investment in learning JavaScript.

Nathan Smith

With any potentially disruptive new technology, those who have staked their claim on the current way of doing things tend to go through the five “stages of grief.

This was my experience, anyway…

  1. Denial — “I’ll never use CoffeeScript.” (or Dart)
  2. Anger — “I wish people would shut up about it already!”
  3. Bargaining — “Okay, I guess it has *some* good parts.”
  4. Depression — “I can’t believe I have to learn this.”
  5. Acceptance — *Shrug* ~ “Use the best tool for the job.”

That said, there are some justifications to the criticisms of CoffeeScript (and Dart). However, whereas CoffeeScript attempts to adhere to the “spirit” of JavaScript (terse code, etc), the end-game for Dart is to get developers writing an entirely different language altogether (preferably interpreted in a browser’s VM, instead of being precompiled to JS). Dart is more akin to Java than JavaScript.

The most valid criticism against any language that would attempt to supplant JavaScript is that JS has the world’s largest install base of any language runtime (on desktop browsers, server, and mobile devices). It might not be perfect, but as far as distribution goes, it “just works.”

Brendan Eich has already expressed his interest in seeing aspects of CS folded back into future versions of ECMAScript. By contrast, Dart has been met with harsher criticism from not only JS developers, but from the WebKit community.

Oscar Godson

Yes and no. I tend to be more critical of things before I’ve tried them, but I did try CoffeeScript to see what all the hype was about. It was nice, but it’s not worth it. Why have a compiled language to *just* help you with common JS warts and to make JS more “pretty”? That’s what puts me off about it. JavaScript engineers do tend to be elitist though, I agree with that, but in this case I believe it’s for a good reason. The reason being, don’t write a totally different language to fix some warts about it.

Ryan Florence

[...] We’re just so tired of fragmentation.

CoffeeScript and Dart aren’t even comparable. Dart aims to replace JavaScript, CoffeeScript is nothing more than a nice coat of paint. You can use CoffeeScript and still “always bet on JS”. I think front-end devs are happy to learn new things (our environment is always broken, you’d have to like learning stuff to survive), we’re just so tired of fragmentation. It’s completely justified to freak out if you see “ActiveX 2.0″ coming. CoffeeScript is not a threat to JavaScript.

Marco Chomut

I believe both reactions were equally justified (although when Google is involved, people always tend to exaggerate their opinions one way or the other for whatever reason). CoffeeScript was a re-imagining of JavaScript from the Ruby and Python communities. Dart was a re-imagining from a subset of the Java community. Language biases aside, I honestly don’t believe that Java-fying an already dynamic and (arguably) verbose language is the correct approach.

It probably didn’t help that the JavaScript community was already allergic to the idea of Dart before it was even announced, due to the set of “leaked” correspondance surrounding it.

Trevor Burnham

Of course some of the criticisms of CoffeeScript are justified. I mean, “significant whitespace is evil” is a lame one, but “it divides the community” is legit. There’s something to be said for JS being a lingua franca. But you look at very common JS mistakes like forgetting a comma in a multi-line object literal (or adding an extra one at the end of the last line), and it causes your whole app to crash… for a certain kind of programmer (myself included), not having to deal with that is a big breath of fresh air.

I think CoffeeScript and JS are going to peacefully coexist for the foreseeable future, and there are gonna be haters, and that’s fine. That’s how you know it’s a real programming language.

Alex MacCaw

CoffeeScript doesn’t intend to replace JavaScript, or abstract it away, but rather to enhance it.

As others have mentioned, Dart is a completely different beast to CoffeeScript, and many of the criticisms directed at Dart were regarding implementation details and Google’s approach, rather than just the existence of another language. Frankly, CoffeeScript is an entirely different language to Dart.

Google took rather a walled garden approach to Dart, and I get the impression they didn’t really look outside the confines of their company for inspiration. Whether this was because of some sort of Not Invented Here syndrome, or the fact that they needed a language that would appeal to their Java developers, I’m not sure. However, Dart strikes me as something that is very specific to Google’s needs, rather than something that’s applicable at large.

CoffeeScript doesn’t intend to replace JavaScript, or abstract it away, but rather to enhance it. So, not only are the languages completely different, but the motives behind them are very different. Thus it’s difficult to compare criticism between the two.


4 – Is it fair to assume that, if you’re against the idea of CoffeeScript, then you’re likely also against CSS preprocessors, like Sass and Less? Or, do you see a specific distinction between the two (as I do)?

James Padolsey

I’ve never used Sass or Less so I can’t really comment. I will say that the general idea is the same in that they’re all slightly heightening the level of abstraction, allowing you to quickly get at functionality without having to type the verbose alternative. I will say that the thing keeping me from picking up CoffeeScript is very different to what would keep me from picking up a CSS preprocessor.

John-David Dalton

I don’t work heavily with CSS and haven’t used a CSS preprocessor but I can understand the need to manage the cluster of vendor prefixes. I’m also not as comfortable with CSS as I am with JS.

Nathan Smith

I don’t think that is an entirely accurate assumption. While there might be some who are against all preprocessing of client-side code, with Sass (and Compass) you get a layer atop CSS that’s very “close to the metal” in terms of syntax. One of the benefits of Compass is the ability to write one line that is transformed into multiple lines of vendor prefixed code. One needn’t memorize different variations on the same styling that will ultimately be deprecated when a standard is agreed upon. Sass (with Compass) example:

#foobar
  +background(linear-gradient(#fff, #ccc))

That reads cleanly, and is somewhat similar to what the standard might become in CSS.

CoffeeScript, on the other hand, adds a new syntactic layer that seeks to be a departure from JavaScript, incorporating idioms from other languages that are not native to JS.

Sass adds variables, color math, and a slew of things that cannot be done in CSS alone. Whereas, CoffeeScript provides an alternative approach to what JavaScript is already perfectly capable of doing. I believe that’s why we’re having this discussion — Some see value in that. Others don’t.

Oscar Godson

I personally have nothing against CSS preprocessors because they add functionality. I don’t use them because I’m a purist you could say, but they do save time with less typing – particularly for people who do lots of CSS coding. They also don’t aim to fix “broken” things – just extend it. I don’t use it and don’t see myself ever using it for personal stuff but I’m not opposed to using it.

Ryan Florence

There is a distinction. SASS, Less, Stylus etc. all bring something to CSS that it doesn’t already have.

There is a distinction. SASS, Less, Stylus etc. all bring something to CSS that it doesn’t already have: logic–it turns your CSS into an application. CoffeeScript doesn’t bring anything “new” to JavaScript in the same way, which is why it’s so debatable. Not using a CSS preprocessor isn’t really even debatable for anything non-trivial.

Marco Chomut

CoffeeScript provides cleaner syntax…

I’m going to have to agree with the other answers here that the CSS “equivalents” of CoffeeScript, such as SASS or Less, are often judged quite differently. For me, SASS is always a default on any new project that I work on, while CoffeeScript continues to be debatable. CoffeeScript provides cleaner syntax, does its best to keep a developer shielded from the bad parts of JavaScript, and allows you to avoid prototype-based inheritance with its built-in class structure. SASS on the other hand offers a slew of (very-necessary) features to CSS that you would otherwise not be able to have. Variables, functions, mixins, the list goes on and on. CoffeeScript doesn’t really offer any of these meta-features to JavaScript, and really just boils down to syntactic sugar.

Trevor Burnham

I’m honestly amazed that people are still using Sass/SCSS.

Sass is an interesting example because it went through a big split itself: Originally, it was a fully whitespace-significant alternative to CSS, and of course some people loved that and others hated it. Now it comes in two flavors: The whitespace-significant “Sass Classic” syntax, and the CSS superset SCSS. They’re both annoyingly strict; the “Sass Classic” compiler will yell at you if you use so much as a semicolon. Then TJ Holowaychuk came along and created Stylus, which lets you use whitespace-significant syntax and curly-brace syntax… in the same file! It’s a much more elegant solution, and I’m honestly amazed that people are still using Sass/SCSS.

Which isn’t to say that CoffeeScript should start accepting curly braces (there would be some ambiguous cases). My point is just that CSS preprocessors aren’t really about cleaner/terser syntax the way CoffeeScript is. (The SCSS syntax is more popular than Sass Classic, probably because designers can keep using the CSS snippets they’re used to without running them through a converter.) They’re about doing things in a totally different way. CSS isn’t really a language; CSS preprocessors (with their variables and functions) are.

Rebuttle from Nathan Smith:

CSS *is* a language. Just not a “programming” language. I see his point though, preprocessors allow for declarative, functional programming.

Alex MacCaw

Well, I don’t think that’s necessarily the case. I personally enjoy Less and Stylus, as much as I enjoy CoffeeScript. However, I’m not a fan of HTML abstractions such as HAML and Jade. I evaluate each technology independently. I’m not for or against preprocessors in general.


5 – A frequent criticism of CoffeeScript is that, if everyone uses it, we may get to a point when nobody remembers (or ever learned) how to write actual JavaScript. Is this a valid concern?

Jeremy Ashkenas

Nope — CoffeeScript exposes a subset of JavaScript semantics. If you learn how to write CoffeeScript, almost by definition you’ll know how to write JavaScript. Learning isn’t a zero-sum game. Learning one language or dialect doesn’t prevent you from knowing others.

In fact, just as people who are comfortable speaking several languages find it easy to pick up more; programmers who know more than one dialect of JavaScript may be better able to learn new concepts and idioms.

John-David Dalton

No. As it is CoffeeScript compiles to JS so developers still have to deal with JS when debugging, for the time being, and can still use JS through the supported embedding syntax.

- http://jashkenas.github.com/coffee-script/#embedded
- https://bugs.webkit.org/show_bug.cgi?id=30933
- https://bugzilla.mozilla.org/show_bug.cgi?id=618650

Dave Ward

Various tools and frameworks have been “compiling” to HTML for nearly as long as HTML has existed

No, I don’t think that’s likely.

Various tools and frameworks have been “compiling” to HTML for nearly as long as HTML has existed, yet knowledge of (and appreciation for) the generated HTML markup has only increased during that time. With most abstractions, you inevitably find yourself dealing with edge cases that force you to learn more deeply about the underlying technology. If anything, a simple abstraction over something more daunting often provides an appealing onramp for new developers, eventually leading them to learn more about the abstracted topic than they would otherwise have been comfortable with.

Nathan Smith

If CoffeeScript goes “mainstream” then more people will take an interest in the JavaScript language itself.

I actually think (hope) maybe the opposite will be true. I think that if CoffeeScript goes “mainstream” then more people will take an interest in the JavaScript language itself. I have met quite a few designers who didn’t care about JavaScript at all, but learned how to cut and paste jQuery snippets. Before long, they’re saying “Man, I really need to learn JavaScript.”

Just as jQuery ignited interest in JS amongst designers with its “reads like CSS” selectors, I think that perhaps CoffeeScript will be that “gateway drug” to greater JS understanding, except for Rubyists. Either way, those who already know JS have a leg-up.

Oscar Godson

Have you been to StackOverflow recently? Try asking a question about JavaScript. I once asked about doing some date parsing (to get the next Wed.) and someone sent me an entire jQuery plugin. It ended up being a one liner and the jQuery plugin got the most votes compared to the right one line answer. This has happened with jQuery where people just pick up jQuery and never bother to learn JavaScript. On Twitter I overheard someone asking about cookie sessions and someone suggested they use jQuery and include a $.cookie plugin. Im worried that CoffeeScript is going to end up like this where people will be including this for simple apps or when they just dont really want to understand JS.

Ryan Florence

You can’t write CoffeeScript without knowing JavaScript. You are debugging the JavaScript. You’re using third-party libs that are JavaScript. You can’t get away from it (the great flaw in using CoffeeScript for real world applications). So no, its not a valid argument for being against CoffeeScript.

The fact that this argument is flawed is a solid argument to not use CoffeeScript. If you can’t break from JavaScript, what’s the point?

Marco Chomut

Similar arguments were made around the time that jQuery was becoming quite popular. I don’t believe that it was a valid concern then, and I don’t think it is now. Learning CoffeeScript will also require you to at some point buckle-down and learn the underlying JavaScript. This isn’t really something that you can avoid, until the day comes (if ever) that browsers parse and execute it natively. You’re going to run into the odd error or interaction that will force you to understand what it’s translating into.

Trevor Burnham

You shouldn’t use CoffeeScript without knowing JavaScript.

What Ryan said.

You shouldn’t use CoffeeScript without knowing JavaScript, although you can learn both at the same time. I mean, there must be a million people out there who are using JavaScript without really knowing JavaScript. A lot of them have other primary languages, and they’ll never really like JavaScript as much as they like Ruby, or PHP, or Java, so they only learn as much as they need to get by. That’s the sort of crowd my book is mainly aimed at. It’s like “Hey, let’s learn this hip new language, and along the way we’ll fill in the gaps in our JavaScript knowledge.”

Alex MacCaw

On the contrary, it’s quite the opposite. I don’t think this is a valid concern. As the others have stated, JavaScript knowledge is a requirement for writing CoffeeScript. Thus by writing CoffeeScript I think your JavaScript knowledge should, if anything, improve.

The JavaScript generated by the CoffeeScript compiler is top notch, and by browsing through it you certainly learn a few tricks.

However, I completely disagree that the fact you can’t break from JavaScript is an argument not to use CoffeeScript. CoffeeScript is a lightweight curated subset of the language, improving it’s syntax and only presenting the ‘good parts’. In other words, I think it’s an improvement.


6 – One argument in favor of CoffeeScript that I rarely see put forth is that it can make you a better JavaScript developer – particularly if you’re somewhat new to the language. Similar to Rails, a huge array of best practices are baked into the compiler. Do you see benefit in that aspect? Use CoffeeScript to become a better JavaScript developer?

Jeremy Ashkenas

A large number of users have reported learning new tricks and patterns from reading their compiled JavaScript.

Yes. A large number of users have reported learning new tricks and patterns from reading their compiled JavaScript.

But having best practices built in to the compiler doesn’t mainly benefit beginners — the benefit is to long-term programmers who can take full advantage of having a concise, readable way to express their JavaScript intentions in code — without having to constantly keep best practice patterns in mind. A best practice that can be enforced and generated by a compiler is better than a best practice that has to be remembered and manually typed out every time.

James Padolsey

The only problem I see with taking this approach is that you’re not really learning JavaScript, and there’s so much magic going on that you won’t necessarily be appreciating the lengths that you might have to go to in order to get similar things done in JavaScript. CoffeeScript is easier for these tasks.

It will teach you to become a better programmer, I think, but if you want to learn JavaScript, then learn it, purely.

John-David Dalton

I think you can take the “it makes you a better JS developer” and apply that to existing JS libs/frameworks. I learned a lot from digging into and fixing issues in libs like Dojo, jQuery, MooTools, and Prototype. The code produced by CoffeeScript is extraneously verbose and promotes micro-optimizations (which isn’t necessarily helpful and not a “best practice”).

I would not look to CoffeeScript or its compiled JS to improve my JS skills and would rather look to mature battle hardened JS libs.

Dave Ward

If someone wants to become a better JavaScript developer, there are less circuitous routes. I think the main things that make JavaScript difficult for beginners are more conceptual than syntactical. CoffeeScript doesn’t change the fact that you need to understand concepts like closures, asynchronous programming, and continuation passing to write non-trivial JavaScript code.

Nathan Smith

I think there is some truth to this. If you are consistently checking what JavaScript is output by the CoffeeScript compiler, I think there are some insights to be gleaned. For instance, declaring all variables at the beginning of a function, to prevent variable hoisting.

Additionally, the concept of closures is introduced automatically. This might seem frustrating at first, if just trying to create a global variable, directly inline (emitting something from the server-side in HTML). Due to this, CoffeeScript enforces good habits, such as explicitly attaching variables to the global object, if that is indeed what you mean to do…

// Global variable in CoffeeScript
window.foobar = 'something'

//=====//

(function() {
  // CoffeeScript output.
  window.foobar = 'something';
}).call(this);

// Versus:

(function() {
  // Manual typo.
  foobar = 'something';
})();

That’s not to say such lessons cannot be learned apart from using a transpiler, but if someone new to JavaScript sought to use CoffeeScript as a way to learn about JS concepts, it might be an interesting place to start. Though, for JS beginners, reading canonical books like “JavaScript: The Good Parts” would probably be more helpful.

Oscar Godson

How do you learn or become better at something you’ve been shielded from? If you never have to worry about global vars leaking how do you know later when working with vanilla JS? It’s like giving someone a camera with auto-focus who’s never used a camera before and then expecting them to know how to use a film camera and adjust the focus, ISO, etc by manual means.

Ryan Florence

My hand-written JavaScript is pretty different from what CoffeeScript spits out.

I think developers who aren’t very experienced in JavaScript have something to learn from the compiler’s output. Take the ?= and ||= operators, CoffeeScript shows them how to solve that problem in JavaScript.

But they are also going to have a hard time debugging code they don’t understand. I don’t think these people can effectively use CoffeeScript.

My hand-written JavaScript is pretty different from what CoffeeScript spits out; it’s also better looking. I think there’s more to learn by reading the source code of some of our community leaders and established JS libraries than from the compiler.

Marco Chomut

If, as a developer, you weren’t already exposed to the finer portions of JavaScript (either through Douglas Crockford’s JSLint or Anton Kovalyov’s JSHint), then CoffeeScript will definitely be a decent crash-course in the subject. But only if you take the chance to really understand why CS made certain decisions in the language. If you rush through it and merely try to push out a working prototype as fast as possible, you’re only harming yourself in the long run. I mentioned it before in a previous answer, but being unaware of some of the inner workings of your black boxes is very dangerous and counter-productive.

Trevor Burnham

Sounds like you’ve been attending my talks; I put this argument forward all the time.

It’s interesting that you mention Rails. A lot of people learn Ruby by learning Rails. A lot of people learn JavaScript by learning jQuery. But if you learn that way, you’re not going to see the whole language. By contrast, you work through something on CoffeeScript, you’re going to see the edges. You’re going to learn all about this and prototype inheritance and typeof/instanceof and iterating through object keys and array values, and a hundred other things that JS noobs ask about on Stack Overflow every day.

So yeah. I see learning CoffeeScript as one path to becoming a knowledgeable JavaScripter. Certainly not the only one, but one that’s fun and rewarding.


7 – Clearly, if you’re a Ruby developer, CoffeeScript will be infinitely more appealing to you, as the syntax is fairly similar. For real world projects, where developers have deadlines, is CoffeeScript not simply a way to get the job done more quickly, with less language shuffling? What’s wrong with that, if anything?

Jeremy Ashkenas

Some Rubyists say that CoffeeScript looks like Ruby, Pythonistas say that CoffeeScript looks like Python, and I’ve heard Haskellers say that CoffeeScript looks like Haskell.

I’m afraid that this is a silly question. Some Rubyists say that CoffeeScript looks like Ruby, Pythonistas say that CoffeeScript looks like Python, and I’ve heard Haskellers say that CoffeeScript looks like Haskell. The truth of the matter is that CoffeeScript semantics are just JavaScript semantics — there’s definitely no less “language shuffling” involved.

James Padolsey

I fear it will become acceptable to forgo the vital learning curve of JavaScript and simply rest falsely assured that the code you write in CoffeeScript works just like it would in that-other-language-you-know. For a team with a deadline I can definitely see the appeal of having a more unified development environment. Ruby and CoffeeScript are a cute match — much more so than JavaScript and Ruby. I think an understanding of JavaScript is vital, especially at this early stage (debugging can still be a nuisance).

John-David Dalton

Depends on their setup. CoffeeScript, like JS libs, has bugs from release to release (even some which affect cross-browser use) which can cause existing CoffeeScript code to break.

Also, debugging still requires digging through raw JS and may not necessarily be an easy task as CoffeeScript applications become more complex.

Unlike JS libs which can live on CDNs, the sugar around CoffeeScript has to be compiled for every JS file (unless compiled together). This can make CoffeeScript generated JS less ideal for separate third-party scripts. CoffeeScript adds yet another “something” the team will have to familiarize themselves with and become proficient in, which costs time/money and could be avoided by simply using JS (JS lib + linter).

Dave Ward

As someone who has spent quite a bit of time in the .NET world, I’ve seen that argument used to support drag ‘n drop development and some particularly leaky abstractions over HTML, CSS, and JavaScript. That experience has left me extremely skeptical about the long-term value of focusing on up-front productivity at the expense of understanding your development stack.

Nathan Smith

I wouldn’t say it’s a way to avoid “language shuffling.” Though CoffeeScript and Ruby might share some syntactic sugar, each has its own ways of dealing with things. While CS will no doubt look familiar to Ruby developers, there is still a learning curve.

If you are under the gun on a deadline, deciding to use CoffeeScript is probably not going to help you get that work done any sooner. As with any new language, you need to set aside some time to get familiar with it, make beginner mistakes, and finally end up at a place where it becomes second nature.

I think the danger to Ruby developers is hoping that CoffeeScript will gloss over some perceived mysterious aspects inherent to JavaScript.

While you might end up typing less overall characters in a *.coffee file, you still need to care about what ends up in the *.js file. That comes with experience, not (only) with new syntax.

Ryan Florence

You write in one language, but debug in another…

As for “less language shuffling” I assume you mean it’s like Ruby everywhere in your app–that is totally false. You write in one language, but debug in another language and neither is Ruby, so it’s actually more shuffling.

If JavaScript’s syntax is slowing you down, then you need to learn how to use your text editor or learn how to type. There is nothing faster about CoffeeScript. Introducing CoffeeScript into your workflow actually increases “shuffling”:

A lot of people gloss over the debugging issue but 20% of the day we write bugs, the other 80% we fix them (don’t deny it). Debugging is a big issue.

You are debugging code you didn’t write. You have to figure out what the compiler is doing, and then figure out why the code is not doing what you wanted. Then you have to go to your CoffeeScript and figure out how to fix it in a different syntax. Usually it’s not that bad, but when using some of the fancier features of CoffeeScript it can get really “machine code” looking. One line in CoffeeScript can turn into several lines of crazy looking stuff (see here), that, again, you didn’t write, so you have to figure out why it looks that way, and then why it’s broken.

This back-and-forth “shuffling” is a weird step that slows you down because it’s not _your_ code you’re looking at. I find I’m back to doing a lot of console.log in my code instead of using break points and watch expressions, etc., which is a total shame, and slower. But it’s the fastest way for me to “shuffle” between the JavaScript I’m debugging and the CoffeeScript I’m writing.

Trevor Burnham

Will CoffeeScript get the job done more quickly? Certainly some prominent JavaScript/Ruby pros have reached that conclusion for themselves.

Rubyists are certainly easier to sell on CoffeeScript than, say, Java programmers. But the most common questions I get from Rubyists are along the lines of “Wait, why do we need a separate language? Why can’t we just compile Ruby to JS?” And I try to explain to them that, well, compiling “a = b” from Ruby into JS would require you to check whether b is a function, and if it is then run it and return its value… and compiling “x = y + 1” would require you to fire up a BigDecimal library, because all Ruby numbers are infinite-precision… and so on. Those folks have to learn that, look, when you’re in the browser, you’re on JavaScript’s turf and you’ve got to make peace with it. It could be worse. It could be statically typed.

Will CoffeeScript get the job done more quickly? Certainly some prominent JavaScript/Ruby pros (like 37signals’ Sam Stephenson, creator of Prototype.js) have reached that conclusion for themselves. Obviously it depends on a lot of factors… sometimes what you need is a fresh perspective, and a new language can give you that.

Alex MacCaw

CoffeeScript isn’t inherently Rubyish.

That’s a pretty leading question, and I don’t think that assumption is necessarily valid. CoffeeScript isn’t inherently Rubyish, just as it’s not inherently Pythonist. It borrows features from both languages but ultimately its schematics are inspired by JavaScript. The aim of CoffeeScript is not to abstract away JavaScript for developers who don’t want to learn it, such as the now defunct RJS. As such, it doesn’t help with language shuffling.


8 – Many might argue that CoffeeScript allows for more beautiful and maintainable code. For example, creating a class in CS is considerably more intuitive and readable than what we might write with plain JavaScript.

It’s not surprising that many will prefer the cleaner and shorter:

class MyClass
  constructor: ->
    alert 'constructor'

  doSomething: ->
    alert 'doing something'

c = new MyClass()
c.doSomething()

Over…

var MyClass = (function() {
  function MyClass() {
    alert('constructor');
  }

  MyClass.prototype.doSomething = function() {
    alert('doing something');
  };

  return MyClass;
})();

c = new MyClass();
c.doSomething();

My question is: does CoffeeScript’s readability alone warrant its usage?

Jeremy Ashkenas

You can write undreadable code in any language.

You can write undreadable code in any language … but yes — one of the main focuses of CoffeeScript is readability: expressing JavaScript concepts and patterns in as minimal and readable a way as we can find.

Your “class” example is a good one. If you want to make many objects that share common methods in JavaScript — it’s not easy to accomplish. There are many ways to break the “prototype” object while you try to set up the prototype chain. You’re left either writing unreadable boilerplate every time you wish to chain two prototypes together, or using a helper library that hides basic object orientation from you. CoffeeScript’s classes are a simple way to define your constructor functions along with their prototypal properties and prototype chain. The side effect is the readability of simply writing what you mean:

    class Square extends Shape
    

… instead of a half dozen lines of prototype manipulation code in JavaScript:

    function Square() {
      ...
    };
    var tempConstructor = function(){
      this.constructor = Square;
    };
    tempConstructor.prototype = Shape.prototype;
    Square.prototype = new tempConstructor;

James Padolsey

Naturally, because I’ve worked more with JavaScript, it’s more readable to me than CoffeeScript.

That’s not the JavaScript I would write, but I see your point. CoffeeScript can have great readability and most of the CS code I’ve seen is both terse and expressive, but I don’t think this necessarily translates to “more intuitive”. Naturally, because I’ve worked more with JavaScript, it’s more readable to me than CoffeeScript. Again, this seems to be about taste, and is very much influenced by prior language exposure. A Ruby person would probably understand the CoffeeScript code sooner than the JavaScript, but it would be the opposite for, say, a PHP or Java developer, where keywords play a central role in class and function definition. In CoffeeScript you have very minimal and expressive operators which aren’t always as clear.

John-David Dalton

No. Developers have different opinions on what they consider readable. CoffeeScript is similar to JS libs in that they all add syntactic sugar and each developer/team has their own preference (MooTools, jQuery, Dojo, CoffeeScript, CoffeeScript+libs, and on and on).

Dave Ward

If you want syntactic sugar around structuring your code, there are JavaScript libraries to help with that without requiring the obtrusive compilation step.

If you want syntactic sugar around structuring your code, there are JavaScript libraries to help with that without requiring the obtrusive compilation step.

Considering this question in the overall context of the others, the developer who doesn’t yet understand JavaScript needs more than a somewhat similar analog to their server-side language’s implementation of classical inheritance. I believe putting the “class” pseudo-keyword in front of a developer coming from a typical object oriented language may even be harmful in the long run.

Nathan Smith

“Readability” is subjective. I think you’ve touched on something with the “class” example. For developers coming from a classical programming background (C#, Ruby, etc), CoffeeScript probably feels like a breath of fresh air. To me, having learned JavaScript as my first “real” programming language, thinking in terms of classes feels foreign.

In my opinion, the perfect blend of CS and JS would be var added automagically, and not needing to write unnecessary parenthesis or curly braces. However, I could do without the automatic return at the end of each function.

I am also not a fan of how CS hijacks the for in to become an i++ loop — requiring instead that you write for of to be able to iterate through objects (when *.length isn’t present).

Oscar Godson

This might be because JavaScript isn’t a class based language. It’s prototypal, and that scares people who aren’t used to it. PHP or Rails developers come to JS, and don’t know how to use it properly. So they come up with hacks to make it work and even look like other languages. This isn’t the answer. If you do need to use classes, you can write a mini-lib and make it clean like:

var Ninja = Person.extend({
  init: function(){
    this._super( false );
  },
  dance: function(){
    // Call the inherited version of dance()
    return this._super();
  },
  swingSword: function(){
    return true;
  }});

// via http://ejohn.org/blog/simple-javascript-inheritance/
  

The only real difference is no parenthesis. I actually like Brendan Eich’s idea of paran-free JS, but I like the idea of it being baked in and not completely changing the language.

Ryan Florence

I review code on gerrit from my team every day. Some JavaScript, some CoffeeScript. I have as hard a time following what they’re trying to do in one syntax vs. the other. It’s perhaps more verbally readable at times, but that has yet to make it more understandable for me. Take this line for example:

scores = (student["assignment_#{@assignment.id}"].score for own idx, student of @gradebook.students when student["assignment_#{@assignment.id}"]?.score?)

That’s 160 columns of verbally readable code straight out of our app but I have no idea what it’s doing. The fun part is that you end up debugging things like this.

There are some aspects to CoffeeScript that are less readable.

The fat arrow => binds the context to the function, which sounds great, but it encourages deep nesting, an anti-pattern.

Couple that with significant whitespace over several lines of code and you’ve got a mess. Unstructured code with callbacks and lots of if else going on is extremely hard to follow: there’s no closing bracket for me to place my cursor over and see where I’m at with my text editor. Some say, “Don’t write code like that”. I don’t write all the code I work with.

Also, not all APIs have functions as the last argument to their signature, so you end up with some commas floating around at the beginning of lines, which looks really weird next to the rest of CoffeeScript’s generally appealing look.

On the flip side, I’ve noticed that the class syntax hits a logical chord in people who aren’t JavaScript experts but experts in some other language(s). Suddenly they grasp that they can write modular front-end code instead of chaining jQuery down to oblivion. I personally don’t use class, or write JavaScript the way you did in the example, but I think its a useful syntax for good programmers less familiar with JavaScript.

Trevor Burnham

As far as readability is concerned, there’s no substitute for good documentation. I look at the annotated source for Backbone.js, and I think, “Wow.” It’d be maybe 30% fewer lines if it were written in CoffeeScript, but it’d only be marginally easier to understand.

I think the bigger win is in writability. It’s not just fewer keystrokes (typing is rarely a bottleneck for coding); it’s less to think about. A common Node.js idiom is writing:

  if (err) throw err;

…at the top of callbacks. I could save that as a snippet, I guess, but I’d much rather just punch in the CoffeeScript equivalent:

It just takes fewer brain cycles. That way, I can focus more on the core of the callback.

Alex MacCaw

Sure, that’s a good reason to learn CoffeeScript, or indeed any high level language. Readability is a crucial part to developing, maintaining and extending code in any language. CoffeeScript takes this a step further by using whitespace, meaning that badly formatted code will simply fail to compile.

Of course it’s possible to write ugly code in any language, but I definitely think CoffeeScript has an inherit aesthetic beauty to it, in both the language and the community; much more so than traditional JavaScript.


Closing Arguments

Jeremy Ashkenas

I’d like to file my general objection to the way in which these questions are framed. They create false drama where none needs to exist. CoffeeScript is a fun little language that attempts to push JavaScript in a certain direction: How minimal and readable a syntax can we find to express the famous good parts of JavaScript. If you enjoy it, that’s great; if you don’t, that’s great as well — JavaScript is a wonderful language. Because CoffeeScript and JavaScript share semantics, they’ll always get along just fine. Personally, I write a good deal of both.

Interviewer’s Notes: Absolutely. It was never my intention to create a flame war, when, ultimately, we’re dealing with helpful tools. That can never be a bad thing! That said, the questions I’ve provided are the ones that I found to be most frequently asked on Twitter, blogs, and social networks. Even if they’re unfounded, it’s important to acknowledge that they are being asked, and discuss them. :)

Ryan Florence

I think CoffeeScript is an excellent choice for hobbyist and one-man operations. On a team, I would advise against it if you aren’t already down the path.

Trevor Burnham

What Ryan said. Learn JavaScript. It’s an awesome language. But it’s not my favorite language, because there’s CoffeeScript.

John-David Dalton

+1 to Ryan Florence’s side note.

Nathan Smith

I don’t think anyone can deny that Jeremy Ashkenas has created something remarkable. The fact we’re all talking about it testament to that. I would encourage anyone who has dug-in their heels against using CoffeeScript to at least give it a shot. Having done so myself, I still prefer JavaScript, but at least now I can appreciate why it’s appealing to others.


Further CoffeeScript Resources

  • JSConf 2011 Presentation
  • A Cup of CoffeeScript
  • Rocking Out with CoffeeScript
  • A Case Against CoffeeScript

  • A Question for the Readers

    Now that some of the best in the business have offered there own opinions, I’d like to hear from you in the comments. While most of these questions came courtesy of social networks and blog posts, this last question is one that I was personally most interested in learning the answer to.

    One of my only concerns with using CoffeeScript is that debugging the generated JavaScript could potentially be a huge concern. Have you found this to be the case?

    Let me know below!


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

    Create a Scalable Widget Using YUI3: Part 1

    Tuesday, December 13th, 2011

    In this tutorial, we’re going to look at how easy it is to create scalable, robust and portable widgets using the latest version of the Yahoo User Interface library. YUI3 provides a Widget class for us to extend in order to create widgets in a consistent way that leverage the power of the library.

    The widget that we’ll create today is a Twitter search client that will query Twitter’s search API and consume the JSON response in order to display tweets that contain the configured search term. We can also add additional functionality such as allowing the visitor to choose another term and do a new search, and viewing paged results. Join me after the jump!


    Getting Started

    All required YUI modules will be retrieved dynamically when the page running our widget is loade

    We’ll need the usual css, img and js folders created within a project folder for us to store our various resources in. The images our widget will use can be found in the code download. We don’t need to worry about downloading a copy of the YUI library itself as all required YUI modules will be retrieved dynamically when the page running our widget is loaded (we’ll look at this in more detail later).


    The Widget Wrapper

    Create a new script file and add to it the following code:

    YUI.add("tweet-search", function (Y) {
    
    }, "0.0.1", { requires: ["widget", "substitute", "jsonp"] });

    This is the outer wrapper for our widget; all of the code we write will reside within the function passed as the second argument to YUI’s add() method. The add() method of the YUI object allows us to add a new module to the library, which could be a simple function or class, a widget, an extension or a plugin.

    In this example, we use the requires property to specify an array of other YUI components that are required for our widget to function. There are other properties that can be used here, but they aren’t required for this example.

    As you can see, one of the required components is the Widget component. When creating a custom widget the Widget component of the library should be extended to make use of the powerful constructs that Widget sets up. We also use the Substitute component for doing some simple string substitution when building the required HTML elements, and the JSONP component in order to interact with Twitter’s search API.


    Top Level Variables, the Constructor and Namespacing

    Now we can begin adding some of the variables our widget will require, as well as adding the class constructor and namespace. Add the following code within the anonymous function:

    var Node = Y.Node,
        getClassName = Y.ClassNameManager.getClassName,
        i, j,
        baseClasses = ["_CLASS", "title", "loader", "viewer", "tweet", "ui", "label", "input", "button", "error"],
        templates = ["_TEMPLATE", "&lt;hgroup class={titleclass}>&lt;h1>{title}&lt;/h1>&lt;h2>{subtitle}&lt;span>{term}&lt;/span>&lt;/h2>&lt;/hgroup>", "&lt;div class={loaderclass}>loading...&lt;/div>", "&lt;div class={viewerclass}>&lt;/div>", "&lt;article>&lt;a href={userurl} title={username}>&lt;img src={avatar} alt={username} />&lt;h1>{username}&lt;/h1>&lt;/a>&lt;p>{text}&lt;/p>&lt;/article>", "&lt;div class={uiclass}>&lt;/div>", "&lt;label class={labelclass}>{labeltext}&lt;/label>", "&lt;input class={inputclass} />", "&lt;button class={buttonclass}>{buttontext}&lt;/button>", "&lt;p class={errorclass}>{message}&lt;/p>"];
    
    function TweetSearch(config) {
        TweetSearch.superclass.constructor.apply(this, arguments);
    }
    
    Y.namespace("DW").TweetSearch = TweetSearch;

    The name of our widget has the first letter of its name capitalized, as is the convention for naming constructors.

    First up, we cache references to the Y.Node component and the Y.ClassNameManager.getClassName() method as we’ll be using these frequently. We also define a couple of variables for use in the for loop, and create two new arrays; the first containing a series of strings that will form part of the class names added to the HTML elements our widget will create, and the second containing the HTML templates, also in string format, that will be used to create the elements themselves.

    Next we add the constructor function for our widget; this is the function that developers implementing our widget will call. The function can accept a single argument which will take the form of an object that sets configuration attributes exposed by our widget. The name of our widget has the first letter of its name capitalized, as is the convention for naming constructors. Within this function our widget’s class is initialised by using the apply() method of the superclass's (Widget) constructor. The value of this is set to our widget instance.

    We can also create a namespace for our widget using YUI’s namespace() method; this isn’t mandatory but it is a very good practice to run code within a namespace in order to minimize the possibility of naming collisions when code is used in the wild. The namespace() method accepts a string which represents the namespace, to which is attached the widget name as a property and the widget as the value.

    I’ve set the namespace to equal my initials but this can be anything you require; you may already have a namespace that all of your web apps reside in, or it could be the name of your company, the name of your client, or anything else that makes sense. This widget will be accessible via Y.DW.TweetSearch


    Static Properties

    Next, we can define the static constants required when extending the Widget class. Add the following code directly after the namespace() method:

    TweetSearch.NAME = "tweetsearch";
    
    for (i = 1, j = baseClasses.length; i < j; i++) {
        var current = baseClasses[i].toUpperCase(),
            prop1 = current + baseClasses[0],
            prop2 = current + templates[0];
    
        TweetSearch[prop1] = getClassName(TweetSearch.NAME, baseClasses[i]);
        TweetSearch[prop2] = templates[i];
    }

    First, we set the NAME property of our widget; the all-caps naming convention here signifies a value that will be constant throughout the life-cycle of our widget instance. The name we set is used by the widget as a prefix when firing events and creating class names for HTML elements.

    Next is the for loop we use to add the required class names and mark-up templates to our widget. We initialize the i and j variables that we declare at the top of the function; the i variable that is used as the counter is initially set to 1 instead of 0 as would usually be the case (you’ll see why in just a moment) and the j variable is set to the length of our baseClasses array (the baseClasses and templates arrays are both the same length as every element we create is given a class name. This may not always be the case).

    Within the loop we cache a reference to the current item from the baseClasses array and in upper case, and then create two new strings called prop1 and prop2. These strings consist of the variable we just created and the first item in our baseClasses array, so on the first iteration for example, this string will equal TITLE_CLASS for prop1 and TITLE_TEMPLATE for prop2.

    We then add these new properties to our widget instance; the first property is set to the result of calling the getClassName() method (remember, we’re using the cached short-cut we created earlier which points to Y.ClassNameManager.getClassName). We pass in the name of our widget as the first argument to this method, and the current item from the baseClasses array. This will result in generated class names such as yui3-tweetsearch-title, available fom the TweetSearch.TITLE_CLASS property for example.

    The second property we add is the current item from the templates array. Continuing with the title example this gives us a property name of TweetSearch.TITLE_TEMPLATE with a value of <hgroup class={titleclass}><h1>{title}</h1><h2>{subtitle} <span>{term}</span></h2></hgroup>. The purpose of the for loop is simply so that we don’t have to attach all of the classes and templates to our instance manually.


    Configurable Attributes with Sensible Defaults

    Now we can define the configurable attributes that our widget will have, which will enable developers implementing the widget to enable or disable different features. Add the following code directly after the for loop:

    TweetSearch.ATTRS = {
        term: {
            value: "yui3",
            validator: "_validateTerm"
        },
        numberOfTweets: {
            value: 5
        },
        baseURL: {
            value: "http://search.twitter.com/search.json?&with_twitter_user_id=true&include_entities=true&callback={callback}"
        },
        tweets: {
            value: null
        },
        showTitle: {
            value: true
        },
        showUI: {
            value: true
        },
    
        strings: {
            value: {
                title: "Twitter Search Widget",
                subTitle: "Showing results for:",
                label: "Search Term",
                button: "Search",
    		errorMsg: "I'm sorry, that search term did not return any results. Please try a different term"
            }
        }
    };

    The YUI library adds a consistent way to add attributes to any class or module.

    The ATTRS constant is used to store the configurable attributes that the implementing developer can set when creating an instance of the widget. The YUI library adds a consistent way to add attributes to any class or module, and this mechanism is automatically available when extending Widget.

    Instead of setting the value of each attribute to a simple native value like a sting or a Boolean, an object is used. The default for each attribute is set using the value property of this object. In the first attribute, we also make use of the validator property, which allows us to specify a function that will be automatically called whenever the value is updated. This enables us to check that the value is in a particular format, or matches other custom criteria. There are also a range of other properties we can set for each attribute including; custom get and set methods, whether the attribute is read-only, and more.

    The attributes used by our widget include the search term, the number of tweets to display, the baseURL of the request sent to Twitter, whether to show a title for the widget and whether to show the search UI. There are a number of other attributes our widget will automatically get, and which we can use. We’ll look at these in more detail later on in the tutorial.

    The final attribute we define is the strings attribute, which is available to all modules that subclass Widget. The value of this attribute is also an object and within this we add all of the text strings that our widget will display. Using an attribute to define any words that the widget needs to display in this way makes our widget super easy to internationalize; implementing developers need only to override the strings attribute with their own collection of strings in whichever language they choose.


    Built-in Support for Progressive Enhancement

    The Widget superclass furnishes us with the HTML_PARSER static property that can retrieve values from any HTML elements that are present within the widget’s container and use these values as attributes, which makes it incredibly easy for us to create widgets that transform underlying mark-up into something more functional and/or pretty.

    We don’t really need to worry about this for our widget; if JavaScript is disabled, no AJAX request will be made to Twitter’s search API and there will be no data to display in any case. However, they give implementing developers more ways of instantiating the widget and configuring attributes, we can make the provision that if a text <input> is present within the widget’s container, the value of the field will be used as the search term instead of the default attribute value. In order to retrieve this value we can make use of the HTML_PARSER; add the following code directly after the ATTRS definition:

    TweetSearch.HTML_PARSER = {
        term: function (srcNode) {
            var input = srcNode.one("input");
    
            if (input) {
                var val = input.get("value");
                    input.remove();
                }
    
                return val;
            }
        };

    The HTML_PARSER property is an object literal where each property within this object maps directly to an attribute. The only attribute that we wish to add progressive-enhancement support for is the term attribute, the value of which is set to a functional that will automatically be called when our widget is initialized.

    This function receives a single argument which is a referece to the srcNode attribute. This is one of the built-in attributes that all widgets automatically get access to and refers explicitly to the element that was passed into the constructor for our widget. This element becomes the content box for the widget.

    The first thing we do is try to select an <input> element from the srcNode using YUI’s one() method, which selects a single matching element from the DOM. If an element is retrieved, we store its value in a variable called val, and then remove the element from the page (we’ll create an alternative <input> element for when the search UI is enabled later). We then return val. If val is not set, i.e. if there wasn’t an <input> in the srcNode, underfined will be returned, and the term attribute will stay set to its configured value. If val does contain a value, it will become the value for the term attribute.


    Extending the Widget Class

    Before we end this part of the tutorial, we’ll take a look at the method we use to extend the Widget class with the functionality specific to our widget. This method will form the bulk of our widget. Directly after the HTML_PARSER add the following:

    TweetSearch = Y.extend(TweetSearch, Y.Widget, {
    
    });

    The YUI extend() method takes three arguments:

    Save this file in the js folder as tweet-search.js.


    Summary

    In this part of the tutorial we setup some of the required scaffolding for our new widget. Although the widget won’t actually do anything at this stage, it can still be initialised and we can see some of the container that is automatically added by the YUI library, and look in the DOM tab of Firebug to see the attributes it has inherited.

    After defining some top-level variables, we first saw how to define the constructor function for our widget so that the widget can be initialized by the library, as well as seeing how easy it is to namespace our widget. We then looked at the static constants that are inherited from the underlying Widget class that we are extending. These included the NAME of the widget, the _CLASS and _TEMPLATE collections and the ATTRS object, the latter of which allowed us to set the attributes that an implementing developer can override if they so wish.

    We also looked momentarily at the extend() method which is used to add the prototype methods to our widget’s class in order to implement that custom functionality it provides. This custom functionality will be the subject of the next part of this tutorial.

    Stay tuned and thank you so much for reading!


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