<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><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:media="http://search.yahoo.com/mrss/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

    <channel>

    	<title>Timothy Fletcher</title>
    	
    	<link>http://timothyfletcher.com/feed</link>
    	<description>Stuff about web development using PHP and jQuery</description>
        <pubDate>Tue, 10 Nov 2009 22:59:00 -0700</pubDate>
        <generator>The timothyfletcher.com Blogging Engine</generator>
    	<language>en</language>
    	
    	    	
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/timothyfletcher" type="application/rss+xml" /><feedburner:emailServiceId>timothyfletcher</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
    		<title>Firefox Still the Winner For Web Development</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/hNoPnax4MPI/firefox-still-the-winner-for-web-development</link>
    		<comments>http://timothyfletcher.com/journal/posts/firefox-still-the-winner-for-web-development#comments</comments>
    		<pubDate>Thu, 16 Jul 2009 05:32:42 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;Firefox and I have a love hate relationship. Firefox has, in my opinion, the greatest developer features of any browser today. However, even on my Core 2 Duo 2.8GHz / 4 Gb RAM Macbook Pro it runs like crap. Safari on the other hand is an absolute joy to load up and browse with. It's super-snappy as a browser should be but it's developer tools, though much improved in Safari 4, are still not quite there. Firefox has a number of features that I consider 'killer' and I will need to see implemented in other browsers before I can full time switch. Belive me, I really want to switch.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Just to be clear, I spent a full month developing with Safari 4 to give it the fairest crack of the whip I could.
&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;Smart Location Bar&lt;/h3&gt;
&lt;p&gt;I don't have to remember the &lt;em&gt;Beginning&lt;/em&gt; of the URL to visit a site I've already been to. Firefox will automatically search my bookmarks/history and suggest matches from any part of the URL or page title based on my browsing history. I believe Chrome has this but we're still waiting for a Mac version. Safari's implementation requires me to jump through hoops to get to the history search and then it's crappy anyway.&lt;/p&gt;

&lt;h3&gt;Code View&lt;/h3&gt;
&lt;p&gt;Firstly, the syntax is highlighted which is absolutely glorious. Safari does not do this at all and although Opera 10b does, I struggled with Opera (particularly it's uglyness and lack of market share - I'll have to test in FF anyway). Secondly, I can click links in the code view and still be in code view when I visit the new page. How great is that?!&lt;/p&gt;

&lt;h3&gt;Reopen Last Closed Tab&lt;/h3&gt;
&lt;p&gt;I'm always closing tabs accidentally. Firefox's Shift + Cmd + T key command will open the last closed tab AND keep it's history information.&lt;/p&gt;

&lt;h3&gt;Firebug&lt;/h3&gt;
&lt;p&gt;Safari 4's web inspector is much improved but still not good enough. I found it keeps 'dropping off' whilst inspecting elements and it has some bizarre decisions in it's offerings such as only being able to see CSS colours in RGB rather than hex. The snappyness that developers require of their tools just isn't there. Firefox's Firebug addon needs no introduction. It is fast, very functional, well supported and easy to use.&lt;/p&gt;

&lt;h3&gt;Extensibility&lt;/h3&gt;
&lt;p&gt;I don't think it's reasonable to have a modern browser that's not (easily) extensible. Nobody will be happy with every browser and the capability to add user features is a succinct solution to this problem.&lt;/p&gt;

&lt;p&gt;I think there's some others but I can't remember them just now. I'll add to them as they come to me.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/hNoPnax4MPI" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/firefox-still-the-winner-for-web-development</feedburner:origLink></item>
        
            	
        <item>
    		<title>OS X Apps I Use for Web Development</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/5SHlevUKJt0/os-x-apps-i-use-for-web-development</link>
    		<comments>http://timothyfletcher.com/journal/posts/os-x-apps-i-use-for-web-development#comments</comments>
    		<pubDate>Wed, 11 Mar 2009 08:33:51 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;A Ruby developer &lt;a href="http://twitter.com/kylesmyth"&gt;friend&lt;/a&gt; of mine has just purchased a MacBook and is interested in the applications I use to develop for the web. Apple's OS X platform enjoys extensive support from independent developers which creates a variety of well built and reasonably priced applications. You could argue that the increased cost of buying a Mac is offset by the savings made on software. Anyway, here's my list. &lt;!--more--&gt;&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://macromates.com/" title="TextMate - The Missing Editor for Mac OS X"&gt;Textmate&lt;/a&gt; An incredibly powerful and extensible text editor. Make sure you hunt around for cool bundles, especially &lt;a href="http://ciaranwal.sh/2008/08/05/textmate-plug-in-projectplus" alt="ProjectPlus"&gt;ProjectPlus&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.adobe.com/products/fireworks/" title="graphics editor | Adobe Fireworks CS4"&gt;Fireworks CS4&lt;/a&gt; The only 'big name' app on this list. Fireworks CS4 is, unfortunately, the buggiest piece of software I've ever used but what it offers in speedy design &lt;i&gt;&lt;b&gt;just&lt;/b&gt;&lt;/i&gt; outweighs the crappiness. Hopefully fixed soon.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.apple.com/downloads/macosx/system_disk_utilities/caffeine.html" title="Apple - Downloads - System/Disk Utipties - Caffeine"&gt;Caffeine&lt;/a&gt; A tiny program that prevent your Mac from automatically going to sleep, dimming the screen or starting screen savers. ESSENTIAL!&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.mozilla.com/en-US/firefox/" title="Firefox web browser | Faster, more secure, &amp;amp; customizable"&gt;Firefox 3&lt;/a&gt; I've tried time and time again to use Safari because of Firefox's performance issues but the quality of developer tools for Firefox simply cannot be beaten.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.zennaware.com/cornerstone/" title="Zennaware  &amp;raquo; Cornerstone Subversion Client for Mac OS X"&gt;Cornerstone&lt;/a&gt; Great SVN client. Includes built in diff with image support. Your choices are between this and &lt;a href="http://versionsapp.com/" title="Versions - Mac Subversion Cpent (SVN)"&gt;Versions&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://getdropbox.com/" title="Dropbox - Home - Secure backup, sync and sharing made easy."&gt;&lt;/a&gt; Syncs your files online and across computers. I use this for all mission critical work. I can access it on any PC/Mac/linux machine and on the web. Versions files too. Free and one of the best apps ever.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://hivelogic.com/enkoder" title="Hivelogic - The Enkoder"&gt;Enkoder&lt;/a&gt; Dan Benjamin's anti-spam email obfuscater.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.xmarks.com/" title="Bookmark-Powered Web Discovery"&gt;Xmarks&lt;/a&gt; Syncs across browsers and backs up all my bookmarks online. I can reinstall and have everything back instantly.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://derailer.org/paparazzi/" title="Paparazzi!"&gt;Paparazzi&lt;/a&gt; Takes snapshots of websites. Captures whole page rather than just visible screen area.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.charcoaldesign.co.uk/pipette" title="Pipette | Software | Charcoal Design"&gt;Pipette&lt;/a&gt; Screen colour dropper. I use this all the time.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.araelium.com/screenflick/" title="Araepum Group : Screenfpck - Screen Recording / Capture"&gt;Screenflick&lt;/a&gt; Nice screencasting app. I use it to record nice jQuery and dynamic website effects.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.sequelpro.com/" title="Sequel Pro &amp;mdash; MySQL database management app for Mac OS X"&gt;Sequel Pro&lt;/a&gt; Nice, free MySQL administration app.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.apple.com/macosx/features/timemachine.html" title="Apple - Mac OS X Leopard - Features - Time Machine"&gt;Time Machine&lt;/a&gt; Apple's backup solution. Does the job without getting in the way. Oh, and it works really well.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://iconfactory.com/software/twitterrific" title="Iconfactory : Software : Twitterrific"&gt;Twitterrific&lt;/a&gt; Nice native Twitter client.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.virtualbox.org/" title="VirtualBox"&gt;Virtualbox&lt;/a&gt; Amazing FREE virtualisation software from Sun. I use this every day for IE testing.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://habilis.net/validator-sac/" title="Validator S.A.C. - Stand-Alone W3C HTML Validator Application for Mac OS X"&gt;Validator S.A.C&lt;/a&gt; Native version of the W3C Validator. Great for checking the validity of (X)HTML on your local development server.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/5SHlevUKJt0" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/os-x-apps-i-use-for-web-development</feedburner:origLink></item>
        
            	
        <item>
    		<title>jQuery Plugin : Image Slideshow / Cycle</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/EQgoYeLrWuI/jquery-plugin-image-slideshow-cycle</link>
    		<comments>http://timothyfletcher.com/journal/posts/jquery-plugin-image-slideshow-cycle#comments</comments>
    		<pubDate>Sat, 07 Mar 2009 16:24:01 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;I frequently find that clients want a dynamic image slideshow banner for their sites; the one where an image displays for a few seconds before fading to the next. The most popular jQuery solution is the excellent &lt;a href="http://malsup.com/jquery/cycle/" title="JQuery Cycle Plugin"&gt;Cycle plugin&lt;/a&gt;. However, I'm a bit picky about file sizes and felt the minified 18k was too much for such a simple effect. Here's my efforts as a jQuery plugin. The file size is a mere 1k.&lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;Demo and Files&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://timothyfletcher.com/demos/jquery-image-slideshow/index.php"&gt;Checkout the demo&lt;/a&gt; | 
&lt;a href="http://timothyfletcher.com/downloads/jquery-image-slideshow.zip"&gt;Download the files&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Usage Instructions&lt;/h3&gt;

