<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The html blog &#187; asvin</title>
	<atom:link href="http://htmlblog.net/author/asvin/feed/" rel="self" type="application/rss+xml" />
	<link>http://htmlblog.net</link>
	<description>The web sandbox of Asvin Balloo</description>
	<lastBuildDate>Tue, 09 Nov 2010 11:39:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>imgble.com &#8211; adaptive image resizing for mobile devices</title>
		<link>http://htmlblog.net/imgble-com-adaptive-image-resizing-for-mobile-devices/</link>
		<comments>http://htmlblog.net/imgble-com-adaptive-image-resizing-for-mobile-devices/#comments</comments>
		<pubDate>Thu, 23 Sep 2010 17:24:03 +0000</pubDate>
		<dc:creator>asvin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://htmlblog.net/?p=137</guid>
		<description><![CDATA[I am happy to announce the launch of www.imgble.com. imgbleis a web-based utility that formats a specified image to best fit in different mobile screens. Those who work with mobile CMS, rendering image for the mobile devices into suitable format and dimension is obviously a big point to be considered which consumes a big portion [...]]]></description>
			<content:encoded><![CDATA[<p>I am happy to announce the launch of <a href="http://imgble.com">www.imgble.com</a>. <a href="http://imgble.com">imgble</a>is a web-based utility that formats a specified image to best fit in different mobile screens. Those who work with mobile CMS, rendering image for the mobile devices into suitable format and dimension is obviously a big point to be considered which consumes a big portion of the development time. Based on the mobile device’s screen resolution, imgble automatically resizes your image, keeping its aspect ratio. imgble also supports the <a href="http://imgble.com/faq/">chaining of different effects</a> on your image, such as <a href="http://imgble.com/blur">blurring</a>, <a href="http://imgble.com/border">adding borders</a>, <a href="http://imgble.com/rotate">rotating</a>, etc. You can find everything in the <a href="http://imgble.com/documentation/">documentation</a>.</p>
<p>So let me know your views, comments, and how imgble will be useful to you ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://htmlblog.net/imgble-com-adaptive-image-resizing-for-mobile-devices/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Attachment unavailable</title>
		<link>http://htmlblog.net/attachment-unavailable/</link>
		<comments>http://htmlblog.net/attachment-unavailable/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 17:20:33 +0000</pubDate>
		<dc:creator>asvin</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://htmlblog.net/?p=133</guid>
		<description><![CDATA[Just had some issues with the server and all attachments have gone including pictures, zip files, demo files etc ;-( Trying to restore from what&#8217;s left&#8230; not too optimistic though&#8230;]]></description>
			<content:encoded><![CDATA[<p>Just had some issues with the server and all attachments have gone including pictures, zip files, demo files etc ;-(</p>
<p>Trying to restore from what&#8217;s left&#8230; not too optimistic though&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://htmlblog.net/attachment-unavailable/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Writing your first Greasemonkey script &#8211; adding menus to Facebook&#8217;s top menu</title>
		<link>http://htmlblog.net/writing-your-first-greasemonkey-script-adding-menus-to-facebooks-top-menu/</link>
		<comments>http://htmlblog.net/writing-your-first-greasemonkey-script-adding-menus-to-facebooks-top-menu/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 19:25:50 +0000</pubDate>
		<dc:creator>asvin</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[greasemonkey]]></category>

		<guid isPermaLink="false">http://htmlblog.net/?p=120</guid>
		<description><![CDATA[This post will show you how to write a basic Greasemonkey script that will add two more menu items to Facebook&#8217;s friends top menu as shown below. These 2 menu items are : &#8220;Recently Updated&#8221; &#8211; show all your friends with recent updates &#8220;Status Updates&#8221; &#8211; show the latest status updates of your friends About [...]]]></description>
			<content:encoded><![CDATA[<p>This post will show you how to write a basic <a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> script that will add two more menu items to Facebook&#8217;s friends top menu as shown below.</p>
<p>These 2 menu items are :</p>
<ul>
<li>&#8220;Recently Updated&#8221; &#8211; show all your friends with recent updates</li>
<li>&#8220;Status Updates&#8221; &#8211; show the latest status updates of your friends</li>
</ul>
<h3 class="post-title">About <a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a></h3>
<p><a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> is a <a href="http://www.mozilla.com/firefox/" target="_blank">Firefox</a> extension that allows you to write scripts that alter the web pages you visit. You can</p>
<ul>
<li>use it to make a web site more readable or more usable</li>
<li>fix rendering bugs that the site owner can&#8217;t be bothered to fix themselves. </li>
<li>alter pages so they work better with assistive technologies that speak a web page out loud or convert it to Braille</li>
<li>even automatically retrieve data from other sites to make two sites more interconnected.</li>
</ul>
<p><a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> by itself does none of these things. In fact, after you install it, you won&#8217;t notice any change at all&#8230; until you start installing what are called “user scripts”. A user script is just a chunk of javascript code, with some additional information that tells <a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> where and when it should be run. Each user script can target a specific page, a specific site, or a group of sites.</p>
<h3 class="post-title">Install <a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> addon for Firefox</h3>
<p>Go to <a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> addon page, click on the &#8220;Add to Firefox&#8221; button and follow the instructions. After restarting Firefox, you will notice a monkey&#8217;s head sitting at the bottom right its status bar.<br />
If you right click on the monkey&#8217;s head and choose &#8220;Manage User Scripts&#8221; from the resulting menu, you will notice there isn&#8217;t any script which is quite normal since we have not installed any ;-).</p>
<h3 class="post-title">Creating your first <a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> script.</h3>
<p>For a <a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> to be recognized, it must end with <strong>.user.js</strong>, so let us create an empty file and save it as <strong>myfirstscript.user.js</strong><br />
Fire up your favourite text editor and open your newly created file.</p>
<h3 class="post-title"><a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> script metadata</h3>
<p>All user scripts has a meta data section which tells <a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a> about the script itself, where it came from, and when to run it. For example, our script :</p>
<pre class="brush: javascript">
// ==UserScript==
// @name          My First GM script
// @namespace     http://htmlblog.net
// @description   basic Greasemonkey script
// @include       http://www.facebook.com/
// ==/UserScript==
</pre>
<p>You can find <a href="http://diveintogreasemonkey.org/helloworld/metadata.html" target="_blank">more information about the metadata here</a>. </p>
<p>Remember we want our script available only for <a href="http://www.facebook.com" target="_blank">Facebook</a> pages, that is why we use <strong>@include http://www.facebook.com</strong></p>
<h3 class="post-title">Show me some code.</h3>
<p>Alright, to add our own menus, we need to get the parent element holding the drop down menu. After inspecting Facebook&#8217;s source code, we can rapidly come to the conclusion that the parent element&#8217;s id is &#8220;fb_menu_friends_dropdown&#8221;. So the current Facebook code looks like that :</p>
<pre class="brush: xhtml">
&lt;div class=&quot;fb_menu_dropdown hidden_elem&quot; id=&quot;fb_menu_friends_dropdown&quot;&gt;
&lt;div class=&quot;fb_menu_item&quot;&gt;&lt;a href=&quot;http://www.facebook.com/friends/?added&amp;amp;ref=tn&quot;&gt;Recently Added&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;fb_menu_item&quot;&gt;&lt;a href=&quot;http://www.facebook.com/friends/?everyone&amp;amp;ref=tn&quot;&gt;All Friends&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;fb_menu_separator&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;fb_menu_item&quot;&gt;&lt;a href=&quot;http://www.facebook.com/invite.php?ref=tn&quot;&gt;Invite Friends&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;fb_menu_item&quot;&gt;&lt;a href=&quot;http://www.facebook.com/find-friends/?ref=friends&quot;&gt;Find Friends&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>and our goal is to insert the two menu items before the &#8220;Recently Added&#8221; item. </p>
<p>For us to do that, we need to get the first child of the parent element and then insert our elements before it and to help us, i.e walking through the DOM selecting parent and childs, I use a <a href="http://gist.github.com/41440" target="_blank">little piece of code found on Github</a>, which eliminates whitespace issues between elements among other features. So our myfirstscript.user.js can be updated to :</p>
<pre class="brush: javascript">
// ==UserScript==
// @name          My First GM script
// @namespace     http://htmlblog.net
// @description   basic &lt;a href=&quot;https://addons.mozilla.org/firefox/addon/748&quot; target=&quot;_blank&quot;&gt;Greasemonkey&lt;/a&gt; script
// @include       http://www.facebook.com/
// ==/UserScript==
DOM = function () {

    function get(id) {
        if (id &amp;&amp; typeof id === &#039;string&#039;) {
            id = document.getElementById(id);
        }
        return id || null;
    }

    function walk(element, tag, walk, start, all) {
        var el = get(element)[start || walk], elements = all ? [] : null;
        while (el) {
            if (el.nodeType === 1 &amp;&amp; (!tag || el.tagName.toLowerCase() === tag)) {
                if (!all) {
                    return el;
                }
                elements.push(el);
            }
            el = el[walk];
        }
        return elements;
    }

    return {

        // Get the element by its id
        get: get,

        walk: walk,

        // Returns the previousSibling of the Element (excluding text nodes).
        getPrevious: function (el, tag) {
            return walk(el, tag, &#039;previousSibling&#039;);
        },

        // Like getPrevious, but returns a collection of all the matched previousSiblings.
        getAllPrevious: function (el, tag) {
            return walk(el, tag, &#039;previousSibling&#039;, null, true);
        },

        // As getPrevious, but tries to find the nextSibling (excluding text nodes).
        getNext: function (el, tag) {
            return walk(el, tag, &#039;nextSibling&#039;);
        },

        // Like getNext, but returns a collection of all the matched nextSiblings.
        getAllNext: function (el, tag) {
            return walk(el, tag, &#039;nextSibling&#039;, null, true);
        },

        // Works as getPrevious, but tries to find the firstChild (excluding text nodes).
        getFirst: function (el, tag) {
            return walk(el, tag, &#039;nextSibling&#039;, &#039;firstChild&#039;);
        },

        // Works as getPrevious, but tries to find the lastChild.
        getLast: function (el, tag) {
            return walk(el, tag, &#039;previousSibling&#039;, &#039;lastChild&#039;);
        },

        // Works as getPrevious, but tries to find the parentNode.
        getParent: function (el, tag) {
            return walk(el, tag, &#039;parentNode&#039;);
        },

        // Like getParent, but returns a collection of all the matched parentNodes up the tree.
        getParents: function (el, tag) {
            return walk(el, tag, &#039;parentNode&#039;, null, true);
        },

        // Returns all the Element&#039;s children (excluding text nodes).
        getChildren: function (el, tag) {
            return walk(el, tag, &#039;nextSibling&#039;, &#039;firstChild&#039;, true);
        },

        // Removes the Element from the DOM.
        dispose: function (el) {
            el = get(el);
            return (el.parentNode) ? el.parentNode.removeChild(el) : el;
        }

    };
}();
</pre>
<p>To get the parent element and its first child, we then append the following code :</p>
<pre class="brush: javascript">
// get drop down menu
var parentNode = DOM.get(&#039;fb_menu_friends_dropdown&#039;);
// get its first child
var firstNode = DOM.getFirst(&#039;fb_menu_friends_dropdown&#039;);
</pre>
<h3 class="post-title">Creating our nodes</h3>
<p>Now we must create our two nodes which will be inserted afterward. This is done easily with the following code which is self explanatory :</p>
<pre class="brush: javascript">
/** For &quot;Recently Updated&quot; */
// create our div with class fb_menu_item
var recentDiv = document.createElement(&#039;div&#039;);
recentDiv.setAttribute(&#039;class&#039;, &#039;fb_menu_item&#039;);

// create our link
var recentLink = document.createElement(&#039;a&#039;);
recentLink.href = &#039;http://www.facebook.com/friends/?recent&amp;ref=tn&#039;;

// add text to our link
var recentDivContent = document.createTextNode(&#039;Recently Updated&#039;);
recentLink.appendChild(recentDivContent);

// add link to our div
recentDiv.appendChild(recentLink);

/** For &quot;Status Updates&quot; */
// create our div with class fb_menu_item
var statusDiv = document.createElement(&#039;div&#039;);
statusDiv.setAttribute(&#039;class&#039;, &#039;fb_menu_item&#039;);

// create our link
var statusLink = document.createElement(&#039;a&#039;);
statusLink.href = &#039;http://www.facebook.com/friends/?status&amp;ref=tn&#039;;

// add text to our link
var statusDivContent = document.createTextNode(&#039;Status Updates&#039;);
statusLink.appendChild(statusDivContent);

// add link to our div
statusDiv.appendChild(statusLink);
</pre>
<p>We can also add a separator, for having a cleaner look :</p>
<pre class="brush: javascript">
/** Creates a separator, just to look good */
var separatorDiv = document.createElement(&#039;div&#039;);
separatorDiv.setAttribute(&#039;class&#039;, &#039;fb_menu_separator&#039;);
</pre>
<p>Finally we insert these 3 nodes before the first child element we got earlier on :</p>
<pre class="brush: javascript">
// add all divs before first child of menu
parentNode.insertBefore(statusDiv, firstNode);
parentNode.insertBefore(recentDiv, firstNode);
parentNode.insertBefore(separatorDiv, firstNode);
</pre>
<p>Just to be on the safe side of things, we surround the whole block of code with a try and catch statement.</p>
<h3 class="post-title">Putting it all together</h3>
<p>So finally our code is like this :</p>
<pre class="brush: javascript">
// ==UserScript==
// @name          My First GM script
// @namespace     http://htmlblog.net
// @description   basic &lt;a href=&quot;https://addons.mozilla.org/firefox/addon/748&quot; target=&quot;_blank&quot;&gt;Greasemonkey&lt;/a&gt; script
// @include       http://www.facebook.com/
// ==/UserScript==

DOM = function () {

    function get(id) {
        if (id &amp;&amp; typeof id === &#039;string&#039;) {
            id = document.getElementById(id);
        }
        return id || null;
    }

    function walk(element, tag, walk, start, all) {
        var el = get(element)[start || walk], elements = all ? [] : null;
        while (el) {
            if (el.nodeType === 1 &amp;&amp; (!tag || el.tagName.toLowerCase() === tag)) {
                if (!all) {
                    return el;
                }
                elements.push(el);
            }
            el = el[walk];
        }
        return elements;
    }

    return {

        // Get the element by its id
        get: get,

        walk: walk,

        // Returns the previousSibling of the Element (excluding text nodes).
        getPrevious: function (el, tag) {
            return walk(el, tag, &#039;previousSibling&#039;);
        },

        // Like getPrevious, but returns a collection of all the matched previousSiblings.
        getAllPrevious: function (el, tag) {
            return walk(el, tag, &#039;previousSibling&#039;, null, true);
        },

        // As getPrevious, but tries to find the nextSibling (excluding text nodes).
        getNext: function (el, tag) {
            return walk(el, tag, &#039;nextSibling&#039;);
        },

        // Like getNext, but returns a collection of all the matched nextSiblings.
        getAllNext: function (el, tag) {
            return walk(el, tag, &#039;nextSibling&#039;, null, true);
        },

        // Works as getPrevious, but tries to find the firstChild (excluding text nodes).
        getFirst: function (el, tag) {
            return walk(el, tag, &#039;nextSibling&#039;, &#039;firstChild&#039;);
        },

        // Works as getPrevious, but tries to find the lastChild.
        getLast: function (el, tag) {
            return walk(el, tag, &#039;previousSibling&#039;, &#039;lastChild&#039;);
        },

        // Works as getPrevious, but tries to find the parentNode.
        getParent: function (el, tag) {
            return walk(el, tag, &#039;parentNode&#039;);
        },

        // Like getParent, but returns a collection of all the matched parentNodes up the tree.
        getParents: function (el, tag) {
            return walk(el, tag, &#039;parentNode&#039;, null, true);
        },

        // Returns all the Element&#039;s children (excluding text nodes).
        getChildren: function (el, tag) {
            return walk(el, tag, &#039;nextSibling&#039;, &#039;firstChild&#039;, true);
        },

        // Removes the Element from the DOM.
        dispose: function (el) {
            el = get(el);
            return (el.parentNode) ? el.parentNode.removeChild(el) : el;
        }

    };
}();

try{
	// get drop down menu
	var parentNode = DOM.get(&#039;fb_menu_friends_dropdown&#039;);
	// get its first child
	var firstNode = DOM.getFirst(&#039;fb_menu_friends_dropdown&#039;);

	/** For &quot;Recently Updated&quot; */
	// create our div with class fb_menu_item
	var recentDiv = document.createElement(&#039;div&#039;);
	recentDiv.setAttribute(&#039;class&#039;, &#039;fb_menu_item&#039;);

	// create our link
	var recentLink = document.createElement(&#039;a&#039;);
	recentLink.href = &#039;http://www.facebook.com/friends/?recent&amp;ref=tn&#039;;

	// add text to our link
	var recentDivContent = document.createTextNode(&#039;Recently Updated&#039;);
	recentLink.appendChild(recentDivContent);

	// add link to our div
	recentDiv.appendChild(recentLink);

	/** For &quot;Status Updates&quot; */
	// create our div with class fb_menu_item
	var statusDiv = document.createElement(&#039;div&#039;);
	statusDiv.setAttribute(&#039;class&#039;, &#039;fb_menu_item&#039;);

	// create our link
	var statusLink = document.createElement(&#039;a&#039;);
	statusLink.href = &#039;http://www.facebook.com/friends/?status&amp;ref=tn&#039;;

	// add text to our link
	var statusDivContent = document.createTextNode(&#039;Status Updates&#039;);
	statusLink.appendChild(statusDivContent);

	// add link to our div
	statusDiv.appendChild(statusLink);

	/** Creates a separator, just to look good */
	var separatorDiv = document.createElement(&#039;div&#039;);
	separatorDiv.setAttribute(&#039;class&#039;, &#039;fb_menu_separator&#039;);

	// add both divs before first child of menu
	parentNode.insertBefore(statusDiv, firstNode);
	parentNode.insertBefore(recentDiv, firstNode);
	parentNode.insertBefore(separatorDiv, firstNode);
}
catch(e){};
</pre>
<h3 class="post-title">Installing and testing our script</h3>
<p>Fire up Firefox and select <strong>&#8220;File&#8221; -> &#8220;Open File&#8230;&#8221;</strong> in the menu bar and then browse for your script, i.e myfirstscript.user.js in our case. You will be prompted to install the script by <a href="https://addons.mozilla.org/firefox/addon/748" target="_blank">Greasemonkey</a>. After installation is complete, head to Facebook, login and hover over the &#8220;Friends&#8221; menu, you will see your newly created menus.</p>
<p><a href="http://htmlblog.net/demo/greasemonkey/fb_recently_updated_link.user.zip"><strong>Download script</strong></a><br />
<a href="http://htmlblog.net/demo/greasemonkey/fb_recently_updated_link.user.js"><strong>Install script</strong></a></p>
]]></content:encoded>
			<wfw:commentRss>http://htmlblog.net/writing-your-first-greasemonkey-script-adding-menus-to-facebooks-top-menu/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>WP To Top &#8211; a WordPress plugin that takes you to the top</title>
		<link>http://htmlblog.net/wp-to-top/</link>
		<comments>http://htmlblog.net/wp-to-top/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 17:23:10 +0000</pubDate>
		<dc:creator>asvin</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[scroll]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp to top]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://htmlblog.net/?p=110</guid>
		<description><![CDATA[About WP To Top WP To Top is a WordPress plugin that adds a &#8220;Back to top&#8221; link in your blog without modifying your template files. This is useful especially if you have long posts or long pages. You will have a nice &#8220;Back to top&#8221; or whatever-text-you-want link floating at the bottom right/left of [...]]]></description>
			<content:encoded><![CDATA[<h3 class="post-title">About WP To Top</h3>
<p><a href="http://wordpress.org/extend/plugins/wp-to-top/" target="_blank">WP To Top</a> is a <a href="http://www.wordpress.org" target="_blank">WordPress</a> plugin that adds a &#8220;Back to top&#8221; link in your blog without modifying your template files. This is useful especially if you have long posts or long pages. You will have a nice &#8220;Back to top&#8221; or whatever-text-you-want link floating at the bottom right/left of your page.</p>
<h3 class="post-title">Features</h3>
<ul>
<li>Smooth scrolling animation and fade in, fade out effect, powered by the YUI library</li>
<li>Customizable options via the admin panel, from the text to the position of the link</li>
<li>Works on almost all browsers including IE6 (yes!)</li>
</ul>
<h3 class="post-title">Download</h3>
<p><a href="http://wordpress.org/extend/plugins/wp-to-top/" target="_blank">You can get the plugin here</a></p>
<h3 class="post-title">Demo</h3>
<p>You have a demo on this page. Just scroll a little bit and you will see a nice &#8220;Take me up&#8221; link appearing at the bottom of your page.</p>
<h3 class="post-title">Installation</h3>
<ul>
<li>Extract <a href="http://wordpress.org/extend/plugins/wp-to-top/" target="_blank">wptotop.zip</a> in the &#8220;/wp-content/plugins/&#8221; directory</li>
<li>Activate the plugin through the &#8220;Plugins&#8221; menu in <a href="http://www.wordpress.org" target="_blank">WordPress</a></li>
<li>Go to &#8220;Settings&#8221; and then &#8220;WP To Top&#8221; to configure the plugin. The options are self explanatory and easy to understand.</li>
</ul>
<h3 class="post-title">Thanks</h3>
<p>I got the inspiration to write this plugin after having a look at <a href="http://davidwalsh.name/jquery-top-link" target="_blank">David Walsh&#8217;s jQuery topLink Plugin</a>. Thanks to the <a href="http://developer.yahoo.com/yui" target="_blank">YUI team</a> for the great YUI library and <a href="http://semihhazar.com/blog/animated-page-scroll-with-yui/" target="_blank">Semih&#8217;s Animated Page Scroll with YUI</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://htmlblog.net/wp-to-top/feed/</wfw:commentRss>
		<slash:comments>70</slash:comments>
		</item>
		<item>
		<title>10 useful PHP PEAR packages</title>
		<link>http://htmlblog.net/10-useful-php-pear-packages/</link>
		<comments>http://htmlblog.net/10-useful-php-pear-packages/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 11:11:33 +0000</pubDate>
		<dc:creator>asvin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[archive]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[geo ip]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[live user]]></category>
		<category><![CDATA[mdb2]]></category>
		<category><![CDATA[net]]></category>
		<category><![CDATA[pear]]></category>
		<category><![CDATA[tar.gz]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[zip]]></category>

		<guid isPermaLink="false">http://htmlblog.net/?p=89</guid>
		<description><![CDATA[MDB2 PEAR MDB2 is a merge of the PEAR DB and Metabase php database abstraction layers. It provides a common API for all supported RDBMS. The main difference to most other DB abstraction packages is that MDB2 goes much further to ensure portability. MDB2 provides most of its many features optionally that can be used [...]]]></description>
			<content:encoded><![CDATA[<h3 class="post-title"><a href="http://pear.php.net/package/MDB2" target="_blank">MDB2</a></h3>
<p><a href="http://pear.php.net/package/MDB2" target="_blank">PEAR MDB2</a> is a merge of the PEAR DB and Metabase php database abstraction layers.</p>
<p>It provides a common API for all supported RDBMS. The main difference to most<br />
other DB abstraction packages is that MDB2 goes much further to ensure<br />
portability. MDB2 provides most of its many features optionally that<br />
can be used to construct portable SQL statements:</p>
<ul>
<li>Object-Oriented API</li>
<li>A DSN (data source name) or array format for specifying database servers</li>
<li>Datatype abstraction and on demand datatype conversion</li>
<li>Various optional fetch modes to fix portability issues</li>
<li>Portable error codes</li>
<li>Sequential and non sequential row fetching as well as bulk fetching</li>
<li>Ability to make buffered and unbuffered queries</li>
<li>Ordered array and associative array for the fetched rows</li>
<li>Prepare/execute (bind) named and unnamed placeholder emulation</li>
<li>Sequence/autoincrement emulation</li>
<li>Replace emulation</li>
<li>Limited sub select emulation</li>
<li>Row limit emulation</li>
<li>Transactions/savepoint support</li>
<li>Large Object support</li>
<li>Index/Unique Key/Primary Key support</li>
<li>Pattern matching abstraction</li>
<li>Module framework to load advanced functionality on demand</li>
<li>Ability to read the information schema</li>
<li>RDBMS management methods (creating, dropping, altering)</li>
<li>Reverse engineering schemas from an existing database</li>
<li>SQL function call abstraction</li>
<li>Full integration into the PEAR Framework</li>
<li>PHPDoc API documentation</li>
</ul>
<p><a href="http://www.installationwiki.org/MDB2" target="_blank">MDB2 &#8211; InstallationWiki</a><br />
<a href="http://codepoets.co.uk/pear_mdb2_php_database_howto_quickstart" target="_blank">How to use PHP and PEAR MDB2 </a></p>
<h3 class="post-title"><a href="http://pear.php.net/package/Text_CAPTCHA" target="_blank">Text_CAPTCHA</a></h3>
<p><a href="http://pear.php.net/package/Text_CAPTCHA" target="_blank">Implementation</a> of CAPTCHAs (Completely Automated Public Turing tests to tell Computers and Humans Apart).<br />
<a href="http://www.kingf1.com/2008/07/16/using-pears-text_captcha-to-secure-web-forms" target="_blank">Using PEAR&#8217;s Text_CAPTCHA to Secure Web Forms</a></p>
<h3 class="post-title"><a href="http://pear.php.net/package/Log">Log</a></h3>
<p><a href="http://pear.php.net/package/Log" target="_blank">The Log package</a> provides an abstracted logging framework. It includes output handlers for log files, databases, syslog, email, Firebug, and the console. It also provides composite and subject-observer logging mechanisms.<br />
<a href="http://www.indelible.org/php/Log/guide.html" target="_blank">The Log Package</a><br />
<a href="http://www.phpbuilder.com/columns/stump20021223.php3?page=2&amp;print_mode=1" target="_blank">PHPBuilder</a><br />
<a href="http://www.appelsiini.net/2007/2/debugging-php-with-firebug" target="_blank">Debugging PHP With Firebug</a><br />
<a href="http://www.go4expert.com/forums/showthread.php?t=1037" target="_blank">Advanced Logging in PHP with PEAR</a></p>
<h3 class="post-title"><a href="http://pear.php.net/package/LiveUser" target="_blank">LiveUser</a></h3>
<p><a href="http://pear.php.net/package/LiveUser" target="_blank">LiveUser</a> is a set of classes for dealing with user authentication<br />
and permission management. Basically, there are three main elements that make up this package:</p>
<ul>
<li>The LiveUser class</li>
<li>The Auth containers</li>
<li>The Perm containers</li>
</ul>
<p>The LiveUser class takes care of the login process and can be configured to use a certain permission container and one or more different auth containers.<br />
That means, you can have your users&#8217; data scattered amongst many data containers and have the LiveUser class try each defined container until the user is found.<br />
For example, you can have all website users who can apply for a new account online on the webserver&#8217;s local database. Also, you want to enable all your company&#8217;s employees to login to the site without the need to create new accounts for all of them. To achieve that, a second container can be defined to be used by the LiveUser class.</p>
<p>You can also define a permission container of your choice that will manage the rights for each user. Depending on the container, you can implement any kind of permission schemes for your application while having one consistent API.<br />
Using different permission and auth containers, it&#8217;s easily possible to integrate newly written applications with older ones that have their own ways of storing permissions and user data. Just make a new container type and you&#8217;re ready to go!</p>
<p><a href="http://wiki.pooteeweet.org/LiveUser/" target="_blank">PEAR::LiveUser Wiki</a><br />
<a href="http://jystewart.net/process/2005/08/getting-started-with-liveuser-permissions/" target="_blank">Getting Started with LiveUser Permissions</a><br />
<a href="http://www.gvngroup.be/doc/LiveUser/authentication.php" target="_blank">Authentication</a><br />
<a href="http://www.sitepoint.com/blogs/2004/06/11/php-authentication-and-access-control-libraries/" target="_blank">PHP Authentication and Access Control Libraries</a></p>
<h3 class="post-title"><a href="http://pear.php.net/package/Translation2" target="_blank">Translation2</a></h3>
<p><a href="http://pear.php.net/package/Translation2" target="_blank">This class provides</a> an easy way to retrieve all the strings for a multilingual site from a data source (i.e. db).<br />
The following containers are provided, more will follow:</p>
<ul>
<li>PEAR::DB</li>
<li>PEAR::MDB</li>
<li>PEAR::MDB2</li>
<li>gettext</li>
<li>XML</li>
<li>PEAR::DB_DataObject (experimental)</li>
</ul>
<p>It is designed to reduce the number of queries to the db, caching the results when possible.<br />
An Admin class is provided to easily manage translations (add/remove a language, add/remove a string).<br />
Currently, the following decorators are provided:</p>
<ul>
<li>CacheLiteFunction (for file-based caching)</li>
<li>CacheMemory (for memory-based caching)</li>
<li>DefaultText (to replace empty strings with their keys)</li>
<li>ErrorText (to replace empty strings with a custom error text)</li>
<li>Iconv (to switch from/to different encodings)</li>
<li>Lang (resort to fallback languages for empty strings)</li>
<li>SpecialChars (replace html entities with their hex codes)</li>
<li>UTF-8 (to convert UTF-8 strings to ISO-8859-1)</li>
</ul>
<p><a href="http://www.alberton.info/pear_translation2_tutorials.html" target="_blank">PEAR::Translation2 tutorials</a></p>
<h3 class="post-title"><a href="http://pear.php.net/package/Validate" target="_blank">Validate</a></h3>
<p><a href="http://pear.php.net/package/Validate" target="_blank">Package to validate</a> various data. It includes :</p>
<ul>
<li>numbers (min/max, decimal or not)</li>
<li>email (syntax, domain check, rfc822)</li>
<li>string (predefined type alpha upper and/or lowercase, numeric,&#8230;)</li>
<li>date (min, max, rfc822 compliant)</li>
<li>uri (RFC2396)</li>
<li>possibility valid multiple data with a single method call (::multiple)</li>
</ul>
<p><a href="http://www.phpbuilder.com/columns/ian_gilfillan20060630.php3" target="_blank">An introduction to PEAR&#8217;s Validate package</a></p>
<h3 class="post-title"><a href="http://pear.php.net/package/Spreadsheet_Excel_Writer" target="_blank">Spreadsheet_Excel_Writer</a></h3>
<p><a href="http://pear.php.net/package/Spreadsheet_Excel_Writer" target="_blank">Spreadsheet_Excel_Writer</a> was born as a porting of the Spreadsheet::WriteExcel Perl module to PHP.<br />
It allows writing of Excel spreadsheets without the need for COM objects.<br />
It supports formulas, images (BMP) and all kinds of formatting for text and cells.<br />
It currently supports the BIFF5 format (Excel 5.0), so functionality appeared in the latest Excel versions is not yet available.<br />
<a href="http://www.sitepoint.com/article/pear-spreadsheet_excel_writer/">Generating Spreadsheets with PHP and PEAR</a><br />
<a href="http://pear.php.net/manual/en/package.fileformats.spreadsheet-excel-writer.intro.php">What is Spreadsheet_Excel_Writer?</a></p>
<h3 class="post-title"><a href="http://pear.php.net/package/Net_GeoIP" target="_blank">Net_GeoIP</a></h3>
<p><a href="http://pear.php.net/package/Net_GeoIP" target="_blank">A library</a> that uses <a href="http://www.maxmind.com/app/geoip_country" target="_blank">Maxmind&#8217;s GeoIP databases</a> to accurately determine geographic location of an IP address.<br />
<a href="http://htmlblog.net/geolocate-your-visitors-with-php-part-1/">Tutorial from HTML Blog</a></p>
<h3 class="post-title"><a href="http://pear.php.net/package/File_Archive" target="_blank">File_Archive</a></h3>
<p><a href="http://pear.php.net/package/File_Archive" target="_blank">This library</a> makes it very easy to use, writing simple code, yet the library is very powerful.<br />
It lets you easily read or generate tar, gz, tgz, bz2, tbz, zip, ar (or deb) archives to files, memory, mail or standard output.<br />
<a href="http://poocl.la-grotte.org/index.php" target="_blank">File_Archive tutorial</a><br />
<a href="http://www.sitepoint.com/blogs/2005/08/06/file_archive/" target="_blank">SitePoint » File_Archive</a></p>
<h3 class="post-title"><a href="http://pear.php.net/package/XML_Serializer" target="_blank">XML_Serializer</a></h3>
<p><a href="http://pear.php.net/package/XML_Serializer" target="_blank">XML_Serializer</a> serializes complex data structures like arrays or object as XML documents.<br />
This class helps you generating any XML document you require without the need for DOM.<br />
Furthermore this package can be used as a replacement to serialize() and unserialize() as it comes with a matching</p>
<p>XML_Unserializer that is able to create PHP data structures (like arrays and objects) from XML documents, if type hints are available.<br />
If you use the XML_Unserializer on standard XML files, it will try to guess how it has to be unserialized. In most cases it does exactly what you expect it to do.</p>
<p><a href="http://www.devshed.com/index2.php?option=content&amp;task=view&amp;id=410&amp;pop=1&amp;page=0&amp;hide_js=1" target="_blank">Dev Shed XML_Serializer</a><br />
<a href="http://www.sitepoint.com/article/xml-php-pear-xml_serializer/" target="_blank">Instant XML with PHP and PEAR::XML_Serializer</a></p>
]]></content:encoded>
			<wfw:commentRss>http://htmlblog.net/10-useful-php-pear-packages/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>twitree.com &#8211; see on which leaves the birds are&#8230;</title>
		<link>http://htmlblog.net/twitreecom-see-on-which-leaves-the-birds-are/</link>
		<comments>http://htmlblog.net/twitreecom-see-on-which-leaves-the-birds-are/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 12:01:02 +0000</pubDate>
		<dc:creator>asvin</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[twitree]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[visualization]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://htmlblog.net/?p=81</guid>
		<description><![CDATA[I am happy to announce the launch of twitree.com. It&#8217;s a twitter application which allows a twitterer to view his followers in a tree-like navigation, which can be expanded. twitree makes extensive use of the YUI library. The following components were used : grids css &#8211; for the layout yahoo dom event &#8211; for DOM [...]]]></description>
			<content:encoded><![CDATA[<p>I am happy to announce the launch of <a href="http://twitree.com/">twitree.com</a>. It&#8217;s a <a href="http://twitter.com">twitter</a> application which allows a twitterer to view his followers in a tree-like navigation, which can be expanded.</p>
<p><a href="http://twitree.com/"><img src="http://htmlblog.net/wp-content/uploads/2008/12/twitree-300x116.jpg" alt="twitree" title="twitree" width="300" height="116" class="aligncenter size-medium wp-image-82" /></a></p>
<p><a href="http://twitree.com/">twitree</a> makes extensive use of the <a href="http://developer.yahoo.com/yui">YUI library</a>. The following components were used :</p>
<ul>
<li><a href="http://developer.yahoo.com/yui/grids">grids css</a> &#8211; for the layout</li>
<li><a href="http://developer.yahoo.com/yui/yahoo/">yahoo</a> <a href="http://developer.yahoo.com/yui/dom/">dom</a> <a href="http://developer.yahoo.com/yui/event/">event</a> &#8211; for DOM and event handling</li>
<li><a href="http://developer.yahoo.com/yui/connection/">connection manager</a> &#8211; for AJAX requests like getting the list of followers for a user</li>
<li><a href="http://developer.yahoo.com/yui/container/">container family</a> &#8211; to display modal dialogs like prompting for a twitter username, displaying the loading panel</li>
<li><a href="http://developer.yahoo.com/yui/json/">JSON utility</a> &#8211; to parse the JSON data twitree receives from the twitter servers</li>
<li><a href="http://developer.yahoo.com/yui/cookie/">cookie utility</a> &#8211; to fetch username information from a cookie so that the user doesn&#8217;t have to input his username every time</li>
<li>and finally the <a href="http://developer.yahoo.com/yui/treeview/">treeview control</a> which provides a nice tree and dynamically loads the data upon clicking on a node</li>
</ul>
<p>The application is very much in an initial phase and there are some limitations, like only 100 followers are being returned, <del datetime="2009-01-07T06:10:37+00:00">rate limiting</del>, etc&#8230;</p>
<p>Stay tuned for further information</p>
<p><strong>Latest update :</strong></p>
<p>twitterers can now </p>
<ul>
<li>update their status via twitree</li>
<li>follow a user by right clicking on the user and choose &#8220;Follow&#8221; from the contextual menu</li>
<li>send a direct message to a fellow twitterer by right clicking on the user and choose &#8220;Send message&#8221; from the contextual menu</li>
</ul>
<p>FAQ has also been added</p>
]]></content:encoded>
			<wfw:commentRss>http://htmlblog.net/twitreecom-see-on-which-leaves-the-birds-are/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Alternate colors to table rows with javascript (YUI)</title>
		<link>http://htmlblog.net/alternate-colors-to-table-rows-with-javascript-yui/</link>
		<comments>http://htmlblog.net/alternate-colors-to-table-rows-with-javascript-yui/#comments</comments>
		<pubDate>Tue, 16 Dec 2008 16:49:36 +0000</pubDate>
		<dc:creator>asvin</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[alternate rows]]></category>
		<category><![CDATA[table]]></category>
		<category><![CDATA[yahoo]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://htmlblog.net/?p=71</guid>
		<description><![CDATA[This article will show you how to add alternate colors to table rows without any server side development or hard coding your scripts, thus providing good readability for your users and great flexibility for you. We will use the YUI library for that. The HTML We need to create our basic HTML file containing a [...]]]></description>
			<content:encoded><![CDATA[<p>This article will show you how to add alternate colors to table rows without any server side development or hard coding your scripts, thus providing good readability for your users and great flexibility for you. We will use the <a href="http://developer.yahoo.com/yui" target="_blank">YUI library</a> for that.<br />
<span id="more-71"></span></p>
<h3>The HTML</h3>
<p>We need to create our basic HTML file containing a table and adding a class name to it.</p>
<pre class="brush: xhtml">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
		&lt;title&gt;Alternate colors&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;table class=&quot;alternateRows&quot;&gt;
			&lt;tr&gt;
				&lt;td&gt;First Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Second Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Third Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Fourth Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Fifth Row&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<h3>The Javascript</h3>
<p>Next we need to include the <a href="http://developer.yahoo.com/yui" target="_blank">YUI libraries</a>, served from their <a href="http://developer.yahoo.com/yui/articles/hosting/" target="_blank">CDN</a>. We need the</p>
<ul>
<li><a href="http://developer.yahoo.com/yui/yahoo/" target="_blank">YAHOO global object</a> which contains a number of methods that are used throughout the library</li>
<li><a href="http://developer.yahoo.com/yui/dom/" target="_blank">DOM collection</a> which provides methods that simplify common DOM-scripting tasks, including element positioning and CSS style management</li>
<li><a href="http://developer.yahoo.com/yui/event/" target="_blank">Event utility</a> for various event handling</li>
</ul>
<pre class="brush: xhtml">
&lt;!-- Combo-handled YUI JS files: --&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&quot;&gt;&lt;/script&gt;
</pre>
<p>And also our javascript file, <a href="http://htmlblog.net/demo/alternate/alternate.zip" target="_blank">alternate.js</a></p>
<pre class="brush: xhtml">
&lt;script type=&quot;text/javascript&quot; src=&quot;alternate.js&quot;&gt;&lt;/script&gt;
</pre>
<p>So our HTML page looks like this:</p>
<pre class="brush: xhtml">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
		&lt;!-- Combo-handled YUI JS files: --&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&quot;&gt;&lt;/script&gt;
		&lt;script type=&quot;text/javascript&quot; src=&quot;alternate.js&quot;&gt;&lt;/script&gt;
		&lt;title&gt;Alternate colors&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;table class=&quot;alternateRows&quot;&gt;
			&lt;tr&gt;
				&lt;td&gt;First Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Second Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Third Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Fourth Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Fifth Row&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<h3>Invoking the javascript</h3>
<p>To add the alternate colors to your table rows, you just have to put the following javascript code in your HTML page.</p>
<pre class="brush: javascript">
	YAHOO.util.Event.on(window, &#039;load&#039;, function(){
		YAHOO.htmlblog.alternateRows.init(&#039;alternateRows&#039;, &#039;#fff&#039;, &#039;#ccc&#039;);
	});
</pre>
<p>That means that after the page has been loaded, we call the alternateRows.init function, with 3 parameters:</p>
<ul>
<li>the table class name, in our case it&#8217;s &#8220;alternateRows&#8221;</li>
<li>the first color in hex, e.g #fff</li>
<li>the second color in hex, e.g #ccc</li>
</ul>
<h3>Our complete HTML page</h3>
<pre class="brush: xhtml">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
		&lt;!-- Combo-handled YUI JS files: --&gt;
&lt;script type=&quot;text/javascript&quot;src=&quot;http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&quot;&gt;&lt;/script&gt;
		&lt;script type=&quot;text/javascript&quot; src=&quot;alternate.js&quot;&gt;&lt;/script&gt;
		&lt;script type=&quot;text/javascript&quot;&gt;
			YAHOO.util.Event.on(window, &#039;load&#039;, function(){
				YAHOO.htmlblog.alternateRows.init(&#039;alternateRows&#039;, &#039;#fff&#039;, &#039;#ccc&#039;);
			});
		&lt;/script&gt;
		&lt;title&gt;Alternate colors&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;table class=&quot;alternateRows&quot;&gt;
			&lt;tr&gt;
				&lt;td&gt;First Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Second Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Third Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Fourth Row&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;Fifth Row&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://htmlblog.net/alternate-colors-to-table-rows-with-javascript-yui/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Bubble menu javascript or playing with YUI&#8217;s event delegation</title>
		<link>http://htmlblog.net/bubble-menu-javascript-or-playing-with-yuis-event-delegation/</link>
		<comments>http://htmlblog.net/bubble-menu-javascript-or-playing-with-yuis-event-delegation/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 15:10:41 +0000</pubDate>
		<dc:creator>asvin</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[event delegation]]></category>
		<category><![CDATA[menu]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://htmlblog.net/?p=63</guid>
		<description><![CDATA[Image courtesy of jobee59&#8242;s photostream Event delegation refers to the use of a single event listener on a parent object to listen for events happening on its children (or deeper descendants). Event delegation allows developers to be sparse in their application of event listeners while still reacting to events as they happen on highly specific [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm1.static.flickr.com/199/469216645_020fc74cce.jpg?v=0" alt="bubble" /><br />
Image courtesy of <a href="http://flickr.com/photos/jobee59/469216645/" target="_blank">jobee59&#8242;s photostream</a></p>
<p>Event delegation refers to the use of a single event listener on a parent object to listen for events happening on its children (or deeper descendants). Event delegation allows developers to be sparse in their application of event listeners while still reacting to events as they happen on highly specific targets. This proves to be a key strategy for maintaining high performance in event-rich web projects, where the creation of hundreds of event listeners can quickly degrade performance. <a href="http://developer.yahoo.com/yui/examples/event/event-delegation.html" target="_blank">More on event delegation including examples</a>.</p>
<p>This post illustrates the use of event delegation to create a &#8220;bubble&#8221; menu, inspired by <a href="http://nettuts.com/html-css-techniques/how-to-create-a-mootools-homepage-inspired-navigation-effect-using-jquery/" target="_blank">Bedrich Rios&#8217; post on Nettuts</a>.<br />
<span id="more-63"></span></p>
<h3>The HTML</h3>
<p>We&#8217;ll need the following components from the <a href="http://developer.yahoo.com/yui" target="_blank">YUI library</a>:</p>
<ul>
<li><a href="http://developer.yahoo.com/yui/dom/" target="_blank">yahoo-dom-event</a> &#8211; for DOM/Event handling</li>
<li><a href="http://developer.yahoo.com/yui/animation/" target="_blank">animation</a> &#8211; for sliding effects </li>
</ul>
<p>So our basic HTML page is like this:</p>
<pre class="brush: xhtml">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
		&lt;!-- Combo-handled YUI JS files: --&gt;
		&lt;script type=&quot;text/javascript&quot; src=&quot;http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&amp;2.6.0/build/animation/animation-min.js&quot;&gt;&lt;/script&gt;
	&lt;/head&gt;
	&lt;body&gt;

	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Next we&#8217;ll add some structural markup, a simple list, with &#8220;menu&#8221; as class name and with 5 items.</p>
<pre class="brush: xhtml">
&lt;ul class=&quot;menu&quot;&gt;
	&lt;li&gt;Menu item 1&lt;/li&gt;
	&lt;li&gt;Menu item 2&lt;/li&gt;
	&lt;li&gt;Menu item 3&lt;/li&gt;
	&lt;li&gt;Menu item 4&lt;/li&gt;
	&lt;li&gt;Menu item 5&lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>Updated HTML page:</p>
<pre class="brush: xhtml">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
		&lt;!-- Combo-handled YUI JS files: --&gt;
		&lt;script type=&quot;text/javascript&quot; src=&quot;http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&amp;2.6.0/build/animation/animation-min.js&quot;&gt;&lt;/script&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;ul class=&quot;menu&quot;&gt;
			&lt;li&gt;Menu item 1&lt;/li&gt;
			&lt;li&gt;Menu item 2&lt;/li&gt;
			&lt;li&gt;Menu item 3&lt;/li&gt;
			&lt;li&gt;Menu item 4&lt;/li&gt;
			&lt;li&gt;Menu item 5&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<h3>The Javascript</h3>
<p>Then we just have to add the <a href="http://htmlblog.net/demo/bubble/bubble.zip" target="_blank">bubble.js</a> javascript file to our page and it&#8217;s done, we&#8217;ll have a nice &#8220;bubble&#8221; menu.</p>
<pre class="brush: xhtml">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
		&lt;!-- Combo-handled YUI JS files: --&gt;
		&lt;script type=&quot;text/javascript&quot; src=&quot;http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&amp;2.6.0/build/animation/animation-min.js&quot;&gt;&lt;/script&gt;
		&lt;!-- our bubble file --&gt;
		&lt;script type=&quot;text/javascript&quot; src=&quot;bubble.js&quot;&gt;&lt;/script&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;ul class=&quot;menu&quot;&gt;
			&lt;li&gt;Menu item 1&lt;/li&gt;
			&lt;li&gt;Menu item 2&lt;/li&gt;
			&lt;li&gt;Menu item 3&lt;/li&gt;
			&lt;li&gt;Menu item 4&lt;/li&gt;
			&lt;li&gt;Menu item 5&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<h3>bubble.js</h3>
<pre class="brush: javascript">
/**
*	Bubble Menu
*	@author Asvin Balloo (http://htmlblog.net)
*/
bubbleMenu = {
	// private variables
	// class name of our menu
	menuClassName: null,
	// by how much we are sliding
	moveToLength : 10,

	/**
	*	Init the whole process here
	*	@method init
	*	@params menuClassName {string} class name of our menus
	*/
	init: function(menuClassName){
		// set our class name to be used later one
		bubbleMenu.menuClassName = menuClassName;

		// get all the lists with the class name
		var list = YAHOO.util.Dom.getElementsByClassName(menuClassName);

		// loop through them
		for(var i=0; i&lt;list.length; i++) {
			// add the onmouseover event to it, call the mouseOverHandler function
			YAHOO.util.Event.on(list[i], &quot;mouseover&quot;, bubbleMenu.mouseOverHandler);

			// get the first child and its padding left for future reference. Useful when using onmouseout to 

restore the item to original state
			var listItems = list[i].getElementsByTagName(&#039;li&#039;);
			var startingPadding = parseInt(YAHOO.util.Dom.getStyle(listItems[0], &#039;paddingLeft&#039;));

			// add the onmouseout event, call the mouseOutHandler function
			YAHOO.util.Event.on(list[i], &quot;mouseout&quot;, bubbleMenu.mouseOutHandler, {&#039;list&#039;:list[i], &quot;padding&quot; : 

startingPadding});
		}
	},

	/**
	*	Mouse over handler
	*	@params e {Event} the event
	*/
	mouseOverHandler: function(e){
		// get the target
		var elTarget = YAHOO.util.Event.getTarget(e);

		// calculate the current padding left
		var paddingLeft = parseInt(YAHOO.util.Dom.getStyle(elTarget, &#039;paddingLeft&#039;));

		// call the delegate method, with the target and the padding left value
		bubbleMenu.delegate(elTarget, paddingLeft);
	},

	/**
	*	Mouse out handler
	*	@params e {Event} the event
	*	@params o {JSON} JSON data containing the list + padding value, eg. {&#039;list&#039;: mylist, &#039;padding&#039;: 10}
	*/
	mouseOutHandler: function(e, o){
		// get the target
		var elTarget = YAHOO.util.Event.getTarget(e);

		// calculate the left padding, the original padding value - by how much we have padded
		var paddingLeft = o.padding - bubbleMenu.moveToLength;

		// call the delegate method with the target and padding value
		bubbleMenu.delegate(elTarget, paddingLeft);
	},

	/**
	*	Cool things go here, like animation
	*	@params elTarget {Target} our target
	*	@params padding {Int} by how much we are going to padd
	*/
	delegate: function(elTarget, padding){
		//walk up the DOM tree looking for an &lt;li&gt; in the target&#039;s ancestry; desist when you reach the container with our class name
		while (elTarget.className != bubbleMenu.menuClassName) {
			// are you an LI?
			if(elTarget.nodeName.toUpperCase() == &quot;LI&quot;) {
				// if so then animate, set the attributes, in our case the left padding
				var attributes = { paddingLeft: {&quot;to&quot;: [padding + bubbleMenu.moveToLength] } };

				// create our animation
				var anim = new YAHOO.util.Motion(elTarget, attributes, 0.6, YAHOO.util.Easing.bounceOut);

				// then animate
				anim.animate();
				break;
			}
			else {
				// it&#039;s not an li, so we keep looking and looking
	            elTarget = elTarget.parentNode;
	        }
		}
	}
};

// init the whole thing here
YAHOO.util.Event.on(window, &quot;load&quot;, function(){
	bubbleMenu.init(&quot;menu&quot;);
});
</pre>
<p>You can have unlimited (don&#8217;t abuse) number of bubble menus by just adding the &#8220;menu&#8221; class to each one of them and including the bubble.js file.<br />
If you&#8217;re not happy with the menu class or you found another cool class name, then you&#8217;ll have to update the bubble.js file towards the end:</p>
<pre class="brush: javascript">
// init the whole thing here
YAHOO.util.Event.on(window, &quot;load&quot;, function(){
	bubbleMenu.init(&quot;mycoolclass&quot;);
});
</pre>
<p>Also you can modify by how much an item slides by modifying the moveToLength variable (default 10):</p>
<pre class="brush: javascript">

// by how much we are sliding
moveToLength : 30,
</pre>
<p>Note that the demo is using reset-fonts-grids CSS and the page has been styled with the following:</p>
<pre class="brush: css">
body {
	margin: 0;
	padding: 0;
	background: #1d1d1d;
	font-family: &quot;Lucida Grande&quot;, Verdana, sans-serif;
	font-size: 100%;
}

.menu li{
	padding-left: 20px;
	line-height: 2em;
	width: 150px;
	color: #999;

	background: #222;
	border: 1px solid #1a1a1a;
	-moz-border-radius: 10px;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://htmlblog.net/bubble-menu-javascript-or-playing-with-yuis-event-delegation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>9 tips to validate your XHTML code</title>
		<link>http://htmlblog.net/9-tips-to-validate-your-xhtml-code/</link>
		<comments>http://htmlblog.net/9-tips-to-validate-your-xhtml-code/#comments</comments>
		<pubDate>Wed, 12 Nov 2008 15:29:14 +0000</pubDate>
		<dc:creator>asvin</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[embed flash]]></category>
		<category><![CDATA[seo]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[validator]]></category>
		<category><![CDATA[w3c]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://htmlblog.net/?p=41</guid>
		<description><![CDATA[What is validation ? According to the W3c, Validation is a process of checking your documents against a formal Standard, such as those published by the World Wide Web Consortium (W3C) for HTML and XML-derived Web document types, or by the WapForum for WML, etc. It serves a similar purpose to spell checking and proofreading [...]]]></description>
			<content:encoded><![CDATA[<h3>What is validation ?</h3>
<p>According to the <a href="http://validator.w3.org/docs/why.html" target="_blank">W3c</a>, Validation is a process of checking your documents against a formal Standard, such as those published by the <a href="http://www.w3.org/" target="_blank">World Wide Web Consortium (W3C)</a>  for HTML and XML-derived Web document types, or by the WapForum for WML, etc. It serves a similar purpose to spell checking and proofreading for grammar and syntax, but is much more precise and reliable than any of those processes because it is dealing with precisely-specified machine languages, not with nebulously-defined human natural language.</p>
<hr/>
<h3>Why taking the trouble to validate your XHTML ?</h3>
<ul>
<li>Properly written XHTML code will render better, render on more browsers, and render faster than XHTML with errors. It&#8217;s also more easily adapted to print and alternative browsing devices like mobile phones and handheld computers.</li>
<li>Properly written XHTML code is more likely to be &#8220;future-proof&#8221; (backward compatible with future standards and future web browsers).</li>
<li>Browsers are becoming more standards compliant, and it is becoming increasingly necessary and important to write valid and standards compliant XHTML code</li>
<li>Poorly written XHTML can greatly reduce the amount of traffic your web site receives from search engines.</li>
<li>Write XHTML code right the first time and write it once.</li>
<li>You don&#8217;t want to look foolish among your friends while not knowing the rules, uh?</li>
</ul>
<p><span id="more-41"></span></p>
<hr/>
<h3>Tip 1: Specify a DOCTYPE and namespace</h3>
<p>Include a <a href="http://en.wikipedia.org/wiki/Document_Type_Declaration" target="_blank">DOCTYPE</a> at the top of your page and specify the <a href="http://en.wikipedia.org/wiki/XML_Namespace" target="_blank">namespace</a></p>
<p>For XHTML1.0 Strict</p>
<pre class="brush: xhtml">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
</pre>
<p>For XHTML1.0 Transitional</p>
<pre class="brush: xhtml">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
</pre>
<p>For XHTML1.0 Frameset</p>
<pre class="brush: xhtml">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Frameset//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
</pre>
<hr/>
<h3>Tip 2: Specify the character encoding</h3>
<pre class="brush: xhtml">
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
</pre>
<hr />
<h3>Tip 3: Avoid using deprecated tags and attributes.</h3>
<p>Deprecated tags :</p>
<ul>
<li>applet</li>
<li>basefont</li>
<li>center</li>
<li>dir</li>
<li>font</li>
<li>isindex</li>
<li>menu</li>
<li>s</li>
<li>strike</li>
<li>u</li>
</ul>
<p>Deprecated attributes and tags in which they are deprecated :</p>
<ul>
<li>align (caption, img, input, object, legend, table, hr, div, h1, h2, h3, h4, h5, h6, p)</li>
<li>alink, link, vlink (body)</li>
<li>background (body)</li>
<li>bgcolor (table, tr, td, th, body)</li>
<li>border (img, object)</li>
<li>clear (br)</li>
<li>compact (dl, ol, ul)</li>
<li>height (td, th)</li>
<li>hspace (img, object)</li>
<li>language (script)</li>
<li>name (img, a, applet, form, frame, iframe, map)</li>
<li>noshade (hr)</li>
<li>nowrap (td, th)</li>
<li>size (hr)</li>
<li>start (ol)</li>
<li>target (a)</li>
<li>text (body)</li>
<li>type (li, ol, ul)</li>
<li>value (li)</li>
<li>version (html)</li>
<li>vspace (img, object)</li>
<li>width (hr, td, th, pre)</li>
</ul>
<hr />
<h3>Tip 4: All tags in lowercase</h3>
<p>All tags and attribute names must be in lower case and attribute values must be between double quotes (&#8220;), i.e</p>
<pre class="brush: xhtml">
&lt;DIV&gt;
	&lt;Img src=&quot;test.jpg&quot; ID=myimage alt=&#039;logo&#039; /&gt;
&lt;/DIV&gt;
</pre>
<p>is incorrect while correct version goes like this:</p>
<pre class="brush: xhtml">
&lt;div&gt;
	&lt;img src=&quot;test.jpg&quot; id=&quot;myimage&quot; alt=&quot;logo&quot; /&gt;
&lt;/div&gt;
</pre>
<hr/>
<h3>Tip 5: XHTML must be well-formed</h3>
<p>All opening tags must have closing ones, or if the tag is empty, like br tag, it must have a closing slash. For e.g</p>
<pre class="brush: xhtml">
&lt;div&gt;
	&lt;p&gt;this is a paragraph&lt;/p&gt;
	&lt;br&gt;
	&lt;hr&gt;
	&lt;img src=&quot;images.jpg&quot; alt=&quot;my company&quot;&gt;
&lt;/div&gt;
</pre>
<p>is invalid. The correct code:</p>
<pre class="brush: xhtml">
&lt;div&gt;
	&lt;p&gt;this is a paragraph&lt;/p&gt;
	&lt;br /&gt;
	&lt;hr /&gt;
	&lt;img src=&quot;images.jpg&quot; alt=&quot;my company&quot; /&gt;
&lt;/div&gt;
</pre>
<p>Also, tags must be properly nested can can&#8217;t overlap. An example of bad nesting is</p>
<pre class="brush: xhtml">
&lt;p&gt;
	&lt;div&gt;&lt;strong&gt;this is a paragraph&lt;/div&gt;&lt;/strong&gt;
&lt;/p&gt;
</pre>
<p>It should be like this in order to validate:</p>
<pre class="brush: xhtml">
&lt;div&gt;
	&lt;p&gt;&lt;strong&gt;this is a paragraph&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
</pre>
<hr/>
<h3>Tip 6: Images must always have alt attribute</h3>
<p>According to the W3C recommendations, the &#8220;alt&#8221; attribute specifies an alternate text for user agents that cannot display images. Including the alt attribute will not only validate your code but also improve your search engine rankings. In Google&#8217;s webmaster guidelines, they advise the use of alternative text for images since they can&#8217;t see the images. Instead they rely on the alt attribute.</p>
<p>Correct code :</p>
<pre class="brush: xhtml">
	&lt;img src=&quot;images/logo.jpg&quot; alt=&quot;My Company&quot; /&gt;
</pre>
<hr/>
<h3>Tip 7: Surround your javascript between CDATA tags</h3>
<p>If you&#8217;re not using external javascript files, to prevent the validator from spitting errors from your javascript code, </p>
<p>simply surround them within CDATA tags, like this:</p>
<pre class="brush: xhtml">
&lt;script type=&quot;text/javascript&quot;&gt;
/* &lt;![CDATA[ */
var myfunction = function(){

};
/* ]]&gt; */
&lt;/script&gt;
</pre>
<hr/>
<h3>Tip 8 : Encode HTML character entities</h3>
<pre class="brush: xhtml">
	&lt;!-- incorrect --&gt;
	my brother &amp; me

	&lt;!-- correct --&gt;
	my brother &amp;amp; me
</pre>
<hr/>
<h3>Tip 9: Correct way to embed flash movies</h3>
<p>Code which won&#8217;t validate</p>
<pre class="brush: xhtml">
&lt;object classid=&quot;clsid:D27CDB6E-AE6D-11cf-96B8-444553540000&quot; codebase=&quot;http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0&quot; width=&quot;30&quot; height=&quot;30&quot;&gt;
	&lt;param name=&quot;movie&quot; value=&quot;music/sound.swf&quot;&gt;
	&lt;param name=&quot;quality&quot; value=&quot;high&quot;&gt;
	&lt;embed src=&quot;music/sound.swf&quot; quality=&quot;high&quot; pluginspage=&quot;http://www.macromedia.com/go/getflashplayer&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;30&quot; height=&quot;30&quot;&gt;&lt;/embed&gt;
&lt;/object&gt;
</pre>
<p>Correct way to embed flash movies</p>
<pre class="brush: xhtml">
&lt;object type=&quot;application/x-shockwave-flash&quot; data=&quot;music/sound.swf&quot; width=&quot;0&quot; height=&quot;0&quot;&gt;
	&lt;param name=&quot;movie&quot; value=&quot;music/sound.swf&quot; /&gt;
	&lt;param name=&quot;quality&quot; value=&quot;high&quot;/&gt;
&lt;/object&gt;
</pre>
<p>Or if you want you can use <a href="http://code.google.com/p/swfobject/" target="_blank">swfobject</a> which offers optimized Flash Player embed methods.</p>
]]></content:encoded>
			<wfw:commentRss>http://htmlblog.net/9-tips-to-validate-your-xhtml-code/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>8 practical tips to make your web pages faster</title>
		<link>http://htmlblog.net/8-practical-tips-to-make-your-web-pages-faster/</link>
		<comments>http://htmlblog.net/8-practical-tips-to-make-your-web-pages-faster/#comments</comments>
		<pubDate>Thu, 06 Nov 2008 16:36:23 +0000</pubDate>
		<dc:creator>asvin</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[mod_deflate]]></category>
		<category><![CDATA[mod_expires]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[speed up]]></category>
		<category><![CDATA[yahoo]]></category>

		<guid isPermaLink="false">http://htmlblog.net/?p=40</guid>
		<description><![CDATA[Yahoo&#8217;s Exceptional Performance team has compiled a list of 34 best practices to have faster web pages. In this post I&#8217;ll show you 8 tips which helped me to get a B grade in YSlow! for web pages that I develop. Currently YSlow&#8217;s web page analysis is based on 13 identified basic rules that affect [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm4.static.flickr.com/3062/2520059957_ae331ae75a.jpg?v=0" alt="" /></p>
<div style="clear:both"></div>
<p><a href="http://developer.yahoo.com/performance/rules.html" target="_blank">Yahoo&#8217;s Exceptional Performance team</a> has compiled a list of <a href="http://developer.yahoo.com/performance/rules.html" target="_blank">34 best practices</a> to have faster web pages. In this post I&#8217;ll show you 8 tips which helped me to get a B grade in <a href="http://developer.yahoo.com/yslow/" target="_blank">YSlow!</a> for web pages that I develop. Currently YSlow&#8217;s web page analysis is based on 13 identified basic rules that affect web page performance. In decreasing order of priority they are:</p>
<ol>
<li><a href="http://developer.yahoo.com/performance/rules.html#num_http" target="_blank">Make Fewer HTTP Requests</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#cdn" target="_blank">Use a Content Delivery Network</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#expires" target="_blank">Add an Expires Header</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#gzip" target="_blank">Gzip Components</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#css_top" target="_blank">Put CSS at the Top</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#js_bottom" target="_blank">Move Scripts to the Bottom</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#css_expressions" target="_blank">Avoid CSS Expressions</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#external" target="_blank">Make JavaScript and CSS External</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#dns_lookups" target="_blank">Reduce DNS Lookups</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#minify" target="_blank">Minify JavaScript</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#redirects" target="_blank">Avoid Redirects</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#js_dupes" target="_blank">Remove Duplicate Scripts</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#etags" target="_blank">Configure ETags</a></li>
</ol>
<p>You can get more info by clicking on each item. Of course using a <a href="http://en.wikipedia.org/wiki/Content_Delivery_Network" target="_blank">CDN</a> is not affordable by everybody, including me. This didn&#8217;t prevent me to have a B grade though. I will guide you through some of the items which worked for me.<br />
<span id="more-40"></span></p>
<hr/>
<strong>Make Fewer HTTP Requests</strong><br />
If you&#8217;re using the <a href="http://developer.yahoo.com" target="_blank">YUI library</a>, the good news is that recently the team graciously offered a <a href="http://developer.yahoo.com/yui/articles/hosting/" target="_blank">Combo Handler Service</a>, served from their CDN. This helps us to eliminate HTTP requests by requesting a single file. For example, to use the <a href="http://developer.yahoo.com/yui/editor/" target="_blank">Rich Text editor</a>, it needed 6 separate HTTP requests:</p>
<pre lang="html4strict">
<script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/container/container_core-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/menu/menu-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/element/element-beta-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/button/button-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/editor/editor-beta-min.js"></script>
</pre>
<p>Now with the Combo Handler service, it has been stripped to only 1 file:</p>
<pre lang="html4strict">
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.5.2/build/yahoo-dom-event/yahoo-dom-event.js&#038;2.5.2/build/container/container_core-min.js&#038;2.5.2/build/menu/menu-min.js&#038;2.5.2/build/element/element-beta-min.js&#038;2.5.2/build/button/button-min.js&#038;2.5.2/build/editor/editor-beta-min.js"></script>
</pre>
<p>If you&#8217;re not using the YUI library or not interested in using the Combo Handler service, you can try <a href="http://code.google.com/p/minify/" target="_blank">Minify!</a><br />
<a href="http://code.google.com/p/minify/" target="_blank">Minify</a> is a <a href="http://php.net" target="_blank">PHP5</a> app that can combine multiple CSS or Javascript files, compress their contents (i.e. removal of unnecessary whitespace/comments), and serve the results with HTTP encoding (gzip/deflate) and headers that allow optimal client-side caching.</p>
<p>Another tool which can be helpful is <a href="http://shrinksafe.dojotoolkit.org/" target="_blank">Dojo Shrinksafe</a> which not only minifies your javascript code but also allows you to upload several javascript files and have them compressed in 1 single file.</p>
<p>Another way to make fewer HTTP requests is by using CSS sprites which are big images containing lots of smaller ones. An online tool which can make CSS sprites out of your smaller ones is the <a href="http://spritegen.website-performance.org/" target="_blank">CSS Sprite Generator</a>. You just have to upload your pics and it will generate your sprite together with the CSS code. More info about CSS sprites can be found on <a href="http://css-tricks.com/css-sprites-what-they-are-why-theyre-cool-and-how-to-use-them/" target="_blank">CSS Tricks</a>.</p>
<hr/>
<strong>Add an Expires Header</strong><br />
For this to work on Apache, you&#8217;ll need to have <a href="http://httpd.apache.org/docs/2.0/mod/mod_expires.html" target="_blank">mod_expires</a> enabled. Then create an .htaccess file or edit your httpd.conf with the following content:</p>
<pre lang="apache">
ExpiresActive On
ExpiresByType image/jpg "access plus 2 years"
ExpiresByType image/jpeg "access plus 2 years"
ExpiresByType image/gif "access plus 2 years"
ExpiresByType application/javascript "access plus 2 years"
ExpiresByTYpe text/css "access plus 2 years"
</pre>
<p>In the above listing, all images(jpg/jpeg/gif) will have an expires header 2 years in the future.</p>
<hr/>
<strong>Gzip Components</strong><br />
You must have <a href="http://httpd.apache.org/docs/2.0/mod/mod_deflate.html" target="_blank">mod_deflate</a> enabled and drop these lines in your httpd.conf file</p>
<pre lang="apache">
SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary
</pre>
<hr/>
<strong>Put CSS at the Top</strong><br />
All CSS must be between your head tag, like that :</p>
<pre lang="html4strict">
	<html>
		<head>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" />
		</head>
		<body>

		</body>
	</html>
</pre>
<hr/>
<strong>Move Scripts to the Bottom</strong><br />
While the CSS are sitting at the top of your page, javascripts must be moved towards the lower part of your page, typically in the body tag. I usually put them before the closing body tag.</p>
<pre lang="html4strict">
	<html>
		<head>
		</head>
		<body>
		...
		...
		<script type="text/javascript" src="myjs.js"></script>
		</body>
	</html>
</pre>
<hr/>
<strong>Reduce DNS Lookups</strong><br />
I don&#8217;t usually have more than 2 DNS lookups in my scripts, else YSlow will be removing some points.</p>
<hr/>
<strong>Minify JavaScript</strong><br />
As I mentioned earlier on, <a href="http://shrinksafe.dojotoolkit.org/" target="_blank">Dojo Shrinksafe</a> is an online tool which minifies your code.</p>
<p>Another great command line tool is <a href="http://www.julienlecomte.net/blog/2007/08/11/" target="_blank">Julien Lecomte YUI Compressor</a>. </p>
<p>In order to use it you must have <a href="http://java.sun.com" target="_blank">Java</a> installed (>= 1.4).</p>
<p><a href="http://www.crockford.com/" target="_blank">Douglas Crockford</a> also has something similar in <a href="http://www.crockford.com/javascript/jsmin.html" target="_blank">JSMin</a></p>
<hr/>
<strong>Configure ETags</strong><br />
Just drop this line in your httpd.conf:</p>
<pre lang="apache">
FileETag None
</pre>
<p>;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://htmlblog.net/8-practical-tips-to-make-your-web-pages-faster/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

