<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Mike G in NYC</title>
	
	<link>http://www.lovemikeg.com/blog</link>
	<description>Mike G's Thoughts on the Web, Code, and Life in The City</description>
	<pubDate>Sat, 30 Aug 2008 15:54:40 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<geo:lat>28.607077</geo:lat><geo:long>-81.30606</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/lovemikeg" type="application/rss+xml" /><item>
		<title>A Week in JavaScript Patterns: Lazy Function Definition</title>
		<link>http://feeds.feedburner.com/~r/lovemikeg/~3/370869265/</link>
		<comments>http://www.lovemikeg.com/blog/2008/08/21/a-week-in-javascript-patterns-lazy-function-definition/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 11:53:06 +0000</pubDate>
		<dc:creator>mikeg</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.lovemikeg.com/blog/?p=205</guid>
		<description><![CDATA[Lazy Function Definition is a pattern of functional JavaScript programming, similar to Load Time Configuration. The key difference is that the final function value isn&#8217;t configured at load time, but rather upon the first invocation of the function.
The Lazy Function Definition pattern was discovered and named by Peter Michaux.
Motivation
Generally there are two main reasons for [...]]]></description>
			<content:encoded><![CDATA[<p>Lazy Function Definition is a pattern of functional JavaScript programming, similar to <a href="/blog/2008/08/18/a-week-in-javascript-patterns-load-time-configuration/">Load Time Configuration</a>. The key difference is that the final function value isn&#8217;t configured at load time, but rather upon the first invocation of the function.</p>
<p>The Lazy Function Definition pattern was discovered and named by <a href="http://peter.michaux.ca/article/3556">Peter Michaux</a>.</p>
<h3>Motivation</h3>
<p>Generally there are two main reasons for wanting to defer defining functions until a later time (although with any pattern, many other applications exist):</p>
<ol>
<li>Resources required for a function to be fully defined are not available until the page fully loads or until a user-driven event (for example, determining page scroll).</li>
<li>The resources created by defining the function are particularly taxing and may not even be needed (for example <a href="http://mattsnider.com/javascript/xbrowser-event-handling/">attaching event handlers</a>).</li>
</ol>
<h3>Implementation</h3>
<p>The Lazy Function Definition solves these problems by defining resources upon the first invocation of the function and then redefining itself so that they are not recreated during subsequent calls. All resources are stored via closure so they remain available to the inner function (which becomes the new definition for the outer function).</p>
<pre class="prettyprint">
var getResource = function () {
    var resource, counter;

    resource = 'foo';
    counter = 0;

    getResource = function () {
        return resource + ' has been accessed ' + (++counter) + ' times';
    };

    return getResource();
};
</pre>
<p>In the code above, a <samp>getResource</samp> function is defined. When the function is called the first time, <samp>resource</samp> and <samp>counter</samp> are created to store important information which is needed in future calls to <samp>getResource</samp>. </p>
<p>The function which immediately follows <em>redefines</em> the original <samp>getResource</samp> function, but because resource <samp>resource</samp> and <samp>counter</samp> are defined in the same scope as the inner function, they remain available.</p>
<p>Finally, the new <samp>getResource</samp> is executed and it&#8217;s value is returned. Now any future calls to <samp>getResource</samp> will use the inner function. </p>
<h3>Conclusion</h3>
<p>The Lazy Function Definition pattern allows for deferred function definition as well as insuring that resources that only need to be created once, are created once.</p>
<ul>
<li><strong>Sunday:</strong> <a href="/blog/2008/08/17/a-week-in-javascript-patterns-self-invocation/">Self-invocation</a></li>
<li><strong>Monday:</strong> <a href="/blog/2008/08/18/a-week-in-javascript-patterns-load-time-configuration/">Load Time Configuration</a></li>
<li><strong>Tuesday:</strong> <a href="/blog/2008/08/19/a-week-in-javascript-patterns-the-module/">The Module</a></li>
<li><strong>Wednesday:</strong> Lazy Function Definition</li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/lovemikeg?a=vfb9uK"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=vfb9uK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=2fPQAK"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=2fPQAK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=gkMbgK"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=gkMbgK" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/lovemikeg/~4/370869265" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.lovemikeg.com/blog/2008/08/21/a-week-in-javascript-patterns-lazy-function-definition/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.lovemikeg.com/blog/2008/08/21/a-week-in-javascript-patterns-lazy-function-definition/</feedburner:origLink></item>
		<item>
		<title>A Week in JavaScript Patterns: The Module</title>
		<link>http://feeds.feedburner.com/~r/lovemikeg/~3/369622112/</link>
		<comments>http://www.lovemikeg.com/blog/2008/08/19/a-week-in-javascript-patterns-the-module/#comments</comments>
		<pubDate>Wed, 20 Aug 2008 03:55:34 +0000</pubDate>
		<dc:creator>mikeg</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.lovemikeg.com/blog/?p=198</guid>
		<description><![CDATA[The Module is a brilliant design pattern which demonstrates the elegance of the JavaScript language by exploiting closure (one of JavaScript&#8217;s most powerful features) to create private members. The Module makes use of Self-invocation making it useful as an application wrapper.
This pattern was originally discovered and named by Douglas Crockford.
Motivation
By default, there is no natural [...]]]></description>
			<content:encoded><![CDATA[<p>The Module is a brilliant design pattern which demonstrates the elegance of the JavaScript language by exploiting closure (one of JavaScript&#8217;s most powerful features) to create private members. The Module makes use of <a href="/blog/2008/08/17/a-week-in-javascript-patterns-self-invocation/">Self-invocation</a> making it useful as an application wrapper.</p>
<p>This pattern was originally discovered and named by <a href="http://crockford.com">Douglas Crockford</a>.</p>
<h3>Motivation</h3>
<p>By default, there is no natural data hiding functionality in the JavaScript language. As developers push the limits by continually creating more complex applications, the need for private object members becomes increasingly apparent.</p>
<h3>Implementation</h3>
<p>Modules are simply a standard self-invoking function who&#8217;s return value is an object of properties and methods which serve as a public API. In the example below, <samp>foo.bar</samp> is not being set to the value of the anonymous function but rather the object that is returned by the anonymous function.</p>
<pre class="prettyprint">
foo.bar = (function () {
    var baz = function () {};
    var bif = function () {};

    return {
        'thud' : function () {},
        'grunt' : function () {}
    };
})();
</pre>
<p><samp>foo.bar</samp> now has an object as its value which contains two methods: <samp>thud</samp> and <samp>grunt</samp>. <samp>baz</samp> and <samp>bif</samp> are not available publicly, however <samp>thud</samp> and <samp>grunt</samp> still have direct access to them through <a href="http://en.wikipedia.org/wiki/Closure_(computer_science)">closure</a>.</p>
<h4>Understanding Closure</h4>
<p>Closure is a byproduct of <a href="http://en.wikipedia.org/wiki/Functional_Programming">functional programming</a> whereby inner functions have access to local variables defined within an outer function, even after the outer function has returned.</p>
<p>There are several important facts to understand:</p>
<ol>
<li>Functions can contain other functions, just like any other variable. These are <em>inner functions</em>.</li>
<li>Anything not returned by the outer function will not be directly available, however it still exists and is available to any inner functions that shared the same scope.</li>
</ol>
<h3>Conclusion</h3>
<p>With the ability to implement public and private members in an API, developers now have the ability to create robust APIs in JavaScript. This allows developers to create powerful applications while exposing only what is necessary to make it function.</p>
<p>The Module also introduces the concept of closure. This is an  extremely powerful concept of JavaScript which is a result of its functional nature. Future patterns in this series will make heavy use of closure in order to better understand its power and to show the various ways it can be applied.</p>
<h3>Posts in this Series</h3>
<ul>
<li><strong>Sunday:</strong> <a href="/blog/2008/08/17/a-week-in-javascript-patterns-self-invocation/">Self-invocation</a></li>
<li><strong>Monday:</strong> <a href="/blog/2008/08/18/a-week-in-javascript-patterns-load-time-configuration/">Load Time Configuration</a></li>
<li><strong>Tuesday:</strong> The Module</li>
<li><strong>Wednesday:</strong> <a href="/blog/2008/08/21/a-week-in-javascript-patterns-lazy-function-definition/">Lazy Function Definition</a></li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/lovemikeg?a=ojHFTK"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=ojHFTK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=h5FZQK"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=h5FZQK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=l48TRK"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=l48TRK" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/lovemikeg/~4/369622112" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.lovemikeg.com/blog/2008/08/19/a-week-in-javascript-patterns-the-module/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.lovemikeg.com/blog/2008/08/19/a-week-in-javascript-patterns-the-module/</feedburner:origLink></item>
		<item>
		<title>A Week in JavaScript Patterns: Load Time Configuration</title>
		<link>http://feeds.feedburner.com/~r/lovemikeg/~3/368624856/</link>
		<comments>http://www.lovemikeg.com/blog/2008/08/18/a-week-in-javascript-patterns-load-time-configuration/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 02:12:21 +0000</pubDate>
		<dc:creator>mikeg</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.lovemikeg.com/blog/?p=175</guid>
		<description><![CDATA[Load time configuration is the process where a JavaScript application configures itself as it is being loaded. This pattern is most commonly found in libraries in which they configure themselves at load time to be optimized for a particular browser.
Load time configuration is also known as load time branching.
Motivation
The primary motivation behind load time configuration [...]]]></description>
			<content:encoded><![CDATA[<p>Load time configuration is the process where a JavaScript application configures itself as it is being loaded. This pattern is most commonly found in libraries in which they configure themselves at load time to be optimized for a particular browser.</p>
<p>Load time configuration is also known as load time branching.</p>
<h3>Motivation</h3>
<p>The primary motivation behind load time configuration is to optimize conditional operations such as generating XMLHttpRequest instances or adding event listeners. Since both operations vary amongst clients, specific conditions must be checked before proceeding. The load time configuration pattern runs once at load time and sets the resulting value so that it doesn&#8217;t need to be checked again.</p>
<h3>Implementation</h3>
<p>The most common technique for implementing load time configuration is by way of a <a href="http://www.lovemikeg.com/blog/2008/08/17/a-week-in-javascript-patterns-self-invocation/">Self-invoking function</a> which returns the correctly configured value.</p>
<p>The example below demonstrates how load time configuration can be used to normalize getting an XMLHttpRequest object.</p>
<pre class="prettyprint">
var getXHR = (function () {
    if (window.XMLHttpRequest) {
        return function () {
            return new XMLHttpRequest;
        }
    }
    else if (window.ActiveXObject) {
        return function () {
            /* Msxml2 and Msxml3 checkes have been omitted
             * for simplicity's sake */
            return new ActiveXObject('Microsoft.XMLHTTP');
        }
    }
})();
</pre>
<p>First, a <samp>getXHR</samp> variable is declared and it&#8217;s value is being assigned by the self-invoking function that follows. Upon execution, a conditional is run which determines the correct method of obtaining an XMLHttpRequest object. When a match is found, a wrapper function is returned and stored as the value for <samp>getXHR</samp> variable.</p>
<h3>Conclusion</h3>
<p>The load time conditional pattern is used to configure a conditional value at load time. The result is a fully optimized value, specific to the the environment in which it is to be used.</p>
<h3>Posts in this Series</h3>
<ul>
<li><strong>Sunday:</strong> <a href="/blog/2008/08/17/a-week-in-javascript-patterns-self-invocation/">Self-invocation</a></li>
<li><strong>Monday:</strong> Load Time Configuration</li>
<li><strong>Tuesday:</strong> <a href="/blog/2008/08/19/a-week-in-javascript-patterns-the-module/">The Module</a></li>
<li><strong>Wednesday:</strong> <a href="/blog/2008/08/21/a-week-in-javascript-patterns-lazy-function-definition/">Lazy Function Definition</a></li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/lovemikeg?a=AoaZXK"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=AoaZXK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=rnaj3K"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=rnaj3K" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=USH6iK"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=USH6iK" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/lovemikeg/~4/368624856" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.lovemikeg.com/blog/2008/08/18/a-week-in-javascript-patterns-load-time-configuration/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.lovemikeg.com/blog/2008/08/18/a-week-in-javascript-patterns-load-time-configuration/</feedburner:origLink></item>
		<item>
		<title>A Week in JavaScript Patterns: Self-invocation</title>
		<link>http://feeds.feedburner.com/~r/lovemikeg/~3/367424588/</link>
		<comments>http://www.lovemikeg.com/blog/2008/08/17/a-week-in-javascript-patterns-self-invocation/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 18:20:02 +0000</pubDate>
		<dc:creator>mikeg</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.lovemikeg.com/blog/?p=156</guid>
		<description><![CDATA[I would like to begin this series of posts with one of the most useful and commonplace patterns in my code. Arguably, this can be considered a feature of the JavaScript language rather than a design pattern; however, when considering the contexts in which it is applied, I regard it as a pattern.
Self-invocation (also known [...]]]></description>
			<content:encoded><![CDATA[<p>I would like to begin this series of posts with one of the most useful and commonplace patterns in my code. Arguably, this can be considered a feature of the JavaScript language rather than a design pattern; however, when considering the contexts in which it is applied, I regard it as a pattern.</p>
<p>Self-invocation (also known as auto-invocation) is when a function executes immediately upon it&#8217;s definition. This is a core pattern and serves as the foundation for many other patterns of JavaScript development. </p>
<h3>Motivation</h3>
<p>The primary motivation behind self-invoking functions is to create scope. In JavaScript, only functions have scope. Any time variables are defined outside of a function, they are carelessly dumped into the global object. </p>
<h3>Implementation</h3>
<p>A self-invoking function is a standard function, just with a set of parentheses appended to the end.</p>
<pre class="prettyprint">
function () {
    var foo = 'Hello';
    var bar = 'world';
    var baz = [foo, bar];
    alert(baz.join(', '));
}();
</pre>
<p>The above example defines an anonymous function. This creates a literal function, yet since no name is attributed to it, the value is never stored. The trailing parenthesis tell the function to execute, just as if you were calling a named function.</p>
<p>Upon execution, the above function creates three variables, formats them, and alerts them to the user. Once the function terminates, the variables are discarded and the global object remains unchanged.</p>
<h4>Distinguishing from Actual Functions</h4>
<p>Given the oddness of the pattern (and lack of widespread understanding), it is very possible for developers to misinterpret this pattern as an actual function. It it <a href="http://peter.michaux.ca/article/8117">recommended</a> that an extra set of parentheses wrap the function definition as well so to provide a visual clue to the developer that the function isn&#8217;t a normal function. The result would be as follows.</p>
<pre class="prettyprint">
(function () {

    var foo = 'Hello';
    var bar = 'world';
    var baz = [foo, bar];
    alert(baz.join(', '));

})();
</pre>
<h4>Passing Parameters</h4>
<p>In the event where a self-invoking function requires parameters, they can be passed in the same manor that you would a regular function.</p>
<p>The following example applies an &#8220;negative&#8221; class on every input element who&#8217;s numeric value is below 0.</p>
<pre class="prettyprint">
(function (elements) {

    for (var i = 0; i < elements.length; i++) {
        if ((elements[i].value * 1) < 0) {
            elements[i].className = 'negative';
        }
    };

})(document.getElementsByTagName('input'));
</pre>
<h4>Executing in Another Scope</h4>
<p>Even though the function is executing within its own local scope, the <samp>this</samp> keyword will still refer to the global object. </p>
<p>The following example uses the <samp>Function.call()</samp> method to execute a self-invoking function within the scope of the first table element on the page.</p>
<pre class="prettyprint">
(function (elements) {

    for (var i = 5; i < this.rows.length; i++) {
        this.rows[i].className = 'hide';
    }

}).call(document.getElementsByTagName('table')[0]);
</pre>
<h3>Conclusion</h3>
<p>In an effort to protect the global object, all JavaScript applications should be written within a self-invoking function. This will create an application scope in which variables can be created without the fear of them colliding with other applications.</p>
<p>If a global variable is needed, developers must take the extra step by setting them directly within the window object. For example <samp>window.foo = &#8216;bar&#8217;;</samp>. </p>
<p>Self-invocation is a fundamental pattern of professional JavaScript development. Nearly every pattern in this weeks catalog uses it as a base to create scope, closure, or to configure cross-platform objects on-the-fly.</p>
<p>Stay tuned folks. This will be a good week.</p>
<h3>Posts in this Series</h3>
<ul>
<li><strong>Sunday:</strong> Self-invocation</li>
<li><strong>Monday:</strong> <a href="/blog/2008/08/18/a-week-in-javascript-patterns-load-time-configuration/">Load Time Configuration</a></li>
<li><strong>Tuesday:</strong> <a href="/blog/2008/08/19/a-week-in-javascript-patterns-the-module/">The Module</a></li>
<li><strong>Wednesday:</strong> <a href="/blog/2008/08/21/a-week-in-javascript-patterns-lazy-function-definition/">Lazy Function Definition</a></li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/lovemikeg?a=fbXNqK"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=fbXNqK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=451X3K"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=451X3K" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=OM7aSK"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=OM7aSK" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/lovemikeg/~4/367424588" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.lovemikeg.com/blog/2008/08/17/a-week-in-javascript-patterns-self-invocation/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.lovemikeg.com/blog/2008/08/17/a-week-in-javascript-patterns-self-invocation/</feedburner:origLink></item>
		<item>
		<title>Ajax for PHP Developers</title>
		<link>http://feeds.feedburner.com/~r/lovemikeg/~3/346684831/</link>
		<comments>http://www.lovemikeg.com/blog/2008/07/26/ajax-for-php-developers/#comments</comments>
		<pubDate>Sat, 26 Jul 2008 15:45:03 +0000</pubDate>
		<dc:creator>mikeg</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Talks]]></category>

		<guid isPermaLink="false">http://www.lovemikeg.com/blog/?p=114</guid>
		<description><![CDATA[Earlier this week I gave an Ajax presentation for NYPHP. It felt a little strange presenting a JavaScript topic to a bunch of PHP developers, but I made it come back to PHP by demonstrating a the latest Panda PHP package which is only in incubation at the moment. (I&#8217;ll formally announce that in a [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this week I gave an Ajax presentation for <a href="http://nyphp.org/">NYPHP</a>. It felt a little strange presenting a JavaScript topic to a bunch of PHP developers, but I made it come back to PHP by demonstrating a the latest <a href="http://pandaphp.org/">Panda PHP</a> package which is only in incubation at the moment. (I&#8217;ll formally announce that in a few weeks. Until then, you&#8217;ll have to come to more NYPHP meetings!)</p>
<p>This was my first presentation at NYPHP. It was also the first time I ever went to a formal meeting where we didn&#8217;t just network and drink beer (although there was plenty of that following the presentation).</p>
<p>You can <a href="http://www.slideshare.net/mgirouard/ajax-for-php-developers">view</a> or <a href="http://www.slideshare.net/signup?from_source=http%3A%2F%2Fwww.slideshare.net%2Fmgirouard%2Fajax-for-php-developers&#038;from=download">download</a> the presentation at Slideshare. I also have the <a href="/downloads/talks/Ajax-for-PHP-Developers/code.zip">sample code</a> which I used to demonstrate my concepts.</p>
<p>Enjoy.</p>
<div style="width:425px;text-align:left" id="__ss_524853"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/mgirouard/ajax-for-php-developers?src=embed" title="Ajax for PHP Developers">Ajax for PHP Developers</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=ajax-for-php-developers-1216780112990882-8"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=ajax-for-php-developers-1216780112990882-8" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">view <a href="http://www.slideshare.net/mgirouard/ajax-for-php-developers?src=embed" title="View Ajax for PHP Developers on SlideShare">presentation</a> (tags: <a style="text-decoration:underline;" href="http://slideshare.net/tag/nyphp">nyphp</a> <a style="text-decoration:underline;" href="http://slideshare.net/tag/php">php</a> <a style="text-decoration:underline;" href="http://slideshare.net/tag/ajax">ajax</a>)</div>
</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/lovemikeg?a=aFT3FJ"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=aFT3FJ" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=C5OwCJ"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=C5OwCJ" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=UBhw3J"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=UBhw3J" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/lovemikeg/~4/346684831" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.lovemikeg.com/blog/2008/07/26/ajax-for-php-developers/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.lovemikeg.com/blog/2008/07/26/ajax-for-php-developers/</feedburner:origLink></item>
		<item>
		<title>JavaScript from Scratch: Parts Three and Four</title>
		<link>http://feeds.feedburner.com/~r/lovemikeg/~3/322960062/</link>
		<comments>http://www.lovemikeg.com/blog/2008/06/29/javascript-from-scratch-parts-three-and-four/#comments</comments>
		<pubDate>Mon, 30 Jun 2008 03:59:45 +0000</pubDate>
		<dc:creator>mikeg</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[events]]></category>

		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://www.lovemikeg.com/blog/?p=113</guid>
		<description><![CDATA[I&#8217;ve uploaded two additional talks which I recently gave covering the basics of events and application development in JavaScript. This continues on with the talks I added earlier this month.
Part Three: Events

 &#124; View &#124; Upload your own

Part Four: Writing JavaScript Applications

 &#124; View &#124; Upload your own

Other Posts in this Series

JavaScript From Scratch: Parts [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve uploaded two additional talks which I recently gave covering the basics of events and application development in JavaScript. This continues on with the <a href="http://www.lovemikeg.com/blog/2008/06/07/javascript-from-scratch-parts-one-and-two/">talks I added</a> earlier this month.</p>
<h3>Part Three: Events</h3>
<div id="__ss_459948" style="width:425px;text-align:left"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=events-1213149665824329-8" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slideshare.net/swf/ssplayer2.swf?doc=events-1213149665824329-8" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><a href="http://www.slideshare.net/?src=embed"><img style="border:0px none;margin-bottom:-5px" src="http://static.slideshare.net/swf/logo_embd.png" alt="SlideShare" /></a> | <a title="View JavaScript From Scratch: Events on SlideShare" href="http://www.slideshare.net/mgirouard/javascript-from-scratch-events?src=embed">View</a> | <a href="http://www.slideshare.net/upload?src=embed">Upload your own</a></div>
</div>
<h3>Part Four: Writing JavaScript Applications</h3>
<div id="__ss_492158" style="width:425px;text-align:left"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=writing-javascript-applications-1214797250451651-9" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slideshare.net/swf/ssplayer2.swf?doc=writing-javascript-applications-1214797250451651-9" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><a href="http://www.slideshare.net/?src=embed"><img style="border:0px none;margin-bottom:-5px" src="http://static.slideshare.net/swf/logo_embd.png" alt="SlideShare" /></a> | <a title="View JavaScript From Scratch: Writing Java Script Applications on SlideShare" href="http://www.slideshare.net/mgirouard/javascript-from-scratch-writing-java-script-applications?src=embed">View</a> | <a href="http://www.slideshare.net/upload?src=embed">Upload your own</a></div>
</div>
<h3>Other Posts in this Series</h3>
<ul>
<li><a href="http://www.lovemikeg.com/blog/2008/06/07/javascript-from-scratch-parts-one-and-two/">JavaScript From Scratch: Parts One and Two</a></li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/lovemikeg?a=CHWq8I"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=CHWq8I" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=5TO59I"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=5TO59I" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=LmXf7I"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=LmXf7I" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/lovemikeg/~4/322960062" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.lovemikeg.com/blog/2008/06/29/javascript-from-scratch-parts-three-and-four/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.lovemikeg.com/blog/2008/06/29/javascript-from-scratch-parts-three-and-four/</feedburner:origLink></item>
		<item>
		<title>Improving the Module</title>
		<link>http://feeds.feedburner.com/~r/lovemikeg/~3/314340749/</link>
		<comments>http://www.lovemikeg.com/blog/2008/06/17/improving-the-module/#comments</comments>
		<pubDate>Wed, 18 Jun 2008 04:52:27 +0000</pubDate>
		<dc:creator>mikeg</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[the module]]></category>

		<guid isPermaLink="false">http://www.lovemikeg.com/blog/?p=111</guid>
		<description><![CDATA[
Update: In my code example below, I make use of a self variable. This probably isn&#8217;t the best idea in hindsight since JavaScript reserves self as a secondary reference to window. 

I’m always fascinated by the JavaScript language. What impressed me most, almost a year ago, was my discovery of Douglas Crockford’s module pattern. This [...]]]></description>
			<content:encoded><![CDATA[<div class="update">
<p><strong>Update:</strong> In my code example below, I make use of a <samp>self</samp> variable. This probably isn&#8217;t the best idea in hindsight since JavaScript reserves <samp>self</samp> as a secondary reference to <samp>window</samp>. </p>
</div>
<p>I’m always fascinated by the JavaScript language. What impressed me most, almost a year ago, was my discovery of Douglas Crockford’s module pattern. This was my first taste of what I consider to be the most intriguing thing in programming: <a href="http://en.wikipedia.org/wiki/Closure_%28computer_science%29">closure</a>. I didn’t understand the concept of closures when I first saw it, but after getting deeper and deeper into the language, it finally clicked. At that point I realized the potential of this type of language.</p>
<p>A few days ago, Peter posted his list of <a href="http://peter.michaux.ca/article/7933">JavaScript warning words</a>. To my surprise, &#8220;this&#8221; made the list.</p>
<p>Don’t get me wrong, I’m well aware of JavaScripts scoping issues, but it was still startling to see such a common element of my code sitting next to words like with, void, and eval.</p>
<p>He&#8217;s right though. If you&#8217;re not careful, &#8220;this&#8221; could quickly become problematic. For example, a constructor method declared without &#8220;new&#8221; would result in &#8220;this&#8221; being a reference to window and not the newly created object&#8230; oops.</p>
<p>This also becomes a problem when you use &#8220;this&#8221; in callbacks used for events. When methods are applied as event handlers, &#8220;this&#8221; generally refers to the element on which the event was applied &#8212; not the object that the function lives in when you write the code.</p>
<p>Peter advocates the use of closure as a means to reduce dependency on &#8220;this.&#8221; Today, I discovered an interesting pattern which does just that. Instead of relying on the ambiguous &#8220;this&#8221;, the following code creates a &#8220;self&#8221; variable in the module which is available in the inner functions as a replacement for &#8220;this&#8221;.</p>
<pre class="prettyprint">
var mikeg = function () {
    /* Create an internal reference to self as a replacement for this */
    var self = {};

    /* Return out self and some methods which have access to itself */
    return self = {
        SomeConstructor : function () {
            console.log(window !== this);
            console.log(self === mikeg);
        },

        someCallback : function () {
            console.log(window !== this);
            console.log(self === mikeg);
        }
    };
}();
</pre>
<p>It seems so obvious now that my fingers have found their way toward this code, but then again, isn&#8217;t that always the case? Looking back, I&#8217;m sure I&#8217;ve seen this elseware, but much like my original discovery of the Module, it didn&#8217;t click until after a little while.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/lovemikeg?a=2ocyJI"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=2ocyJI" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=OGwYDI"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=OGwYDI" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=pdMDWI"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=pdMDWI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/lovemikeg/~4/314340749" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.lovemikeg.com/blog/2008/06/17/improving-the-module/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.lovemikeg.com/blog/2008/06/17/improving-the-module/</feedburner:origLink></item>
		<item>
		<title>JavaScript from Scratch: Parts One and Two</title>
		<link>http://feeds.feedburner.com/~r/lovemikeg/~3/307165489/</link>
		<comments>http://www.lovemikeg.com/blog/2008/06/07/javascript-from-scratch-parts-one-and-two/#comments</comments>
		<pubDate>Sun, 08 Jun 2008 04:39:21 +0000</pubDate>
		<dc:creator>mikeg</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Talks]]></category>

		<guid isPermaLink="false">http://www.lovemikeg.com/blog/?p=108</guid>
		<description><![CDATA[I&#8217;ve put together a series of eight talks which covers the basics of the JavaScript language. Below are the first two which handle most of the introductory material. Next week, I will post two more which cover the event model and writing JavaScript applications. The week following that, will be an overview of the DOM [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve put together a series of eight talks which covers the basics of the JavaScript language. Below are the first two which handle most of the introductory material. Next week, I will post two more which cover the event model and writing JavaScript applications. The week following that, will be an overview of the DOM and object-oriented JavaScript. In the last week I will post talks which cover AJAX and JavaScript best practices</p>
<p>This whole series presents a basic set of knowledge that I think any front-end developer should know.</p>
<h3 id="part-one">Part One: Getting Your Feet Wet</h3>
<p>This talk talks about the four basic building blocks of programming: variables, conditionals, loops and functions.</p>
<div id="__ss_445794" style="width:425px;text-align:left"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=getting-your-feed-wet-1212552357322016-9" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slideshare.net/swf/ssplayer2.swf?doc=getting-your-feed-wet-1212552357322016-9" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><a href="http://www.slideshare.net/?src=embed"><img style="border:0px none;margin-bottom:-5px" src="http://static.slideshare.net/swf/logo_embd.png" alt="SlideShare" /></a> | <a title="View JavaScript from Scratch: Getting Your Feet Wet on SlideShare" href="http://www.slideshare.net/mgirouard/getting-your-feed-wet?src=embed">View</a> | <a href="http://www.slideshare.net/upload?src=embed">Upload your own</a></div>
</div>
<h3 id="part-two">Part Two: Playing With Data</h3>
<p>This talk details the data types available in JavaScript applications. Strings, Numbers, Booleans, Arrays, and Objects are discussed. Functions as values has been omitted until a later talk.</p>
<div id="__ss_450597" style="width:425px;text-align:left"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=playing-with-data-1212720095504612-8" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slideshare.net/swf/ssplayer2.swf?doc=playing-with-data-1212720095504612-8" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><a href="http://www.slideshare.net/?src=embed"><img style="border:0px none;margin-bottom:-5px" src="http://static.slideshare.net/swf/logo_embd.png" alt="SlideShare" /></a> | <a title="View Playing With Data on SlideShare" href="http://www.slideshare.net/mgirouard/playing-with-data?src=embed">View</a> | <a href="http://www.slideshare.net/upload?src=embed">Upload your own</a></div>
</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/lovemikeg?a=1WjxZI"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=1WjxZI" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=MUDdMI"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=MUDdMI" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=XLEEWI"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=XLEEWI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/lovemikeg/~4/307165489" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.lovemikeg.com/blog/2008/06/07/javascript-from-scratch-parts-one-and-two/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.lovemikeg.com/blog/2008/06/07/javascript-from-scratch-parts-one-and-two/</feedburner:origLink></item>
		<item>
		<title>Come See Me Speak at AJAXWorld West</title>
		<link>http://feeds.feedburner.com/~r/lovemikeg/~3/283608246/</link>
		<comments>http://www.lovemikeg.com/blog/2008/05/04/come-see-me-speak-at-ajaxworld-west/#comments</comments>
		<pubDate>Mon, 05 May 2008 01:24:04 +0000</pubDate>
		<dc:creator>mikeg</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[Talks]]></category>

		<category><![CDATA[conference]]></category>

		<category><![CDATA[talk]]></category>

		<guid isPermaLink="false">http://www.lovemikeg.com/blog/?p=106</guid>
		<description><![CDATA[Please excuse the break in my MVC series, I just want to announce that one of my talks has been accepted for AJAXWorld 2008 West. I will be presenting on The Beauty of JavaScript &#8212; a topic of great interest to me as of late.
If you want to see me speak, see if you can [...]]]></description>
			<content:encoded><![CDATA[<p>Please excuse the break in my MVC series, I just want to announce that one of my talks has been accepted for <a href="http://www.ajaxworld.com/">AJAXWorld 2008 West</a>. I will be presenting on <em>The Beauty of JavaScript</em> &#8212; a topic of great interest to me <a href="http://www.lovemikeg.com/blog/2007/09/22/barcamp-orlando-slides/">as of late</a>.</p>
<p>If you want to see me speak, see if you can get your boss to pay for your fare. The lineup for the recent AJAXWorld East was pretty phenomenal (<a href="http://crockford.com/">Doug Crockford</a> gave the keynote&#8230; need I say more?) and I&#8217;m certain this event will be even better. If you can&#8217;t get your boss to flip the bill, submit a proposal. At the time of this writing <a href="http://www.ajaxworld.com/general/papers.htm">the CFP is still open</a>.</p>
<p>For those of you who are interested, my session abstract is as follows:</p>
<h3>The Beauty of JavaScript</h3>
<blockquote><p>
JavaScript is one of the most interesting and misunderstood programming languages in common use today. Most developers will go their entire careers without realizing its full potential. It&#8217;s not often that you get a language that supports the feature set that JavaScript does, while still being as widely deployed. This talk will spotlight some some patterns surrounding JavaScript&#8217;s most elegant features such as closures, lambdas, object and array literals, object prototypes, private members and dynamic scope resolution &#8212; all without boring you to tears.
</p></blockquote>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/lovemikeg?a=j3TSIH"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=j3TSIH" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=VCDiuH"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=VCDiuH" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=8iFJFH"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=8iFJFH" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/lovemikeg/~4/283608246" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.lovemikeg.com/blog/2008/05/04/come-see-me-speak-at-ajaxworld-west/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.lovemikeg.com/blog/2008/05/04/come-see-me-speak-at-ajaxworld-west/</feedburner:origLink></item>
		<item>
		<title>Rolling Your Own MVC: The View</title>
		<link>http://feeds.feedburner.com/~r/lovemikeg/~3/279164314/</link>
		<comments>http://www.lovemikeg.com/blog/2008/04/28/rolling-your-own-mvc-the-view/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 05:31:23 +0000</pubDate>
		<dc:creator>mikeg</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Design Patterns]]></category>

		<category><![CDATA[mvc]]></category>

		<category><![CDATA[oop]]></category>

		<guid isPermaLink="false">http://www.lovemikeg.com/blog/?p=100</guid>
		<description><![CDATA[Welcome to the third part of my series on MVC framework development. In the previous two articles, I discussed the general feature set that our framework will have and I also gave an overview of the page load scenario. In today&#8217;s episode I am going to switch gears and discuss a single component of the [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome to the third part of my series on MVC framework development. In the previous two articles, I <a href="http://www.lovemikeg.com/blog/2008/02/21/rolling-your-own-mvc-introduction/">discussed the general feature set</a> that our framework will have and I also <a href="http://www.lovemikeg.com/blog/2008/04/07/rolling-your-own-mvc-the-page-load-scenario/">gave an overview of the page load scenario</a>. In today&#8217;s episode I am going to switch gears and discuss a single component of the framework in detail: the view. </p>
<p>Using the view as a starting point may seem odd at first considering the view-related actions are some of the last steps in the page load scenario, but since our views don&#8217;t have any external dependencies, unit tests are very easy to write and so is the accompanying code.</p>
<p>Views in an MVC are responsible for everything presentational. This means that if it gets sent to the browser, it is the view&#8217;s job to handle it. Views must also also incredibly versatile. For example: if a client makes a request and asks for JSON instead of the default HTML, the framework should be able to accommodate this request. Likewise, if the client prefers to consume XML data, it should be able to handle that as well. Furthermore, views shouldn&#8217;t be confined to just a web-based output. There&#8217;s no reason why we couldn&#8217;t use the majority of our code to build a command-line application.  </p>
<p>The code presented in this article will cover views that emit raw (serialized) PHP, JSON, XML, and HTML. We&#8217;ll start by looking at the functions which make up the core API to be shared by all view classes. Both an interface and an abstract class are provided for an example implementation. Following that, examples of concrete views will be demonstrated to show the flexibility of this method of handling views.</p>
<h3>How Views Work</h3>
<p>The easiest way to understand views is to think of them as classes whose sole purpose is to render data. A view&#8217;s core API consists of only a few simple methods which allow for data to be manipulated and also a method which renders it out to the client.</p>
<p>During the execution stage of the page load scenario, the controller will populate the view&#8217;s internal data store with data from the model. Having its own data independent from that of the model&#8217;s allows it to be restructured, modified, escaped, etc. without destroying the original data.</p>
<h3>The View Interface</h3>
<p>The code that follows defines an interface which is to be implemented by all view classes. Any components that interact with view classes will expect these methods.</p>
<pre class="prettyprint">interface Panda_View_Interface
{
    public function getVar($name);
    public function setVar($name, $value);
    public function unsetVar($name);
    public function getData();
    public function setData(array $data);
    public function setEchoOutput($bool);
    public function render();
}
</pre>
<p>The <samp>getVar</samp>, <samp>setVar</samp>, <samp>unsetVar</samp>, <samp>getData</samp> and <samp>setData</samp> methods all deal with modifying the view&#8217;s internal data. <samp>setEchoOutput</samp> should determine whether or not the view will be sent directly to the client, or just returned as a string. <samp>render</samp>, of course, should do the processing and rendering of the data.</p>
<h3>The Base View Class</h3>
<p>The following abstract class defines code for most of the methods of the interface. All concrete view classes that inherit this class will need to define the <samp>render</samp> method. Since only one method needs to be defined (generally speaking), view classes are generally short, simple, and very easy to extend or to build new ones with minimal effort.</p>
<pre class="prettyprint">abstract class Panda_View_Abstract
implements Panda_View_Interface
{
    protected $data = array();
    protected $echoOutput = true;

    public function getVar($name)
    {
        if (array_key_exists($name, $this-&gt;data)) {
            return $this-&gt;data[$name];
        }
        else {
            return null;
        }
    }

    public function setVar($name, $value)
    {
        return $this-&gt;data[$name] = $value;
    }

    public function unsetVar($name)
    {
        if (array_key_exists($name, $this-&gt;data)) {
            unset($this-&gt;data[$name]);
        }
    }

    public function getData()
    {
        return $this-&gt;data;
    }

    public function setData(array $data)
    {
        $this-&gt;data = $data;
    }

    public function setEchoOutput($bool)
    {
        $this-&gt;echoOutput = (bool)$bool;
    }

    protected function output($output)
    {
        if ($this-&gt;echoOutput) {
            echo $output;
        }

        return $output;
    }
}</pre>
<p>The code above should pretty much speak for itself. The only new method added to the API was the <samp>output</samp> method, which does the actual displaying/returning of data. While defining render methods, remember to return your data through this method in order to always insure it gets rendered properly.</p>
<h3>The Serialized PHP View</h3>
<p>Serialized PHP is very handy for PHP clients which consume PHP services. The emitted data can quickly be imported by the client much like JSON is to JavaScript (except without the need for eval()). Serialized PHP is also popular amongst larger PHP driven organizations such as Digg, Flickr and Yahoo, each of whom use it as an output type for their web service APIs.</p>
<p>This is how easy it is to implement into our view library:</p>
<pre class="prettyprint">class Panda_View_PHP
extends Panda_View_Abstract
{
    public function render()
    {
        return $this-&gt;output(serialize($this-&gt;data));
    }
}</pre>
<h3>The JSON View</h3>
<p>JSON has recently become the preferred data-interchange format for the web. It is most commonly consumed by JavaScript applications, however libraries exist for nearly every modern language in wide use today.</p>
<p>As of PHP 5.2, the json extension has been enabled by default in all installations. Much like the View_PHP class above, no processing of the data needs to take place before the render &#8212; only a single function needs to be wrapped.</p>
<pre class="prettyprint">class Panda_View_JSON
extends Panda_View_Abstract
{
    public function render()
    {
        return $this-&gt;output(json_encode($this-&gt;data));
    }
}</pre>
<p>I suppose that it is worth mentioning that this method <em>could be considered harmful</em> for the purists in the audience (that would be all of us, right?). According to the JSON specification, JSON is built on top of two data structures: name and value pairs and an ordered list of values. </p>
<p>In other words, JSON emitting functions should forcefully reject any input which is not an object or an array. PHP&#8217;s native set of functions will happily accept any type of data and send it out without warning. </p>
<h3>The XML View</h3>
<p>Generating a basic XML document from the view data is considerably more complex that the aforementioned methods. XML documents have the potential to be tremendously complex. The code that follows takes the easy way out and completely avoids the use of attribute nodes and makes the bold assumption that only nested nodes are required to display your data. Think of this more of a proof of concept than an ideal implementation. That said, for simple data structures this should work just fine.</p>
<p>When the<samp>render</samp> method is called a <samp>DOMDocument</samp> is created and a loop is begun over the view&#8217;s data via the recursive method <samp>getNodes</samp>. Whenever a compound value is detected, <samp>getNodes</samp> is called again as necessary.</p>
<p>The name of the root node defaults to &#8220;data&#8221; and the output is assumed to be formatted. These settings may be changed by the <samp>setRootNodeName</samp> method. Also, output may be formatted or minified by passing a boolean value to the <samp>setFormatOutput</samp> method.</p>
<pre class="prettyprint">class Panda_View_XML
extends Panda_View_Abstract
{
    protected $document;
    protected $rootNode = &#x27;data&#x27;;
    protected $formatOutput = true;

    public function setRootNodeName($name)
    {
        $name = (string) $name;

        if (!empty($name)) {
            $this-&gt;rootNode = $name;
        }
    }

    public function setFormatOutput($bool)
    {
        $this-&gt;formatOutput = (bool) $bool;
    }

    public function render()
    {
        $this-&gt;document = new DOMDocument;
        $this-&gt;document-&gt;formatOutput = $this-&gt;formatOutput;

        $root  = $this-&gt;document-&gt;createElement($this-&gt;rootNode);
        $this-&gt;getNodes($this-&gt;data, $root);

        $this-&gt;document-&gt;appendChild($root);
        return $this-&gt;output($this-&gt;document-&gt;saveXML());
    }

    protected function getNodes($struct, DOMNode $parentNode)
    {
        if ($this-&gt;isIteratable($struct)) {
            foreach ($struct as $key =&gt; $value) {
                /* Numbers don&#x27;t make good node names, use the parent&#x27;s */
                if (is_numeric($key)) {
                    $key = $parentNode-&gt;nodeName;
                }

                $childNode = $this-&gt;document-&gt;createElement($key);
                $this-&gt;getNodes($value, $childNode);
                $parentNode-&gt;appendChild($childNode);
            }
        }
        else {
            $nodeValue = $this-&gt;document-&gt;createTextNode((string)$struct);
            $parentNode-&gt;appendChild($nodeValue);
        }
    }

    protected function isIteratable($struct)
    {
        return is_object($struct) || is_array($struct) || $struct instanceof Iterator;
    }
}</pre>
<h3>The HTML View</h3>
<p>The most common output format will be HTML. My first reaction while coding the HTML view was to extend View_XML, but I quickly trashed the idea. By their very nature, HTML documents implement heavy reuse of UI components (headers, navigations, footers, etc). Of course you don&#8217;t want to store that kind of data inside the view&#8217;s data so a template system needs to be implemented.</p>
<p>In the old days template systems consisted of header and footer includes which wrapped a bunch of code. Frankly, I always hated the idea of managing two documents when one would do just fine. The solution I came up with was to have two types of HTML documents: <em>templates</em> and <em>partials</em>. </p>
<p>Templates are documents which are designed to provide HTML for the areas of a web UI which don&#8217;t change very often. In other words, this is a single-document solution to the the header and footer includes mentioned before.</p>
<p>Partials are page-specific HTML documents which are injected into templates at render time. The view knows where to put views by a <samp>target</samp> argument which is just an XPath location.</p>
<pre class="prettyprint">class Panda_View_HTML
extends Panda_View_Abstract
{
    protected $document;
    protected $template;
    protected $partials;

    public function setTemplate($template)
    {
        if (is_file($template)) {
            $this-&gt;template = $template;
        }
    }

    public function setPartial($partial, $target)
    {
        if (is_file($partial) &amp;&amp; !empty($target)) {
            $this-&gt;partials[$partial] = $target;
        }
    }

    public function unsetPartial($partial)
    {
        if (array_key_exists($partial, $this-&gt;partials)) {
            unset($this-&gt;partials[$partial]);
        }
    }

    protected function parse($file)
    {
        $out = &#x27;&#x27;;

        if (is_file($file)) {
            ob_start();

            include $file;
            $out = ob_get_contents();

            ob_end_clean();
        }

        return $out;
    }

    protected function load($source, $target)
    {
        $xpath = new DOMXPath($this-&gt;document);
        $items = $xpath-&gt;query($target);

        if ($items-&gt;length &gt; 0) {
            $source   = $this-&gt;parse($source);
            $fragment = $this-&gt;document-&gt;createDocumentFragment();

            $fragment-&gt;appendXML($source);
            $items-&gt;item(0)-&gt;appendChild($fragment);
        }
    }

    public function render()
    {
        if (empty($this-&gt;template) || !is_array($this-&gt;partials)) {
            throw new Exception(&#x27;Unable to render: incomplete view configuration.&#x27;);
        }

        $templateContents = $this-&gt;parse($this-&gt;template);

        if (!empty($templateContents)) {
            $this-&gt;document = new DOMDocument;
            $this-&gt;document-&gt;loadHTML($templateContents);

            foreach ($this-&gt;partials as $source =&gt; $target) {
                $this-&gt;load($source, $target);
            }

            return $this-&gt;output($this-&gt;document-&gt;saveHTML());
        }
    }
}</pre>
<h3>Thoughts for Improvement</h3>
<p>The motivation behind this post was to demonstrate the potential of highly abstracted views. It&#8217;s important to note that this process can and will be improved upon in future iterations. Here are a few ideas that came to mind as I was writing this post:</p>
<ul>
<li>More complex views (such as View_XML and View_HTML) need to be dynamically configured at runtime. Since each class has a proprietary set of properties and helper methods, it would be a good idea to have a simple configure method which accepts an array of configuration directives.</li>
<li>JSON output in View_JSON should be properly handled. Because it utilizes PHP&#8217;s native <samp>json_encode</samp>, it is inherently broken. JavaScript applications have the potential to be very brittle at times so data integrity should come first.</li>
<li>The View_XML class needs to be more precise. A SimpleXML-like structure would be much better suited for generating more complex XML documents.</li>
<li>I feel dirty every time I look at code that uses output buffering. I still don&#8217;t like the idea that View_HTML uses it to parse partials before they are injected into the document. A much more elegant solution would be to emit raw XML data and to have the client transform it into HTML via XSLT. The downside to this method would be that it assumes the client supports XSLT, which just doesn&#8217;t fly. You could transform the XML on the server-side, but that could be overkill for most implementations.</li>
</ul>
<h3>Conclusion</h3>
<p>So there you have it. One interface, one abstract class and four distinct output formats coming in at just over 200 lines of code.</p>
<p>You can download the code above via SVN by checking out the following URI:<br />
<samp><a href="http://panda-php.googlecode.com/svn/trunk/Panda/View/">http://panda-php.googlecode.com/svn/trunk/Panda/View/</a></samp></p>
<p>As always I welcome your comments on this article.</p>
<h3>Other Posts in this Series</h3>
<ul>
<li><a href="http://www.lovemikeg.com/blog/2008/02/21/rolling-your-own-mvc-introduction/">Part I: Introduction</a></li>
<li><a href="http://www.lovemikeg.com/blog/2008/04/07/rolling-your-own-mvc-the-page-load-scenario/">Part II: The Page Load Scenario</a></li>
<li>You are currently reading Part III: The View</li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/lovemikeg?a=yclotG"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=yclotG" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=7Jhi0G"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=7Jhi0G" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/lovemikeg?a=eIifNG"><img src="http://feeds.feedburner.com/~f/lovemikeg?i=eIifNG" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/lovemikeg/~4/279164314" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.lovemikeg.com/blog/2008/04/28/rolling-your-own-mvc-the-view/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.lovemikeg.com/blog/2008/04/28/rolling-your-own-mvc-the-view/</feedburner:origLink></item>
	</channel>
</rss>