&lt;p&gt;First, include jQuery and the &lt;strong&gt;jquery.slideshow.js&lt;/strong&gt; plugin. I recommend using &lt;a href="http://code.google.com/apis/ajaxlibs/"&gt;Google's hosted library&lt;/a&gt;.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot; src=&amp;quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot; src=&amp;quot;plugins/jquery.slideshow.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Your basic HTML should look as below. You don't need to use an id of #banner, it can be anything that's selectable by jQuery (which is pretty much everything).&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
&amp;lt;div id=&amp;quot;slideshow&amp;quot;&amp;gt;
    &amp;lt;img src=&amp;quot;images/image-slideshow/image1.jpg&amp;quot; alt=&amp;quot;image1&amp;quot;&amp;gt;
    &amp;lt;img src=&amp;quot;images/image-slideshow/image2.jpg&amp;quot; alt=&amp;quot;image2&amp;quot;&amp;gt;
    &amp;lt;img src=&amp;quot;images/image-slideshow/image3.jpg&amp;quot; alt=&amp;quot;image3&amp;quot;&amp;gt;
    &amp;lt;img src=&amp;quot;images/image-slideshow/image4.jpg&amp;quot; alt=&amp;quot;image4&amp;quot;&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Finally, setup the options if (you don't like the defaults) and away you go!&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
$(document).ready(function(){
    var options = {
		crossFadeTime: 1000,
		displayTime: 5000
	};
    $(&amp;apos;#slideshow&amp;apos;).slideshow(options);  
});    
&lt;/pre&gt;

&lt;p&gt;I've tested in IE6/7, FF2/3 and Safari 3/4. If you like this plugin, use it on a site or you've got anything to add, please hit me up in the comments. Ta!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/EQgoYeLrWuI" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/jquery-plugin-image-slideshow-cycle</feedburner:origLink></item>
        
            	
        <item>
    		<title>Un-Minimise OS X Applications with the Keyboard</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/Ux4SMUjyjaw/unminimise-os-x-applications-with-the-keyboard</link>
    		<comments>http://timothyfletcher.com/journal/posts/unminimise-os-x-applications-with-the-keyboard#comments</comments>
    		<pubDate>Tue, 27 Jan 2009 20:10:27 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;I thought I'd share one of my all time favourite OS X keyboard shortcuts: How to un-minimise an application window without using the mouse. It's not at all obvious but it's easy to use and once you're into it you'll be wondering how you ever managed to use a Mac without it.&lt;!--more--&gt;&lt;/p&gt;
&lt;p&gt;If you use Cmd + Tab to traverse currently open applications, you'll have noticed that minimised applications (minimised with Cmd + M, naturally) do not un-minimise when you switch to them. You actually have to click on the app/window in the dock to get it to slide into view. However, there is a way of getting these minimised windows onto the screen without sliding further towards carpal tunnel. Once you've landed on the app with Cmd + Tab, continue to hold Cmd and press Option, then release Cmd (and then Option) and the app will un-minimise!&lt;/p&gt;
&lt;p&gt;I use this every single day. It's also useful for pulling up a Finder window of your home folder. Ta!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/Ux4SMUjyjaw" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/unminimise-os-x-applications-with-the-keyboard</feedburner:origLink></item>
        
            	
        <item>
    		<title>Simple jQuery Link Color Animation Tutorial</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/VrqI1ZxJaE8/simple-jquery-link-color-animation-tutorial</link>
    		<comments>http://timothyfletcher.com/journal/posts/simple-jquery-link-color-animation-tutorial#comments</comments>
    		<pubDate>Fri, 23 Jan 2009 08:48:13 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;Beginner tutorials for jQuery are all over the tubes. I believe it's in the good spirit of the Internet to give back a little for the free tutorials and books from which my programming skills are borne. Hence I present here a beginner's tutorial on using jQuery to create a navigation menu with on-hover colour transition/fading links. &lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;As with all Javascript, and particularly with navigation, we should ensure that the page is still usable with Javascript disabled. The best way of doing this is to build your page with XHTML/CSS so it works in all browsers and apply your Javascript afterwards. You could also test it afterwards by turning off Javascript in your browser.&lt;/p&gt;
&lt;p&gt;We will be using jQuery's &lt;a href="http://plugins.jquery.com/project/color" title="jQuery Colour Plugin"&gt;color plugin&lt;/a&gt; which adds the ability for colour animations to jQuery 1.2 and newer.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://timothyfletcher.com/demos/jquery-menu-fade/index.html"&gt;DEMO&lt;/a&gt; - &lt;a href="http://timothyfletcher.com/downloads/jquery-menu-fade.zip"&gt;FILES&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;The (X)HTML&lt;/h3&gt;
&lt;p&gt;The XHTML is super simple, just how I like it. Check the &lt;a href="http://timothyfletcher.com/demos/jquery-menu-fade/index.html"&gt;demo&lt;/a&gt; for CSS/JS file includes in the header etc.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
&amp;lt;ul id=&amp;quot;menu&amp;quot;&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; &amp;gt;Home&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;curr&amp;quot;&amp;gt;Journal&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; &amp;gt;Portfolio&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; &amp;gt;Services&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; &amp;gt;About&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; &amp;gt;Contact&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/pre&gt;

&lt;h3&gt;The CSS&lt;/h3&gt;
&lt;p&gt;Full CSS can be grabbed from the &lt;a href="http://timothyfletcher.com/downloads/jquery-menu-fade.zip"&gt;download&lt;/a&gt;, the salient bits are shown here.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;
/* Navigation */
#menuContainer          {width: 960px; margin: 0 auto; padding: 0;}
ul#menu                 {font: 13px Verdana,arial,helvetica,sans-serif; width: 700px; text-transform: uppercase; margin: 0; padding: 0; background: #181E24; float: left;}
ul#menu li              {margin-right: 10px; float:left; list-style-type:none;}
ul#menu li a            {font-weight: normal; color: #EEEEEE; display: block; padding: 60px 12px 10px 12px;}
ul#menu li a:hover      {text-decoration:none; color: #B03024;}
ul#menu li a#curr       {text-decoration:none; background: #B03024;}
ul#menu li a#curr:hover {color: #EEEEEE;}
&lt;/pre&gt;
&lt;h3&gt;The jQuery&lt;/h3&gt;
&lt;pre class="prettyprint"&gt;
$(document).ready(function(){

    // Set initial colour of menu links so that CSS a:hover is overridden
    $(&amp;#x27;#menu a&amp;#x27;).css({&amp;#x27;color&amp;#x27; : &amp;#x27;#EEEEEE&amp;#x27;});

    // Add colour transitions to menu links but not current link
    $(&amp;#x27;#menu li a:not(#curr)&amp;#x27;).hover(
        function () {
            $(this).animate({ color: &amp;#x27;menuon&amp;#x27; }, 300);
        }, 
        function () {
            $(this).animate({ color: &amp;#x27;menuoff&amp;#x27; }, 300);
        }
    );

});
&lt;/pre&gt;
&lt;p&gt;Again, this is relatively simple stuff. Firstly, we set the colour of the navigation's links to &lt;code&gt;#EEEEEE&lt;/code&gt;, the same colour as they are set initially in the CSS. This is done to solve the issue the CSS's of a:hover causing an immediate change in the link's colour with the first mouseover. You can see this in action by commenting out the line.&lt;/p&gt;
&lt;p&gt;Next we select all links within the &lt;code&gt;ul&lt;/code&gt; with an id of &lt;code&gt;menu&lt;/code&gt; but &lt;em&gt;exclude&lt;/em&gt; links with the id of &lt;code&gt;curr&lt;/code&gt;. As the menu item for the current page is highlighted in orange (the current page it detected with PHP), we don't want this item to change colour. Now we have the correct selection we can bind the &lt;code&gt;hover&lt;/code&gt; action to it. &lt;code&gt;Hover&lt;/code&gt; takes two (anonymous) functions as it's parameters, one for mouseover and one for mouseout. We define these functions using the animate method of the jQuery color plugin. I've tweaked the plugin slightly to assign the colours I need to &lt;code&gt;menuon&lt;/code&gt; and &lt;code&gt;menuoff&lt;/code&gt;. The final animate parameter is the time for the transition.&lt;/p&gt;
&lt;p&gt;This effect is really simple to achieve and adds a nice touch to an otherwise basic navigation. Hit me up in the comments if you have any questions.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/VrqI1ZxJaE8" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/simple-jquery-link-color-animation-tutorial</feedburner:origLink></item>
        
            	
        <item>
    		<title>Moving Feeds - Please Update</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/N488oFlM6l8/moving-feeds-please-update</link>
    		<comments>http://timothyfletcher.com/journal/posts/moving-feeds-please-update#comments</comments>
    		<pubDate>Tue, 20 Jan 2009 08:05:43 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;As part of my site rebranding and of Google's requirement for me to move my Feedburner feeds, I will be moving my RSS feed from &lt;strong&gt;http://feeds.feedburner.com/dreamadelica&lt;/strong&gt; to &lt;a href="http://feeds2.feedburner.com/timothyfletcher" title="New Timothy Fletcher Feed"&gt;http://feeds2.feedburner.com/timothyfletcher&lt;/a&gt;. I've already noted that this caused Google Reader to update itself with all of my posts. Sorry 'bout that. Not much I could do. I'll be deleting the old feed in a day or two. Cheers.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/N488oFlM6l8" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/moving-feeds-please-update</feedburner:origLink></item>
        
            	
        <item>
    		<title>PHP Twitter Status Class for Your Blog With cURL</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/HHOHiJWEWgM/php-twitter-status-class-for-your-blog-with-curl</link>
    		<comments>http://timothyfletcher.com/journal/posts/php-twitter-status-class-for-your-blog-with-curl#comments</comments>
    		<pubDate>Mon, 19 Jan 2009 07:57:58 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;A little while ago, I posted some code for a &lt;a href="http://timothyfletcher.com/journal/posts/simple-php-twitter-status-badge" title="Simple PHP Twitter Status Badge"&gt;Simple PHP Twitter Status Badge&lt;/a&gt;. Whereas that code was fine, my programming skills have moved on and I recently built a much better solution using Twitter's REST API and PHP's cURL extension.&lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;Why Reinvent the Wheel?&lt;/h3&gt;
&lt;p&gt;The original badge did not provide access to authenticated APIs, tweet caching or particularly informative error handling. The cURL extension is an excellent library that, according to the &lt;a href="http://ca2.php.net/manual/en/intro.curl.php" title="PHP: Introduction - Manual"&gt;PHP manual page&lt;/a&gt;, allows you to:&lt;/p&gt;

&lt;blockquote&gt;
...connect and communicate to many different types of servers with many different types of protocols. libcurl currently supports the http, https, ftp, gopher, telnet, dict, file, and ldap protocols. libcurl (which cURL basically is) also supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading (this can also be done with PHP's ftp extension), HTTP form based upload, proxies, cookies, and user+password authentication. 
&lt;/blockquote&gt;

&lt;h3&gt;Class Description&lt;/h3&gt;
&lt;p&gt;I've designed the class such that it can be easily extended with additional methods in the future. For this reason, authentication is set up in the constructor even thought it's not actually required to display the latest tweet from a user. Reference to the &lt;a href="http://apiwiki.twitter.com/REST+API+Documentation#StatusMethods" title="Twitter API Wiki / REST API Documentation"&gt;Twitter API Wiki page&lt;/a&gt; shows that you can use the &lt;code&gt;public_timeline&lt;/code&gt; status method to return the 20 most recent statuses from non-protected users who have set a custom user icon. The &lt;code&gt;getLatestTweet()&lt;/code&gt; method in my class uses the authenticated &lt;code&gt;user_timeline&lt;/code&gt; status method to provide the same functionality but including protected tweets etc. I wanted to learn how to use authentication so I did it this way.&lt;/p&gt;
    
&lt;p&gt;The code is well commented so I won't describe it in too much detail here. The main things to make sure you do is handle the exceptions properly. There are two different types; &lt;code&gt;Exception&lt;/code&gt; and &lt;code&gt;FileException&lt;/code&gt;, both of which are handled by my exception processing class in the ending catch blocks. You should adapt the code to handle these as you wish. One other thing is the &lt;code&gt;ResultObject&lt;/code&gt; class which is a simple object wrapper for data. You don't have to use this, I just like objects.&lt;/p&gt;

&lt;p&gt;Below is the code. It's a little tricky to follow due to scrolling so I've included &lt;a href="http://timothyfletcher.com/downloads/class.twitter.php.txt"&gt;downloadable version&lt;/a&gt; to negate copy/pasting errors. Cheers!&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;?php

class Twitter_Library
{
  private $_username;
  private $_password;
  private $_curl;
    
//=====================================================================
    
  public function __construct()
  {
    $this-&amp;gt;_username = &amp;#x27;TwitterUsername&amp;#x27;;
    $this-&amp;gt;_password = &amp;#x27;TwitterPassword&amp;#x27;;

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_USERPWD, $this-&amp;gt;_username . &amp;#x27;:&amp;#x27; . $this-&amp;gt;_password);
    curl_setopt($curl, CURLOPT_FAILONERROR, 1);

    // Return the actual output from curl_exec() rather than true/false
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    // Timeouts
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 4);
    curl_setopt($curl, CURLOPT_TIMEOUT, 4);

    // Set the PHP script&amp;#x27;s timeout to be greater than CURL&amp;#x27;s
    set_time_limit(6);

    $this-&amp;gt;_curl = $curl;
  }
    
//=====================================================================
    
  public function getLatestTweet()
  {
    // You must create this cache file manually
    $tweetCache = SITE_ROOT . &amp;#x27;private/temp/tweet.txt&amp;#x27;;
  
    try {

      if (file_exists($tweetCache)) {

        // Have 2.5 minutes passed since file was created? (24 requests per hour)
        if ((time() - filemtime($tweetCache)) &amp;gt; 150) {

          // Yes - Get tweet from twitter
          curl_setopt($this-&amp;gt;_curl, CURLOPT_URL, &amp;#x27;http://twitter.com/statuses/user_timeline.xml&amp;#x27;);
          $result = curl_exec($this-&amp;gt;_curl);

          // Check for errors in returned content
          if (curl_errno($this-&amp;gt;_curl) == 0) {

            curl_close($this-&amp;gt;_curl);

            // SimpleXML throws an exception of type Exception on fail
            $tweets = @new SimpleXMLElement($result);

            // Write new tweet to cache
            if (is_writable($tweetCache)) {
              
              $tweetHandle = File::fopen($tweetCache, &amp;#x27;w&amp;#x27;);
              File::fwrite($tweetHandle, $tweets-&amp;gt;status[0]-&amp;gt;text);
              return $tweets-&amp;gt;status[0];

            } else {

              throw new FileException(&amp;#x27;The tweet cache file is not writable&amp;#x27;, FILE_ERROR);
            }

          } else {

              curl_close($this-&amp;gt;_curl);
              return false;
          }

        } else {

          // No - Get tweet from cache
          $tweetHandle = File::fopen($tweetCache, &amp;#x27;r&amp;#x27;);
          $result = new ResultObject();
          $result-&amp;gt;text = File::fgets($tweetHandle);
          File::fclose($tweetHandle);
          return $result;
        }

      } else {

        throw new FileException(&amp;#x27;The tweet cache file does not exist&amp;#x27;, FILE_ERROR);
      }
  
    } catch (FileException $e) {
      
      ExceptionHandler::handleException($e);

    } catch (Exception $e) {

      ExceptionHandler::handleException($e);
    }
  }
}
?&amp;gt;
&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/HHOHiJWEWgM" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/php-twitter-status-class-for-your-blog-with-curl</feedburner:origLink></item>
        
            	
        <item>
    		<title>Add Textmate's Missing Slashes for Valid XHTML</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/lOip-738Caw/add-textmates-missing-slashes-for-valid-xhtml</link>
    		<comments>http://timothyfletcher.com/journal/posts/add-textmates-missing-slashes-for-valid-xhtml#comments</comments>
    		<pubDate>Fri, 26 Dec 2008 15:22:36 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;In its default configuration, Textmate doesn't add closing slashes for self closing XHTML elements such as &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt;. This is not an oversight on the part of the bundle's creator, it's just that the default configuration is for HTML. Fortunately it's easy to set up Textmate's HTML bundle to generate valid XHTML instead.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;If you look into the HTML bundle using the bundle editor (Ctrl-Option-Cmd-B), you'll see that the offending snippets contain the variable TM_XHTML in place of where you'd expect to see the XHTML's closing slash.&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/textmate-bundle-editor.png" alt="Textmate Bundle Editor" title="Textmate's Bundle Editor" /&gt;

&lt;p&gt;To assign a value to this variable we go to the advanced tab in Textmate's preferences and enter a new variable called TM_XHTML and assign it the value of /.&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/textmate-advanced-prefs.png" alt="Textmate Advanced Preferences" title="Textmate's Advanced Preferences" /&gt;

&lt;p&gt;That's it! You don't even need to restart Textmate for these changes to come into effect. That's potentially a lot less slashes to add when you validate your pages.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/lOip-738Caw" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/add-textmates-missing-slashes-for-valid-xhtml</feedburner:origLink></item>
        
            	
        <item>
    		<title>How to Use Subversion for Your Website</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/J4X6FvKOy1A/how-to-use-subversion-for-your-website</link>
    		<comments>http://timothyfletcher.com/journal/posts/how-to-use-subversion-for-your-website#comments</comments>
    		<pubDate>Wed, 17 Dec 2008 20:49:08 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;&lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; is the most popular revision control system available today. If you're not using it to manage your website's files then you should be be. Why? Because it offers you lots of really cool features that, once you get used to, you'll wonder how you ever managed without.&lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;The Wrong Way&lt;/h3&gt;
&lt;p&gt;When I first started using Subversion I didn't think it was that great. I had a repository set up on my local dev environment into which I committed the various revisions of the files I was working on. Once happy I would then FTP the whole lot (or at least the files I knew had changed) up to my server and meticulously check that my changes were working as intended. This is &lt;strong&gt;totally&lt;/strong&gt; the wrong way to work. &lt;strong&gt;Totally.&lt;/strong&gt; Why use versioning software if you don't know which files have changed? Let's explore another way.&lt;/p&gt;

&lt;h3&gt;The Right Way&lt;/h3&gt;
&lt;p&gt;The location of the repository is the key. It needs to be on your server, not your local machine. Consider this: You upload your website once (and once only) to the server. From there it's imported into a new repository and, with the files safe, the original files are deleted. Now, assuming your site is in a suitable state to be live on the Internet, you can simply check out a working copy to your server's web root folder and your site is live. Because this is a local file transfer, it takes a fraction of the time it would if you were uploading.&lt;/p&gt;

&lt;p&gt;To make changes to your site, check out another working copy to your local machine. You then make a project from these files and work locally, doing all your testing and development until, once you're 100% happy, you commit your revisions back to the repository. Because each working copy contains a number of additional (invisible) &lt;code&gt;.svn&lt;/code&gt; files, it knows which files have been modified and transmits only them to the server. The online repository now exactly mirrors your local copy. To 'push' your new code to the site you issue a quick &lt;code&gt;svn update&lt;/code&gt; command and bang! Instant website update! Only the files that require modification/addition/deletion are updated. If you're not happy for any reason it's just as quick to revert to an older version as they're all available in the repository.&lt;/p&gt;

&lt;h3&gt;How to Implement Subversion&lt;/h3&gt;
&lt;p&gt;There's a bit of a learning curve associated with Subversion but with new &lt;a href="http://www.versionsapp.com/"&gt;graphical&lt;/a&gt; &lt;a href="http://www.zennaware.com/"&gt;clients&lt;/a&gt; coming out a plenty you'll be away in no time. My site runs on a 256 &lt;a href="http://www.slicehost.com"&gt;Slicehost&lt;/a&gt; Slice onto which I installed and configured Subversion using the &lt;a href="http://articles.slicehost.com/sitemap"&gt;outstanding documentation&lt;/a&gt; provided by Slicehost. These guides apply to any Linux server and offer valuable information to anyone hoping to grow as a web professional. Give them a look.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/J4X6FvKOy1A" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/how-to-use-subversion-for-your-website</feedburner:origLink></item>
        
            	
        <item>
    		<title>Screen Measuring with Screen Capture in OS X</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/LeXfoPNZNS8/screen-measuring-with-screen-capture-in-os-x</link>
    		<comments>http://timothyfletcher.com/journal/posts/screen-measuring-with-screen-capture-in-os-x#comments</comments>
    		<pubDate>Wed, 17 Dec 2008 07:20:15 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;Sometimes you just want to have a quick and dirty way to approximate a pixel-based measurement within the browser. Yes, there are Firefox extensions such as &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/539"&gt;MeasureIt&lt;/a&gt;, but I'm talking about an even better way: one without installing any additional software to OS X.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;OS X has had some excellent built-in screen capture features:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt; ⇧ ⌘ 3 - Capture Entire Screen(s)&lt;/li&gt;
    &lt;li&gt; ⇧ ⌘ 4 - Capture Screen Portion&lt;/li&gt;
    &lt;li&gt; ⇧ ⌘ 4 followed by Space - Capture entire window or menu&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key feature here is the second one: Capture Screen Portion. Hitting  ⇧ ⌘ 4 brings up a small crosshair which is used to designate the capture selection with the mouse. Initially it shows the coordinates of the cursor on the screen but once you're dragging out the selection, the actual selection size is shown next to the crosshair. Perfect for measuring screen sections! To avoid taking a picture to your desktop everytime you measure something, you can hit Esc to cancel the selection. I use this feature almost every time I XHTML/CSS designs.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/LeXfoPNZNS8" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/screen-measuring-with-screen-capture-in-os-x</feedburner:origLink></item>
        
            	
        <item>
    		<title>Simple Disjoint Image Swap With JQuery</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/AEYCYdpUrcY/simple-disjoint-image-swap-with-jquery</link>
    		<comments>http://timothyfletcher.com/journal/posts/simple-disjoint-image-swap-with-jquery#comments</comments>
    		<pubDate>Tue, 25 Nov 2008 07:26:10 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;Having spent a good 9 months intensively studying PHP and gettting to a pretty good standard, I'm onto Javascript now, specifically &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt;. Despite the many awesome and tempting effects, I'm starting at the beginning and solving the kinds of problems that you come across in a typical web project. Here I document how to perform a basic disjoint rollover or swap image. This script will allow you to hover over a thumbnail and display a larger preview of that image.&lt;!--more--&gt; &lt;a href="http://timothyfletcher.com/demos/jquery-image-swap/index.html"&gt;DEMO&lt;/a&gt; - &lt;a href="http://timothyfletcher.com/downloads/jquery-image-swap.zip"&gt;FILES&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;The HTML&lt;/h3&gt;
&lt;p&gt;The HTML is semantic and as simple as possible.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;div id=&amp;quot;imageContainer&amp;quot;&amp;gt;

    &amp;lt;img src=&amp;quot;images/image-swap/image1.jpg&amp;quot; width=&amp;quot;240&amp;quot; height=&amp;quot;180&amp;quot; alt=&amp;quot;Image1&amp;quot; id=&amp;quot;image1&amp;quot;&amp;gt;
    &amp;lt;img src=&amp;quot;images/image-swap/image2.jpg&amp;quot; width=&amp;quot;240&amp;quot; height=&amp;quot;180&amp;quot; alt=&amp;quot;Image2&amp;quot; id=&amp;quot;image2&amp;quot;&amp;gt;
    &amp;lt;img src=&amp;quot;images/image-swap/image3.jpg&amp;quot; width=&amp;quot;240&amp;quot; height=&amp;quot;180&amp;quot; alt=&amp;quot;Image3&amp;quot; id=&amp;quot;image3&amp;quot;&amp;gt;

&amp;lt;/div&amp;gt;

&amp;lt;div id=&amp;quot;thumbContainer&amp;quot;&amp;gt;
    
    &amp;lt;a href=&amp;quot;#image1&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;images/image-swap/thumb1.jpg&amp;quot; width=&amp;quot;80&amp;quot; height=&amp;quot;60&amp;quot; alt=&amp;quot;Thumb1&amp;quot; id=&amp;quot;thumb1&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;quot;#image2&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;images/image-swap/thumb2.jpg&amp;quot; width=&amp;quot;80&amp;quot; height=&amp;quot;60&amp;quot; alt=&amp;quot;Thumb2&amp;quot; id=&amp;quot;thumb2&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;quot;#image3&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;images/image-swap/thumb3.jpg&amp;quot; width=&amp;quot;80&amp;quot; height=&amp;quot;60&amp;quot; alt=&amp;quot;Thumb3&amp;quot; id=&amp;quot;thumb3&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;
    
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;h3&gt;The CSS&lt;/h3&gt;
&lt;pre&gt;
#imageContainer         {width: 255px; height: 180px; overflow: hidden;}
#imageContainer img     {margin-bottom: 5px; display: block;}
#thumbContainer         {margin-top: 5px;}
#thumbContainer img     {display: block; float: left;}
&lt;/pre&gt;

&lt;p&gt;The operation of this code is simple. The three identically sized large images are contained within the &lt;code&gt;div#imageContainer&lt;/code&gt; which is limited in size via CSS to the size of a single image and has &lt;code&gt;overflow: hidden&lt;/code&gt; to remove any scroll bars. This means that all the images exist on the page and are preloaded but hidden from view. Standards compliant browsers render images as inline elements which have an associated line-height. We must therefore use &lt;code&gt;display:block;&lt;/code&gt; to remove the few pixels of gap at the bottom of &lt;code&gt;div#imageContainer&lt;/code&gt;. Each thumbnail image is contained within an anchor link which associates it with the appropriate main image. When clicked, the &lt;code&gt;div#imageContainer&lt;/code&gt; will scroll/jump to display the appropriate image.&lt;/p&gt;

&lt;p&gt;It's important to make sure that your script manipulated HTML/CSS will still be usable if your users have Javascript turned off. This is why we are taking the XHTML/CSS approach first and then applying the Javascript to it later. It's not 100% perfect as each click takes you to a 'new' url which breaks the back button. It should be stressed that &lt;em&gt;only&lt;/em&gt; users with Javascript turned off will see this.&lt;/p&gt;

&lt;h3&gt;The Javascript&lt;/h3&gt;
&lt;p&gt;Currently our XHTML/CSS needs the thumbnail to be clicked to get the large image to swap. What we need is for the swap to occur when the user mouses over the thumbnail. With jQuery this is simple. Place the following within your &lt;code&gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&lt;/code&gt; tags or, more properly in an external script and link it in the head.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; charset=&amp;quot;utf-8&amp;quot;&amp;gt;
    
    $(document).ready(function(){

        // Hide all large images except the first one
        $(&amp;#x27;#imageContainer img&amp;#x27;).hide().filter(&amp;#x27;:first&amp;#x27;).show();

        // Select all thumb links
        $(&amp;#x27;#thumbContainer a&amp;#x27;).hover(function(event) {

                // Hide all large images except for the one with the same hash as our thumb link
                $(&amp;#x27;#imageContainer img&amp;#x27;).hide().filter(this.hash).show();
            },
            function () {} // Because the hover method has a mouseout state we need to define too
        );
    });

&amp;lt;/script&amp;gt;
&lt;/pre&gt;

&lt;p&gt;I'll not explain the very basics as they're covered well on the &lt;a href="http://www.jquery.com"&gt;jQuery&lt;/a&gt; site but what is happening here is that we are selecting all of the large images, hiding them and then displaying the first one. Next we select all of the links within &lt;code&gt;#thumbContainer&lt;/code&gt; and attach a &lt;code&gt;.hover&lt;/code&gt; action to them. The hover event accepts two callbacks as it's parameters: mouseover and mouseout, both of which need to be defined. When the link is hovered, all the large images are hidden except for the one which matches the hash link from the anchor we hovered. The currently selected element is represented by &lt;code&gt;$(this)&lt;/code&gt; and you access it's methods using period notation.&lt;/p&gt;

&lt;p&gt;Here's the code demo and download: &lt;a href="http://timothyfletcher.com/demos/jquery-image-swap/index.html"&gt;DEMO&lt;/a&gt; - &lt;a href="http://timothyfletcher.com/downloads/jquery-image-swap.zip"&gt;FILES&lt;/a&gt;&lt;!--more--&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/AEYCYdpUrcY" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/simple-disjoint-image-swap-with-jquery</feedburner:origLink></item>
        
            	
        <item>
    		<title>Changing Textmate Key Commands</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/kJL9hHSsgMU/changing-textmate-key-commands</link>
    		<comments>http://timothyfletcher.com/journal/posts/changing-textmate-key-commands#comments</comments>
    		<pubDate>Fri, 21 Nov 2008 20:15:19 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;I've found it a little annoying that Textmate's default key commands for switching tabs is different from that of Safari and Firefox. Textmate defaults to &amp;#8997; &amp;#8984; &amp;larr; and &amp;#8997; &amp;#8984; &amp;rarr; whereas the browsers are  ⇧ &amp;#8984; [ and  ⇧ &amp;#8984; ]. Every time I have to move my hand to the cursor keys it slows me down and is less comfortable. Strange then that it took me so long to get around to changing Textmate's defaults, particularly as it's so straightforward.&lt;!--more--&gt;&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;System Preferences -&gt; Keyboard &amp;amp; Mouse&lt;/li&gt;
    &lt;li&gt;Click the + icon at the bottom left of the scrollable window&lt;/li&gt;
    &lt;li&gt;Select Textmate as the Application&lt;/li&gt;
    &lt;li&gt;Type "Next File Tab" as the Menu Title&lt;/li&gt;
    &lt;li&gt;Hit  ⇧ &amp;#8984; [ whilst in the keyboard shortcut box&lt;/li&gt;
    &lt;li&gt;Repeat using "Previous File Tab" and  ⇧ &amp;#8984; ]&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Note: &lt;/strong&gt;For the special characters to show up in this post, the page must be rendered using a font that supports them. Typically, Mac fonts do but Windows fonts don't.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/kJL9hHSsgMU" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/changing-textmate-key-commands</feedburner:origLink></item>
        
            	
        <item>
    		<title>Free 100% Cross Browser 2/3 Column Layouts</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/_N8ahlEuqhQ/free-100-cross-browser-23-column-layouts</link>
    		<comments>http://timothyfletcher.com/journal/posts/free-100-cross-browser-23-column-layouts#comments</comments>
    		<pubDate>Tue, 18 Nov 2008 07:38:44 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;A couple of months ago I put together two cross-browser, pixel-perfect two and three column fixed width layouts. I'd found that when slicing Photoshop comps at work that the &lt;a href="http://developer.yahoo.com/yui/grids/"&gt;YUI Grids Framework&lt;/a&gt; was just too inflexible when having to specify precise widths. YUI sets everything in &lt;code&gt;ems&lt;/code&gt; so you have to calculate widths. In fact you need to calculate twice as IE requires a different value. &lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;d highly recommend having a go at building your own as it taught me a lot about cross-browser compatibility, particularly the quirks of IE5.5 and 6. However, if you just want to get going, I've provided them here for download. They're pixel-perfect in most (all?) browsers including IE 5.5.&lt;/p&gt;

&lt;p&gt;Download: &lt;a href="http://timothyfletcher.com/downloads/2-column-fixed.zip"&gt;2-column-fixed.zip&lt;/a&gt;&lt;br /&gt;
Download: &lt;a href="http://timothyfletcher.com/downloads/3-column-fixed.zip"&gt;3-column-fixed.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/_N8ahlEuqhQ" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/free-100-cross-browser-23-column-layouts</feedburner:origLink></item>
        
            	
        <item>
    		<title>Is There Such a Thing as a Simple Web App?</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/kkCaOLlMpcY/is-there-such-a-thing-as-a-simple-web-app</link>
    		<comments>http://timothyfletcher.com/journal/posts/is-there-such-a-thing-as-a-simple-web-app#comments</comments>
    		<pubDate>Mon, 17 Nov 2008 19:45:25 -0700</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;As a professional development exercise over the last couple of weeks, I've built myself a new blog using the PHP5 framework I've been putting together. I was getting a little frustrated with Wordpress and my reliance on the plugins of others. Inevitably they break after one of Wordpress's many critical security updates. What initially started as a small project with intentions of simplicity quickly grew into a fairly complex application. It's difficult to launch a modern web application of any sort without a level of complexity and it seems that managing that complexity is one of the skills of application development. &lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;To give an example of how a seemingly simple feature can become a huge amount of work, consider the example of commenting. On the face of it you simply have a form that accepts input, writes it to a database and your page then pulls the comments from the database and displays them with the post. For an amateur job that would be fine. For a professional like myself we should consider the following:&lt;/p&gt;

&lt;h3&gt;Receiving comments&lt;/h3&gt;

&lt;ul&gt;
    &lt;li&gt;Filtering of $_POST input&lt;/li&gt;
    &lt;li&gt;Sanitising of $_POST input&lt;/li&gt;
    &lt;li&gt;Setting of cookies to show the comment only to its author until it is approved&lt;/li&gt;
    &lt;li&gt;Spam filtering&lt;/li&gt;
    &lt;li&gt;Alerting the administrator via email&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Displaying comments&lt;/h3&gt;

&lt;ul&gt;
    &lt;li&gt;Are we accepting comments?&lt;/li&gt;
    &lt;li&gt;Is the current reader the comment author? How should we show the unapproved comment?&lt;/li&gt;
    &lt;li&gt;Is commenting on for this post?&lt;/li&gt;
    &lt;li&gt;Comment anchors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So you see it's not as simple to build a good application as it is to build a basic one. PHP's learning curve may be famously shallow but to build a well structured, efficient and secure application takes a lot of thought, time and effort. The barebones features I've integrated for this 1.0 release are:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Tagging&lt;/li&gt;
    &lt;li&gt;Commenting with specific allowed HTML tags using &lt;a href="http://htmlpurifier.org/"&gt;HTML Purifier&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;Syntax highlighting using &lt;a href="http://code.google.com/p/google-code-prettify/"&gt;Google Code Prettyfier&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;Post Administration&lt;/li&gt;
    &lt;li&gt;RSS Feeds&lt;/li&gt;
    &lt;li&gt;Secure login area&lt;/li&gt;
    &lt;li&gt;Toggle for post publishing on/off&lt;/li&gt;
    &lt;li&gt;Toggle for commenting on/off&lt;/li&gt;
    &lt;li&gt;Comment approval administration&lt;/li&gt;
    &lt;li&gt;Post writing and editing&lt;/li&gt;
    &lt;li&gt;Full tagging&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/kkCaOLlMpcY" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/is-there-such-a-thing-as-a-simple-web-app</feedburner:origLink></item>
        
            	
        <item>
    		<title>Custom Block Widths with YUI Grids</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/H_Tg_lTuXew/custom-block-widths-with-yui-grids</link>
    		<comments>http://timothyfletcher.com/journal/posts/custom-block-widths-with-yui-grids#comments</comments>
    		<pubDate>Thu, 21 Aug 2008 06:14:26 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;Having just started my first job as a professional web developer, I'm now trying to integrate some of the site building techniques I've learned into the company's way of working. Something I've not done before is to slice up Photoshop compositions (I'm a programmer) and turn them into nice XHTML/CSS sites. For site structure I use Yahoo's User Interface suite, a highly researched, optimised and cross-browser set of tools designed to increase productivity for basic site structuring. However, it needs a bit of customisation to build sites that are not within one of Yahoo's standard bundled templates. &lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;Custom Page Widths&lt;/h3&gt;
&lt;p&gt;The width of a page is easily customisable by specifying a width using a &lt;code&gt;#custom-doc&lt;/code&gt; selector as in following CSS example. Page widths are specified in em to allow for zooming/accessibility should a user change the font size. The width in em is calculated by dividing the pixel width by 13 (for most browsers) or by 13.3333 for IE.&lt;/p&gt;

&lt;pre&gt;
/* CSS for a custom page width of 600px */
#custom-doc {
    width:46.154em;    /* 600px/13 */
    *width:45.042em;   /* 600px/13.3333 */
}
&lt;/pre&gt;

&lt;h3&gt;Custom Template Block Widths&lt;/h3&gt;
&lt;p&gt;There are six grid templates for the YUI encompassing a variety of dual columns of varying widths. If somebody else is designing your sites these templates will almost certainly be inappropriate. To give an example, the &lt;code&gt;.yui-t4&lt;/code&gt; template class specifies a 180 pixel right block with the left (master) block taking up the remainder of the page width save for a 3 pixel 'safety' space in between the two column blocks. Here is the salient HTML and CSS taken from the grids.css YUI file.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;!-- HTML for a standard template with a custom width --&amp;gt;
&amp;lt;div id=&amp;quot;custom-doc&amp;quot; class=&amp;quot;yui-t4&amp;quot;&amp;gt; &amp;lt;!-- Custom set at 600px wide --&amp;gt;
    &amp;lt;div id=&amp;quot;hd&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div id=&amp;quot;bd&amp;quot;&amp;gt;
        &amp;lt;div id=&amp;quot;yui-main&amp;quot;&amp;gt;    &amp;lt;!-- Wrap .yui-b div in a #yui-main div to make it the main div --&amp;gt;
            &amp;lt;div class=&amp;quot;yui-b leftColumn&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class=&amp;quot;yui-b rightColumn&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;div id=&amp;quot;ft&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;					
&lt;/pre&gt;

&lt;pre&gt;
/* CSS for the yui-t4 template */
.yui-t4 .yui-b {
    float:right;
    width:13.8461em;    /* 190px/13 */
    *width:13.50em;     /* 190px/13.333 for IE */
}

.yui-t4 #yui-main .yui-b {
    margin-right:14.8456em;    /* 193px/13 */
    *margin-right:14.55em;     /* 193px/13.333 for IE */
}
&lt;/pre&gt;

&lt;p&gt;Now to customise these block columns we simply need to respecify the widths of the .yui-t4 selector within our own css file. Here we are specifying a right column width of 190px and a spacer of 10px thus assigning the rest of the space (the left column) 400px in our 600px custom width layout. Make sure that when your css files are linked in your HTML file they are in the correct order - grids.css goes first.&lt;/p&gt;

&lt;pre&gt;
/* Customisation of YUI grids for template*/
.yui-t4 .yui-b{
    float: right;
    width: 14.615em;       /* 190px/13 */
    *width: 14.250em;      /* 190px/13.333 for IE */
}

.yui-t4 #yui-main .yui-b {
    margin-right: 15.385em;      /* 200px/13 */
    *margin-right: 15.000em;     /* 200px/13.333 for IE*/
}
&lt;/pre&gt;

&lt;p&gt;One note that needs adding is that it is probably useful to work in pixels and then change to em at the end of your designing/slicing. If you need to add padding to the block column divs then you'll also need to recalculate the ems which will get boring after...well...one time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE: &lt;/strong&gt;I no longer use YUI grids. In the long run I found them to be inflexible when slicing other designers' comps. I have moved to using some simple custom 2 and 3 column templates that I developed and heavily tested.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/H_Tg_lTuXew" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/custom-block-widths-with-yui-grids</feedburner:origLink></item>
        
            	
        <item>
    		<title>Making Zend Framework Applications Portable</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/0UL3Jcsrv98/making-zend-framework-applications-portable</link>
    		<comments>http://timothyfletcher.com/journal/posts/making-zend-framework-applications-portable#comments</comments>
    		<pubDate>Sun, 10 Aug 2008 08:04:07 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;I recently put my first Zend Framework application onto my Slicehost slice only to be greeted with the inevitable pages of errors generated by not found pages and the like. Clearly this wasted the time I value so much and so I thought I'd write a few notes on how to avoid this if you are transferring applications to production servers.&lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;Database Configuration&lt;/h3&gt;
&lt;p&gt;It's highly likely that your local and production database configuration files are going to be different. The config.ini file in Zend Framework allows you to specify many different configurations for anything you like. Why not specify two database configurations and switch between them in your bootstrap based on the contents of the &lt;code&gt;$_SERVER[&amp;#x27;SERVER_NAME&amp;#x27;]&lt;/code&gt; variable? This is my &lt;code&gt;config.ini&lt;/code&gt;.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
[local]
;Local server database
db.adapter=PDO_MYSQL
db.host=localhost
db.username=localuser
db.password=localpassword
db.dbname=localdbname

[production]
;Production server database
db.adapter=PDO_MYSQL
db.host=localhost
db.username=productionuser
db.password=productionpassword
db.dbname=productiondbname
&lt;/pre&gt;

&lt;p&gt;Now in my bootstrap file I use the following&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
// Load config - query server variables to get local / remote
$productionServer = array(&amp;#x27;dev.adeli.ca&amp;#x27;);
$localServer = array(&amp;#x27;dreamadelica.dev&amp;#x27;);
if (in_array($_SERVER[&amp;#x27;SERVER_NAME&amp;#x27;], $localServer)) { $locale = &amp;#x27;local&amp;#x27;; }
if (in_array($_SERVER[&amp;#x27;SERVER_NAME&amp;#x27;], $productionServer)) { $locale = &amp;#x27;production&amp;#x27;; }
$config = new Zend_Config_Ini(ROOT . DIRECTORY_SEPARATOR . &amp;#x27;config&amp;#x27; . DIRECTORY_SEPARATOR . &amp;#x27;config.ini&amp;#x27;, $locale);
&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;$locale&lt;/code&gt; variable contains a string that is a parameter in the instantiation of the new &lt;code&gt;Zend_Config_Ini()&lt;/code&gt; object created using whichever database configuration details are appropriate for our server location.&lt;/p&gt;

&lt;h3&gt;Case Sensitivity&lt;/h3&gt;
&lt;p&gt;I develop on a Mac which I though had a case sensitive file system in Leopard's Mac OS Extended (Journaled). It turns out that this is not the case and although volumes can be created with case sensitivity enabled, some 3rd party applications (like the recently fixed Adobe CS3 suite) do not seem to support it yet. I found out a class &lt;code&gt;Forms_CommentForm()&lt;/code&gt; does not get found via the &lt;code&gt;Zend_Loader&lt;/code&gt; class if it is located at &lt;code&gt;forms/CommentForm.php&lt;/code&gt;. A simple enough problem to fix but bugs of this nature could arise if you develop on a case insensitive file system and then upload to a live Linux server which does feature case sensitivity.&lt;/p&gt;

&lt;h3&gt;PHP Short Tags&lt;/h3&gt;
As noted in my &lt;a href='http://timothyfletcher.com/archives/posts/syntax-error-when-creating-xmlrss-views'&gt;previous post&lt;/a&gt; PHP&amp;#x27;s short tags doesn&amp;#x27;t play happily with the XML declaration ( &lt;code&gt;&amp;lt;?xml and ?&amp;gt;&lt;/code&gt; ) It thinks it&amp;#x27;s going into PHP and then throws syntax errors. You shouldn&amp;#x27;t be using short tags anyway. It&amp;#x27;s bad for code portability. Turn them off in php.ini.

&lt;h3&gt;Relative URLs&lt;/h3&gt;
The thing that really caused me problems was my lack of use of dynamically generated URLs in my controllers and views. I used relative URLs (i.e. &amp;lt;code&amp;gt;&amp;amp;lt;a href=&amp;amp;quot;/link/to/somewhere&amp;amp;quot;&amp;amp;gt;Somewhere&amp;amp;lt;/a&amp;amp;gt;&amp;lt;/code&amp;gt;) which is a really bad idea if you want to avoid code portability issues. The best policy is to obtain the base URL from within the request object which exists within each controller object. At the beginning of your controller class, use a &amp;lt;code&amp;gt;init()&amp;lt;/code&amp;gt; (like a constructor) method to assign the base URL to a property of the controller class and make it accessible to all the action methods.

&lt;pre class="prettyprint"&gt;
public function init()
{
    $this-&amp;gt;view-&amp;gt;baseUrl = $this-&amp;gt;_request-&amp;gt;getBaseUrl();
}
&lt;/pre&gt;

&lt;p&gt;Now from within the views we can access the base URL with:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;

echo $this-&amp;gt;baseUrl;
&lt;/pre&gt;

&lt;p&gt;One final note is that if you're using background CSS images, you need to ensure that your URLs within the CSS file are relative to the current CSS file location. If your CSS is located in a folder and your images are located in a folder on the same level then you need to go up a level using &lt;code&gt;.. &lt;/code&gt;before the path. For example:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
#ft{background-image: url(&amp;#x27;../images/footer.png&amp;#x27;);}
&lt;/pre&gt;

&lt;p&gt;Let me know if this saved you time. Best.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update: &lt;/strong&gt; After uploading my second app - &lt;a href="http://highlandersrugbyclub.com"&gt;Highlanders Rugby Club&lt;/a&gt; - I've come across a few more portability issues. They are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not copying the .htaccess file (files starting with a period are system files and do not show in the finder&lt;/li&gt;
&lt;li&gt;I had capitals within my model class definitions but not on the file names.&lt;/li&gt;
&lt;li&gt;File names for the admin module's controller classes were not capitalised.&lt;/li&gt;
&lt;li&gt;I had written Zend_Form_Element_TextArea instead of Zend_Form_Element_Textarea&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/0UL3Jcsrv98" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/making-zend-framework-applications-portable</feedburner:origLink></item>
        
            	
        <item>
    		<title>Syntax Error When Creating XML/RSS Views</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/bTbC7VEr5gw/syntax-error-when-creating-xmlrss-views</link>
    		<comments>http://timothyfletcher.com/journal/posts/syntax-error-when-creating-xmlrss-views#comments</comments>
    		<pubDate>Sat, 02 Aug 2008 19:35:14 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;I was recently trying to render an XML view in the Zend Framework for an RSS feed but couldn't get past a syntax error generated on line 1 of the XML view file. The answer is to turn off short tags in your PHP config file This is good practice anyway as if you use short tags you reduce the portability of your code. It was a frustrating one and took me longer to figure out than I would have liked, mainly because I thought it was me using the framework incorrectly! To solve this, simply turn off short tags in your php.ini.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;The offending line was:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt;
&lt;/pre&gt;

&lt;p&gt;To fix this amend your php.ini (approx. line 76) file to...&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
short_open_tag = Off
&lt;/pre&gt;

&lt;p&gt;Don't forget to restart Apache!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/bTbC7VEr5gw" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/syntax-error-when-creating-xmlrss-views</feedburner:origLink></item>
        
            	
        <item>
    		<title>Finder Button to Show/Hide Hidden Files in OS X</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/z6j0TURdMOc/finder-button-to-showhide-hidden-files-in-os-x</link>
    		<comments>http://timothyfletcher.com/journal/posts/finder-button-to-showhide-hidden-files-in-os-x#comments</comments>
    		<pubDate>Sat, 19 Jul 2008 22:27:38 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;I recently found &lt;a href="http://henrik.nyh.se/2007/10/open-in-textmate-from-leopard-finder"&gt;Henrik Nyh's cool 'Open in Textmate' script&lt;/a&gt; which includes the ability to be added to the Finder toolbar in OS X. I also often find the need to show hidden files in the Finder and run &lt;a href="http://infosonic.wordpress.com/2007/09/23/mac-os-x-show-hidden-files-script/"&gt;Shane Duffy's AppleScript&lt;/a&gt; to do so. I though it would be great if I could have the 'ToggleHiddenFiles' script as a button on the Finder toolbar too so I created one.&lt;!--more--&gt;&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/finderwithhidefilesbutton.jpg" alt="Finder With Hide Files Button" title="Finder With Hide Files Button" class="alignnone size-medium wp-image-148" /&gt;

&lt;p&gt;Basically what I did is take Shane's script, open it in Leopard's Script Editor and save it as an application (such that it has the .app extension. I then took Henrik's script and extracted the droplet.icns icon file from it (Ctrl-Click -&gt; Show Package Contents -&gt; Contents -&gt; Resources -&gt; droplet.ics) and opened it in Adobe Fireworks. I then modified the icon and saved it as a .psd Photoshop file. Next I opened the .psd in Icon Composer (part of the XCode Tools) and saved as a .icns file. I wish there was an easier way to do this but I found lots of problems with other basic (read:free) icon manipulation tools.&lt;/p&gt;

&lt;p&gt;Finally, in the .app package I created with Script Editor, I replaced applet.icns (which was named droplet.icns in Henrik's script) with my version of the icon, placed the .app file into /Applications/Scripts and dragged the script file to the Finder Toolbar. Voila!&lt;/p&gt;

&lt;p&gt;If you want to create your own icon then use my instructions above. If you're happy with my handiwork then download my version of this great script and drag to your menu bar.&lt;/p&gt;

&lt;p&gt;Download: &lt;a href="http://timothyfletcher.com/downloads/ToggleHiddenFiles.zip"&gt;ToggleHiddenFiles.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/z6j0TURdMOc" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/finder-button-to-showhide-hidden-files-in-os-x</feedburner:origLink></item>
        
            	
        <item>
    		<title>How to Code a Web App?</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/cD66j4ITHsg/how-to-code-a-web-app</link>
    		<comments>http://timothyfletcher.com/journal/posts/how-to-code-a-web-app#comments</comments>
    		<pubDate>Sun, 11 May 2008 07:51:15 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;I've hit a bit of a problem with my study of PHP. Over the last 3-4 months I've become well up to speed with the syntax and understand the theory of object orientation. However, when I'm sitting in front of a &lt;a href="http://macromates.com/"&gt;text editor's&lt;/a&gt; blank page, I have no clue on how to go about building a well coded, extensible web application. &lt;!--more--&gt;Where do I begin? Yes, I could easily just start hacking away and creating code but as the site grows and new features are added it will eventually develop into the infamous 'spaghetti code' where I (or anyone else for that matter) will have to deal with a completely structureless and unmanageable mess. For me this is not acceptable and enough of a barrier to necessitate further study before beginning to code proper applications.&lt;/p&gt;

&lt;p&gt;One of the solutions to this is to use a framework and my last few posts have documented my experiences with &lt;a href="http://codeigniter.com/"&gt;CodeIgniter's&lt;/a&gt; implementation of the &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;Model-View-Controller&lt;/a&gt; design pattern. Great though frameworks are, I've come across two issues. Firstly, the proliferation of PHP 5 is not as widespread as I would like. I'm &lt;a href="http://www.derekallard.com/blog/post/codeigniter-will-not-be-dropping-support-for-php-4-anytime-soon/"&gt;told&lt;/a&gt; that many shared hosts do not support it despite its release nearly four years ago - Would you pick a host that didn't support PHP 5!?!? Anyway, this means that the most popular frameworks are necessarily supporting adn thus coded to be compatible with PHP 4 and it's 'tacked on' implementation of object orientation. As a fledgling coder and someone who embraces new (or 4 year old) technologies I want to code in PHP 5, learn its 'new' object-oriented features and become a better developer. There are currently few frameworks that are PHP 5 only and in my opinion none of these have sufficient community support / documentation for me to dissect and learn effectively.&lt;/p&gt;

&lt;p&gt;Secondly, though I hold firm in my beliefs that frameworks are an essential part of modern web development, I also believe that is important to understand their implementation, at least on a basic level. Trying to dissect a framework like &lt;a href="http://codeigniter.com/"&gt;CodeIgniter&lt;/a&gt;, &lt;a href="http://www.cakephp.org/"&gt;CakePHP&lt;/a&gt; or &lt;a href="http://kohanaphp.com"&gt;Kohana&lt;/a&gt; (at least for a relative beginner like me) is a near impossible task. The issue is that if you blindly use a framework for every project you will ultimately become reliant upon it and your knowledge of the fundamental principals of development will be dulled. A very bad thing, particularly for a programming beginner.&lt;/p&gt;

&lt;p&gt;So with these thoughts in mind I'm now moving onto a new book - &lt;a href="http://www.amazon.com/gp/product/1932394753/ref=cm_rdp_product"&gt;PHP in Action: Objects, Design, Agility&lt;/a&gt; I've read the first chapter and a few Amazon reviews and it appears to be at my current level. I'll maybe post a review in a while if it's any good...&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/cD66j4ITHsg" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/how-to-code-a-web-app</feedburner:origLink></item>
        
            	
        <item>
    		<title>Simple PHP Twitter Status Badge</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/bBfRDakAiRI/simple-php-twitter-status-badge</link>
    		<comments>http://timothyfletcher.com/journal/posts/simple-php-twitter-status-badge#comments</comments>
    		<pubDate>Sat, 10 May 2008 07:43:46 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;The concept of learning by doing is one I firmly believe in. The intention of 'rolling my own' blog is that inevitably I will happen upon and have to overcome many typical programming problems as I implement new features. One such problem was how to add the 'latest Tweet' feature that the &lt;a href="http://eightface.com/wordpress/twitterrss/"&gt;twitterRSS&lt;/a&gt; plugin solved on my old &lt;a href="http://wordpress.org/"&gt;Wordpress&lt;/a&gt; blog.&lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;Reverse Engineering&lt;/h3&gt;
&lt;p&gt;Important though an understanding of the theory taught by books is, I find that reverse engineering somebody else's code, stripping it down to the absolute basics and then building it back up in a way that I can fully understand is a great method of making that knowledge stick. Yes, I could just find and use a third party class but I almost always find that it's features are way beyond my needs resulting in the obfuscation of the code I'm trying to learn from. Stripping it to the basics lets you simplify, analyse and understand its core processes. The code I stripped for this tutorial came from a the &lt;a href="http://codeigniter.com/"&gt;CodeIgniter&lt;/a&gt; &lt;a href="http://codeigniter.com/wiki/RSSParser/"&gt;RSSParser&lt;/a&gt; class although the resultant code is not framework dependant.&lt;/p&gt;

&lt;p&gt;The first thing you need to do is find your Twitter RSS feed URL. Log into Twitter and click on the 'home' link in the upper menu bar. Then scroll to the bottom and click the RSS button. This will load your RSS feed in your browser or feed reader. Note that for the feed to work in the code the protocol must be http:// and not feed://. You username is your full twitter name. It's important to get this exactly correct else your tweet will have your username prepended at the start (we remove it later).&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
function getTweet() {
  // Set up variables
  $twitter_feed = &amp;#x27;http://twitter.com/statuses/user_timeline/13395012.rss&amp;#x27;;
  $twitter_username = &amp;#x27;timfletcher&amp;#x27;;
&lt;/pre&gt;

&lt;p&gt;Next we need to get the RSS feed and write it into a string. Using the @ symbol before a function suppresses errors. Remember only to do this if you're implementing error handling in some other way.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
  // Get the RSS file and put it into a string
  // Supress errors with the @ symbol
  $rawfeed = @file_get_contents($twitter_feed);
&lt;/pre&gt;

&lt;p&gt;If the feed was successfully read (i.e. does not return FALSE) then we can process it by creating a new SimpleXMLElement object and passing the feed to it. Passing a variable when instantiating an object causes the object's constructor to create the object using that variable. To quote from the PHP manual:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The SimpleXML extension provides a very simple and easily usable toolset to convert XML to an object that can be processed with normal property selectors and array iterators.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The SimpleXML extension requires PHP5. Seriously, if your host doesn't yet support PHP5 then get another one!&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
if ($rawfeed != FALSE) {
  $xml = new SimpleXmlElement($rawfeed);
&lt;/pre&gt;

&lt;p&gt;To get the latest tweet from the RSS file you can use (as stated in the manual) property selectors and array iterators. The way I worked all this out was by using the essential PHP function &lt;a href="http://ca3.php.net/var_dump"&gt;var_dump()&lt;/a&gt;. It basically spews the contents of a variable or object onto the display so you can see its structure. I have &lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt; set up to throw a var_dump(&lt;i&gt;variable&lt;/i&gt;); die(); into the code from a tab command when I type 'var'. It's invaluable for debugging.&lt;/p&gt;

&lt;p&gt;So after a bit of using var_dump I worked out that you can display your latest tweet using this code.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
$tweet = $xml-&amp;gt;channel-&amp;gt;item[0]-&amp;gt;description;
&lt;/pre&gt;

&lt;p&gt;As is the structure of Twitter's RSS stream, this line will output your Twitter name and a colon before the tweet. If you want this then fine but I'll remove by using str_replace() to change it to nothing. This is why $username needs to be exactly correct.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
echo str_replace($twitter_username . &amp;#x27;: &amp;#x27;,&amp;#x27;&amp;#x27;, $tweet);
&lt;/pre&gt;

&lt;p&gt;And that's pretty much it. All you need to do is call the getTweet() function and it will output your single, latest tweet as unformatted text. To make it all a bit easier to use here's the full code. Give me a shout with any comments or problems!&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
function getTweet() {
    
    // Set up variables
    $twitter_feed = &amp;#x27;http://twitter.com/statuses/user_timeline/13395012.rss&amp;#x27;;
    $twitter_username = &amp;#x27;timfletcher&amp;#x27;;
    
    // Get the RSS file and put it into a string
    // Supress errors with the @ symbol
    $rawfeed = @file_get_contents($twitter_feed);
    
    // if file_get_contents returned true...
    if ($rawfeed != FALSE) {
        
        $xml = new SimpleXmlElement($rawfeed);
        
        // Fetch the latest tweet
        $tweet = $xml-&amp;gt;channel-&amp;gt;item[0]-&amp;gt;description;

        // Remove username from the front of the tweet and output
        echo str_replace(TWITTER_USERNAME . &amp;#x27;: &amp;#x27;,&amp;#x27;&amp;#x27;, $tweet);
        
    } else {
        
    echo &amp;#x27;There is a problem with the Twitter feed just now...&amp;#x27;;
    }
}
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;UPDATE: &lt;/strong&gt;I've just realised that when Twitter (or at least its RSS) is unavailable (i.e. often), it takes over a minute for the page to load. Arrrgh!!!! Talk about learning the hard way!&lt;/p&gt;

&lt;p&gt;This can be resolved by setting a timeout value on the file_get_contents(); function. From the &lt;a href="http://ca.php.net/manual/en/function.file-get-contents.php#82527"&gt;php.net site for file_get_contents()&lt;/a&gt;, Change the above code to include the following.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
// Setting the timeout properly without messing with ini values
$ctx = stream_context_create(array(&amp;#x27;http&amp;#x27; =&amp;gt; array(&amp;#x27;timeout&amp;#x27; =&amp;gt; 1)));
//Parse the document
$rawfeed = @file_get_contents(TWITTER_FEED, 0, $ctx);
&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/bBfRDakAiRI" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/simple-php-twitter-status-badge</feedburner:origLink></item>
        
            	
        <item>
    		<title>Frameworks - The Advancement of Technology</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/dcwzl2eGEbc/frameworks-the-advancement-of-technology</link>
    		<comments>http://timothyfletcher.com/journal/posts/frameworks-the-advancement-of-technology#comments</comments>
    		<pubDate>Thu, 24 Apr 2008 20:41:57 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;I've been thinking a lot lately over the best approach for learning &lt;a href="http://www.php.net/"&gt;PHP&lt;/a&gt;. I don't mean the syntax, there's only one was to learn that, but the learning that takes place through the practical application of techniques that ultimately results in a well designed web application. One of the strengths of PHP is its shallow learning curve and a basic application (typically usable by only the author) can be knocked up very quickly with little experience. &lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Where it all becomes tricky is that advancing that application into a production project for a paying client requires a large amount of coding discipline, planning and experience. Not only must you consider how easy it is for you or another developer to change and extend your application but you must think about all the nefarious (or stupid) ways that your application will be used by the 'Joe Bloggs' internet user. You must validate their input, make the site ultra-usable and in general protect people from themselves. All of these things add a huge level of complexity to a project which then detracts from the fun of learning to code. Of course you could spend a very long while creating a series of classes / functions to take care of the laborious work (and this would probably be the ultimate way of learning) BUT is this not reinventing the wheel?&lt;/p&gt;

&lt;h3&gt;The Advancement of Technology&lt;/h3&gt;
&lt;p&gt;The development of high-level languages like C meant that people were no longer forced to code in assembly language and, at the expense of a little efficiency, were able to develop software much more quickly and effectively. The point here is that you don't have to learn assembler to use C to its full potential. To do so would be to reinvent the wheel. Though it still has its uses, to go back to assembler is to be going against the advancement of technology and that is a bad thing. Another maybe more contentious example would be the ubiquity of the calculator. Although I did know how to once, long multiplication and division are skills I no longer consider important. It is inefficient, error prone and against technological advancement to calculate by hand when a calculator will always give me the correct answer instantly.&lt;/p&gt;

&lt;h3&gt;Frameworks&lt;/h3&gt;
&lt;p&gt;So back to PHP - my question is how do you gain the experience necessary to develop secure and extensible web applications without spending months (or even years) studying? Of course frameworks are the answer but they aren't without their drawbacks, particularly for the beginner. &lt;a href="http://www.wikipedia.org/"&gt;Wikipedia&lt;/a&gt; defines a framework as:&lt;/p&gt;

&lt;blockquote&gt;
A re-usable design for a software system (or subsystem). A software framework may include support programs, code libraries, a scripting language, or other software to help develop and glue together the different components of a software project.
&lt;/blockquote&gt;

&lt;p&gt;Basically frameworks are the wheel you don't need to invent. The extra layer of abstraction that frameworks provide is great for fast development and often forces application development using a tried and tested design pattern that helps you to write easily maintainable code. Most importantly, the tried and tested nature of the code is excellent for security. The fundamental issue is whether frameworks are good or bad for learning to code and thus for the industry in general. Do you want 'dumb' developers who can use a framework to throw together a secure and well coded web application or do you want well bred coders with years of low-level coding experience? Perhaps the answer can be found, in part, in the huge number of PHP frameworks that are available.&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/php_frameworks.gif" alt="A collection of PHP frameworks" title="A collection of PHP frameworks" /&gt;

&lt;h3&gt;Innovation&lt;/h3&gt;
&lt;p&gt;I've thought about this quite a bit and I firmly believe that frameworks are the only way to go. They encourage innovation by their very nature because they free developers from the constraints of considering security et al. and allow them time to conceive new ideas. &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; is a great example of giving developers the freedom to quickly realise new concepts resulting, ultimately, in a better and more forward thinking web. To not use a framework is, in effect, to program in assembler, use a calculator and otherwise not advance our use and development of technology.&lt;/p&gt;

&lt;p&gt;So with this article 'out there' I have fully justified my decision to learn a PHP framework. My first project will be to redevelop dream.adeli.ca rather than using &lt;a href="http://wordpress.org/"&gt;Wordpress&lt;/a&gt;, great though it is. I'll write my thoughts on practical framework use in a few weeks.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/dcwzl2eGEbc" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/frameworks-the-advancement-of-technology</feedburner:origLink></item>
        
            	
        <item>
    		<title>Media Temple's Grid-Service Not That Good Really</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/bM01GHWowMA/media-temples-gridservice-not-that-good-really</link>
    		<comments>http://timothyfletcher.com/journal/posts/media-temples-gridservice-not-that-good-really#comments</comments>
    		<pubDate>Mon, 21 Apr 2008 07:29:53 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;Whilst optimising the code for my site I learned a few interesting things about my host &lt;a href="http://mediatemple.net/"&gt;Media Temple's&lt;/a&gt; &lt;a href="http://www.mediatemple.net/webhosting/gs/"&gt;Grid-Service (gs)&lt;/a&gt; product. The upshot of it all being that I don't think it's very good. I hear nothing but praise for their (dv) dedicated virtual servers but Grid-Server? To test I put on a &lt;!--more--&gt;2Kb static holding page and received some 'fairly' respectable response times of 0.5 to 1 second. However, upgrading that to a default Kubrick theme &lt;a href="http://wordpress.org/"&gt;Wordpress&lt;/a&gt; installation (26.9K) and thus using a little bit of PHP/MySQL rockets the response times up to 3-4 seconds! Take a look at this response time chart from my favourite web monitoring company &lt;a href="http://www.pingdom.com/"&gt;Pingdom&lt;/a&gt;. Can you guess what date I installed Wordpress?&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/response_times.gif" alt="Media Temple Response Times" title="Media Temple Response Times"/&gt;

&lt;p&gt;The reason for the increase in performance towards the end of the graph is my extensive attempts at optmising the Apahce server and Wordpress theme. I hard-coded PHP calls, &lt;a href="http://timothyfletcher.com/archives/posts/speed-up-your-site-compression"&gt;compressed file sizes&lt;/a&gt; and &lt;a href="http://timothyfletcher.com/archives/posts/speed-up-your-site-with-image-sprites"&gt;minimised HTTP requests&lt;/a&gt; resulting in my ultra-lightweight 18.7Kb 'Titan' theme. Almost half of that size was the highly optimised and very quickly served JavaScript for &lt;a href="http://analytics.google.com"&gt;Google Analytics&lt;/a&gt; but it still averaged out over 2 seconds to load. For a company that actually pushes it's response times as an exceptional feature of the (gs)...&lt;/p&gt;

&lt;blockquote&gt;
Beyond simple load balancing, the Grid uses an ever-expanding "cluster of clusters" all working together to serve your site with blazing fast response times.
&lt;/blockquote&gt;

&lt;p&gt;... they're just not delivering the service they claim to offer.&lt;/p&gt;

&lt;p&gt;The other problem I had was downtime. Without fail, on a daily basis, the service was down. Usually not for long but it gets a bit depressing to never see that fabled 100% uptime stat. Just for one day? I again quote from the &lt;a href="http://www.mediatemple.net/webhosting/gs/"&gt;Grid-Service&lt;/a&gt; page on Media Temple's site:&lt;/p&gt;

&lt;blockquote&gt;
The Grid was designed and built with numerous layers of redundant hardware, software, network and power systems. Downtime caused by device failures will be a distant memory once you switch to The Grid.
&lt;/blockquote&gt;

&lt;p&gt;Simply, sadly, no they're not. A favourite blog of mine by &lt;a href="http://snook.ca"&gt;Jonathan Snook&lt;/a&gt; is share-hosted by (mt)'s arch-rival Dreamhost. Barring a (pretty major) blip a month ago, his uptime has been 100%.&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/snook_uptime.gif" alt="Jonathan Snook Uptime" title="Jonathan Snook Uptime"/&gt;

&lt;h3&gt;Support&lt;/h3&gt;
&lt;p&gt;I didn't really have any of the support problems that others have experienced. I usually got answers within a (good) few hours or so. However I distinctly remember being very impressed when I started using the service 3 years ago - support response times were always within a few minutes. Either they have a policy of prioritising new customers or their support has lapsed in recent years. I was fortunate enough not to call on them too often so I can't comment too much.&lt;/p&gt;

&lt;h3&gt;SliceHost&lt;/h3&gt;
&lt;p&gt;So what to do? Change hosts of course! Being the sort of chap that likes to have full control over software and server configuration I was keen on a virtual or dedicated private server. The problem is that typically they're expensive compared to shared hosting. The Grid-Service is relatively pricy at $20/month and I wasn't keen on spending much more than that. After bit of reading I found that &lt;a href="http://www.slicehost.com/"&gt;Slicehost&lt;/a&gt; comes highly recommended by many, particularly in Ben Allen's &lt;a href="http://www.sysadminschronicles.com/articles/2007/10/30/slicehosts_slicemanager/"&gt; comprehensive review&lt;/a&gt; of their virtual private server (VPS) 'slice'. There were three key things that sold me. Firstly, their smallest 256slice plan (256MB RAM, 10GB storage, 100GB bandwidth) was only a mere $20/month so no extra cost. Secondly, you have complete control over everything on your server from distribution of Linux to brand of web/mail server, version of PHP / MySQL... you install it all yourself via an SSH terminal prompt. That brings me onto the third key point - documentation. Slicehost has a huge array of installation guides to get you up and running with your own server. Learning SSH and Linux has been a desire of mine for a while and I now have the perfect opportunity to learn some of those skills. As on (mt), I can still host multiple sites through virtual hosts only now and for the same price, I'm on my own personal server. Great stuff!&lt;/p&gt;

&lt;p&gt;I'll write a proper roundup of my thoughts on Slicehost in a couple of months once I've attained a reasonable level of knowledge. For the moment you should know that using the documentation on the Slicehost and Ubuntu websites I managed to get Apache, PHP, MySQL and Postfix all up and running within a few hours. That by starting from near zero knowledge. Ok, ok, so I got my IP spam blacklisted due to some mis-configuration but I've fixed that now! I'm now hosting dream.adeli.ca on Slicehost. One thing that's keeping me very happy with my investment is the all-new speedy response times. Enjoy!&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/dreamadelica_response_times.gif" alt="Slicehost dream.adeli.ca Response Times" title="Slicehost dream.adeli.ca Response Times"/&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/bM01GHWowMA" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/media-temples-gridservice-not-that-good-really</feedburner:origLink></item>
        
            	
        <item>
    		<title>Speed Up Your Site - Compression</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/Gz85c1uv0Yw/speed-up-your-site-compression</link>
    		<comments>http://timothyfletcher.com/journal/posts/speed-up-your-site-compression#comments</comments>
    		<pubDate>Sat, 19 Apr 2008 06:28:59 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;Continuing with my mini-series on website optimisation, probably the single most important factor a fast loading site will have is a lightweight footprint. The more data the server has to send to the browser, the higher your bandwidth usage will be, the harder the server will have to work and consequently the slower your site &lt;!--more--&gt; will load. There are two main ways that a reduction in data transfer can be achieved - by removing any unnecessary 'bloat' code and by implementing HTTP compression.&lt;/p&gt;

&lt;h3&gt;Reasons to be Lightweight&lt;/h3&gt;
&lt;p&gt;We no longer access the internet solely using computers. Mobile web usage on the comparatively slow 3G/EDGE networks is increasing, not only with the release of the &lt;a href="http://www.apple.com/iphone"&gt;iPhone&lt;/a&gt; and ubiquitous &lt;a href="http://www.blackberry.com/"&gt;BlackBerry&lt;/a&gt;, but also notably with services intended for laptop usage like &lt;a href="http://online.vodafone.co.uk/dispatch/Portal/appmanager/vodafone/wrp?_nfpb=true&amp;_pageLabel=template05&amp;pageID=BS_0034"&gt;Vodafone's 3G Mobile Connect&lt;/a&gt; (which is heavily compressed). As a consequence, site designers definitely should take into account the user experience on these connections and devices. Further, although most of the Western world uses speedy broadband, there are many countries where users are struggling to load sites. There's 2.5 billion people in China and India alone, the vast majority of which do not have fast broadband. Having blogged from India I can tell you it's very frustrating!&lt;/p&gt;

&lt;p&gt;As in my last article, &lt;a href="http://timothyfletcher.com/archives/posts/speed-up-your-site-with-image-sprites"&gt;Speed Up Your Site - Image Sprites&lt;/a&gt;, you need a good diagnostic tool to show your site's improvements. I use the &lt;a href="http://www.getfirefox.com"&gt;Firefox&lt;/a&gt; addons &lt;a href="http://www.getfirebug.com/"&gt;Firebug&lt;/a&gt; and &lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Expensive Javascript&lt;/h3&gt;
&lt;p&gt;I'm not a fan of Javascript and avoid it unless absolutely necessary (e.g. Google Analytics). I was a little horrified to find my first run through of YSlow telling me that my 103K front page consisted of 72.9K of JavaScript, 64.5K of which was in the form of &lt;a href="http://jquery.com/"&gt;JQuery&lt;/a&gt; via the &lt;a href="http://wordpress.org/extend/plugins/contact-form-7/"&gt;WP-Contact-Form-7&lt;/a&gt; plugin. I uninstalled it and instead went for &lt;a href="http://wordpress.org/extend/plugins/wp-contact-form/"&gt;WP Contact Form&lt;/a&gt; which uses server side validation and CSS notifications instead of JavaScript. It's infinitely more lightweight - the total page size dropped considerably to 38.2Kb.&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/optimise_contact_form.gif" alt="Contact Form Optimisation" title="Contact Form Optimisation"/&gt;

&lt;p&gt;I did go through a few PHP files and remove some whitespace but the resultant code was so difficult to read and the gains so negligible that I put it all back in. There are much better ways of reducing the file sizes by using HTTP compression.&lt;/p&gt;

&lt;h3&gt;HTTP Compression with mod_deflate&lt;/h3&gt;
&lt;p&gt;By far the best way of reducing your file sizes is through HTTP compression and spectacular results can be had. The uncompressed size of the the XHTML and CSS files on dream.adeli.ca is 20.7Kb. Using Apache's mod_deflate compression module reduces that to 5.6k. Nearly a 75% reduction. In the vast majority of cases compression is a good idea however it requires more CPU on your server so it's usually a good idea to turn it off if you are fortunate enough to get &lt;a href="http://www.digg.com"&gt;dugg&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are two main compression modules for Apache: mod_gzip and mod_deflate. Whoever your host is you're much more likely to have the newer mod_deflate then mod_gzip for a variety of reasons, not least because the former comes as a pre-compiled module in the current Apache distribution whereas mod_gzip doesn't. If you're using a dedicated virtual server you can enable mod_deflate via SSH by running the following command:&lt;/p&gt;

&lt;pre&gt;
sudo a2enmod deflate
&lt;/pre&gt;

&lt;p&gt;Which will give the response:&lt;/p&gt;

&lt;pre&gt;
Module deflate installed; run /etc/init.d/apache2 force-reload to enable.
&lt;/pre&gt;

&lt;p&gt;So we do as it says and run:&lt;/p&gt;

&lt;pre&gt;
sudo /etc/init.d/apache2 force-reload
&lt;/pre&gt;

&lt;p&gt;At this point mod_deflate compression is enabled and will automatically compress the MIME types specified in the '&lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html"&gt;Accept&lt;/a&gt;' field of the HTTP header - the request created by your browser when you want to pull a web page from a server. You can view the HTTP headers in Firefox via the Tools-&gt;Page Info menu and click the Headers tab. For Firefox 2 on OS X the default MIME types in the Accept field of the header are: &lt;code&gt;text/xml, application/xml, application/xhtml+xml, text/html, text/plain, image/png&lt;/code&gt;. From that you can see that there is no &lt;code&gt;text/css&lt;/code&gt; or &lt;code&gt;application/x-javascript&lt;/code&gt; and as a result CSS and JavaScript are not compressed. Their compression can be enabled by adding the following code to your .htaccess file. Be aware that binary file types such as images are usually heavily compressed formats and will not benefit from further compression. They are left out here. Code courtesy of &lt;a href="http://nathanbowers.com/wp-content/uploads/2008/04/htaccess.txt"&gt;Nathan Bowers&lt;/a&gt;&lt;/p&gt;

&lt;pre &gt;
# Use mod_deflate to compress text files of type
# html, text, js, and css but not binary files.
# Also properly handle requests from behind proxies

&amp;lt;IfModule mod_deflate.c&amp;gt;
  SetOutputFilter DEFLATE
  AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript application/javascript application/x-javascript
  &amp;lt;IfModule mod_headers.c&amp;gt;
    Header append Vary User-Agent
  &amp;lt;/IfModule&amp;gt;
&amp;lt;/IfModule&amp;gt;

# Properly handle old browsers that do not support compression
# and explicitly exclude binary files from compression

&amp;lt;IfModule mod_deflate.c&amp;gt;
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
  SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|pdf|swf|ico|zip)$ no-gzip
&amp;lt;/IfModule&amp;gt;
&lt;/pre&gt;

&lt;p&gt;These rules also apply to any shared host where mod_deflate is enabled. If it's not ask your host to turn it on.&lt;/p&gt;

&lt;h3&gt;Checking Your Results&lt;/h3&gt;
&lt;p&gt;You can check your files for compression in Firefox with the &lt;strong&gt;Components&lt;/strong&gt; option selected on the YSlow tab of FireBug. The important column is  on the far right hand side. In the upper table (mod_deflate enabled) it shows the amount of data transferred per file and then the approximate unzipped size in parentheses The lower image (mod_deflate disabled) simply shows the uncompressed size.&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/mod_deflate.png" alt="mod_deflate on dream.adeli.ca" title="mod_deflate"/&gt;

&lt;p&gt;So hopefully you now have a much faster loading web page. If you get stuck &lt;a href="http://timothyfletcher.com/page/contact/"&gt;give me a shout&lt;/a&gt; and I'll do my best to help you. Good luck!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/Gz85c1uv0Yw" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/speed-up-your-site-compression</feedburner:origLink></item>
        
            	
        <item>
    		<title>Speed Up Your Site with Image Sprites</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/kVd_mnIqnCg/speed-up-your-site-with-image-sprites</link>
    		<comments>http://timothyfletcher.com/journal/posts/speed-up-your-site-with-image-sprites#comments</comments>
    		<pubDate>Wed, 16 Apr 2008 17:34:15 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;Reducing HTTP requests is a great way to decrease the load time of your site without sacrificing any of the content. Each and every component of your site be it a HTML file, image, or external CSS file requires a HTTP request to fetch the data. HTTP requests take time so the fewer of them you have, the faster your site will load.&lt;!--more--&gt; To quote from the Yahoo developer network's &lt;a href="http://developer.yahoo.com/performance/"&gt;34 best practices for making web pages fast&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
80% of the end-user response time is spent on the front-end. Most of this time is tied up in downloading all the components in the page: images, stylesheets, scripts, Flash, etc. Reducing the number of components in turn reduces the number of HTTP requests required to render the page. This is the key to faster pages.
&lt;/blockquote&gt;

&lt;p&gt;It can be a little tricky to measure the decreases in load time because of variations that are out of your control. Times may vary due to network traffic or the processing load from other dynamic sites on a shared host. Also if you only manage to remove a few requests then an empirical observation may be difficult to make. However, if you manage to significantly minimise your requests then you definitely should notice a drastic improvement.&lt;/p&gt;

&lt;h3&gt;FireBug and Y-Slow&lt;/h3&gt;
&lt;p&gt;Before you can start to make your site faster you need a diagnostic tool to see how your improvements are working. The &lt;a href="http://www.getfirefox.com"&gt;Firefox&lt;/a&gt; addons &lt;a href="http://www.getfirebug.com/"&gt;Firebug&lt;/a&gt; and Yahoo's &lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow&lt;/a&gt; are perfect for the task. YSlow shows you a wealth of information about your site including file types and sizes, total page size for full and empty caches, the number of HTTP requests and whether files are compressed or not. It also grades your site based on Yahoo’s performance rules. Admittedly some of these rules are excessively tweaky and geared towards large sites but the basics are covered well and provide a fantastic resource for speeding up your website.&lt;/p&gt;

&lt;h3&gt;Image Sprites&lt;/h3&gt;
&lt;p&gt;A popular technique for reducing image requests is to use Image Sprites. This is where all your page's images are combined into a single image and CSS is used to position each image as a background into a 'window' &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;. This way only one request is made for the combined image rather than one for each individual image. Google is a user of this technique and if it's good enough for Google then it's good enough for me!&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/google_image_sprite.png" alt="Image Sprites" title="Image Sprites"/&gt;

&lt;p&gt;Once you've created a combined image like Google's above, you need to display the image as a background in a window &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;. Place a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; with an appropriate selector into your HTML page e.g. &lt;code&gt;&amp;lt;div id=&amp;quot;rss_logo&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt; and then style it using this CSS:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
#rss_logo{
    width:14px;     /* image width and height */
    height:14px;
    background-image: url(&amp;#x27;path...to.../image_sprite.gif&amp;#x27;);
    background-position: 0px -53px;     /* image position within the composite image */
}
&lt;/pre&gt;

&lt;p&gt;The important bits of CSS here are the width and height attributes which dictate the window size (i.e. the dimensions of the image showing through) and the background-position attribute which tells the browser which bit of the composite image to display. The background-position attribute works such that if your image to display is placed at co-ordinates 0,53 within the composite image then you must position it using 0,-53. That is moving the image up to display content lower in the image. It might take bit of fiddling to get right but ultimately it's pretty straightforward. You do not need to use a background-repeat: no-repeat; because the window div masks off the rest of the image and you won't see it. I've verified this method in Firefox, Opera and Safari cross platform and IE6 / IE7 on PC.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/kVd_mnIqnCg" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/speed-up-your-site-with-image-sprites</feedburner:origLink></item>
        
            	
        <item>
    		<title>Guide: Audiophile Quality Sound for Student Dollars</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/zGg36okwFDk/guide-audiophile-quality-sound-for-student-dollars</link>
    		<comments>http://timothyfletcher.com/journal/posts/guide-audiophile-quality-sound-for-student-dollars#comments</comments>
    		<pubDate>Sun, 06 Apr 2008 06:49:34 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;Over the last couple of months I've been testing a new breed of budget sound system based on a &lt;a href="http://www.trendsaudio.com/EN/Product/TA-10_desc.htm"&gt;Trends Audio TA-10.1&lt;/a&gt; Class-T amplifier, a &lt;a href="http://www.mood-lab.com/concept.htm"&gt;Moodlab Concept&lt;/a&gt; zero oversampling digital to analogue converter (DAC), and &lt;a href="http://www.apple.com/itunes/"&gt;iTunes&lt;/a&gt;. This $400 (+ speakers) combo completely outclassed my $1400 Rotel RA-01 amp and RCD-01 CD player and made me remember why I love music so much.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;As part of my move to Canada, I needed to downsize / ebay of a lot of my gear to make it cheaper to send over the Atlantic. With iTunes on my Macbook I rarely listen to CDs or vinyl anymore. Having my &lt;strong&gt;entire&lt;/strong&gt; music collection indexed at my fingertips is the new model. Just set to random and start the journey of discovery...&lt;/p&gt;

&lt;h3&gt;The Trends Audio TA-10.1 Class-T Amplifer&lt;/h3&gt;
&lt;p&gt;You may have heard of Class A or AB amplifiers but probably not Class T. Rather than a design topology, Class T is a registered trademark for Tripath's Digital Power Processing™ brand of amplifier technologies. The TA-10.1 is essentially a digitally controlled analogue amplifier that provides superb performance at an unbeatable price point.&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/trends_ta1011.jpg" alt="Trends TA-10.1 Class-T Amplifier" title="Trends TA-10.1 Class-T Amplifier" /&gt;

&lt;p&gt;This amplifier has put a good few noses out of joint in the audiophile world, receiving the kind of &lt;a href="http://www.6moons.com/audioreviews/trends/ta10.html"&gt;rave&lt;/a&gt; &lt;a href="http://www.tnt-audio.com/ampli/trends_ta10_e.html"&gt;reviews&lt;/a&gt; normally associated with amplifiers 10 times its price. The TA-10.1 costs $150. People with $15,000 amps don't like that. It's a pretty small affair, about the size of a packet of butter and although its output is a fairly modest 10 Watts into 8 Ohms - you shouldn't expect to power a house party with it - it's more than loud enough for 99% of listening situations. You get a bit of distortion creeping in around 3/4 volume but that's getting really loud and out of realistic usage norms. It has gold plated connectors for both RCA input (from the DAC) and speaker outputs which can take bare wires or standard banana plugs and is powered via an external 'wall wart' adaptor. All in all it's a very compact amp. You could easily stick it and the Moodlab in a laptop bag and take it around to wow amaze all your friends.&lt;/p&gt;

&lt;h3&gt;The Moodlab Concept&lt;/a&gt; Zero-Oversampling DAC&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.mood-lab.com/concept.htm"&gt;Moodlab&lt;/a&gt; are a Hong Kong based consumer electronics manufacturer specialising in digital to analogue converters for application in computer based audio systems. As with the TA-10.1 they take advantage of a different approach to DAC design called zero oversampling. I'll spare you the details but it's essentially using a simple output filter to get rid of the (very) high frequencies before they hit the amplifier rather than a more complex and inferior sounding oversampling design. The overall result is a less processed (i.e. filtered) audio signal which is perceived as sounding much more natural without any of the digital 'harshness' that allegedly plagues digital sound.&lt;/p&gt;

&lt;p&gt;I love the looks of the Concept. The frosted acrylic fascia is rear illuminated by an LED that changes from red to green when it detects a digital input. Looks great in the dark! Its a very simple setup - S/PDIF coaxial and optical in (switch selectable plus mute so you could have two digital sources) and stereo RCAs out to the TA-10.1 amp. I'm a big fan of simple, functional kit. Both the Trends and the Moodlab are exactly this. As with the Trends, the Concept is available at a great pricepoint - $249. One standard feature of modern DACs is reclocking to reduce 'jitter', a degradation of digital sound caused by the clock encoded into the digital audio stream not being exactly regular. What this means is that &lt;em&gt;&lt;strong&gt;any&lt;/strong&gt;&lt;/em&gt; digital sound source can be 'cleaned up'. For example you could use a crappy CD player's digital out and it'll sound great!&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/moodlab_concept.jpg" alt="Moodlab Concept" title="Moodlab Concept" /&gt;

&lt;h3&gt;B&amp;W 602 Series 3 Loudspeakers&lt;/h3&gt;
&lt;p&gt;I've had my &lt;a href="http://www.bowers-wilkins.com/"&gt;B&amp;W 603 S3s&lt;/a&gt; for about 3 years after buying them through &lt;a href="http://www.airstudios.com"&gt;AIR Studios&lt;/a&gt; where I used to work as a studio tech. We had their flagship Nautilus speakers down from &lt;a href="http://www.abbeyroad.co.uk"&gt;Abbey Road&lt;/a&gt; for a demo and I liked them so much I bought a pair of 602 S3s (you need to be a millionaire for the Nautiluses!) The 602s sound great but as the hifi loudspeaker market is so competitive I think any decent loudspeaker would do this setup justice.&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/hifi_setup.jpg" alt="" title="hifi_setup" /&gt;

&lt;h3&gt;Sound Sources and Connecting Up&lt;/h3&gt;
&lt;p&gt;In the first paragraph I put the cost of this setup at $400. That's a bit misleading because it doesn't include speakers or a digital sound source. I left these out because firstly, I already had speakers and if you're upgrading your system to this you should keep your speakers unless they're &lt;strong&gt;really&lt;/strong&gt; cheap and secondly &lt;strong&gt;everyone&lt;/strong&gt; has a digital sound source - their computer. Even the crappiest motherboard has onboard digital sound. I'm running an S/PDIF optical cable from my Macbook's analogue/digital combi output straight into the Moodlab DAC which then goes into the Trends amp and to my speakers. In the future I'll get an &lt;a href="http://www.apple.com/airportexpress"&gt;Airport Express&lt;/a&gt; so I can stream music &lt;a href="http://www.apple.com/airportexpress/features/airtunes.html"&gt;over AirTunes&lt;/a&gt; from anywhere in the house. If you look at the picture above you get an impression of just how compact the Trends and Moodlab really are.&lt;/p&gt;

&lt;p&gt;All my music has been ripped from CD into Apple Lossless format. I bought a couple of 500Gb &lt;a href="http://www.freecom.com/ecproduct_detail.asp?ID=3234&amp;CatID=8020&amp;sCatID=1146184&amp;ssCatID=1146551"&gt;Freecom USB drives&lt;/a&gt; which I configured as RAID 1 through Leopard. They host the library which is managed via iTunes with full artwork. It took a week or so to rip all of my CDs, that's why I invested in two drives!&lt;/p&gt;

&lt;h3&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;I think the best way to put it is this: I sold my Rotel amp and CD player (original cost $1400) for $600 and bought this setup for $400. I now have more money, better sound quality and flexibility and ultra-portability so I can take it to Canada. This is a great system I cannot recommend enough, for the price I think it's unbeatable. These technologies are revolutionising the hifi industry. Can't say fairer than that, eh?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/zGg36okwFDk" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/guide-audiophile-quality-sound-for-student-dollars</feedburner:origLink></item>
        
            	
        <item>
    		<title>Setup Guide for MAMP, Parallels Desktop and Wordpress</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/JnzYCT6rSX4/setup-guide-for-mamp-parallels-desktop-and-wordpress</link>
    		<comments>http://timothyfletcher.com/journal/posts/setup-guide-for-mamp-parallels-desktop-and-wordpress#comments</comments>
    		<pubDate>Fri, 04 Apr 2008 21:41:36 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;There's a large community of Mac web developers using &lt;a href="http://www.mamp.info/en/index.php"&gt;MAMP&lt;/a&gt; as their development environment of choice. For the uninitiated, MAMP is an integrated web development solution combining Mac/Apache/MySQL/PHP into a single, easy to install and well featured package. Through some extensive research into Mac web dev environments, I believe that MAMP is an optimal solution. If you want to change or add modules to the PHP build that Leopard ships with then you're getting into compiling and all sorts of deep OS stuff. I'm not too keen on that. &lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;Testing in Internet Explorer&lt;/h3&gt;
&lt;p&gt;Great though Apple's computers are for web dev, you still need to test the visual integrity of your masterpieces in the misguidedly popular IE6 and IE 7. Take note of IE 7 because since Microsoft made it a &lt;a href="http://www.microsoft.com/windows/products/winfamily/ie/automaticupdates.mspx"&gt;priority update&lt;/a&gt; it recently superseded IE6 as the &lt;a href="http://www.thecounter.com/stats/2008/February/browser.php"&gt;World's most popular browser&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.parallels.com/"&gt;Parallels Desktop&lt;/a&gt; is an amazing piece of software that allows you to 'virtualise' another operating system within OS X with barely any performance hit to the guest OS. For this article I'm virtualising Windows XP running IE 6. Detailing the installation of &lt;a href="http://www.mamp.info/en/index.php"&gt;MAMP&lt;/a&gt; and &lt;a href="http://www.parallels.com/"&gt;Parallels Desktop&lt;/a&gt; is beyond the scope of this article so read the documentation (i.e. become a power user) and get these working before attempting this setup guide.&lt;/p&gt;

&lt;p&gt;What we're trying to achieve here is a setup whereby typing an identical URL into either a Windows or OS X browser yields the same page, processed by PHP and referencing the MySQL database from within the MAMP environment. With a basic web application this is relatively simple but with a webapp like Wordpress you are required to store the Wordpress and blog URLs in its database which will cause problems if you're using different URLs in each OS to access the server - One of them won't work.&lt;/p&gt;

&lt;h3&gt;The Easy Apple Way&lt;/h3&gt;
&lt;p&gt;In Windows download Apple's &lt;a href="http://www.apple.com/support/downloads/bonjourforwindows.html"&gt;Bonjour For Windows&lt;/a&gt; computer communications technology and install it. Then in OS X go to System Preferences and click the Sharing Icon under Internet and Network.&lt;/p&gt;

&lt;p&gt;Make sure that the File Sharing check box is checked and click the Edit button to change the computer name that the guest OS (XP) will use to access MAMP on the host OS (OS X). I've changed it to localhost.local. Unfortunately the .local is always tagged on the end so you'll have to accommodate it. It's a minor price to pay for such an easy setup.&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/file_sharing_prefs.gif" alt="File Sharing Preferences in Leopard for MAMP Setup" title="File Sharing Preferences"/&gt;

&lt;p&gt;Now you need to setup MAMP so that Apache runs on port 80. I've also changed the MySQL port to it's native 3306 although you don't necessarily need to do this. Note that you must enter your admin password when starting a web server using port 80 on OS X.&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/mamp_ports_setup.gif" alt="Setting MAMP's Ports to 80" title="MAMP Ports Setup"/&gt;

&lt;p&gt;Finally, you need to configure Wordpress so that it runs on localhost.local. You do this on the settings page in your Wordpress admin. Here I have configured Wordpress so that it resides in its own directory on the root of your Apache server but is still accessible from localhost.local. Depending on where you've installed Wordpress you may need to modify this. For info on how give Wordpress its own directory see &lt;a href="http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;img src="http://timothyfletcher.com/uploads/wordpress_mamp_setup.gif" alt="Wordpress MAMP Setup for localhost.local" title="Wordpress MAMP Setup" /&gt;

&lt;p&gt;You should now be able to access your Wordpress install in both Windows and OS X using the URL http://localhost.local. I hope this works for everyone. Give me a shout if you run into problems!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/JnzYCT6rSX4" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/setup-guide-for-mamp-parallels-desktop-and-wordpress</feedburner:origLink></item>
        
            	
        <item>
    		<title>Tutorial: Intelligent Wordpress Navigation Menus</title>
    		<link>http://feedproxy.google.com/~r/timothyfletcher/~3/Sxmc0RfDwv0/tutorial-intelligent-wordpress-navigation-menus</link>
    		<comments>http://timothyfletcher.com/journal/posts/tutorial-intelligent-wordpress-navigation-menus#comments</comments>
    		<pubDate>Wed, 02 Apr 2008 21:19:22 -0600</pubDate>
    		<dc:creator>Tim Fletcher</dc:creator>
    		<description>&lt;p&gt;Creating an 'intelligent' navigation menu for &lt;a href="http://wordpress.org/"&gt;Wordpress&lt;/a&gt; is a good challenge for PHP beginners. In this context I take intelligent to mean that the menu knows which page is being displayed and highlights the appropriate menu item. The navigation menus on this site are an example of this technique in action. In this tutorial I'll show you how to create these menus.&lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;What's wrong with the default theme's navigation?&lt;/h3&gt;
&lt;p&gt;If you look at the image below, you'll see a screenshot of the page navigation menu for the default Kubrick theme. You can see that there's no quick visual clues as to the current page. Naturally if you saw the rest of the page then you'd work it out but in the interests of usability a more obvious system is needed. This is what we're going to change.
&lt;img src="http://timothyfletcher.com/uploads/default_wp_nav.gif" alt="The Default Wordpress Theme Navigaton Menu" title="Default Theme Wordpress Navigation" /&gt;&lt;/p&gt;

&lt;h3&gt;Displaying the Pages&lt;/h3&gt;
&lt;p&gt;Page links are displayed in Wordpress enclosed in &amp;lt;li&amp;gt;...&amp;lt;/li&amp;gt; tags by use of the &lt;a href="http://codex.wordpress.org/wp_list_pages"&gt;wp_list_pages('title_li=')&lt;/a&gt; function. What you need to do is query Wordpress to see which page you're on and then style each list item appropriately. Wordpress automatically handles selectors for pages by appending 'current_page_item' to the class attribute of the current page's menu &amp;lt;li&amp;gt;.&lt;/p&gt;

&lt;p&gt;You can check which page you're on by the use of Wordpress's &lt;a href="http://codex.wordpress.org/Conditional_Tags"&gt; conditional tags&lt;/a&gt;. Referring to &lt;a href="http://dream.adeli.ca"&gt;dream.adeli.ca&lt;/a&gt;, we can see that we need to highlight the BLOG item if we are displaying any of the front, single, archive, search or 404 error pages. To do this we create a simple if statement that sets a different css selector for the BLOG &amp;lt;li&amp;gt; if any of the conditional tags return as true. In this case we set the class to current_page_item (as that&amp;#x27;s the class Wordpress uses to style the &amp;lt;li&amp;gt; for the current page) and then list the other pages with wp_list_pages(). The other pages&amp;#x27; &amp;lt;li&amp;gt; tags are styled by Wordpress using a selector similar to class="page_item page-item-3".&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;?php if (is_home() || is_single() || is_archive() || is_search() || is_404()){ ?&amp;gt;
    &amp;lt;li class=&amp;quot;current_page_item&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;?php bloginfo(&amp;#x27;url&amp;#x27;);?&amp;gt;&amp;quot;&amp;gt;BLOG&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;?php wp_list_pages(&amp;#x27;title_li=&amp;#x27;); ?&amp;gt;
&amp;lt;?php }  ?&amp;gt;
&lt;/pre&gt;

&lt;p&gt;When the current page is not one of the above, we want to style the BLOG item normally so we just append an else statement to the above code that sets the &amp;lt;li&amp;gt; tag class to the normal menu styling, class=&amp;quot;page_item&amp;quot;. Remembering to enclose the menu&amp;#x27;s &amp;lt;li&amp;gt; tags in &amp;lt;ul&amp;gt; tags, the complete code will be:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;ul class=&amp;quot;menu&amp;quot;&amp;gt;		
    &amp;lt;?php if (is_home() || is_single() || is_archive() || is_search() || is_404()){ ?&amp;gt;
        &amp;lt;li class=&amp;quot;current_page_item&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;?php bloginfo(&amp;#x27;url&amp;#x27;);?&amp;gt;&amp;quot;&amp;gt;BLOG&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;?php wp_list_pages(&amp;#x27;title_li=&amp;#x27;); ?&amp;gt;
        &amp;lt;?php } else { ?&amp;gt;
        &amp;lt;li class=&amp;quot;page_item&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;?php bloginfo(&amp;#x27;url&amp;#x27;);?&amp;gt;&amp;quot;&amp;gt;BLOG&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;?php wp_list_pages(&amp;#x27;title_li=&amp;#x27;); ?&amp;gt;
    &amp;lt;?php } ?&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Of course to make all this work you'll need the CSS to style the unordered list. So you don't have to procure it from the site, here it is. Tested with IE6 &amp; 7, Firefox Mac &amp; PC and Safari.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
ul.menu{
    list-style-type: none;
    font-size: 1em;
    text-align: left;
    width: 100%;
    text-transform: uppercase
}
.menu li{
    margin-right: 10px;
    float: left;
}
.menu li a{
    color: #9D9D9D;
    display: block;
    padding: 10px 10px 10px 10px;
}
.menu li a:hover,
.menu li.current_page_item a,
.menu li.current_page_item a:hover {
    color: #CCCCCC;
    background-color: #C13A03;
}
&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/timothyfletcher/~4/Sxmc0RfDwv0" height="1" width="1"/&gt;</description>
        <feedburner:origLink>http://timothyfletcher.com/journal/posts/tutorial-intelligent-wordpress-navigation-menus</feedburner:origLink></item>
        
                
	</channel>
	
</rss>
