<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Terry Dunham is a graphic designer, web designer and illustrator for hire &#187; Nettuts</title>
	<atom:link href="http://terrytoledo.com/category/nettuts/feed/" rel="self" type="application/rss+xml" />
	<link>http://terrytoledo.com</link>
	<description>Free Estimates for Graphic Design, Web Design, Illustration and Designing a Marketing Plan</description>
	<lastBuildDate>Sat, 04 Feb 2012 05:00:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Best of Tuts+ in January 2012</title>
		<link>http://terrytoledo.com/2012/02/best-of-tuts-in-january-2012/</link>
		<comments>http://terrytoledo.com/2012/02/best-of-tuts-in-january-2012/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 05:00:13 +0000</pubDate>
		<dc:creator>Nettuts</dc:creator>
				<category><![CDATA[Nettuts]]></category>

		<guid isPermaLink="false">http://terrytoledo.com/2012/02/best-of-tuts-in-january-2012/</guid>
		<description><![CDATA[Each month, we bring together a selection of the best tutorials and articles from across the whole Tuts+ network. Whether you&#8217;d like to read the top posts from your favourite site, or would like to start learning something completely new, this is the best place to start! Psdtuts+ — Photoshop Tutorials Create a Pimped Out [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23918&amp;c=1454003484" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23918&amp;c=1454003484" border="0" alt="" /></a>
<p>Each month, we bring together a selection of the best tutorials and articles from across the whole <a href="http://tutsplus.com/">Tuts+ network</a>. Whether you&#8217;d like to read the top posts from your favourite site, or would like to start learning something completely new, this is the best place to start!</p>
<p><span></span></p>
<hr />
<h2>Psdtuts+ — Photoshop Tutorials</h2>
<ul>
<li>
<div>
			<img src="http://d2f8dzk2mhcqts.cloudfront.net/0808_Truck/preview.jpg" alt="Create a Pimped Out Truck Using Photoshop and Point and Shoot Photos" width="200" height="200" />
		</div>
<h4><a href="http://psd.tutsplus.com/tutorials/photo-effects-tutorials/pimped-out-truck/">Create a Pimped Out Truck Using Photoshop and Point and Shoot Photos</a></h4>
<p>Making modifications to your car or truck in Photoshop can be a lot of fun. In this tutorial we will demonstrate how to create a pimped out truck modification using photos taken with a simple point and shoot camera, with no advanced lighting setup. Let&#8217;s get started!</p>
<p><a href="http://psd.tutsplus.com/tutorials/photo-effects-tutorials/pimped-out-truck/">Visit Article</a></p>
</li>
<li>
<div>
			<img src="http://d2f8dzk2mhcqts.cloudfront.net/0806_Elephant/preview.jpg" alt="Create an Elephant Sundae Using Photo Manipulation Techniques" width="200" height="200" />
		</div>
<h4><a href="http://psd.tutsplus.com/tutorials/photo-effects-tutorials/elephant-sundae/">Create an Elephant Sundae Using Photo Manipulation Techniques</a></h4>
<p>Photoshop is great at seamlessly combing photos to create an entirely new scene. In this tutorial we will create an elephant sundae using several stock photos. Let&#8217;s get started!</p>
<p><a href="http://psd.tutsplus.com/tutorials/photo-effects-tutorials/elephant-sundae/">Visit Article</a></p>
</li>
<li>
<div>
			<img src="http://d2f8dzk2mhcqts.cloudfront.net/0818_Michaelo/preview.jpg" alt="The Incredible Digital Art of Michael Oswald" width="200" height="200" />
		</div>
<h4><a href="http://psd.tutsplus.com/articles/inspiration/michael-oswald/">The Incredible Digital Art of Michael Oswald</a></h4>
<p>In this article we will be featuring the work of <a href="http://www.bymichaelo.com/">Michael Oswald</a>. Oswald is a digital artist with a unique style. His technique involves a combination of photo manipulation and digital painting techniques and the results are often stunning. Let&#8217;s take a look!</p>
<p><a href="http://psd.tutsplus.com/articles/inspiration/michael-oswald/">Visit Article</a></p>
</li>
<hr />
<h2>Nettuts+ — Web Development Tutorials</h2>
<li>
<div>
		<img src="http://d2o0t5hpnwv4c1.cloudfront.net/1038_sublime/sublime-text-2-tips-and-tricks.jpg" alt="Sublime Text 2 Tips and Tricks (Updated)" width="200" height="200" />
	</div>
<h4><a href="http://net.tutsplus.com/tutorials/tools-and-tips/sublime-text-2-tips-and-tricks/">Sublime Text 2 Tips and Tricks (Updated)</a></h4>
<p><a href="http://www.sublimetext.com/dev">Sublime Text 2</a> is one of the fastest and most incredible code editors to be released in a long time! With a community and plugin ecosystem as passionate as this one, it just might be impossible for any other editor to catch up. I&#8217;ll show you my favorite tips and tricks today. </p>
<p><a href="http://net.tutsplus.com/tutorials/tools-and-tips/sublime-text-2-tips-and-tricks/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d2o0t5hpnwv4c1.cloudfront.net/1119_html5/html5-media-and-accessibility.jpg" alt="An In Depth Analysis of HTML5 Multimedia and Accessibility" width="200" height="200" />
	</div>
<h4><a href="http://net.tutsplus.com/tutorials/html-css-techniques/an-in-depth-overview-of-html5-multimedia-and-accessibility/">An In Depth Analysis of HTML5 Multimedia and Accessibility</a></h4>
<p>In this tutorial, youll learn how HTML5 helps to provide you with several ways of presenting your media content to users. As a result, youll increase the availability of your media to users with different<br />
needs and requirements, making it more accessible.</p>
<p><a href="http://net.tutsplus.com/tutorials/html-css-techniques/an-in-depth-overview-of-html5-multimedia-and-accessibility/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d2o0t5hpnwv4c1.cloudfront.net/1129_api_wrapper_tdd/api-wrapper-for-dribbble.png" alt="Writing an API Wrapper in Ruby with TDD" width="200" height="200" />
	</div>
<h4><a href="http://net.tutsplus.com/tutorials/ruby/writing-an-api-wrapper-in-ruby-with-tdd/">Writing an API Wrapper in Ruby with TDD</a></h4>
<p>Sooner or later, all developers are required to interact with an API. The most difficult part is always related to reliably testing the code we write, and, as we want to make sure that everything works properly, we continuosly run code that queries the API itself. This process is slow and inefficient, as we can experience network issues and data inconsistencies (the API results may change). Let&#8217;s review how we can avoid all of this effort with Ruby.</p>
<p><a href="http://net.tutsplus.com/tutorials/ruby/writing-an-api-wrapper-in-ruby-with-tdd/">Visit Article</a></p>
</li>
<hr />
<h2>Vectortuts+ — Illustrator Tutorials</h2>
<li>
<div>
		<img src="http://dsmy2muqb7t4m.cloudfront.net/tuts/000-2012/477-microscope/preview.jpg" alt="How to Illustrate a Microscope in Illustrator" width="200" height="200" />
	</div>
<h4><a href="http://vector.tutsplus.com/tutorials/illustration/illustrate-a-microscope/">How to Illustrate a Microscope in Illustrator</a></h4>
<p>The microscopes is a symbol of our civilization. Throughout this tutorial on how to illustrate a vector microscope you&#8217;ll take advantage of numerous Illustrator tools. You will learn how to use blends, art brushes and 3D rendering in Adobe Illustrator. Let&#8217;s get started!</p>
<p><a href="http://vector.tutsplus.com/tutorials/illustration/illustrate-a-microscope/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://dsmy2muqb7t4m.cloudfront.net/tuts/000-2012/471-gallery/preview.jpg" alt="Create a Picture Gallery in Illustrator" width="200" height="200" />
	</div>
<h4><a href="http://vector.tutsplus.com/tutorials/illustration/create-a-picture-gallery/">Create a Picture Gallery in Illustrator</a></h4>
<p>This work is a common project created together with <a href="http://vector.tutsplus.com/author/iaroslav-lazunov/">Iaroslav Lazunov</a> and <a href="http://vector.tutsplus.com/author/alexander-egupov/">Alexander Egupov</a>. We have used 3D rendering, Blends, Opacity masks, making this three-dimensional stage with vanishing points. Learn every step in how to create this picture gallery work.</p>
<p><a href="http://vector.tutsplus.com/tutorials/illustration/create-a-picture-gallery/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://dsmy2muqb7t4m.cloudfront.net/articles/2012/article-tutorials-typeface-font-design/preview.jpg" alt="13 Important Resources for Learning How to Design Typefaces and Full Fonts" width="200" height="200" />
	</div>
<h4><a href="http://vector.tutsplus.com/articles/web-roundups/how-to-design-typefaces-fonts/">Important Resources for Learning How to Design Typefaces and Full Fonts</a></h4>
<p>If you&#8217;re serious about creating a typeface design, then you&#8217;ll need some solid resources to get started. Learn effective typeface design workflows, how to take an initial spark of an idea from sketch, through Illustrator, into Fontlab, and then work your creation into a complete and custom font design. Here are multiple tutorials that show you how to create fonts in Illustrator and Fontlab, and you can also dive into articles that describe the foundation of quality type design with ample inspirational examples.</p>
<p><a href="http://vector.tutsplus.com/articles/web-roundups/how-to-design-typefaces-fonts/">Visit Article</a></p>
</li>
<hr />
<h2>Webdesigntuts+ — Web Design Tutorials</h2>
<li>
<div>
		<img src="http://d3pr5r64n04s3o.cloudfront.net/articles/062_pairing_fonts/preview.png" alt="A Beginner’s Guide to Pairing Fonts" width="200" height="200" />
	</div>
<h4><a href="http://webdesign.tutsplus.com/articles/typography-articles/a-beginners-guide-to-pairing-fonts/">A Beginner&#8217;s Guide to Pairing Fonts</a></h4>
<p>Pairing fonts can be a challenge. Selecting two or more fonts which work well is one thing &#8211; selecting two which work <em>together</em> to achieve your typographic aims may have you reaching for the aspirin. Let&#8217;s see if we can alleviate any headaches. This guide will help you get started with font pairing for the web.</p>
<p><a href="http://webdesign.tutsplus.com/articles/typography-articles/a-beginners-guide-to-pairing-fonts/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d3pr5r64n04s3o.cloudfront.net/tuts/235_banner_ads/preview.png" alt="Design a Series of Smart Banner Ads in Photoshop" width="200" height="200" />
	</div>
<h4><a href="http://webdesign.tutsplus.com/tutorials/visuals/design-a-series-of-smart-banner-ads-in-photoshop/">Design a Series of Smart Banner Ads in Photoshop</a></h4>
<p>With the continuous growth of the Internet, online marketing has gotten bigger every year, and along with it, the advertising industry. One major factor in all this craziness is buying and selling ads. </p>
<p><a href="http://webdesign.tutsplus.com/tutorials/visuals/design-a-series-of-smart-banner-ads-in-photoshop/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="https://d3pr5r64n04s3o.cloudfront.net/tuts/231_twitter_bootstrap_101/bootstrap.png" alt="Twitter Bootstrap 101: Introduction" width="200" height="200" />
	</div>
<h4><a href="http://webdesign.tutsplus.com/tutorials/complete-websites/twitter-bootstrap-101-introduction/">Twitter Bootstrap 101: Introduction</a></h4>
<p>Twitter&#8217;s Bootstrap is an excellent set of carefully crafted user interface elements, layouts, and javascript tools, freely available to use in your next web design project. This video series aims to introduce you to Bootstrap; taking you all the way from downloading the resources, to building a complete Bootstrap-based website.</p>
<p><a href="http://webdesign.tutsplus.com/tutorials/complete-websites/twitter-bootstrap-101-introduction/">Visit Article</a></p>
</li>
<hr />
<h2>Phototuts+ — Photography Tutorials</h2>
<li>
<div>
		<img src="http://d2f29brjr0xbt3.cloudfront.net/805_hdrtakeleave/preview.jpg" alt="HDR: Love it or Leave It?" width="200" height="200" />
	</div>
<h4><a href="http://photo.tutsplus.com/articles/post-processing-articles/hdr-love-it-or-leave-it/">HDR: Love it or Leave It?</a></h4>
<p>There are few techniques in the photography world that divide our community as much as HDR. High dynamic range images, or HDR images, are a special type of composite image that combines several images at different exposure settings in order to create an image with increased dynamic range. The look provided by HDR is loved by many, and disliked by perhaps just as many. In today&#8217;s article, we&#8217;re going to take a better look at what HDR is, and get some opinions from photographers using HDR.<span></span></p>
<p><a href="http://photo.tutsplus.com/articles/post-processing-articles/hdr-love-it-or-leave-it/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d2f29brjr0xbt3.cloudfront.net/807_motorsportRU/preview.jpg" alt="50 Inspiring Images of Cars and Motorcycles" width="200" height="200" />
	</div>
<h4><a href="http://photo.tutsplus.com/articles/inspiration/50-inspiring-images-of-cars-and-motorcycles/">Inspiring Images of Cars and Motorcycles</a></h4>
<p>Cars and motorbikes have been around for 100 years. Throughout the century, they have looked beautiful, satisfied our need for speed and become a symbol for thrill seeking. Today, we&#8217;ll look at photos ranging from brand new Ferrari&#8217;s to classic muscle cars.<span></span></p>
<p><a href="http://photo.tutsplus.com/articles/inspiration/50-inspiring-images-of-cars-and-motorcycles/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d2f29brjr0xbt3.cloudfront.net/822_gimpQT/preview.jpg" alt="Quick Tip: GIMP Portable – Take Your Editing Software With You" width="200" height="200" />
	</div>
<h4><a href="http://photo.tutsplus.com/articles/post-processing-articles/quick-tip-gimp-portable-take-your-editing-software-with-you/">Quick Tip: GIMP Portable &#8211; Take Your Editing Software With You</a></h4>
<p>While a number of smartphones now offer photo editing basics (and a plethora of apps to expand things even more), the portability of a solid photo editing program has been hard to come by. Photoshop is a monster in regards to space requirements and its ability to work on any system where it is not expressively installed. Picasa can be fairly &#8216;lightweight&#8217; but lacks many of the more advanced photo editing tools. So what about GIMP?<span></span></p>
<p><a href="http://photo.tutsplus.com/articles/post-processing-articles/quick-tip-gimp-portable-take-your-editing-software-with-you/">Visit Article</a></p>
</li>
<hr />
<h2>Cgtuts+ — Computer Graphics Tutorials</h2>
<li>
<div>
		<img src="http://d2d04grx5ahzvh.cloudfront.net/336_Blender_TRex_Modeling/Thumb.png" alt="Modeling, UVmapping And Texturing A Low Poly T-Rex In Blender, Part 1" width="200" height="200" />
	</div>
<h4><a href="http://cg.tutsplus.com/tutorials/blender/modeling-uvmapping-and-texturing-a-low-poly-t-rex-in-blender-part-1/">Modeling, UVmapping And Texturing A Low Poly T-Rex In Blender, Part 1</a></h4>
<p>In the first tutorial of 2012 you’ll learn how to create an awesome low-poly dinosaur using Blender and Gimp. In today’s post artist Karan Shah will walk you through the entire modeling process step by step, and show you how to create an optimized model suitable for use in any game engine.</p>
<p><a href="http://cg.tutsplus.com/tutorials/blender/modeling-uvmapping-and-texturing-a-low-poly-t-rex-in-blender-part-1/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d2d04grx5ahzvh.cloudfront.net/337_Maya_Fluids_Explosion/Thumb.jpg" alt="Create A Realistic Explosion In Maya Using Maya Fluids" width="200" height="200" />
	</div>
<h4><a href="http://cg.tutsplus.com/tutorials/autodesk-maya/create-a-realistic-explosion-in-maya-using-maya-fluids/">Create A Realistic Explosion In Maya Using Maya Fluids</a></h4>
<p>Today you’ll learn to animate and shade fluids, understand all of the major attributes, learn how adding fields will allow you to gain better control over your simulation, and how to light and render the final animation.</p>
<p><a href="http://cg.tutsplus.com/tutorials/autodesk-maya/create-a-realistic-explosion-in-maya-using-maya-fluids/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d2d04grx5ahzvh.cloudfront.net/339_UDK_Speedtree_Part_1/Thumb.jpg" alt="SpeedTree To UDK: The Complete Workflow, Part 1 Creating The Tree" width="200" height="200" />
	</div>
<h4><a href="http://cg.tutsplus.com/tutorials/game-dev/speedtree-to-udk-the-complete-workflow-part-1/">SpeedTree To UDK: The Complete Workflow, Part 1 Creating The Tree</a></h4>
<p>Due to the shear number of polygons often required to make believable 3D trees, creating realistic ones for use &#8220;in-game&#8221; can be a challenging, time consuming task. SpeedTree from IDV aims to change all that with it&#8217;s intuitive UI, ease of use and powerful toolset. Making believable trees and plants has literally never been easier!</p>
<p><a href="http://cg.tutsplus.com/tutorials/game-dev/speedtree-to-udk-the-complete-workflow-part-1/">Visit Article</a></p>
</li>
<hr />
<h2>Aetuts+ — After Effects Tutorials</h2>
<li>
<div>
		<img src="http://d3gphd0pfuxn95.cloudfront.net/694_dominoes/dominoes_thumbnail.jpg" alt="“Dominoes” CameraTracker and Cinema 4d Case Study – Day 1" width="200" height="200" />
	</div>
<h4><a href="http://ae.tutsplus.com/tutorials/workflow/dominoes-cameratracker-and-cinema-4d-case-study-day-1/">Dominoes&#8221; CameraTracker and Cinema 4d Case Study &#8211; Day 1</a></h4>
<p>In this tutorial we&#8217;re going to go over the principle functionality of <a href="http://www.thefoundry.co.uk/products/cameratracker/">CameraTracker</a> from The Foundry, learning basic workflow, optimizing results, aligning the ground plane and exporting this data from After Effects to <a href="http://www.maxon.net/" rel="external">Cinema 4d</a>.<span></span></p>
<p><a href="http://ae.tutsplus.com/tutorials/workflow/dominoes-cameratracker-and-cinema-4d-case-study-day-1/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://tutsplus.s3.amazonaws.com/tutspremium/after-effects/59_flame_react/Flame_Reactant_Thumbnail.jpg" alt="Make An Amazing Motion Reactant Flame – Tuts+ Premium" width="200" height="200" />
	</div>
<h4><a href="http://ae.tutsplus.com/tutorials/vfx/make-an-amazing-motion-reactant-flame-tutsplus-premium/">Make An Amazing Motion Reactant Flame &#8211; Tuts+ Premium</a></h4>
<p>Using just a few video elements of torch flames, we composite a burning hand by using a series of null objects and expressions to drive a <strong>time lagged displacement effect</strong> to simulate fire burning from a moving source. We use the Puppet tool for the distortion and throw on some tracked lighting effects and a displacement map for the Heat. This principle can be used to <strong>add realistic, fluid motion to any tracked object</strong>.</p>
<p><a href="http://ae.tutsplus.com/tutorials/vfx/make-an-amazing-motion-reactant-flame-tutsplus-premium/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d3gphd0pfuxn95.cloudfront.net/misc/freelancer.jpg" alt="10 Key Tips To Becoming A Successful Video Freelancer" width="200" height="200" />
	</div>
<h4><a href="http://ae.tutsplus.com/articles/in-depth/10-key-tips-to-becoming-a-successful-video-freelancer/">Key Tips To Becoming A Successful Video Freelancer</a></h4>
<p>Youve watched thousands of tutorials. Youve put in countless hours and spent many late nights working on personal projects. Youve finally come to the conclusion that this may just be something you would like to do for a career. It can seem a little intimidating at first, because how are you going to convince someone to pay you to do this? Up until now youve been your only client. How do you get more?  Im going to share my insight and experiences on how to successfully launch your freelance career this year!</p>
<p><a href="http://ae.tutsplus.com/articles/in-depth/10-key-tips-to-becoming-a-successful-video-freelancer/">Visit Article</a></p>
</li>
<hr />
<h2>Audiotuts+ — Audio &#038; Production Tutorials</h2>
<li>
<div>
		<img src="http://d3vvl31cy8gagb.cloudfront.net/713_8free/Preview Image.jpg" alt="8 Free Professional Quality Audio Unit Plug-ins for Mac" width="200" height="200" />
	</div>
<h4><a href="http://audio.tutsplus.com/articles/general/8-free-professional-quality-audio-unit-plug-ins-for-mac/">Free Professional Quality Audio Unit Plug-ins for Mac</a></h4>
<p>Lets face it, software is expensive. While there are hundreds of free plug-ins available online, more often than not two problems will arise: One, most of them are for PCs leaving us Mac users feeling left out. Two, most of them are vary poor quality.</p>
<p>While I do agree with the saying, &#8220;The tools are only as good as the artist,&#8221; I also believe the opposite is true; that at some point the artist can only be as good as his tools are.</p>
<p><a href="http://audio.tutsplus.com/articles/general/8-free-professional-quality-audio-unit-plug-ins-for-mac/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d3vvl31cy8gagb.cloudfront.net/qt_168_drums4/Thumbnail.jpg" alt="Quick Tip: Drum Processing Part 4: Tips and Tricks" width="200" height="200" />
	</div>
<h4><a href="http://audio.tutsplus.com/tutorials/production/quick-tip-drum-processing-part-4-tips-and-tricks/">Quick Tip: Drum Processing Part 4: Tips and Tricks</a></h4>
<p>This short series of quick tips is designed to give you a good overview of the audio processing techniques involved in creating a professional sounding drum beat for use in house, electro and breaks in Cubase. In this final part we will look at a few ways to add even more life to your drums.<br />
<span></span><br />
Here is a sample of the type of beat you could expect to end up with at the end of this series of tips:</p>
<p><a href="http://audio.tutsplus.com/tutorials/production/quick-tip-drum-processing-part-4-tips-and-tricks/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d3vvl31cy8gagb.cloudfront.net/qt_164_math/preview.jpg" alt="Quick Tip: Use the Doubling Technique for Quick Drums" width="200" height="200" />
	</div>
<h4><a href="http://audio.tutsplus.com/tutorials/production/quick-tip-use-the-doubling-technique-for-quick-drums/">Quick Tip: Use the Doubling Technique for Quick Drums</a></h4>
<p>It&#8217;s 3:30 in the afternoon when your phone rings. The head of a music library is calling and she needs your help. They have a commercial for an A-list client that needs music, and they want you to submit an entry. You&#8217;ll get $10,000 if you land the gig.</p>
<p><a href="http://audio.tutsplus.com/tutorials/production/quick-tip-use-the-doubling-technique-for-quick-drums/">Visit Article</a></p>
</li>
<hr />
<h2>Activetuts+ — Flash, Flex &#038; ActionScript Tutorials</h2>
<li>
<div>
		<img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/394_microphoneGameCode/preview.jpg" alt="Create a Microphone-Controlled Flash Game: Code" width="200" height="200" />
	</div>
<h4><a href="http://active.tutsplus.com/tutorials/games/create-a-microphone-controlled-flash-game-code/">Create a Microphone-Controlled Flash Game: Code</a></h4>
<p>In this mini-series, we&#8217;re creating a spaceship game where the main control is via the microphone: shout louder to make the ship fly higher. <a href="http://active.tutsplus.com/tutorials/games/create-a-microphone-controlled-flash-game-design/">So far</a>, we&#8217;ve created all the required graphical elements for the game. Now, it&#8217;s time to work on our code. We&#8217;ve got a lot to do, so let&#8217;s get started!<span></span></p>
<p><a href="http://active.tutsplus.com/tutorials/games/create-a-microphone-controlled-flash-game-code/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d2fhka9tf2vaj2.cloudfront.net/articles/084_whyBotherWithjQuery/why_bother_with_jquery.png" alt="Why Bother With jQuery? A Guide for (Former) Flash Developers" width="200" height="200" />
	</div>
<h4><a href="http://active.tutsplus.com/articles/explanatory/why-bother-with-jquery-a-guide-for-former-flash-developers/">Why Bother With jQuery? A Guide for (Former) Flash Developers</a></h4>
<p>If you, like many Flash developers, are looking into using HTML5 for your web apps, you&#8217;ll almost certainly have come across jQuery. It&#8217;s a very popular JavaScript library, used by <a href="http://trends.builtwith.com/javascript/JQuery" rel="external">a large percentage</a> of the most visited websites &#8211; but what&#8217;s all the fuss about, and should you use it?<span></span></p>
<p><a href="http://active.tutsplus.com/articles/explanatory/why-bother-with-jquery-a-guide-for-former-flash-developers/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d2fhka9tf2vaj2.cloudfront.net/tuts/398_gamepadAPIIntro/gamepadAPI-preview.jpg" alt="An Introduction to the HTML5 Gamepad API" width="200" height="200" />
	</div>
<h4><a href="http://active.tutsplus.com/tutorials/games/an-introduction-to-the-html5-gamepad-api/">An Introduction to the HTML5 Gamepad API</a></h4>
<p>As HTML games begin to gradually increase in popularity, vendors are starting to introduce some exciting new APIs to make gaming that little bit sweeter for both us developers and our end players. One of these is the GamepadAPI, which allows you to connect your good old console gamepad into your computer and use it for browser based games, plug and play style. Let&#8217;s dive in!<span></span></p>
<p><a href="http://active.tutsplus.com/tutorials/games/an-introduction-to-the-html5-gamepad-api/">Visit Article</a></p>
</li>
<hr />
<h2>Wptuts+ — WordPress Tutorials</h2>
<li>
<div>
		<img src="http://wptutsplus.s3.amazonaws.com/159_RiseHTML5/html5.jpg" alt="The Rise of HTML5 in WordPress" width="200" height="200" />
	</div>
<h4><a href="http://wp.tutsplus.com/articles/the-rise-of-html5-in-wordpress/">The Rise of HTML5 in WordPress</a></h4>
<p>2011 was a big year for the advancement of HTML5 in the web development community. It became pretty widely adopted, especially for the mobile web. There have been major projects that help developers use HTML5, like Paul Irish&#8217;s <a href="http://html5boilerplate.com/">HTML5 Boilerplate</a> (technically 2010, but popularized in 2011) and books galore!</p>
<p><a href="http://wp.tutsplus.com/articles/the-rise-of-html5-in-wordpress/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://wptutsplus.s3.amazonaws.com/131_MetaBoxPt1/metabox_0.jpg" alt="Reusable Custom Meta Boxes Part 3: Extra Fields" width="200" height="200" />
	</div>
<h4><a href="http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-3-extra-fields/">Reusable Custom Meta Boxes Part 3: Extra Fields</a></h4>
<p>In <a href="http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-1-intro-and-basic-fields/">Part 1</a> and <a href="http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-2-advanced-fields/">Part 2</a> of our custom meta box template tutorial series, we learned how to create a field array to loop through and create a custom meta box with your standard fields. Now let&#8217;s throw in a bit of JavaScript for some fancy, but highly useful fields.</p>
<p><a href="http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-3-extra-fields/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://wptutsplus.s3.amazonaws.com/167_ySlowTut/img/uwo.png" alt="The Ultimate Quickstart Guide to Speeding Up Your WordPress Site" width="200" height="200" />
	</div>
<h4><a href="http://wp.tutsplus.com/tutorials/the-ultimate-quickstart-guide-to-speeding-up-your-wordpress-site/">The Ultimate Quickstart Guide to Speeding Up Your WordPress Site</a></h4>
<p>Give your site a boost! Implement crucial optimization techniques that will improve not only your <strong><a href="http://developer.yahoo.com/yslow/">ySlow </a></strong>score, but your Google rank too. In this tutorial we will cover all aspects of W3 caching, ySlow, Google page speed, CSS sprites &#038; htaccess rules, to achieve a high ySlow score like i have done on <a href="http://imattic.com/">my blog.</a></p>
<p><a href="http://wp.tutsplus.com/tutorials/the-ultimate-quickstart-guide-to-speeding-up-your-wordpress-site/">Visit Article</a></p>
</li>
<hr />
<h2>Mobiletuts+ — Mobile Development Tutorials</h2>
<li>
<div>
		<img src="http://d339vfjsz5zott.cloudfront.net/iOS-SDK_Creating-A-Carousel/carousel.jpg" alt="iOS SDK: Creating an Awesome Carousel" width="200" height="200" />
	</div>
<h4><a href="http://mobile.tutsplus.com/tutorials/iphone/ios-sdk-creating-an-awesome-carousel/">iOS SDK: Creating an Awesome Carousel</a></h4>
<p>Engage your users with stunning carousels.  We&#8217;ll look at how easy and clean it can be to implement scrollable, interactive carousels in your iOS applications.  With high configurability, you can have 3D, flat, rotating, and endless scrolling arrays for data, images, or buttons.<br />
<span></span></p>
<p><a href="http://mobile.tutsplus.com/tutorials/iphone/ios-sdk-creating-an-awesome-carousel/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d339vfjsz5zott.cloudfront.net/PhoneGap-From-Scratch/phonegap.jpg" alt="PhoneGap From Scratch: Introduction" width="200" height="200" />
	</div>
<h4><a href="http://mobile.tutsplus.com/tutorials/phonegap/phonegap-from-scratch/">PhoneGap From Scratch: Introduction</a></h4>
<p>Want to learn how to use PhoneGap, but don&#8217;t know where to get started? Join us as we put together &#8220;Sculder&#8221;, not only a tribute to an excellent science fiction TV series, but a fully-fledged native mobile application for the believer in you!</p>
<p><a href="http://mobile.tutsplus.com/tutorials/phonegap/phonegap-from-scratch/">Visit Article</a></p>
</li>
<li>
<div>
		<img src="http://d339vfjsz5zott.cloudfront.net/Mobile-Flash-Is-Far-From-Dead/mobile-flash.png" alt="Mobile Flash is Far From Dead: Setting the Record Straight" width="200" height="200" />
	</div>
<h4><a href="http://mobile.tutsplus.com/?p=9436">Mobile Flash is Far From Dead: Setting the Record Straight</a></h4>
<p>In light of recent announcements from Adobe, there has been a lot of confusion over the state of the Flash Platform &#8211; specifically in regard to Flash content on mobile devices. This article seeks to clarify many of the misconceptions that exist by addressing the main points of confusion around these announcements regardless of the initial, monumental, and absolutely unbelievable blunders from failed public (and private) relations messaging and general marketing surrounding these announcements.<span></span></p>
<p><a href="http://mobile.tutsplus.com/?p=9436">Visit Article</a></p>
</li>
</ul>
<p><a href="http://feedads.g.doubleclick.net/~a/ZnKEytR8CAyz5VqSywXNd4mIAGI/0/da"><img src="http://feedads.g.doubleclick.net/~a/ZnKEytR8CAyz5VqSywXNd4mIAGI/0/di" border="0"></img></a><br />
<a href="http://feedads.g.doubleclick.net/~a/ZnKEytR8CAyz5VqSywXNd4mIAGI/1/da"><img src="http://feedads.g.doubleclick.net/~a/ZnKEytR8CAyz5VqSywXNd4mIAGI/1/di" border="0"></img></a></p>
<div>
<a href="http://feeds.feedburner.com/~ff/nettuts?a=JtBVW0IlEaE:CeiJ0V3T4Gg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=JtBVW0IlEaE:CeiJ0V3T4Gg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=JtBVW0IlEaE:CeiJ0V3T4Gg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=JtBVW0IlEaE:CeiJ0V3T4Gg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=JtBVW0IlEaE:CeiJ0V3T4Gg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=JtBVW0IlEaE:CeiJ0V3T4Gg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=JtBVW0IlEaE:CeiJ0V3T4Gg:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=JtBVW0IlEaE:CeiJ0V3T4Gg:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/JtBVW0IlEaE" height="1" width="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://terrytoledo.com/2012/02/best-of-tuts-in-january-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learn jQuery in 30 Days</title>
		<link>http://terrytoledo.com/2012/02/learn-jquery-in-30-days/</link>
		<comments>http://terrytoledo.com/2012/02/learn-jquery-in-30-days/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 05:00:11 +0000</pubDate>
		<dc:creator>Nettuts</dc:creator>
				<category><![CDATA[Nettuts]]></category>

		<guid isPermaLink="false">http://terrytoledo.com/2012/02/learn-jquery-in-30-days/</guid>
		<description><![CDATA[Sometimes, it&#8217;s easy to become overwhelmed by how much there is to learn in this industry. If jQuery happens to be on your personal &#8220;need to learn soon&#8221; list, then I&#8217;m happy to announce my new course: &#8220;Learn jQuery in 30 Days&#8221;. If you&#8217;ll give me fifteen minutes a day for the next month, I&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23901&amp;c=1933359587" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23901&amp;c=1933359587" border="0" alt="" /></a>
<p>Sometimes, it&#8217;s easy to become overwhelmed by how much there is to learn in this industry. If jQuery happens to be on your personal &#8220;need to learn soon&#8221; list, then I&#8217;m happy to announce my new course: <a href="http://learnjquery.tutsplus.com">&#8220;Learn jQuery in 30 Days&#8221;</a>. If you&#8217;ll give me fifteen minutes a day for the next month, I&#8217;ll help you become a jQuery pro &#8211; <strong>and it&#8217;s free!</strong><span></span></p>
<hr />
<h2> How Does it Work? </h2>
<div>
<a href="http://learnjquery.tutsplus.com"><img src="http://tutsplus.s3.amazonaws.com/tutspremium/courses_$folder$/30DaysJquery/images/learnjQuerySite.jpg" alt="Learn jQuery"></a>
</div>
<blockquote>
<p>Sporadically, your skills will be put to the test, when you take the interactive quizzes! </p>
</blockquote>
<p>Once you <a href="http://learnjquery.tutsplus.com">enroll (free) via email</a>, each day, you&#8217;ll receive a 10-15 minute video lesson. As you might expect, every episode will build upon the one it proceeds, and, sporadically, your skills will be put to the test, when you take the interactive quizzes! </p>
<p>Along the way, you&#8217;ll learn the essentials (querying and manipulating the DOM), while incrementally working your way up to more advanced topics, such as jQuery&#8217;s AJAX methods and plugin development. </p>
<p>I worked particularly hard to make the process of picking up this new skill as easy as possible for everyone &#8211; even if you have very, very little JavaScript experience. So&#8230;<a href="http://learnjquery.tutsplus.com">do you want to join me?</a> </p>
<p><a href="http://feedads.g.doubleclick.net/~a/qoqfN_7sSYlSCIU7i0_Z6H8XH9M/0/da"><img src="http://feedads.g.doubleclick.net/~a/qoqfN_7sSYlSCIU7i0_Z6H8XH9M/0/di" border="0"></img></a><br />
<a href="http://feedads.g.doubleclick.net/~a/qoqfN_7sSYlSCIU7i0_Z6H8XH9M/1/da"><img src="http://feedads.g.doubleclick.net/~a/qoqfN_7sSYlSCIU7i0_Z6H8XH9M/1/di" border="0"></img></a></p>
<div>
<a href="http://feeds.feedburner.com/~ff/nettuts?a=hI3XrFMnqw8:9H-58M5y3RI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=hI3XrFMnqw8:9H-58M5y3RI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=hI3XrFMnqw8:9H-58M5y3RI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=hI3XrFMnqw8:9H-58M5y3RI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=hI3XrFMnqw8:9H-58M5y3RI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=hI3XrFMnqw8:9H-58M5y3RI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=hI3XrFMnqw8:9H-58M5y3RI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=hI3XrFMnqw8:9H-58M5y3RI:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/hI3XrFMnqw8" height="1" width="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://terrytoledo.com/2012/02/learn-jquery-in-30-days/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recently in Web Development (January ’12 Edition)</title>
		<link>http://terrytoledo.com/2012/01/recently-in-web-development-january-%e2%80%9912-edition/</link>
		<comments>http://terrytoledo.com/2012/01/recently-in-web-development-january-%e2%80%9912-edition/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 05:00:35 +0000</pubDate>
		<dc:creator>Nettuts</dc:creator>
				<category><![CDATA[Nettuts]]></category>

		<guid isPermaLink="false">http://terrytoledo.com/2012/01/recently-in-web-development-january-%e2%80%9912-edition/</guid>
		<description><![CDATA[Web development is an industry that&#8217;s in a state of constant flux with technologies and jargon changing and mutating in an endless cycle. Not to mention the sheer deluge of information one has to process everyday. In this series, published monthly, we&#8217;ll seek to rectify this by bringing you all the important news, announcements, releases [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23889&amp;c=611572451" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23889&amp;c=611572451" border="0" alt="" /></a>
<p>Web development is an industry that&#8217;s in a state of constant flux with technologies and jargon changing and mutating in an endless cycle. Not to mention the sheer deluge of information one has to process everyday.</p>
<p>In this series, published monthly, we&#8217;ll seek to rectify this by bringing you all the important news, announcements, releases and interesting discussions within the web development industry in a concise package. Join me after the jump for an extra dose of community content this month!</p>
<p><span></span></p>
<h2>
<hr />News and Releases</h2>
<p>All of the important news in a single place: releases, announcements, companies bickering, security issues and all related hoopla.</p>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/html.png" width="250" /></div>
<h3>&#8216;HTML5 Please&#8217; Helps Devs Make Informed Decisions</h3>
<p>HTML5 is a beast of a spec with no one <em>truly</em> knowing everything there is to know. This shiny new site gives you all the information you need to use HTML5 features on your site, right now.</p>
<p>The site provides you with recommendations as to whether you should be using that specific facet of HTML5 right now and provides you with helpful links to polyfills, when necessary. Time saver!</p>
<p><a href="http://html5please.us/">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/enyo.png" width="250" /></div>
<h3>HP Open Sources Enyo</h3>
<p>Enyo is the engine that powers webOS. But what exactly is Enyo, you ask? Well, it&#8217;s a spiffy JavaScript framework that helps you build better performing, easier to maintain application.</p>
<p>I&#8217;m sure you&#8217;ve heard this plenty of times before so why don&#8217;t you check out the link below to find out for yourself?</p>
<p><a href="http://enyojs.com/">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1112_riwd7/sopa.png" width="250" /></div>
<h3>Tech Giants Protest SOPA</h3>
<p>Last month saw a figurative deluge of protests against SOPA. If you have no idea what SOPA is, hit the link below to find out.</p>
<p>While many services merely blackened out their logo, many others, including Wikipedia and Reddit, went the extra length and completely blacked out their sites. The proposed bill has been shelved but I predict that we&#8217;ll see another in a different skin soon&#8230;</p>
<p><a href="http://en.wikipedia.org/wiki/SOPA">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/vim.png" width="250" /></div>
<h3>Vim on a Tablet? Yes, Please!</h3>
<p>I understand not everyone uses a tablet but the number is growing, quite rapidly. Wouldn&#8217;t it be great to SSH into your server to fix that pesky bug? Get a proper laptop, you say? I&#8217;m going to ask you to shush for now and go with the flow.</p>
<p>This month saw the release of Vim for the iOS platform. And no, it&#8217;s not a gimped version. From a quick run through, it seems that all the nice bits are still in there. If you&#8217;re in the intersection between developers and iPad users, let us know in the comments below as to whether it fits your needs.</p>
<p><a href="http://applidium.com/en/applications/vim/">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/ctr.jpg" width="250" /></div>
<h3>Cut the Rope Ported to the Browser</h3>
<p>I&#8217;m sure a lot of you have played this ridiculously cute &#8216;aww&#8217; inducing game. What brings the game to our list is the fact that it has been ported to the browser by the newly cool Internet Explorer team. </p>
<p>And true to their current vision, they&#8217;ve ported it using JavaScript and the magic of HTML5. The link below leads you to a write up about the game development instead of the game itself to protect your productivity.</p>
<p><a href="http://www.cuttherope.ie/dev/">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1002_riwd1/rails.png" width="250" /></div>
<h3>The Rails Tutorial, Version Two, Inches Towards Completion</h3>
<p>&#8216;The&#8217; Rails tutorial? Indeed it is! Michael Hartl&#8217;s <em>free</em> has helped many learn the voodoo that is Rails and Michael is slowly updating his ebook for Ruby 1.9 and Rails 3.2</p>
<p>Thus far, six chapters are out with a chapter expected every week in the future. Make sure to check the site out! </p>
<p><a href="http://news.railstutorial.org/ruby-on-rails-tutorial-second-edition-updated">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/st2.png" width="250" /></div>
<h3>Sublime Text 2 Piles on More Features with New Beta</h3>
<p>Sublime Text 2 is a grand piece of work and every build only reaffirms this. This new build introduces a ton of features including auto complete, performance improvements, a new UI theme and a ton more.</p>
<p><a href="http://www.sublimetext.com/blog/articles/sublime-text-2-build-2165">Read more</a></p>
<div></div>
<div></div>
<h2>
<hr />New Kids on the Block</h2>
<p>As web developers, the sheer amount of resources we can tap into increases exponentially with time. Here is just a quick look at some recently created resources that deserve your attention &#8212; everything from new books to scripts and frameworks.</p>
<hr />
<h3>wrap.js</h3>
<blockquote><p>My wrap.js plugin handles the nested require based on a config, and takes it to the next level by generating an actual AMD module for you during the build. So now you don’t have to write wrappers around scripts that you wish were modules, wrap.js does that for you. </p>
</blockquote>
<p><a href="https://github.com/geddesign/wrap.js">Github Repo</a></p>
<hr />
<h3>Resumable.js</h3>
<blockquote><p>Resumables is a JavaScript library providing multiple simultaneous, stable and resumable uploads via the HTML5 File API.<br />
The library is designed to introduce fault-tolerance into the upload of large files through HTTP. This is done by splitting each files into small chunks; whenever the upload of a chunk fails, uploading is retried until the procedure completes.</p>
</blockquote>
<p><a href="https://github.com/23/resumable.js">Github Repo</a></p>
<hr />
<h3>IcedCoffeeScript</h3>
<blockquote><p>IcedCoffeeScript is a fork of CoffeeScript. It is superset of the CoffeeScript language. The iced interpreter is a drop-in replacement for the standard coffee interpreter since it will interpret all existing CoffeeScript programs. IcedCoffeeScript (ICS) adds two new keywords: await and defer. These additions simply and powerfully streamline asynchronous control flow, both on the server and on the browser. </p>
</blockquote>
<p><a href="http://maxtaco.github.com/coffee-script/">Github Repo</a></p>
<hr />
<h3>Banking.js</h3>
<blockquote><p> Banking.JS retrieves all of your bank transactions similiar to how quickbooks does it. There is no need to depend on or pay for third party services. The bank statement results are in JSON or Valid XML and supports all financial institutions.</p>
</blockquote>
<p><a href="https://github.com/euforic/banking.js">Github Repo</a></p>
<hr />
<h3>Roy</h3>
<blockquote><p>Roy is a small functional language that compiles to JavaScript. The main features include whitespace significant syntax, compile-time meta-programming, structural typing and monad syntax</p>
</blockquote>
<p><a href="https://github.com/pufuwozu/roy">Github Repo</a></p>
<hr />
<h3>jsgif</h3>
<blockquote><p>jsgif an animated GIF player bookmarklet with support for pausing, going frame-by-frame, playing in reverse, and other features that one might expect from a video player. </p>
</blockquote>
<p><a href="https://github.com/shachaf/jsgif">Github Repo</a></p>
<hr />
<h3>zip.js</h3>
<blockquote><p>zip.js offers a low-level API for writing and reading large zip files (up to 4GB) with a stable RAM use. It also offers a Filesystem API in order to manipulate zip file structure.</p>
</blockquote>
<p><a href="http://gildas-lormeau.github.com/zip.js/">Github Repo</a></p>
<hr />
<h3>Seriously.js</h3>
<blockquote><p>Seriously.js is a real-time, node-based video compositor for the web. Inspired by professional software such as After Effects and Nuke, Seriously.js renders high-quality video effects, but allows them to be dynamic and interactive.</p>
</blockquote>
<p><a href="https://github.com/brianchirls/Seriously.js">Github Repo</a></p>
<h2>
<hr />Best of the Internet</h2>
<p>Often, you&#8217;re not really looking for a tutorial as much as you&#8217;re looking for a rant, an opinion or the musings of a tired developer or just something cool with absolutely zero real world use. This sections contains links to precisely those &#8212; interesting and cool stuff from the developer community. </p>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/749_WebHostFeatures/preview.jpg" width="250" /></div>
<h3>The Five Stages of Hosting</h3>
<p>Five common options for hosting a web business, ranked in decreasing order of &#8216;cloudiness&#8217;. </p>
<p><a href="http://blog.pinboard.in/2012/01/the_five_stages_of_hosting/">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/913_jsDevs/yehuda_katz.png" width="250" /></div>
<h3>JavaScript Needs Blocks</h3>
<p>Yehuda Katz talks about why he wants to see block lambdas in JavaScript. It&#8217;s a bit technical but well worth a read. </p>
<p><a href="http://yehudakatz.com/2012/01/10/javascript-needs-blocks/">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1002_riwd1/ror.png" width="250" /></div>
<h3>How I Learned Enough Ruby On Rails In 12 Weeks To Launch Freelancify</h3>
<p>A Non-Developer explains how&#8230; I think you know already. Just click the darn link and move on.</p>
<p><a href="http://www.webstartup.me/learned-ruby-rails-12-weeks-launch-freelancify">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1096_riwd6/cfn.gif" width="250" /></div>
<h3>Why are software development task estimations regularly off by a factor of 2-3?</h3>
<p>Is it the developer&#8217;s fault? Is it a management issue? Bad methodology, or lack thereof? Or is it ingrained in the nature of the process?</p>
<p><a href="http://www.quora.com/Engineering-Management/Why-are-software-development-task-estimations-regularly-off-by-a-factor-of-2-3">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/wat.png" width="250" /></div>
<h3>Explanation for the &#8216;Wat&#8217; Talk &#8211; CodeMash 2012</h3>
<p>This StackOverflow question, along with the well written answers below, explore the code that was demonstrated in the talk mentioned in the title. Provides a quick look at the quirkier portions of JavaScript. </p>
<p><a href="http://stackoverflow.com/questions/9032856/can-anyone-explain-these-bizarre-javascript-behaviours-mentioned-in-the-wat-ta">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/db.png" width="250" /></div>
<h3>Why are column oriented databases so much faster than row oriented databases?</h3>
<p>A quick little read that explains why, and how, different databases perform differently. There isn&#8217;t much jargon there and gets the point quite clearly. </p>
<p><a href="http://siganakis.com/using-bitmap-indexes-in-query-processing">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/734_oop/200x200.jpg" width="250" /></div>
<h3>PHP Mind Love</h3>
<p>The link below points to some PHP code. Figure out what the output is and you get a cookie!</p>
<p><a href="https://github.com/TheFox/JaPHPh/blob/master/japhph.php">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1096_riwd6/2d.jpg" width="250" /></div>
<h3>Testing Socket.IO With Mocha, Should.js and Socket.IO Client</h3>
<p>A clean writeup that details how the author got all the named technologies working together. </p>
<p><a href="http://net.tutsplus.com/gg">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1019_riwd2/js.jpg" width="250" /></div>
<h3>What is the difference between semicolons in JavaScript and in Python?</h3>
<p>Ever had to think about the question above? How exactly do they each handle semicolons and newlines? Read up below.</p>
<p><a href="http://stackoverflow.com/questions/7219541/what-is-the-difference-between-semicolons-in-javascript-and-in-python">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/dj.png" width="250" /></div>
<h3>The Programming Djinn</h3>
<p>The Least Boring Programming Book teaches Ruby programming to beginners in an unconventional way. </p>
<p><a href="http://ethanfast.com/2012/01/the-least-boring-programming-book-chapter-1-excerpt/">Read more</a></p>
<div></div>
<div></div>
<div><img alt="Nettuts image" src="http://d2o0t5hpnwv4c1.cloudfront.net/1130_riwd8/hg.png" width="250" /></div>
<h3>Non-Canvas Wizardry</h3>
<p>I don&#8217;t really have much context to go on here so just give the link below a click. Pretty smooth stuff for something that&#8217;s not canvas or Flash based.</p>
<p><a href="http://scorcher.de/palette/palette.html?fps=10&amp;colors=500&amp;pixels=30&amp;container=680">Read more</a></p>
<div></div>
<h2>
<hr />Wrapping Up</h2>
<p>Well, that&#8217;s about all the major changes that happened in our industry lately. </p>
<p>Do you want us to cover more standard news? A focus on upcoming scripts maybe? Or just more interesting posts and discussions from the community? Let us know in the comments and thank you so much for reading! </p>
<p><a href="http://feedads.g.doubleclick.net/~a/o14hrPeKkS8Ns_WS_2Ws4iicyPo/0/da"><img src="http://feedads.g.doubleclick.net/~a/o14hrPeKkS8Ns_WS_2Ws4iicyPo/0/di" border="0"></img></a><br />
<a href="http://feedads.g.doubleclick.net/~a/o14hrPeKkS8Ns_WS_2Ws4iicyPo/1/da"><img src="http://feedads.g.doubleclick.net/~a/o14hrPeKkS8Ns_WS_2Ws4iicyPo/1/di" border="0"></img></a></p>
<div>
<a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=CZhjBpTuRuM:8hIim0ry3ZU:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=CZhjBpTuRuM:8hIim0ry3ZU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=CZhjBpTuRuM:8hIim0ry3ZU:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=CZhjBpTuRuM:8hIim0ry3ZU:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/CZhjBpTuRuM" height="1" width="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://terrytoledo.com/2012/01/recently-in-web-development-january-%e2%80%9912-edition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing an API Wrapper in Ruby with TDD</title>
		<link>http://terrytoledo.com/2012/01/writing-an-api-wrapper-in-ruby-with-tdd/</link>
		<comments>http://terrytoledo.com/2012/01/writing-an-api-wrapper-in-ruby-with-tdd/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 05:00:11 +0000</pubDate>
		<dc:creator>Nettuts</dc:creator>
				<category><![CDATA[Nettuts]]></category>

		<guid isPermaLink="false">http://terrytoledo.com/2012/01/writing-an-api-wrapper-in-ruby-with-tdd/</guid>
		<description><![CDATA[Sooner or later, all developers are required to interact with an API. The most difficult part is always related to reliably testing the code we write, and, as we want to make sure that everything works properly, we continuosly run code that queries the API itself. This process is slow and inefficient, as we can [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23875&amp;c=1274595345" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23875&amp;c=1274595345" border="0" alt="" /></a>
<p>Sooner or later, all developers are required to interact with an API. The most difficult part is always related to reliably testing the code we write, and, as we want to make sure that everything works properly, we continuosly run code that queries the API itself. This process is slow and inefficient, as we can experience network issues and data inconsistencies (the API results may change). Let&#8217;s review how we can avoid all of this effort with Ruby.</p>
<p><span></span></p>
<hr />
<h2>Our Goal</h2>
<blockquote>
<p>&#8220;Flow is essential: write the tests, run them and see them fail, then write the minimal implementation code to make them pass. Once they all do, refactor if needed.&#8221;</p>
</blockquote>
<p>Our goal is simple: write a small wrapper around the <a href="http://dribbble.com/api">Dribbble API</a> to retrieve information about a user (called &#8216;player&#8217; in the Dribbble world).<br />
As we will be using Ruby, we will also follow a TDD approach: if you&#8217;re not familiar with this technique, Nettuts+ has a <a href="http://net.tutsplus.com/tutorials/ruby/ruby-for-newbies-testing-with-rspec/">good primer on RSpec</a> you can read. In a nutshell, we will write tests before writing our code implementation, making it easier to spot bugs and to achieve a high code quality. Flow is essential: write the tests, run them and see them fail, then write the minimal implementation code to make them pass. Once they all do, refactor if needed.</p>
<h3>The API</h3>
<p>The Dribbble API is fairly straightforward. At the time of this   it supports only GET requests and doesn&#8217;t require authentication: an ideal candidate for our tutorial. Moreover, it offers a 60 calls per minute limit, a restriction that perfectly shows why working with APIs require a smart approach.</p>
<hr />
<h2>Key Concepts</h2>
<p>This tutorial needs to assume that you have some familiarity with testing concepts: fixtures, mocks, expectations. Testing is an important topic (especially in the Ruby community) and even if you are not a Rubyist,  I&#8217;d encourage you to dig deeper into the matter and to search for equivalent tools for your everyday language. You may want to read <a href="http://pragprog.com/book/achbd/the-rspec-book">&#8220;The RSpec book&#8221; by David Chelimsky et al.</a>, an excellent primer on Behavior Driven Development. </p>
<p>To summarize here, here are three key concepts you must know:</p>
<ul>
<li><strong>Mock</strong>: also called double, a mock is &#8220;an object that stands in for another object in an example&#8221;. This means that if we want to test the interaction between an object and another, we can mock the second one. In this tutorial, we will mock the Dribbble API, as to test our code we don&#8217;t need the API, itself, but something that behaves like it and exposes the same interface.</li>
<li><strong>Fixture</strong>: a dataset that recreates a specific state in the system. A fixture can be used to create the needed data to test a piece of logic.</li>
<li><strong>Expectation</strong>: a test example written the from the point of view of the result we want to achieve.</li>
</ul>
<hr />
<h2>Our Tools</h2>
<blockquote>
<p>&#8220;As a general practice, run tests every time you update them.&#8221;</p>
</blockquote>
<p><a href="https://github.com/bblimke/webmock">WebMock</a> is a Ruby mocking library that is used to mock (or stub) http requests. In other words, it allows you to simulate any HTTP request without actually making one. The primary advantage to this is being able to develop and test against any HTTP service without needing the service itself and without incurring in related issues (like API limits, IP restrictions and such).<br />
<a href="https://github.com/myronmarston/vcr">VCR</a> is a complementary tool that records any real http request and creates a fixture, a file that contains all the needed data to replicate that request without performing it again. We will configure it to use WebMock to do that. In other words, our tests will interact with the real Dribbble API just once: after that, WebMock will stub all the requests thanks to the data recorded by VCR. We will have a perfect replica of the Dribbble API responses recorded locally. In addition, WebMock will let us test edge cases (like the request timing out) easily and consistently. A wonderful consequence of our setup is that everything will be extremely fast.</p>
<p>
As for unit testing, we will be using <a href="https://github.com/seattlerb/minitest">Minitest</a>. It&#8217;s a fast and simple unit testing library that also supports expectations in the RSpec fashion. It offers a  smaller feature set, but I find that this actually encourages and pushes you to separate your logic into small, testable methods. Minitest is part of Ruby 1.9, so if you&#8217;re using it (I hope so) you don&#8217;t need to install it. On Ruby 1.8, it&#8217;s only a matter of <code>gem install minitest</code>.</p>
<p>
I will be using Ruby 1.9.3: if you don&#8217;t, you will probably encounter some issues related to <code>require_relative</code>, but I&#8217;ve included fallback code in a comment right below it. As a general practice, you should run tests every time you update them, even if I won&#8217;t be mentioning this step explicitly throughout the tutorial.</p>
<hr />
<h2>Setup</h2>
<div>
  <img src="http://d2o0t5hpnwv4c1.cloudfront.net/1129_api_wrapper_tdd/images/01_setup.jpg" alt="Setup">
</div>
<p>We will use the conventional <code>/lib</code> and <code>/spec</code> folder structure to organize our code. As for the name of our library, we&#8217;ll call it <b>Dish</b>, following the Dribbble convention of using basketball related terms.</p>
<p>The Gemfile will contain all our dependencies, albeit they&#8217;re quite small.</p>
<pre>
source :rubygems

gem 'httparty'

group :test do
  gem 'webmock'
  gem 'vcr'
  gem 'turn'
  gem 'rake'
end
</pre>
<p><a href="https://github.com/jnunemaker/httparty">Httparty</a> is an easy to use gem to handle HTTP requests; it will be the core of our library. In the test group, we will also add <a href="https://github.com/TwP/turn">Turn</a> to change the output of our tests to be more descriptive and to support color.</p>
<p>The <code>/lib</code> and <code>/spec</code> folders have a symmetrical structure: for every file contained in the <code>/lib/dish</code> folder, there should be a file inside <code>/spec/dish</code> with the same name and the &#8216;_spec&#8217; suffix.</p>
<p>
Let&#8217;s start by creating a <code>/lib/dish.rb</code> file and add the following code:</p>
<pre>
require &quot;httparty&quot;
Dir[File.dirname(__FILE__) + '/dish/*.rb'].each do |file|
  require file
end
</pre>
<p>It doesn&#8217;t do much: it requires &#8216;httparty&#8217; and then iterates over every <code>.rb</code> file inside <code>/lib/dish</code> to require it. With this file in place, we will be able to add any functionality inside separate files in <code>/lib/dish</code> and have it automatically loaded just by requiring this single file.</p>
<p>Let&#8217;s move to the <code>/spec</code> folder. Here&#8217;s the content of the <code>spec_helper.rb</code> file.</p>
<pre>
#we need the actual library file
require_relative '../lib/dish'
# For Ruby &lt; 1.9.3, use this instead of require_relative
# require(File.expand_path('../../lib/dish', __FILE__))

#dependencies
require 'minitest/autorun'
require 'webmock/minitest'
require 'vcr'
require 'turn'

Turn.config do |c|
 # <img src='http://terrytoledo.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> utline  - turn's original case/test outline mode [default]
 c.format  = <img src='http://terrytoledo.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> utline
 # turn on invoke/execute tracing, enable full backtrace
 c.trace   = true
 # use humanized test names (works only with <img src='http://terrytoledo.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> utline format)
 c.natural = true
end

#VCR config
VCR.config do |c|
  c.cassette_library_dir = 'spec/fixtures/dish_cassettes'
  c.stub_with :webmock
end
</pre>
<p>There&#8217;s quite a few things here worth noting, so let&#8217;s break it piece by piece:</p>
<ul>
<li>At first, we require the main lib file for our app, making the code we want to test available to the test suite. The <code>require_relative</code> statement is a Ruby 1.9.3 addition.
<li>We then require all the library dependencies: <code>minitest/autorun</code> includes all the expectations we will be using, <code>webmock/minitest</code> adds the needed bindings between the two libraries, while <code>vcr</code> and <code>turn</code> are pretty self-explanatory.
<li> The Turn config block merely needs to tweak our test output. We will use the outline format, where we can see the description of our specs.
<li>The VCR config blocks tells VCR to store the requests into a fixture folder (note the relative path) and to use WebMock as a stubbing library (VCR supports some other ones).</p>
</ul>
<p>Last, but not least, the <code>Rakefile</code> that contains some support code:</p>
<pre>
require 'rake/testtask'

Rake::TestTask.new do |t|
  t.test_files = FileList['spec/lib/dish/*_spec.rb']
  t.verbose = true
end

task :default =&gt; test
</pre>
<p>The <code>rake/testtask</code> library includes a <code>TestTask</code> class that is useful to set the location of our test files. From now on, to run our specs, we will only type <code>rake</code> from the library root directory.</p>
<p>As a way to test our configuration, let&#8217;s add the following code to <code>/lib/dish/player.rb</code>:</p>
<pre>
module Dish
  class Player
  end
end
</pre>
<p>Then <code>/spec/lib/dish/player_spec.rb</code>:</p>
<pre>
require_relative '../../spec_helper'
# For Ruby &lt; 1.9.3, use this instead of require_relative
# require (File.expand_path('./../../../spec_helper', __FILE__))

describe Dish::Player do

  it &quot;must work&quot; do
    &quot;Yay!&quot;.must_be_instance_of String
  end

end
</pre>
<p>Running <code>rake</code> should give you one test passing and no errors. This test is by no means useful for our project, yet it implicitly verifies that our library file structure is in place (the <code>describe</code> block would throw an error if the <code>Dish::Player</code> module was not loaded).</p>
<hr />
<h2>First Specs</h2>
<p>To work properly, Dish requires the Httparty modules and the correct <code>base_uri</code>, i.e. the base url of the Dribbble API. Let&#8217;s write the relevant tests for these requirements in <code>player_spec.rb</code>:</p>
<pre>
...
describe Dish::Player do

  describe &quot;default attributes&quot; do

    it &quot;must include httparty methods&quot; do
      Dish::Player.must_include HTTParty
    end

    it &quot;must have the base url set to the Dribble API endpoint&quot; do
      Dish::Player.base_uri.must_equal 'http://api.dribbble.com'
    end

  end

end
</pre>
<p>As you can see, Minitest expectations are self-explanatory, especially if you are an RSpec user: the biggest difference is wording, where Minitest prefers &#8220;must/wont&#8221; to &#8220;should/should_not&#8221;.</p>
<p>Running these tests will show one error and one failure. To have them pass, let&#8217;s add our first lines of implementation code to <code>player.rb</code>:</p>
<pre>
module Dish

  class Player

    include HTTParty

    base_uri 'http://api.dribbble.com'

  end

end
</pre>
<p>Running <code>rake</code> again should show the two specs passing. Now our <code>Player</code> class has access to all Httparty class methods, like <code>get</code> or <code>post</code>.</p>
<hr />
<h2>Recording our First Request</h2>
<p>As we will be working on the <code>Player</code> class, we will need to have API data for a player. The Dribbble API documentation page shows that the endpoint to get data about a specific player is <code>http://api.dribbble.com/players/:id</code></p>
<p>As in typical Rails fashion, <code>:id</code> is either the <em>id</em> or the <em>username</em> of a specific player. We will be using <code>simplebits</code>, the username of Dan Cederholm, one of the Dribbble founders.</p>
<p>To record the request with VCR, let&#8217;s update our <code>player_spec.rb</code> file by adding the following <code>describe</code> block to the spec, right after the first one:</p>
<pre>
  ...

  describe &quot;GET profile&quot; do

  before do
    VCR.insert_cassette 'player', :record =&gt; :new_episodes
  end

  after do
    VCR.eject_cassette
  end

  it &quot;records the fixture&quot; do
    Dish::Player.get('/players/simplebits')
  end

  end

end
</pre>
<blockquote>
<p>After running <code>rake</code>, you can verify that the fixture has been created. From now on, all our tests will be completely network independent.</p>
</blockquote>
<p>The <code>before</code> block is used to execute a specific portion of code before every expectation: we use it to add the VCR macro used to record a fixture that we will call &#8216;player&#8217;. This will create a <code>player.yml</code> file under <code>spec/fixtures/dish_cassettes</code>. The <code>:record</code> option is set to record all new requests once and replay them on every subsequent, identical request. As a proof of concept, we can add a spec whose only aim is to record a fixture for simplebits&#8217;s profile. The <code>after</code> directive tells VCR to remove the cassette after the tests, making sure that everything is properly isolated. The <code>get</code> method on the <code>Player</code> class is made available, thanks to the inclusion of the <code>Httparty</code> module.</p>
<p>After running <code>rake</code>, you can verify that the fixture has been created. From now on, all our tests will be completely network independent.</p>
<hr />
<h2>Getting the Player Profile</h2>
<div><img src="http://d2o0t5hpnwv4c1.cloudfront.net/1129_api_wrapper_tdd/images/02_dribbble.jpg" alt="Dribbble"></div>
<p>Every Dribbble user has a profile that contains a pretty extensive amount of data. Let&#8217;s think about how we would like our library to be when actually used: this is a useful way to flesh out our DSL will work. Here&#8217;s what we want to achieve:</p>
<pre>
simplebits = Dish::Player.new('simplebits')
simplebits.profile
  =&gt; #returns a hash with all the data from the API
simplebits.username
  =&gt; 'simplebits'
simplebits.id
  =&gt; 1
simplebits.shots_count
  =&gt; 157
</pre>
<p>Simple and effective: we want to instantiate a Player by using its username and then get access to its data by calling methods on the instance that map to the attributes returned by the API. We need to be consistent with the API itself.</p>
<p>Let&#8217;s tackle one thing at a time and write some tests related to getting the player data from the API. We can modify our <code>"GET profile"</code> block to have:</p>
<pre>
describe &quot;GET profile&quot; do

  let(:player) { Dish::Player.new }

  before do
    VCR.insert_cassette 'player', :record =&gt; :new_episodes
  end

  after do
    VCR.eject_cassette
  end

  it &quot;must have a profile method&quot; do
    player.must_respond_to :profile
  end

  it &quot;must parse the api response from JSON to Hash&quot; do
    player.profile.must_be_instance_of Hash
  end

  it &quot;must perform the request and get the data&quot; do
    player.profile[&quot;username&quot;].must_equal 'simplebits'
  end

end
</pre>
<p>The <code>let</code> directive at the top creates a <code>Dish::Player</code> instance available in the expectations. Next, we want to make sure that our player has got a profile method whose value is a hash representing the data from the API. As a last step, we test a sample key (the username) to make sure that we actually perform the request.</p>
<p>
Note that we&#8217;re not yet handling how to set the username, as this is a further step. The minimal implementation required is the following:</p>
<pre>
...
class Player

  include HTTParty

  base_uri 'http://api.dribbble.com'

  def profile
    self.class.get '/players/simplebits'
  end

end
...
</pre>
<p>A very little amount of code: we&#8217;re just wrapping a get call in the <code>profile</code> method. We then pass the hardcoded path to retrieve simplebits&#8217;s data, data that we had already stored thanks to VCR.</p>
<p>All our tests should be passing.</p>
<hr />
<h2>Setting the Username</h2>
<p>Now that we have a working profile function, we can take care of the username. Here are the relevant specs:</p>
<pre>
describe &quot;default instance attributes&quot; do

  let(:player) { Dish::Player.new('simplebits') }

  it &quot;must have an id attribute&quot; do
    player.must_respond_to :username
  end

  it &quot;must have the right id&quot; do
    player.username.must_equal 'simplebits'
  end

end

describe &quot;GET profile&quot; do

  let(:player) { Dish::Player.new('simplebits') }

  before do
    VCR.insert_cassette 'base', :record =&gt; :new_episodes
  end

  after do
    VCR.eject_cassette
  end

  it &quot;must have a profile method&quot; do
    player.must_respond_to :profile
  end

  it &quot;must parse the api response from JSON to Hash&quot; do
    player.profile.must_be_instance_of Hash
  end

  it &quot;must get the right profile&quot; do
    player.profile[&quot;username&quot;].must_equal &quot;simplebits&quot;
  end

end
</pre>
<p>We&#8217;ve added a new describe block to check the username we&#8217;re going to add and simply amended the <code>player</code> initialization in the <code>GET profile</code> block to reflect the DSL we want to have. Running the specs now will reveal many errors, as our <code>Player</code> class doesn&#8217;t accept arguments when initialized (for now).</p>
<p>Implementation is very straightforward:</p>
<pre>
...
class Player

  attr_accessor :username

  include HTTParty

  base_uri 'http://api.dribbble.com'

  def initialize(username)
    self.username = username
  end

  def profile
    self.class.get &quot;/players/#{self.username}&quot;
  end

end
...
</pre>
<p>The initialize method gets a username that gets stored inside the class thanks to the <code>attr_accessor</code> method added above. We then change the profile method to interpolate the username attribute.</p>
<p>We should get all our tests passing once again.</p>
<hr />
<h2>Dynamic Attributes</h2>
<p>At a basic level, our lib is in pretty good shape. As profile is a Hash, we could stop here and already use it by passing the key of the attribute we want to get the value for. Our goal, however, is to create an easy to use DSL that has a method for each attribute.</p>
<p>Let&#8217;s think about what we need to achieve. Let&#8217;s assume we have a player instance and stub how it would work:</p>
<pre>
player.username
  =&gt; 'simplebits'
player.shots_count
  =&gt; 157
player.foo_attribute
  =&gt; NoMethodError
</pre>
<p>Let&#8217;s translate this into specs and add them to the <code>GET profile</code> block:</p>
<pre>
...
describe &quot;dynamic attributes&quot; do

  before do
    player.profile
  end

  it &quot;must return the attribute value if present in profile&quot; do
    player.id.must_equal 1
  end

  it &quot;must raise method missing if attribute is not present&quot; do
    lambda { player.foo_attribute }.must_raise NoMethodError
  end

end
...
</pre>
<p>We already have a spec for username, so we don&#8217;t need to add another one. Note a few things:</p>
<ul>
<li>we explicitly call <code>player.profile</code> in a before block, otherwise it will be nil when we try to get the attribute value.</li>
<li>to test that <code>foo_attribute</code> raises an exception, we need to wrap it in a lambda and check that it raises the expected error.</li>
<li>we test that <code>id</code> equals <code>1</code>, as we know that that is the expected value (this is a purely data-dependent test).</li>
</ul>
<p>Implementation-wise, we could define a series of methods to access the <code>profile</code> hash, yet this would create a lot of duplicated logic. Moreover, the would rely on the API result to always have the same keys.</p>
<blockquote>
<p>&#8220;We will rely on <code>method_missing</code> to handle this cases and &#8216;generate&#8217; all those methods on the fly.&#8221;</p>
</blockquote>
<p>Instead, we will rely on <code>method_missing</code> to handle this cases and &#8216;generate&#8217; all those methods on the fly. But what does this mean? Without going into too much metaprogramming, we can simply say that every time we call a method not present on the object, Ruby raises a <code>NoMethodError</code> by using <code>method_missing</code>. By redefining this very method inside a class, we can modify its behaviour.</p>
<p>In our case, we will intercept the <code>method_missing</code> call, verify that the method name that has been called is a key in the profile hash and in case of positive result, return the hash value for that key. If not, we will call <code>super</code> to raise a standard <code>NoMethodError</code>: this is needed to make sure that our library behaves exactly the way any other library would do. In other words, we want to guarantee the least possible surprise.</p>
<p>Let&#8217;s add the following code to the Player class:</p>
<pre>
def method_missing(name)
  if profile.has_key?(name.to_s)
    profile[name.to_s]
  else
    super
  end
end
</pre>
<p>The code does exactly what described above. If you now run the specs, you should have them all pass. I&#8217;d encorage you to add some more to the spec files for some other attribute, like <code>shots_count</code>.</p>
<p>This implementation, however, is not really idiomatic Ruby. It works, but it can be streamlined into a ternary operator, a condensed form of an if-else conditional. It can be rewritten as:</p>
<pre>
def method_missing(name, *args, &amp;block)
  profile.has_key?(name.to_s) ? profile[name.to_s] : super
end
</pre>
<p>It&#8217;s not just a matter of length, but also a matter of consistency and shared conventions between developers. Browsing source code of Ruby gems and libraries is a good way to get accustomed to these conventions.</p>
<hr />
<h2>Caching</h2>
<p>As a final step, we want to make sure that our library is efficient. It should not make any more requests than needed and possibly cache data internally. Once again, let&#8217;s think about how we could use it:</p>
<pre>
player.profile
  =&gt; performs the request and returns a Hash
player.profile
  =&gt; returns the same hash
player.profile(true)
  =&gt; forces the reload of the http request and then returns the hash (with data changes if necessary)
</pre>
<p>How can we test this? We can by using WebMock to enable and disable network connections to the API endpoint. Even if we&#8217;re using VCR fixtures, WebMock can simulate a network Timeout or a different response to the server. In our case, we can test caching by getting the profile once and then disabling the network. By calling <code>player.profile</code> again we should see the same data, while by calling <code>player.profile(true)</code> we should get a <code>Timeout::Error</code>, as the library would try to connect to the (disabled) API endpoint.</p>
<p>Let&#8217;s add another block to the <code>player_spec.rb</code> file, right after <code>dynamic attribute generation</code>:</p>
<pre>
describe &quot;caching&quot; do

  # we use Webmock to disable the network connection after
  # fetching the profile
  before do
    player.profile
    stub_request(:any, /api.dribbble.com/).to_timeout
  end

  it &quot;must cache the profile&quot; do
    player.profile.must_be_instance_of Hash
  end

  it &quot;must refresh the profile if forced&quot; do
    lambda { player.profile(true) }.must_raise Timeout::Error
  end

end
</pre>
<p>The <code>stub_request</code> method intercepts all calls to the API endpoint and simulates a timeout, raising the expected <code>Timeout::Error</code>. As we did before, we test the presence of this error in a lambda.</p>
<p>Implementation can be tricky, so we&#8217;ll split it into two steps. Firstly, let&#8217;s move the actual http request to a private method:</p>
<pre>
...
def profile
  get_profile
end

...

private

def get_profile
  self.class.get(&quot;/players/#{self.username}&quot;)
end
...
</pre>
<p>This will not get our specs passing, as we&#8217;re not caching the result of <code>get_profile</code>. To do that, let&#8217;s change the <code>profile</code> method:</p>
<pre>
...
def profile
  @profile ||= get_profile
end
...
</pre>
<p>We will store the result hash into an instance variable. Also note the <code>||=</code> operator, whose presence makes sure that <code>get_profile</code> is run only if @profile returns a falsy value (like <code>nil</code>).</p>
<p>Next we can add the forced reload directive:</p>
<pre>
...
def profile(force = false)
  force ? @profile = get_profile : @profile ||= get_profile
end
...
</pre>
<p>We&#8217;re using a ternary again: if <code>force</code> is false, we perform <code>get_profile</code> and cache it, if not, we use the logic written in the previous version of this method (i.e. performing the request only if we don&#8217;t have already an hash).</p>
<p>Our specs should be green now and this is also the end of our tutorial.</p>
<hr />
<h2>Wrapping Up</h2>
<p>Our purpose in this tutorial was writing a small and efficient library to interact with the Dribbble API; we&#8217;ve laid the foundation for this to happen. Most of the logic we&#8217;ve written can be abstracted and requesed to access all the other endpoints. Minitest, WebMock and VCR have proven to be valuable tools to help us shape our code.</p>
<p>
We do, however, need to be aware of a small caveat: VCR can become a double-edged sword, as our tests can become too much data-dependent. If, for any reason, the API we&#8217;re building against changes without any visible sign (like a version number), we may risk having our tests perfectly working with a dataset, which is no longer relevant. In that case, removing and recreating the fixture is the best way to make sure that our code still works as expected.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/LER8jqe63jWFyvChbz31gykQOd8/0/da"><img src="http://feedads.g.doubleclick.net/~a/LER8jqe63jWFyvChbz31gykQOd8/0/di" border="0"></img></a><br />
<a href="http://feedads.g.doubleclick.net/~a/LER8jqe63jWFyvChbz31gykQOd8/1/da"><img src="http://feedads.g.doubleclick.net/~a/LER8jqe63jWFyvChbz31gykQOd8/1/di" border="0"></img></a></p>
<div>
<a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=UkklRP6FQRY:yOuKNfaF-Xw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=UkklRP6FQRY:yOuKNfaF-Xw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=UkklRP6FQRY:yOuKNfaF-Xw:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=UkklRP6FQRY:yOuKNfaF-Xw:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/UkklRP6FQRY" height="1" width="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://terrytoledo.com/2012/01/writing-an-api-wrapper-in-ruby-with-tdd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>24 Extremely Useful Ruby Gems for Web Development</title>
		<link>http://terrytoledo.com/2012/01/24-extremely-useful-ruby-gems-for-web-development/</link>
		<comments>http://terrytoledo.com/2012/01/24-extremely-useful-ruby-gems-for-web-development/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 05:00:07 +0000</pubDate>
		<dc:creator>Nettuts</dc:creator>
				<category><![CDATA[Nettuts]]></category>

		<guid isPermaLink="false">http://terrytoledo.com/2012/01/24-extremely-useful-ruby-gems-for-web-development/</guid>
		<description><![CDATA[One of the nicer things about developing on the Ruby platform is the sheer amount of meticulously categorized, highly reusable code wrapped up in the form of aptly named &#8216;gems&#8217;. I&#8217;m sure you&#8217;ve heard of popular frameworks like Sinatra or the super popular Rails that ship as gems but you&#8217;re missing an entire spectrum of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23863&amp;c=2136191273" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23863&amp;c=2136191273" border="0" alt="" /></a>
<p>One of the nicer things about developing on the Ruby platform is the sheer amount of meticulously categorized, highly reusable code wrapped up in the form of aptly named &#8216;gems&#8217;. </p>
<p>I&#8217;m sure you&#8217;ve heard of popular frameworks like Sinatra or the super popular Rails that ship as gems but you&#8217;re missing an entire spectrum of others that handle issues at a much lower level. Start using these and watch your productivity shoot through the roof!</p>
<p><span></span></p>
<hr />
<h2>A Quick Note</h2>
<p>I&#8217;m well aware that some of the gems listed here have Rails, or parts of Rails, as a dependency. That doesn&#8217;t mean that they are any less useful or need to be sneered at. </p>
<hr />
<h2>CarrierWave</h2>
<blockquote><p>Upload files in your Ruby applications, map them to a range of ORMs, store them on different backends. It works well with Rack based web applications, such as Ruby on Rails.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/jnicklas/carrierwave">Github repo</a></li>
<li><a href="http://www.engineyard.com/blog/2011/a-gentle-introduction-to-carrierwave/">A Gentle Introduction to CarrierWave</a></li>
</ul>
<p>&lt;hr /</p>
<h2>Kaminari</h2>
<blockquote><p>Kaminari is a Scope &#038; Engine based, clean, powerful, customizable and sophisticated paginator. Kaminari supports multiple ORMs (ActiveRecord, Mongoid, MongoMapper) multiple web frameworks (Rails, Sinatra), and multiple template engines (ERB, Haml).</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/amatsuda/kaminari">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/254-pagination-with-kaminari">Railscasts #254 Pagination with Kaminari</a></li>
</ul>
<hr />
<h2>HAML</h2>
<blockquote><p>Haml (HTML Abstraction Markup Language) is a layer on top of XHTML or XML that&#8217;s designed to express the structure of XHTML or XML documents in a non-repetitive, elegant, easy way, using indentation rather than closing tags and allowing Ruby to be embedded with ease. It was originally envisioned as a plugin for Ruby on Rails, but it can function as a stand-alone templating engine.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="http://haml-lang.com/">HAML website</a></li>
<li><a href="http://net.tutsplus.com/tutorials/ruby/an-introduction-to-haml-and-sinatra/">An Introduction to Haml and Sinatra </a></li>
<li><a href="http://rubysource.com/an-introduction-to-haml/">An Introduction to Haml </a></li>
</ul>
<hr />
<h2>Authlogic</h2>
<blockquote><p>A simple, unobtrusive model based Ruby authentication solution. Authlogic is very flexible, it has a strong public API and a plethora of hooks to allow you to modify behavior and extend it.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/binarylogic/authlogic">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/160-authlogic">Railscasts #160 Authlogic</a></li>
</ul>
<hr />
<h2>Shoulda</h2>
<blockquote><p>Shoulda is a gem that allows you to create more understandable tests for your Ruby application. Shoulda allows you to provide context to your tests enabling you to categorize tests according to a specific feature or scenario you&#8217;re testing.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/thoughtbot/shoulda">Github repo</a></li>
<li><a href="http://railstips.org/blog/archives/2009/02/21/shoulda-looked-at-it-sooner/">Shoulda Looked At It Sooner</a></li>
</ul>
<hr />
<h2>factory_girl</h2>
<blockquote><p>factory_girl provides a framework and DSL for defining and using factories &#8211; less error-prone, more explicit, and all-around easier to work with than fixtures. It has straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/thoughtbot/factory_girl">Github repo</a></li>
<li><a href="http://www.agileweboperations.com/real-world-example-using-factory_girl-to-simplify-our-test-setup">Using factory_girl to simplify our test setup</a></li>
</ul>
<hr />
<h2>RMagick</h2>
<blockquote><p>RMagick is an interface between the Ruby programming language and the ImageMagick and GraphicsMagick image processing libraries.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/rmagick/rmagick">Github repo</a></li>
<li><a href="http://www.imagemagick.org/RMagick/doc/rvgtut.html">Drawing with RVG</a></li>
</ul>
<hr />
<h2>Cancan</h2>
<blockquote><p>CanCan is an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access and is decoupled from user roles. All permissions are stored in a single location and not duplicated across controllers, views, and database queries.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/ryanb/cancan">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/192-authorization-with-cancan">Railscasts #192 Authorization with CanCan</a></li>
</ul>
<hr />
<h2>Nokogiri</h2>
<blockquote><p>Nokogiri is an HTML, XML, SAX, and Reader parser. Among Nokogiri’s many features is the ability to search documents via XPath or CSS3 selectors. Nokogiri parses and searches XML/HTML very quickly, and also has correctly implemented CSS3 selector support as well as XPath support.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/tenderlove/nokogiri">Github repo</a></li>
<li><a href="http://www.engineyard.com/blog/2010/getting-started-with-nokogiri/">Getting Started with Nokogiri</a></li>
<li><a href="http://railscasts.com/episodes/190-screen-scraping-with-nokogiri">Railscasts #190 Screen Scraping with Nokogiri</a></li>
</ul>
<hr />
<h2>SASS</h2>
<blockquote><p>Sass makes CSS fun again. Sass is an extension of CSS3, adding nested rules, variables, mixins, selector inheritance, and more. It’s translated to well-formatted, standard CSS using the command line tool or a web-framework plugin.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/nex3/sass">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/268-sass-basics">Railscasts #268 Sass Basics</a></li>
</ul>
<hr />
<h2>Formtastic</h2>
<blockquote><p>Formtastic is a Rails FormBuilder DSL (with some other goodies) to make it far easier to create beautiful, semantically rich, syntactically awesome, readily stylable and wonderfully accessible HTML forms in your Rails applications.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/justinfrench/formtastic/">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/184-formtastic-part-1">Railscasts #184 Formtastic Part 1</a></li>
<li><a href="http://railscasts.com/episodes/185-formtastic-part-2">Railscasts #185 Formtastic Part 2</a></li>
</ul>
<hr />
<h2>Capistrano</h2>
<blockquote><p>Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH. It uses a simple DSL (borrowed in part from Rake) that allows you to define tasks, which may be applied to machines in certain roles. It also supports tunneling connections via some gateway machine to allow operations to be performed behind VPN&#8217;s and firewalls.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/capistrano/capistrano/">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/133-capistrano-tasks">Railscasts #133 Capistrano Tasks</a></li>
</ul>
<hr />
<h2>Omniauth</h2>
<blockquote><p>OmniAuth is a Ruby authentication framework that provides a standardized interface to many different authentication providers such as Facebook, OpenID, and even traditional username and password.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/intridea/omniauth">Github repo</a></li>
<li><a href="http://net.tutsplus.com/tutorials/ruby/how-to-use-omniauth-to-authenticate-your-users/">How to Use Omniauth to Authenticate your Users </a></li>
<li><a href="http://railscasts.com/episodes/241-simple-omniauth">Railscasts #241 Simple OmniAuth</a></li>
</ul>
<hr />
<h2>Bundler</h2>
<blockquote><p>Bundler is a tool that manages gem dependencies for your ruby application. It takes a gem manifest file and is able to fetch, download, and install the gems and all child dependencies specified in this manifest. It can manage any update to the gem manifest file and update the bundle&#8217;s gems accordingly. It also lets you run any ruby code in context of the bundle&#8217;s gem environment.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/carlhuda/bundler">Github repo</a></li>
<li><a href="http://yehudakatz.com/2009/11/03/using-the-new-gem-bundler-today/">Using the New Gem Bundler Today</a></li>
</ul>
<hr />
<h2>resque</h2>
<blockquote><p>Resque (pronounced like &#8220;rescue&#8221;) is a Redis-backed library for creating background jobs, placing those jobs on multiple queues, and processing them later. Resque is heavily inspired by DelayedJob.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/defunkt/resque">Github repo</a></li>
<li><a href="http://net.tutsplus.com/rubylearning.com/blog/2010/11/08/do-you-know-resque/">Do YOU know Resque?</a></li>
<li><a href="http://railscasts.com/episodes/271-resque">Railscasts #271 Resque</a></li>
</ul>
<hr />
<h2>Jammit</h2>
<blockquote><p>Jammit is an industrial strength asset packaging library for Rails, providing both the CSS and JavaScript concatenation and compression that you&#8217;d expect, as well as YUI Compressor and Closure Compiler compatibility, ahead-of-time gzipping, built-in JavaScript template support, and optional Data-URI / MHTML image embedding.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="http://documentcloud.github.com/jammit/">Github repo</a></li>
<li><a href="http://www.ruby-on-rails-outsourcing.com/articles/2011/07/21/using-jammit-in-rails/">Using Jammit in Rails</a></li>
</ul>
<hr />
<h2>capybara</h2>
<blockquote><p>Capybara helps you test Rails and Rack applications by simulating how a real user would interact with your app. It is agnostic about the driver running your tests and comes with Rack::Test and Selenium support built in. </p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/jnicklas/capybara">Github repo</a></li>
<li><a href="http://opinionatedprogrammer.com/2011/02/capybara-and-selenium-with-rspec-and-rails-3/">Capybara (and Selenium) with RSpec &#038; Rails 3</a></li>
</ul>
<hr />
<h2>Active Merchant</h2>
<blockquote><p>Active Merchant is an extraction from the e-commerce system Shopify. Shopify&#8217;s requirements for a simple and unified API to access dozens of different payment gateways with very different internal APIs was the chief principle in designing the library. It was developed for usage in Ruby on Rails web applications and integrates seamlessly as a plugin but it also works excellently as a stand alone library.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/Shopify/active_merchant">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/144-active-merchant-basics">Railscasts #144 Active Merchant Basics</a></li>
</ul>
<hr />
<h2>eventmachine</h2>
<blockquote><p>EventMachine implements a fast, single-threaded engine for arbitrary networkcommunications. It&#8217;s extremely easy to use in Ruby. EventMachine wraps all interactions with IP sockets, allowing programs to concentrate on the implementation of network protocols. It can be used to create both network servers and clients.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/eventmachine/eventmachine">Github repo</a></li>
<li><a href="http://rubylearning.com/blog/2010/10/01/an-introduction-to-eventmachine-and-how-to-avoid-callback-spaghetti/">An introduction to eventmachine, and how to avoid callback spaghetti</a></li>
</ul>
<hr />
<h2>mustache</h2>
<blockquote><p>Inspired by ctemplate, Mustache is a framework-agnostic way to renderlogic-free views.As ctemplates says, &#8220;It emphasizes separating logic from presentation:it is impossible to embed application logic in this templatelanguage.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/defunkt/mustache">Github repo</a></li>
</ul>
<hr />
<h2>Passenger</h2>
<blockquote><p>Phusion Passenger™ — a.k.a. mod_rails or mod_rack — makes deployment of Ruby web applications, such as those built on the revolutionary Ruby on Rails web framework, a breeze.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/FooBarWidget/passenger">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/122-passenger-in-development">Railscasts #122 Passenger in Development</a></li>
</ul>
<hr />
<h2>Chef</h2>
<blockquote><p>Chef is a system integration framework designed to bring the benefits of configuration management to your entire infrastructure. With Chef, you can manage your servers by writing code, not by running commands. </p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/opscode/chef">Github repo</a></li>
<li><a href="http://www.themomorohoax.com/2010/07/31/ruby-chef-tutorial">Getting started with Chef tutorial</a></li>
</ul>
<hr />
<h2>Thinking Sphinx</h2>
<blockquote><p>A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.</p>
</blockquote>
<p><strong>Related reading</strong></p>
<ul>
<li><a href="https://github.com/freelancing-god/thinking-sphinx">Github repo</a></li>
<li><a href="http://railscasts.com/episodes/120-thinking-sphinx-revised">Railscasts #120 Thinking Sphinx</a></li>
</ul>
<hr />
<h2>Wrapping Up</h2>
<p>So those were some of the awesome gems I&#8217;ve found extremely useful when I&#8217;m whipping up a web app in Ruby. I&#8217;m a 100% sure I&#8217;m missing a metric butt load of others though. Let me know about your favorite gems in the comments below and thank you so much for reading!</p>
<p><a href="http://feedads.g.doubleclick.net/~a/XYAplGGeRKQScEO8UN0xyy22P9M/0/da"><img src="http://feedads.g.doubleclick.net/~a/XYAplGGeRKQScEO8UN0xyy22P9M/0/di" border="0"></img></a><br />
<a href="http://feedads.g.doubleclick.net/~a/XYAplGGeRKQScEO8UN0xyy22P9M/1/da"><img src="http://feedads.g.doubleclick.net/~a/XYAplGGeRKQScEO8UN0xyy22P9M/1/di" border="0"></img></a></p>
<div>
<a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TQXIcZXrplk:FMeideHSUKQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TQXIcZXrplk:FMeideHSUKQ:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/TQXIcZXrplk" height="1" width="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://terrytoledo.com/2012/01/24-extremely-useful-ruby-gems-for-web-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Meet Crockford’s JSDev</title>
		<link>http://terrytoledo.com/2012/01/meet-crockford%e2%80%99s-jsdev/</link>
		<comments>http://terrytoledo.com/2012/01/meet-crockford%e2%80%99s-jsdev/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 05:00:31 +0000</pubDate>
		<dc:creator>Nettuts</dc:creator>
				<category><![CDATA[Nettuts]]></category>

		<guid isPermaLink="false">http://terrytoledo.com/2012/01/meet-crockford%e2%80%99s-jsdev/</guid>
		<description><![CDATA[Recently, Douglas Crockford released a neat tool that makes the process of developing and testing your JavaScript a bit easier. Interested in learning more? Watch today&#8217;s quick tip to find out! Watch the Screencast Show Link Douglas Crockford&#8217;s Google+ Post JSDev &#124; Github Labelled blocks, useful? Gist of test_code script I created in the screencast [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23852&amp;c=1331912403" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23852&amp;c=1331912403" border="0" alt="" /></a>
<p>Recently, Douglas Crockford <a href="https://plus.google.com/118095276221607585885/posts/CTZ7BNx7a8z">released a neat tool</a> that makes the process of developing and testing your JavaScript a bit easier. Interested in learning more? Watch today&#8217;s quick tip to find out!</p>
<p><span></span></p>
<hr />
<h2>Watch the Screencast</h2>
<div>
</div>
<hr />
<h2>Show Link</h2>
<ul>
<li><a href="https://plus.google.com/118095276221607585885/posts/CTZ7BNx7a8z">Douglas Crockford&#8217;s Google+ Post</a></li>
<li><a href="https://github.com/douglascrockford/JSDev">JSDev | Github</a></li>
<li><a href="http://james.padolsey.com/javascript/labelled-blocks-useful/">Labelled blocks, useful?</a></li>
<li><a href="https://gist.github.com/1592711">Gist of <code>test_code</code> script I created in the screencast</a></li>
</ul>
<hr />
<h2>Will you use JSDev?</h2>
<p>I&#8217;m curious; is this something that you&#8217;ll use in your daily coding? I&#8217;m still not sure, myself. Let us hear your thoughts in the comments!</p>
<p><a href="http://feedads.g.doubleclick.net/~a/AuLlI8DBMyZWkW2AEl2ID0gOYGE/0/da"><img src="http://feedads.g.doubleclick.net/~a/AuLlI8DBMyZWkW2AEl2ID0gOYGE/0/di" border="0"></img></a><br />
<a href="http://feedads.g.doubleclick.net/~a/AuLlI8DBMyZWkW2AEl2ID0gOYGE/1/da"><img src="http://feedads.g.doubleclick.net/~a/AuLlI8DBMyZWkW2AEl2ID0gOYGE/1/di" border="0"></img></a></p>
<div>
<a href="http://feeds.feedburner.com/~ff/nettuts?a=ZH540ucyI7o:REMkazE4P1M:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=ZH540ucyI7o:REMkazE4P1M:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=ZH540ucyI7o:REMkazE4P1M:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=ZH540ucyI7o:REMkazE4P1M:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=ZH540ucyI7o:REMkazE4P1M:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=ZH540ucyI7o:REMkazE4P1M:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=ZH540ucyI7o:REMkazE4P1M:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=ZH540ucyI7o:REMkazE4P1M:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/ZH540ucyI7o" height="1" width="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://terrytoledo.com/2012/01/meet-crockford%e2%80%99s-jsdev/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.htaccess Files for the Rest of Us</title>
		<link>http://terrytoledo.com/2012/01/htaccess-files-for-the-rest-of-us/</link>
		<comments>http://terrytoledo.com/2012/01/htaccess-files-for-the-rest-of-us/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 00:37:06 +0000</pubDate>
		<dc:creator>Nettuts</dc:creator>
				<category><![CDATA[Nettuts]]></category>

		<guid isPermaLink="false">http://terrytoledo.com/2012/01/htaccess-files-for-the-rest-of-us/</guid>
		<description><![CDATA[.htaccess files are used to configure Apache, as well a range of other web servers. Despite the .htaccess file type extension, they are simply text files that can be edited using any text-editor. In this article, we&#8217;ll review what they are, and how you can use them in your projects. Please note that .htaccess files [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23827&amp;c=2095469125" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23827&amp;c=2095469125" border="0" alt="" /></a>
<p>.htaccess files are used to configure Apache, as well a range of other web servers. Despite the <code>.htaccess</code> file type extension, they are simply text files that can be edited using any text-editor. In this article, we&#8217;ll review what they are, and how you can use them in your projects.</p>
<p><span></span></p>
<blockquote>
<p>
      Please note that .htaccess files don&#039;t work on Windows-based systems, although they can be edited and uploaded to a compatible web server, and on Linux-based systems they are hidden by default.
  </p>
</blockquote>
<p>In order to work with htaccess files locally, to see how they work and generally play around with them, we can use <a href="http://www.apachefriends.org/en/xampp.html">XAMPP</a> (or <a href="http://www.mamp.info/en/index.html">MAMP</a>) on the Mac &#8211; a package that installs and configures Apache, PHP and MySQL. To edit these .htaccess files on Mac, we should use a text editor that allows for the opening of hidden files, such as <a href="http://www.barebones.com/products/textwrangler/">TextWrangler</a>.</p>
<p>A .htaccess file follows the same format as Apache’s main configuration file: <code>httpd.conf</code>. Many of the settings that can be configured using the main configuration file can also be configured with them, and vice versa. </p>
<blockquote>
<p>
      A setting configured in an .htaccess file will override the same setting in the main configuration file for the directory which contains the file, as well as all of its subdirectories.
  </p>
</blockquote>
<p>They are sometimes referred to as dynamic configuration files because they are read by the server on every request to the directory they are contained within. This means that any changes to an .htaccess file will take effect immediately, without requiring a reboot of the server, unlike changes made to the global configuration file. It also means that you pay a slight performance hit for using them, but they can be useful when you don&#039;t have access to the server&#039;s main configuration file.</p>
<p>So now we all know what .htaccess files are, how they are edited and worked with, and some of their pros and cons, let&#039;s look at how they can be used and some of the cool stuff they can do.</p>
<hr />
<h2>Redirects and URL Rewriting</h2>
<p>A popular use of .htaccess files is to perform redirects or rewrite URLs. This can help with SEO following a domain name change, or file-structure reorganisation, or can make long unsightly URL more friendly and memorable.</p>
<h3> Redirections </h3>
<p>A redirection can be as simple as the following:</p>
<pre>Redirect 301 ^old\.html$ &lt;a href=&quot;http://localhost/new.html&quot; target=&quot;_blank&quot;&gt;http://localhost/new.html&lt;/a&gt; </pre>
<p>This sets the HTTP status code to 301 (moved permanently) and redirects all requests to <code>old.html</code> transparently to <code>new.html</code>. We use a regular expression to match the URL to redirect, which gives us a fine degree of control to ensure only the correct URL is matched for redirection, but adds complexity to the configuration and administration of it. The full URL of the resource being redirected to is required.</p>
<h3> Rewrites</h3>
<p>A rewrite rule can be as simple as this:</p>
<pre>RewriteEngine on
RewriteRule ^old\.html$ new.html</pre>
<p>In this example, we just provide a simple file redirect from one file to another, which will also be performed transparently, without changing what is displayed in the address bar. The first directive, <code>RewriteEngine on</code>, simply ensures that the rewrite engine is enabled.</p>
<p>In order to update what is displayed in the address bar of the visitor&#039;s browser, we can use the <code>R</code> flag at the end of the <code>RewriteRule</code> e.g.</p>
<pre>RewriteRule ^old\.html$ &lt;a href=&quot;http://hostname/new.html&quot; target=&quot;_blank&quot;&gt;http://hostname/new.html&lt;/a&gt; [r=301]</pre>
<p>The <code>r</code> flag causes an external redirection which is why the full URL (an example URL here) to the new page is given. We can also specify the status code when using the flag. This causes the address bar to be updated in the visitor&#039;s browser.</p>
<p>One of the possible uses for URL rewriting I gave at the start of this section was to make unsightly URLs (containing query-string data) friendlier to visitors and search engines. Let&#039;s see this in action now:</p>
<pre>RewriteRule ^products/([^/]+)/([^/]+)/([^/&lt;WBR&gt;]+) product.php?cat=$1&amp;brand=$2&amp;&lt;WBR&gt;prod=$3</pre>
<p>This rule will allow visitors to use a URL like <em>products/turntables/technics/sl1210</em>, and have it transformed into <em>product.php?cat=turntables&amp;&lt;WBR&gt;brand=technics&#038;prod=sl1210.</em> The parentheses in between the forward slashes in the above regular expression are capturing groups – we can use each of these as <code>$1</code>, <code>$2</code> and <code>$3</code> respectively. The <code>[^/]+</code> character class within the parentheses means match any character except a forward-slash 1 or more times.</p>
<p>In practice, URL rewriting can be (and usually is) much more complex and achieve far greater things than this. URL rewriting is better explained using entire tutorials so we won&#039;t look at them in any further detail here.</p>
<hr />
<h2>Serving Custom Error Pages</h2>
<p>It&#039;s just not cool to show the default 404 page anymore. Many sites take the opportunity offered by a file not found error to inject a little humour into their site, but at the very least, people expect the 404 page of a site to at least match the style and theme of any other page of the site.</p>
<p>Very closely related to URL rewriting, serving a custom error page instead of the standard 404 page is easy with an .htaccess file: </p>
<pre>ErrorDocument 404 &quot;;/404.html&quot;;</pre>
<p>That&#039;s all we need; whenever a 404 error occurs, the specified page is displayed. We can configure pages to be displayed for many other server errors too.</p>
<hr />
<h2>Restricting Access to Specific Resources</h2>
<p>Using .htaccess files, we can enable password protection of any file or directory, to all users, or based on things like domain or IP address. This is after all one of their core uses. To prevent access to an entire directory, we would simple create a new .htaccess file, containing the following code:</p>
<pre>AuthName &quot;;Username and password required&quot;;
AuthUserFile /path/to/.htpasswd
Require valid-user
AuthType Basic</pre>
<p>This file should then be saved into the directory we wish to protect. The <code>AuthName</code> directive specifies the message to display in the username/password dialog box, the <code>AuthUserFile</code> should be the path to the .htpasswd file. The <code>Require</code> directive specifies that only authenticated users may access the protected file while the <code>AuthType</code> is set to <code>Basic</code>.</p>
<p>To protect a specific file, we can wrap the above code in a <code>&lt;files&gt;</code> directive, which specifies the protected file: </p>
<pre>Files &quot;;protectedfile.html&quot;;&gt;
AuthName &quot;;Username and password required&quot;;
AuthUserFile /path/to/.htpasswd
Require valid-user
AuthType Basic
&lt;/Files&gt;</pre>
<p>We also require an .htpasswd file for these types of authentication, which contains a colon-separated list of usernames and encrypted passwords required to access the protected resource(s). This file should be saved in a directory that is not accessible to the web. There are a range of services that can be used to generate these files automatically as the password should be stored in encrypted form.</p>
<hr />
<h2>Block Access to Certain Entities</h2>
<p>Another use of .htaccess files is to quickly and easily block all requests from an IP address or user-agent. To block a specific IP address, simply add the following directives to your .htaccess file: </p>
<pre>order allow,deny
deny from 192.168.0.1
allow from all</pre>
<p>The <code>order</code> directive tells Apache in which order to evaluate the allow/deny directives. In this case, <code>allow</code> is evaluated first, then <code>deny</code>. The <code>allow from all</code> directive is evaluated first (even though it appears after the <code>deny</code> directive) and all IPs are allowed, then if the client&#039;s IP matches the one specified in the <code>deny</code> directive, access is forbidden. This lets everyone in except the specified IP. Note that we can also deny access to entire IP blocks by supplying a shorter IP, e.g. <em>192.168</em>.</p>
<p>To deny requests based on user-agent, we could do this:</p>
<pre>RewriteCond %{HTTP_USER_AGENT} ^OrangeSpider
RewriteRule ^(.*)$ http://%{REMOTE_ADDR}/$ [r=301,l]</pre>
<p>In this example, any client with a <code>HTTP_USER_AGENT</code> string starting with <code>OrangeSpider</code> (a bad bot) is redirected back to the address that it originated from. The regular expression matches any single character <code>(.)</code> zero or more times <code>(*)</code> and redirects to the <code>%{REMOTE_ADDR}</code> environment variable. The <code>l</code> flag we used here instructs Apache to treat this match as the last rule so will not process any others before performing the rewrite.</p>
<hr />
<h2>Force an IE Rendering Mode</h2>
<p>Alongside controlling how the server responds to certain requests, we can also do things to the visitor&#039;s browser, such as forcing IE to render pages using a specific rendering engine. For example, we can use the <code>mod_headers</code> module, if it is present, to set the <code>X-UA-Compatible</code> header:</p>
<pre>Header set X-UA-Compatible &quot;;IE=Edge&quot;;</pre>
<p>Adding this line to an .htaccess file will instruct IE to use the highest rendering mode available. As demonstrated by <a href="http://html5boilerplate.com">HTML5 Boilerplate</a>, we can also avoid setting this header on files that don&#039;t require it by using a <code>&lt;FilesMatch</code> directive like so:</p>
<pre>&lt;FilesMatch &quot;;\.(js|css|gif|png|jpe?g|pdf|&lt;WBR&gt;xml|oga|ogg|m4a|ogv|mp4|m4v|&lt;WBR&gt;webm|svg|svgz|eot|ttf|otf|&lt;WBR&gt;woff|ico|webp|appcache|&lt;WBR&gt;manifest|htc|crx|xpi|&lt;WBR&gt;safariextz|vcf)$&quot;;&gt;;
  Header unset X-UA-Compatible
&lt;/FilesMatch&gt;</pre>
<hr />
<h2>Implement Caching</h2>
<blockquote>
<p>
Caching is easy to set up and can make your site load faster.
</p>
</blockquote>
<p>Caching is easy to set up and can make your site load faster. &#039;Nuff said! By setting a far-future expires date on elements of sites that don&#039;t change very often, we can prevent the browser from requesting unchanged resources on every request.</p>
<p>If you&#039;re running your site through Google PageSpeed or Yahoo&#039;s YSlow and you get the message about setting far-future expiry headers, this is how you fix it:</p>
<pre>ExpiresActive on
ExpiresByType image/gif                 &quot;;access plus 1 month&quot;;
ExpiresByType image/png                 &quot;;access plus 1 month&quot;;
ExpiresByType image/jpg                 &quot;;access plus 1 month&quot;;
ExpiresByType image/jpeg                &quot;;access plus 1 month&quot;;
ExpiresByType video/ogg                 &quot;;access plus 1 month&quot;;
ExpiresByType audio/ogg                 &quot;;access plus 1 month&quot;;
ExpiresByType video/mp4                 &quot;;access plus 1 month&quot;;
ExpiresByType video/webm                &quot;;access plus 1 month&quot;;</pre>
<p>You can add different <code>ExpiresByType</code> directives for any content that is listed in the performance tool you&#039;re using, or anything else that you want to control caching on. The first directive, <code>ExpiresActive on</code>, simply ensures the generation of Expires headers is switched on. These directives depend on Apache having the <em>mod_expires</em> module loaded.</p>
<hr />
<h2>Enabling Compression</h2>
<p>Another warning we may get in a performance checker refers to enabling compression, and this is also something we can fix simply by updating our .htaccess file: </p>
<pre>FilterDeclare   COMPRESS
FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/html
FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/css
FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/javascript
FilterChain     COMPRESS
FilterProtocol  COMPRESS  DEFLATE change=yes;byteranges=no</pre>
<p>This compression scheme works on newer versions of Apache (2.1+) using the <em>mod_filter</em> module. It uses the <code>DEFLATE</code> compression algorithm to compress content based on its response content-type, in this case we specify <code>text/html</code>, <code>text/css</code> and <code>text/javascript</code> (which will likely be the types of files flagged in PageSpeed/Yslow anyhow).</p>
<p>In the above example we start out by declaring the filter we wish to use, in this case <code>COMPRESS</code>, using the <code>FilterDeclare</code> directive. We then list the content types we wish to use this filter. The <code>FilterChain</code> directive then instructs the server to build a filter chain based on the <code>FilterProvider</code> directives we have listed. The <code>FilterProtocol</code> directive allows us to specify options that are applied to the filter chain whenever it is run, the options we need to use are <code>change=yes</code> (the content may be changed by the filter (in this case, compressed)) and <code>byteranges=no</code> (the filter must only be applied to complete files).</p>
<p>On older versions of Apache, the <em>mod_deflate</em> module is used to configure DEFLATE compression. We have less control of how the content is filtered in this case, but the directives are simpler:</p>
<pre>SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/html text/css text/javascript</pre>
<p>In this case we just set the compression algorithm using the <code>SetOutputFilter</code> directive, and then specify the content-types we&#039;d like to compress using the <code>AddOutputFilterByType</code> directive.</p>
<p>Usually your web server will use one of these modules depending on which version of Apache is in use. Generally, you will know this beforehand, but if you are creating a generic .htaccess file that you can use on a variety of sites, or which you may share with other people and therefore you don&#039;t know which modules may be in use, you may wish to use both of the above blocks of code wrapped in <code>&lt;IfModule module_name&gt;</code> directives so that the correct module is used and the server doesn&#039;t throw a 500 error if we try to configure a module that isn&#039;t included. You should be aware that it&#039;s also relatively common for hosts that run a large number of sites from a single box to disable compression as there is a small CPU performance hit for compressing on the server.</p>
<hr />
<h2>Summary</h2>
<p>We looked at some of the most common uses for .htaccess files, and reviewed how we can achieve certain tasks that, as website builders/maintainers, are of particular interest to us. As is the case with any introductory tutorial of this nature, the subjects we&#039;ve covered are presented as introductions to a particular topic. There are many other options and configurations than we have been able to look at, so I&#039;d strongly recommend further reading on any subject that is of particular interest.</p>
</p>
<p><a href="http://feedads.g.doubleclick.net/~a/ldznx8jOs0gC5jKM-wm9nnvJ0iU/0/da"><img src="http://feedads.g.doubleclick.net/~a/ldznx8jOs0gC5jKM-wm9nnvJ0iU/0/di" border="0"></img></a><br />
<a href="http://feedads.g.doubleclick.net/~a/ldznx8jOs0gC5jKM-wm9nnvJ0iU/1/da"><img src="http://feedads.g.doubleclick.net/~a/ldznx8jOs0gC5jKM-wm9nnvJ0iU/1/di" border="0"></img></a></p>
<div>
<a href="http://feeds.feedburner.com/~ff/nettuts?a=0tRWn4s8wo4:xVL2Ue3MeIM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=0tRWn4s8wo4:xVL2Ue3MeIM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=0tRWn4s8wo4:xVL2Ue3MeIM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=0tRWn4s8wo4:xVL2Ue3MeIM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=0tRWn4s8wo4:xVL2Ue3MeIM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=0tRWn4s8wo4:xVL2Ue3MeIM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=0tRWn4s8wo4:xVL2Ue3MeIM:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=0tRWn4s8wo4:xVL2Ue3MeIM:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/0tRWn4s8wo4" height="1" width="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://terrytoledo.com/2012/01/htaccess-files-for-the-rest-of-us/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing your PHP Codebase with EnhancePHP</title>
		<link>http://terrytoledo.com/2012/01/testing-your-php-codebase-with-enhancephp/</link>
		<comments>http://terrytoledo.com/2012/01/testing-your-php-codebase-with-enhancephp/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 05:00:21 +0000</pubDate>
		<dc:creator>Nettuts</dc:creator>
				<category><![CDATA[Nettuts]]></category>

		<guid isPermaLink="false">http://terrytoledo.com/2012/01/testing-your-php-codebase-with-enhancephp/</guid>
		<description><![CDATA[You know it; I know it. We should be testing our code more than we do. Part of the reason we don&#8217;t, I think, is that we don&#8217;t know exactly how. Well, I&#8217;m getting rid of that excuse today: I&#8217;m teaching you to test your PHP with the EnhancePHP framework. Meet EnhancePHP I&#8217;m not going [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23752&amp;c=30014281" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23752&amp;c=30014281" border="0" alt="" /></a>
<p>You know it; I know it. We should be testing our code more than we do. Part of the reason we don&#8217;t, I think, is that we don&#8217;t know exactly how. Well, I&#8217;m getting rid of that excuse today: I&#8217;m teaching you to test your PHP with the <a href="http://www.enhance-php.com">EnhancePHP</a> framework.</p>
<p><span></span></p>
<hr />
<h2>Meet EnhancePHP</h2>
<p>I&#8217;m not going to try to convince you to test your code; and we&#8217;re not going to discuss Test Driven Development, either. That&#8217;s been <a href="http://net.tutsplus.com/tutorials/php/the-newbies-guide-to-test-driven-development/">done before on Nettuts+</a>. In that article, Nikko Bautista explains exactly why testing is a good thing and outlines a TDD workflow. Read that sometime, if you aren&#8217;t familiar with TDD. He also uses the SimpleTest library for his examples, so if you don&#8217;t like the look of EnhancePHP, you might try SimpleTest as an alternative.</p>
<blockquote><p>As I said, we&#8217;ll be using the <a href="http://www.enhance-php.com">EnhancePHP</a>. It&#8217;s a great little PHP library&#8212;a single file&#8212;that offers a lot of testing functionality.</p>
</blockquote>
<p>Start by heading over to their <a href="http://www.enhance-php.com/Content/Download/">download page</a> and grabbing the latest version of the framework.</p>
<p>We&#8217;re going to be building a really simple Validation class to test. It won&#8217;t do too much: just return <code>true</code> if the item passes validation, or <code>false</code> if it doesn&#8217;t. So, set up a really simple little project:</p>
<div><img alt="" src="http://d2o0t5hpnwv4c1.cloudfront.net/1125_enhancephp/project.png" /></div>
<p>We&#8217;ll do this is a semi-TDD fashion, so let&#8217;s start by writing a few tests.</p>
<hr />
<h2>Writing Tests</h2>
<p>Out little  class is going to validate three things: email addresses, usernames, and phone numbers.</p>
<p>But before we get to writing actual tests, we&#8217;ll need to set up our class:</p>
<pre>
&lt;?php

class Validation_test extends \Enhance\TestFixture {
	public function setUp () {
		$this-&gt; val = new Validation();
	}

}
</pre>
<p>This is our start; notice that we&#8217;re extending the class <code>\Enhance\TestFixture</code>. By doing so, we let EnhancePHP know that any public methods of this class are tests, with the exception of methods <code>setUp</code> and <code>tearDown</code>. As you might guess, these methods run before and after all your tests (not before and after each one). In this case, our <code>setUp</code> method will create a new <code>Validation</code> instance and assign it to a property on our instance.</p>
<p>By the way, if you&#8217;re relatively new to PHP, you might not be familiar with that <code>\Enhance\TestFixture</code> syntax: what&#8217;s with the slashes? That&#8217;s PHP namespacing for you; <a href="http://www.php.net/manual/en/language.namespaces.php">check out the docs if you aren&#8217;t familiar with it</a>.</p>
<p>So, the tests!</p>
<h3>Email Addresses</h3>
<p>Let&#8217;s start by validating email addresses. As you&#8217;ll see, just doing a basic test is pretty simple:</p>
<pre>
public function validates_a_good_email_address () {
	$result = $this-&gt;val-&gt;validate_email(&quot;john@doe.com&quot;);
	\Enhance\Assert::isTrue($result);
}
</pre>
<p>We simply call the method we want to test, passing it a valid email address, and storing the <code>$result</code>. Then, we hand  <code>$result</code> to the <code>isTrue</code> method. That method belongs to the <code>\Enhance\Assert</code> class.</p>
<p>We want to make sure our class will reject non-email addresses. So, let&#8217;s test for that:</p>
<pre>
public function reject_bad_email_addresses () {
	$val_wrapper = \Enhance\Core::getCodeCoverageWrapper('Validation');
	$val_email = $this-&gt;get_scenario('validate_email');
	$addresses = array(&quot;john&quot;, &quot;jo!hn@doe.com&quot;, &quot;john@doe.&quot;, &quot;jo*hn@doe.com&quot;);

	foreach ($addresses as $addr) {
  		$val_email-&gt;with($addr)-&gt;expect(false);
	}
	$val_email-&gt;verifyExpectations();
}
</pre>
<p>This introduces a pretty cool feature of EnhancePHP: scenarios. We want to test a bunch of non-email addresses to make sure our method will return <code>false</code>. By creating a scenario, we essentially wrap an instance of our class in some EnhancePHP goodness, are write much less code to test all our non-addresses. That&#8217;s what <code>$val_wrapper</code> is: a modified instance of our <code>Validation</code> class. Then, <code>$val_email</code> is the scenario object, somewhat like a shortcut to the <code>validate_email</code> method.</p>
<p>Then, we&#8217;ve got an array of strings that should not validate as email addresses. We&#8217;ll loop over that array with a <code>foreach</code> loop. Notice how we run the test: we call the <code>with</code> method on our scenario object, passing it the parameters for the method we&#8217;re testing. Then, we call the <code>expect</code> method on that, and pass it whatever we expect to get back.</p>
<p>Finally, we call the scenario&#8217;s <code>verifyExpectations</code> method.</p>
<p>So, the first tests are written; how do we run them?</p>
<hr />
<h2>Running Tests</h2>
<p>Before we actually run the tests, we&#8217;ll need to create our <code>Validation</code> class. Inside <code>lib.validation.php</code>, start with this:</p>
<pre>
&lt;?php

class Validation {
	public function validate_email ($address) {

	}
}
</pre>
<p>Now, in <code>test.php</code>, we&#8217;ll pull it all together:</p>
<pre>
&lt;?php

require &quot;vendor/EnhanceTestFramework.php&quot;;
require &quot;lib/validation.php&quot;;
require &quot;test/validation_test.php&quot;;

\Enhance\Core::runTests();
</pre>
<p>First, we&#8217;ll require all the necessary files. Then, we call the <code>runTests</code> method, which finds our tests.</p>
<p>Next comes the neat part. Fire up a server, and you&#8217;ll get some nice HTML output:</p>
<div><img alt="" src="http://d2o0t5hpnwv4c1.cloudfront.net/1125_enhancephp/html_output.png" /></div>
<p>Very nice, right? Now, if you&#8217;ve got PHP in your terminal, run this is in the terminal:</p>
<div><img alt="" src="http://d2o0t5hpnwv4c1.cloudfront.net/1125_enhancephp/cli_output.png" /></div>
<p>EnhancePHP notices that you&#8217;re in a different environment, and adjusts its output appropriately. A side benefit of this is that if you&#8217;re using an IDE, like <a href="http://www.jetbrains.com/phpstorm/">PhpStorm</a>, that can run unit tests, you can view this terminal output right inside the IDE.</p>
<p>You can also get XML and <a href="http://en.wikipedia.org/wiki/Test_Anything_Protocol">TAP</a> output, if that&#8217;s what you prefer, just pass <code>\Enhance\TemplateType::Xml</code> or <code>\Enhance\TemplateType::Tap</code> to the <code>runTests</code> method to get the appropriate output. Note that running it in the terminal will also produce command-line results, no matter what you pass to <code>runTests</code>.</p>
<h3>Getting the Tests to Pass</h3>
<p>Let&#8217;s write the method that causes our tests to pass. As you know, that&#8217;s the <code>validate_email</code>. At the top of the <code>Validation</code> class, let&#8217;s define a public property:</p>
<pre>
public $email_regex = '/^[\w+-_\.]+@[\w\.]+\.\w+$/';
</pre>
<p>I&#8217;m putting this in a public property so that if the user wants to replace it with their own regex, they could. I&#8217;m using this simple version of an email regex, but you can replace it with your favourite regex if you want.</p>
<p>Then, there&#8217;s the method:</p>
<pre>
public function validate_email ($address) {
	return preg_match($this-&gt;email_regex, $address) == 1
}
</pre>
<p>Now, we run the tests again, and:</p>
<div><img alt="" src="http://d2o0t5hpnwv4c1.cloudfront.net/1125_enhancephp/html_output_2.png" /></div>
<hr />
<h2>Writing More Tests</h2>
<p>Time for more tests:</p>
<h3>Usernames</h3>
<p>Let&#8217;s create some tests for usernames now. Our requirements are simply that it must be a 4 to 20 character string consisting only of word characters or periods. So:</p>
<pre>
public function validates_a_good_username () {
	$result = $this-&gt;val-&gt;validate_username(&quot;some_user_name.12&quot;);
	\Enhance\Assert::isTrue($result);
}
</pre>
<p>Now, how about a few usernames that shouldn&#8217;t validate:</p>
<pre>
public function rejects_bad_usernames () {
	$val_username = $this-&gt;get_scenario('validate_username');
	$usernames = array(
		&quot;name with space&quot;,
		&quot;no!exclaimation!mark&quot;,
		&quot;ts&quot;,
		&quot;thisUsernameIsTooLongItShouldBeBetweenFourAndTwentyCharacters&quot;);

	foreach ($usernames as $name) {
  		$val_username-&gt;with($name)-&gt;expect(false);
	}
	$val_username-&gt;verifyExpectations();
}
</pre>
<p>This is very similar to our <code>reject_bad_email_addresses</code> function. Notice, however, that we&#8217;re calling this <code>get_scenario</code> method: where&#8217;s that come from? I&#8217;m abstracting the scenario creation functionality into private method, at the bottom of our class:</p>
<pre>
private function get_scenario ($method) {
	$val_wrapper = \Enhance\Core::getCodeCoverageWrapper('Validation');
    return \Enhance\Core::getScenario($val_wrapper, $method);
}
</pre>
<p>We can use this in our <code>reject_bad_usernames</code> and replace the scenario creation in <code>reject_bad_email_addresses</code> as well. Because this is a private method, EnhancePHP won&#8217;t try to run it as a normal test, the way it will with public methods.</p>
<p>We&#8217;ll make these tests pass similarly to how we made the first set pass:</p>
<pre>
# At the top . . .
public  $username_regex = '/^[\w\.]{4,20}$/';

# and the method . . .
public function validate_username ($username) {
	return preg_match($this-&gt;username_regex, $username) == 1;
}
</pre>
<p>This is pretty basic, of course, but that&#8217;s all that&#8217;s needed to meet our goal. If we wanted to return an explanation in the case of failure, you might do something like this:</p>
<pre>
public function validate_username ($username) {
	$len = strlen($username);
	if ($len &lt; 4 || $len &gt; 20) {
  		return &quot;Username must be between 4 and 20 characters&quot;;
	} elseif (preg_match($this-&gt;username_regex, $username) == 1) {
  		return true;
	} else {
  		return &quot;Username must only include letters, numbers, underscores, or periods.&quot;;
	}
}
</pre>
<p>Of course, you might also want to check if the username already exists.</p>
<p>Now, run the tests and you should see them all passing.</p>
<h3>Phone Numbers</h3>
<p>I think you&#8217;re getting the hang of this by now, so let&#8217;s finish of our validation example by checking phone numbers:</p>
<pre>
public function validates_good_phonenumbers () {
	$val_phonenumber = $this-&gt;get_scenario(&quot;validate_phonenumber&quot;);
	$numbers = array(&quot;1234567890&quot;, &quot;(890) 123-4567&quot;,
		&quot;123-456-7890&quot;, &quot;123 456 7890&quot;, &quot;(123) 456 7890&quot;);

	foreach($numbers as $num) {
  		$val_phonenumber-&gt;with($num)-&gt;expect(true);
	}
	$val_phonenumber-&gt;verifyExpectations();
}

public function rejects_bad_phonenumnbers () {
	$result = $this-&gt;val-&gt;validate_phonenumber(&quot;123456789012&quot;);
	\Enhance\Assert::isFalse($result);
}
</pre>
<p>You can probably figure out the <code>Validation</code> method:</p>
<pre>
public $phonenumber_regex = '/^\d{10}$|^(\(?\d{3}\)?[ |-]\d{3}[ |-]\d{4})$/';

public function validate_phonenumber ($number) {
	return preg_match($this-&gt;phonenumber_regex, $number) == 1;
}
</pre>
<p>Now, we can run all the tests together. Here&#8217;s what that looks like from the command line (my preferred testing environment):</p>
<div><img alt="" src="http://d2o0t5hpnwv4c1.cloudfront.net/1125_enhancephp/cli_output_2.png" /></div>
<hr />
<h2>Other Test Functionality</h2>
<p>Of course, EnhancePHP can do a lot more than what we&#8217;ve looked at in this little example. Let&#8217;s look at some of that now.</p>
<p>We very briefly met the <code>\Enhance\Assert</code> class in our first test. We didn&#8217;t really use it otherwise, because it&#8217;s not useful when using scenarios. However, it&#8217;s where all the assertion methods are. The beauty of them is that their names make their functionality incredibly obvious. The following test examples would pass:</p>
<ul>
<li><code>\Enhance\Assert::areIdentical("Nettuts+", "Nettuts+")</code></li>
<li><code>\Enhance\Assert::areNotIdentical("Nettuts+", "Psdtuts+")</code></li>
<li><code>\Enhance\Assert::isTrue(true)</code></li>
<li><code>\Enhance\Assert::isFalse(false)</code></li>
<li><code>\Enhance\Assert::contains("Net", "Nettuts+")</code></li>
<li><code>\Enhance\Assert::isNull(null)</code></li>
<li><code>\Enhance\Assert::isNotNull('Nettust+')</code></li>
<li><code>\Enhance\Assert::isInstanceOfType('Exception', new Exception(""))</code></li>
<li><code>\Enhance\Assert::isNotInstanceOfType('String', new Exception(""))</code></li>
</ul>
<p>There are a few other assertion methods, too; you can <a href="http://www.enhance-php.com/Content/Assertions/">check the docs</a> for a complete list and examples.</p>
<h3> Mocks</h3>
<p>EnhancePHP can also do mocks and stubs. Haven&#8217;t heard of mocks and stubs? Well, they aren&#8217;t too complicated. A mock is a wrapper for object, that can keep track of what methods are called, with what properties they are called, and what values are returned. A mock will have some test to verify, as we&#8217;ll see.</p>
<p>Here&#8217;s a small example of a mock. Let&#8217;s start with a very simple class that counts:</p>
<pre>
&lt;?php

require &quot;vendor/EnhanceTestFramework.php&quot;;

class Counter {
  public $num = 0;
  public function increment ($num = 1) {
    $this-&gt;num = $this-&gt;num + $num;
    return $this-&gt;num;
  }
}
</pre>
<p>We have one function: <code>increment</code>, that accepts a parameter (but defaults to 1), and increments the <code>$num</code> property by that number.</p>
<p>We might use this class if we were building a scoreboard:</p>
<pre>
class Scoreboard {
  public $home = 0;
  public $away = 0;

  public function __construct ($home, $away) {
    $this-&gt;home_counter = $home;
    $this-&gt;away_counter = $away;
  } 

  public function score_home () {
    $this-&gt;home = $this-&gt;home_counter-&gt;increment();
    return $this-&gt;home;
  }
  public function score_away () {
    $this-&gt;away = $this-&gt;away_counter-&gt;increment();
    return $this-&gt;home;
  }
}
</pre>
<p>Now, we want to test to make sure that the <code>Counter</code> instance method <code>increment</code> is working properly when the <code>Scoreboard</code> instance methods call it. So we creat this test:</p>
<pre>
class ScoreboardTest extends \Enhance\TestFixture {
  public function score_home_calls_increment () {
    $home_counter_mock = \Enhance\MockFactory::createMock(&quot;Counter&quot;);
    $away_counter = new Counter();

    $home_counter_mock-&gt;addExpectation( \Enhance\Expect::method('increment') );

    $scoreboard = new Scoreboard($home_counter_mock, $away_counter);
    $scoreboard-&gt;score_home();

    $home_counter_mock-&gt;verifyExpectations();
  }
}

\Enhance\Core::runTests();
</pre>
<p>Notice that we start by creating <code>$home_counter_mock</code>: we use the EnhancePHP mock factory, passing it the name of the class we&#8217;re mocking. This returns a &#8220;wrapped&#8221; instance of <code>Counter</code>. Then, we add an expectation, with this line</p>
<pre>
$home_counter_mock-&gt;addExpectation( \Enhance\Expect::method('increment') );
</pre>
<p>Our expectation just says that we expect the <code>increment</code> method to be called.</p>
<p>After that, we go on to create the <code>Scoreboard</code> instance, and call <code>score_home</code>. Then, we <code>verifyExpectations</code>. If you run this, you&#8217;ll see that our test passes.</p>
<p>We could also state what parameters we want a method on the mock object to be called with, what value is returned, or how many times the method should be called, with something like this:</p>
<pre>
$home_counter_mock-&gt;addExpectation( \Enhance\Expect::method('increment')-&gt;with(10) );
$home_counter_mock-&gt;addExpectation( \Enhance\Expect::method('increment')-&gt;times(2) );
$home_counter_mock-&gt;addExpectation( \Enhance\Expect::method('increment')-&gt;returns(1) );
$home_counter_mock-&gt;addExpectation( \Enhance\Expect::method('increment')-&gt;with(3)-&gt;times(1) );
$home_counter_mock-&gt;addExpectation( \Enhance\Expect::method('increment')-&gt;with(2)-&gt;returns(2) );
</pre>
<p>I should mention that, while <code>with</code> and <code>times</code> will show failed tests if the expectations aren&#8217;t meant, <code>returns</code> doesn&#8217;t. You&#8217;ll have to store the return value and use an assertion to very that. I&#8217;m not sure why that&#8217;s the case, but every library has its quirks <img src='http://terrytoledo.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . (You can see an example of this in <a href="https://github.com/Enhance-PHP/Enhance-PHP/blob/master/Self-Test/MockTestFixture.php">the library examples in Github</a>.)</p>
<h3>Stubs</h3>
<p>Then, there are stubs. A stub fills in for a real object and method, returning exactly what you tell it to. So, let&#8217;s say we want to make sure that our <code>Scoreboard</code> instance is correctly using the value it receives from <code>increment</code>, we can stub a <code>Counter</code> instance so we can control what <code>increment</code> will return:</p>
<pre>
class ScoreboardTest extends \Enhance\TestFixture {
  public function score_home_calls_increment () {
    $home_counter_stub = \Enhance\StubFactory::createStub(&quot;Counter&quot;);
    $away_counter = new Counter();

    $home_counter_stub-&gt;addExpectation( \Enhance\Expect::method('increment')-&gt;returns(10) );

    $scoreboard = new Scoreboard($home_counter_stub, $away_counter);
    $result = $scoreboard-&gt;score_home();

    \Enhance\Assert::areIdentical($result, 10);

  }
}

\Enhance\Core::runTests();
</pre>
<p>Here, we&#8217;re using <code>\Enhance\StubFactory::createStub</code> to create our stub counter. Then, we add an expectation that the method <code>increment</code> will return 10. We can see that the result it what we&#8217;d expect, given our code.</p>
<p>For more examples of mocks and stub with the EnhancePHP library, <a href="https://github.com/Enhance-PHP/Enhance-PHP/tree/master/Self-Test">check out the Github Repo</a>.</p>
<hr />
<h2>Conclusion</h2>
<p>Well, that&#8217;s a look at testing in PHP, using the EnhancePHP framework. It&#8217;s an incredibly simple framework, but it provides everything you need to do some simple unit testing on your PHP code. Even if you choose a different method/framework for testing your PHP (or perhaps roll your own!), I hope this tutorial has sparked an interest in testing your code, and how simple it can be.</p>
<p>But maybe you already test your PHP. Let us all know what you use in the comments; after all, we&#8217;re all here to learn from each other! Thank you so much for stopping by!</p>
<p><a href="http://feedads.g.doubleclick.net/~a/diGGwUb0yNESfohOlt3GjENk-Po/0/da"><img src="http://feedads.g.doubleclick.net/~a/diGGwUb0yNESfohOlt3GjENk-Po/0/di" border="0"></img></a><br />
<a href="http://feedads.g.doubleclick.net/~a/diGGwUb0yNESfohOlt3GjENk-Po/1/da"><img src="http://feedads.g.doubleclick.net/~a/diGGwUb0yNESfohOlt3GjENk-Po/1/di" border="0"></img></a></p>
<div>
<a href="http://feeds.feedburner.com/~ff/nettuts?a=cCcgjNI0wlQ:RcVYBd4xy60:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=cCcgjNI0wlQ:RcVYBd4xy60:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=cCcgjNI0wlQ:RcVYBd4xy60:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=cCcgjNI0wlQ:RcVYBd4xy60:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=cCcgjNI0wlQ:RcVYBd4xy60:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=cCcgjNI0wlQ:RcVYBd4xy60:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=cCcgjNI0wlQ:RcVYBd4xy60:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=cCcgjNI0wlQ:RcVYBd4xy60:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/cCcgjNI0wlQ" height="1" width="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://terrytoledo.com/2012/01/testing-your-php-codebase-with-enhancephp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Course: Introduction to Web Typography</title>
		<link>http://terrytoledo.com/2012/01/new-course-introduction-to-web-typography/</link>
		<comments>http://terrytoledo.com/2012/01/new-course-introduction-to-web-typography/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 05:00:12 +0000</pubDate>
		<dc:creator>Nettuts</dc:creator>
				<category><![CDATA[Nettuts]]></category>

		<guid isPermaLink="false">http://terrytoledo.com/2012/01/new-course-introduction-to-web-typography/</guid>
		<description><![CDATA[Web typography is accessible to everyone. If you&#8217;ve ever built or designed a web page, you&#8217;ve almost definitely turned your hand to web typography of some sort. As a discipline, typography has been practiced for hundreds of years, and as a result there are many lessons and conventions we can learn from. Saying that, web [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23808&amp;c=25961766" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23808&amp;c=25961766" border="0" alt="" /></a>
<p>Web typography is accessible to everyone. If you&#8217;ve ever built or designed a web page, you&#8217;ve almost definitely turned your hand to web typography of some sort. As a discipline, typography has been practiced for hundreds of years, and as a result there are many lessons and conventions we can learn from.</p>
<p><span></span></p>
<p>Saying that, web typography is a bit like skiing. It&#8217;s unwise to just grab a couple of wooden planks and throw yourself down a black piste; you&#8217;ll develop bad habits and perhaps even break a bone. Before diving into your next web project, make sure you&#8217;ve at least considered the fundamentals.</p>
<p>I can&#8217;t help you with skiing, but I can help you with web typography. If you&#8217;ve never looked properly into the subject, or even if you need a refresher, <a href="http://tutsplus.com/course/introduction-to-web-typography/">Introduction to Web Typography</a> is for you!</p>
<hr />
<h2>Free Preview Lessons</h2>
<ul>
<li><a href="http://tutsplus.com/lesson/welcome-2/">Welcome</a> (2m 10s)</li>
<li><a href="http://tutsplus.com/lesson/an-introduction/">An Introduction</a> (10m 22s)</li>
<li><a href="http://tutsplus.com/lesson/anatomy-of-type/">Anatomy of Type</a> (11m 36s)</li>
</ul>
<hr />
<h2>Overview </h2>
<p>As with all Tuts+ Premium courses, we&#8217;ll start at the beginning, working through the basics and some terminology, before moving on to the practicalities. During the process we&#8217;ll build ourselves a demo web page which will highlight the theory we cover. Even if you&#8217;re not yet confident with HTML and CSS, each video comes with source files stepping off from where the previous video ended.</p>
<p>Take a look at the episodes listed below and be sure to check out the preview videos even if you don&#8217;t yet have a Premium subscription.</p>
<div>
<a href="http://tutsplus.com/course/introduction-to-web-typography/"><img alt="Lesson Overview" src="http://webdesigntutsplus.s3.amazonaws.com/articles/060_introducing_web_typography/course.png" /></a><br />This course comprises 11 helpful videos.
</div>
<p>As with all Tuts+ Premium courses, each lesson has an accompanying forum where you can discuss ideas and questions which arise as you watch the videos.</p>
<div>
<a href="http://tutsplus.com/course/introduction-to-web-typography/"><img alt="Course Forum" src="http://webdesigntutsplus.s3.amazonaws.com/articles/060_introducing_web_typography/forum.png" /></a><br />Get involved with the forum, where you can discuss each lesson.
</div>
<hr />
<h2>Tuts+ Premium</h2>
<p><a href="http://tutsplus.com/take-the-tour/"><img src="http://webdesigntutsplus.s3.amazonaws.com/articles/060_introducing_web_typography/250x250.jpg" /></a>The recently re-launched <a href="http://tutsplus.com">Tuts+ Premium</a> is a service that provides top-tier training in a variety of creative fields. Whether you prefer <a href="http://tutsplus.com/ebooks">books</a>, <a href="http://tutsplus.com/courses">visual training</a>, or <a href="http://tutsplus.com/tutorials">in depth tutorials</a>, we have you covered. While we unfortunately can’t afford to provide the service for free, it’s only $19 a month – less than you’d spend on dinner. </p>
<p>I hope you’ll consider <a href="http://tutsplus.com">checking it out</a>! In addition to learning a huge variety of new skills, it’s also a fantastic way to say thank you to Nettuts+. </p>
<p><a href="http://feedads.g.doubleclick.net/~a/cSD3hqiUqFlJzoC_hBCalYaCOaA/0/da"><img src="http://feedads.g.doubleclick.net/~a/cSD3hqiUqFlJzoC_hBCalYaCOaA/0/di" border="0"></img></a><br />
<a href="http://feedads.g.doubleclick.net/~a/cSD3hqiUqFlJzoC_hBCalYaCOaA/1/da"><img src="http://feedads.g.doubleclick.net/~a/cSD3hqiUqFlJzoC_hBCalYaCOaA/1/di" border="0"></img></a></p>
<div>
<a href="http://feeds.feedburner.com/~ff/nettuts?a=9tUUMf1qNew:nNoQ-JInL5o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=9tUUMf1qNew:nNoQ-JInL5o:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=9tUUMf1qNew:nNoQ-JInL5o:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=9tUUMf1qNew:nNoQ-JInL5o:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=9tUUMf1qNew:nNoQ-JInL5o:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=9tUUMf1qNew:nNoQ-JInL5o:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=9tUUMf1qNew:nNoQ-JInL5o:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=9tUUMf1qNew:nNoQ-JInL5o:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/9tUUMf1qNew" height="1" width="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://terrytoledo.com/2012/01/new-course-introduction-to-web-typography/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>From jQuery to JavaScript: A Reference</title>
		<link>http://terrytoledo.com/2012/01/from-jquery-to-javascript-a-reference/</link>
		<comments>http://terrytoledo.com/2012/01/from-jquery-to-javascript-a-reference/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 05:00:11 +0000</pubDate>
		<dc:creator>Nettuts</dc:creator>
				<category><![CDATA[Nettuts]]></category>

		<guid isPermaLink="false">http://terrytoledo.com/2012/01/from-jquery-to-javascript-a-reference/</guid>
		<description><![CDATA[Whether we like it or not, more and more developers are being introduced to the world of JavaScript through jQuery first. In many ways, these newcomers are the lucky ones. They have access to a plethora of new JavaScript APIs, which make the process of DOM traversal (something that many folks depend on jQuery for) [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23703&amp;c=2036355230" target="_blank"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=23703&amp;c=2036355230" border="0" alt="" /></a>
<p>Whether we like it or not, more and more developers are being introduced to the world of JavaScript through jQuery first. In many ways, these newcomers are the lucky ones. They have access to a plethora of new JavaScript APIs, which make the process of DOM traversal (something that many folks depend on jQuery for) considerably easier. Unfortunately, they don&#8217;t know about these APIs!</p>
<p> In this article, we&#8217;ll take a variety of common jQuery tasks, and convert them to both modern and legacy JavaScript.</p>
<p><span></span></p>
<blockquote>
<p>
     <strong>Modern vs. Legacy</strong> &#8211; For each item in the list below, you&#8217;ll find the modern, &#8220;cool kids&#8221; way to accomplish the task, and the legacy, &#8220;make old browsers happy&#8221; version. The choice you choose for your own projects will largely depend on your visitors.
  </p>
</blockquote>
<hr />
<h2>Before We Begin </h2>
<p>Please note that some of the <strong>legacy</strong> examples in this article will make use of a simple, cross-browser, <code>addEvent</code> function. This function will simply ensure that both the W3C-recommended event model, <code>addEventListener</code>, and Internet Explorer&#8217;s legacy <code>attachEvent</code> are normalized. </p>
<p>So, when I refer to <code>addEvent(els, event, handler)</code> in the legacy code snippets below, the following function is being referenced. </p>
<pre>
var addEvent = (function () {
	var filter = function(el, type, fn) {
		for ( var i = 0, len = el.length; i &lt; len; i++ ) {
			addEvent(el[i], type, fn);
		}
	};
	if ( document.addEventListener ) {
		return function (el, type, fn) {
			if ( el &amp;&amp; el.nodeName || el === window ) {
				el.addEventListener(type, fn, false);
			} else if (el &amp;&amp; el.length) {
				filter(el, type, fn);
			}
		};
	}

	return function (el, type, fn) {
		if ( el &amp;&amp; el.nodeName || el === window ) {
			el.attachEvent('on' + type, function () { return fn.call(el, window.event); });
		} else if ( el &amp;&amp; el.length ) {
			filter(el, type, fn);
		}
	};
})();

// usage
addEvent( document.getElementsByTagName('a'), 'click', fn);
</pre>
<hr />
<h2><span>1 &#8211; </span><code>$('#container'); </code></h2>
<p>This function call will query the DOM for the element with an <code>id</code> of <code>container</code>, and create a new <code>jQuery</code> object.</p>
<h4>Modern JavaScript</h4>
<pre>
var container = document.querySelector('#container');
</pre>
<p><code>querySelector</code> is part of the <a href="http://www.w3.org/TR/selectors-api2/">Selectors API</a>, which provides us with the ability to query the DOM using the CSS selectors that we&#8217;re already familiar with. </p>
<p>This particular method will return the first element that matches the passed selector. </p>
<h4>Legacy </h4>
<pre>
var container = document.getElementById('container');
</pre>
<p>Pay special attention to how you reference the element. When using <code>getElementById</code>, you pass the value alone, while, with <code>querySelector</code>, a CSS selector is expected. </p>
<hr />
<h2><span>2 &#8211; </span><code>$('#container').find('li');</code></h2>
<p>This time, we&#8217;re not hunting for a single element; instead, we&#8217;re capturing any number of list items that are descendants of <code>#container</code>.
</p>
<h4>Modern JavaScript </h4>
<pre>
var lis = document.querySelectorAll('#container li');
</pre>
<p><code>querySelectorAll</code> will return <em>all</em> elements that match the specified CSS selector.</p>
<h5>Selector Limitations </h5>
<p>
While nearly all relevant browsers support the Selectors API, the specific CSS selectors you pass are still limited to the capability of the browser. Translation: Internet Explorer 8 will only support CSS 2.1 selectors.</p>
<h4>Legacy </h4>
<pre>
var lis = document.getElementById('container').getElementsByTagName('li');
</pre>
<hr />
<h2><span>3 &#8211; </span> <code>$('a').on('click', fn);</code> </h2>
<p>In this example, we&#8217;re attaching a <code>click</code> event listener to all anchor tags on the page. </p>
<h4>Modern JavaScript</h4>
<pre>
[].forEach.call( document.querySelectorAll('a'), function(el) {
   // anchor was clicked
});
</pre>
<p>The above snippet looks scary, but it&#8217;s not too bad. Because <code>querySelectorAll</code> returns a <code>NodeList</code> rather than an <code>Array</code>, we can&#8217;t directly access methods, like <code>forEach</code>. This is remedied by calling <code>forEach</code> on the <code>Array</code> object, and passing the the results of <code>querySelectorAll</code> as <code>this</code>.</p>
<h4>Legacy </h4>
<pre>
var anchors = document.getElementsbyTagName('a');
addEvent(anchors[i], 'click', fn);
</pre>
<hr />
<h2><span>4 &#8211; </span><code>$('ul').on('click', 'a', fn);</code></h2>
<p>Ahh &#8211; this example is slightly different. This time, the jQuery snippet is using event delegation. The <code>click</code> listener is being applied to all unordered lists, however, the callback function will only fire if the target (what the user specifically clicked on) is an anchor tag.</p>
<h4>Modern JavaScript</h4>
<pre>
document.addEventListener('click', function(e) {
   if ( e.target.matchesSelector('ul a') ) {
      // proceed
   }
}, false);
</pre>
<p>Technically, this vanilla JavaScript method isn&#8217;t the same as the jQuery example. Instead, it&#8217;s attaching the event listener directly to the <code>document</code>. It then uses the new <code><a href="http://caniuse.com/matchesselector">matchesSelector</a></code> method to determine if the <code>target</code> &#8211; the node that was clicked &#8211; matches the provided selector. This way, we&#8217;re attaching a single event listener, rather than many.</p>
<p>
Please note that, at the time of this writing, all browsers implement <code>matchesSelector</code> via their own respective prefixes: <code>mozMatchesSelector</code>, <code>webkitMatchesSelector</code>, etc. To normalize the method, one might write:</p>
<pre>
var matches;

(function(doc) {
   matches =
      doc.matchesSelector ||
      doc.webkitMatchesSelector ||
      doc.mozMatchesSelector ||
      doc.oMatchesSelector ||
      doc.msMatchesSelector;
})(document.documentElement);

document.addEventListener('click', function(e) {
   if ( matches.call( e.target, 'ul a') ) {
      // proceed
   }
}, false);
</pre>
<blockquote>
<p>
      With this technique, in Webkit, matches will refer to <code>webkitMatchesSelector</code>, and, in Mozilla, <code>mozMatchesSelector</code>.
  </p>
</blockquote>
<h4>Legacy </h4>
<pre>
var uls = document.getElementsByTagName('ul');

addEvent(uls, 'click', function() {
   var target = e.target || e.srcElement;
   if ( target &amp;&amp; target.nodeName === 'A' ) {
      // proceed
   }
});
</pre>
<p>As a fallback, we determine if the <code>nodeName</code> property (the name of the target element) is equal to our desired query. Pay special attention to the fact that older versions of Internet Explorer sometimes plays by their own rules &#8211; sort of like the kid who eats play-doh during lunch time. You won&#8217;t be able to access <code>target</code> directly from the <code>event</code> object. Instead, you&#8217;ll want to look for <code>event.srcElement</code>.</p>
<hr />
<h2><span>5  -</span> <code>$('#box').addClass('wrap');</code></h2>
<p>jQuery provides a helpful API for modifying class names on a set of elements. </p>
<h4>Modern JavaScript</h4>
<pre>
document.querySelector('#box').classList.add('wrap');
</pre>
<p>This new technique uses the new <code><a href="https://developer.mozilla.org/en/DOM/element.classList">classList</a></code> API to <code>add</code>, <code>remove</code>, and <code>toggle</code> class names.</p>
<pre>
var container = document.querySelector('#box');

container.classList.add('wrap');
container.classList.remove('wrap');
container.classList.toggle('wrap');
</pre>
<h4>Legacy </h4>
<pre>
var box = document.getElementById('box'),

    hasClass = function (el, cl) {
        var regex = new RegExp('(?:\\s|^)' + cl + '(?:\\s|$)');
        return !!el.className.match(regex);
    },

    addClass = function (el, cl) {
        el.className += ' ' + cl;
    },

    removeClass = function (el, cl) {
        var regex = new RegExp('(?:\\s|^)' + cl + '(?:\\s|$)');
        el.className = el.className.replace(regex, ' ');
    },

    toggleClass = function (el, cl) {
        hasClass(el, cl) ? removeClass(el, cl) : addClass(el, cl);

    };

addClass(box, 'drago');
removeClass(box, 'drago');
toggleClass(box, 'drago'); // if the element does not have a class of 'drago', add one.
</pre>
<p>The fallback technique requires just a tad more work, ay? </p>
<hr />
<h2><span>6 -</span> <code>$('#list').next();</code></h2>
<p>jQuery&#8217;s <code>next</code> method will return the element that immediately follows the current element in the wrapped set.</p>
<h4>Modern JavaScript </h4>
<pre>
var next = document.querySelector('#list').nextElementSibling; // IE9
</pre>
<p><code>nextElementSibling</code> will refer specifically to the next <em>element</em> node, rather than any node (text, comment, element). Unfortunately, Internet Explorer 8 and below do not support it.</p>
<h4>Legacy </h4>
<pre>
var list = document.getElementById('list'),
	next = list.nextSibling;

// we want the next element node...not text.
while ( next.nodeType &gt; 1 ) next = next.nextSibling;
</pre>
<p>
There&#8217;s a couple ways to write this. In this example, we&#8217;re detecting the <code>nodeType</code> of the node that follows the specified element. It could be text, element, or even a comment. As we specifically need the next element, we desire a <code>nodeType</code> of <code>1</code>. If <code>next.nodeType</code> returns a number greater than <code>1</code>, we should skip it and keep going, as it&#8217;s probably a text node. </p>
<hr />
<h2><span>7 -</span> <code>$('&lt;div id=box&gt;&lt;/div&gt;').appendTo('body');</code></h2>
<p>In addition to querying the DOM, jQuery also offers the ability to create and inject elements. </p>
<h4>Modern JavaScript </h4>
<pre>
var div = document.createElement('div');
div.id = 'box';
document.body.appendChild(div);
</pre>
<p>There&#8217;s nothing modern about this example; it&#8217;s how we&#8217;ve accomplished the process of creating and injecting elements into the DOM for a long, long time. </p>
<p>You&#8217;ll likely need to add content to the element, in which case you can either use <code>innerHTML</code>, or <code>createTextNode</code>.</p>
<pre>
div.appendChild( document.createTextNode('wacka wacka') );

// or

div.innerHTML = 'wacka wacka';
</pre>
<hr />
<h2><span>8 &#8211; </span><code>$(document).ready(fn)</code></h2>
<p>jQuery&#8217;s <code>document.ready</code> method is incredibly convenient. It allows us to begin executing code as soon as possible after the DOM has been loaded.</p>
<h4>Modern JavaScript </h4>
<pre>
document.addEventListener('DOMContentLoaded', function() {
   // have fun
});
</pre>
<p>Standardized as part of HTML5, the <code>DOMContentLoaded</code> event will fire as soon as the document has been completed parsed.</p>
<h4>Legacy</h4>
<pre>
// http://dustindiaz.com/smallest-domready-ever
function ready(cb) {
	/in/.test(document.readyState) // in = loadINg
		? setTimeout('ready('+cb+')', 9)
		: cb();
}

ready(function() {
   // grab something from the DOM
});
</pre>
<p>The fallback solution, every nine milliseconds, will detect the value of <code>document.readyState</code>. If &#8220;loading&#8221; is returned, the document hasn&#8217;t yet been fully parsed (<code>/in/.test()</code>. Once it has, though, <code>document.readyState</code> will equal &#8220;complete,&#8221; at which point the user&#8217;s callback function is executed. </p>
<hr />
<h2><span>9 &#8211; </span><code>$('.box').css('color', 'red');</code></h2>
<p>If possible, always add a <code>class</code> to an element, when you need to provide special styling. However, sometimes, the styling will be determined dynamically, in which case it needs to be inserted as an attribute. </p>
<h4>Modern JavaScript</h4>
<pre>
[].forEach.call( document.querySelectorAll('.box'), function(el) {
  el.style.color = 'red'; // or add a class
});
</pre>
<p>Once again, we&#8217;re using the <code>[].forEach.call()</code> technique to filter through all of the elements with a class of <code>box</code>, and make them red, via the <code>style</code> object.</p>
<h4>Legacy</h4>
<pre>
var box = document.getElementsByClassName('box'), // refer to example #10 below for a cross-browser solution
   i = box.length;
 
while ( i-- &gt; 0 &amp;&amp; (box[i].style.color = 'red') );
</pre>
<p>This time, we&#8217;re getting a bit tricky with the <code>while</code> loop. Yes, it&#8217;s a bit snarky, isn&#8217;t it? Essentially, we&#8217;re mimicking: </p>
<pre>
var i = 0, len;

for ( len = box.length; i &lt; len; i++ ) {
   box[i].style.color = 'red';
}
</pre>
<p>However, as we only need to perform a single action, we can save a couple lines. Note that readability is far more important than saving two lines &#8211; hence my &#8220;snarky&#8221; reference. Nonetheless, it&#8217;s always fun to see how condensed you can make your loops. We&#8217;re developers; we do this sort of stuff for fun! Anyhow, feel free to stick with the <code>for</code> statement version. </p>
<hr />
<h2><span>10 &#8211; </span><code>$()</code></h2>
<p>Clearly, our intention is not to replicate the entire jQuery API. Typically, for non-jQuery projects, the <code>$</code> or <code>$$</code> function is used as shorthand for retrieving one or more elements from the DOM.</p>
<h4>Modern JavaScript</h4>
<pre>
var $ = function(el) {
	return document.querySelectorAll(el);
};
// Usage = $('.box');
</pre>
<p>Notice that <code>$</code> is simply a one-character pointer to <code>document.querySelector</code>. It saves time! </p>
<h4>Legacy </h4>
<pre>
if ( !document.getElementsByClassName ) {
	document.getElementsByClassName = function(cl, tag) {
	   var els, matches = [],
	      i = 0, len,
	      regex = new RegExp('(?:\\s|^)' + cl + '(?:\\s|$)');
	 
	   // If no tag name is specified,
	   // we have to grab EVERY element from the DOM	 
	   els = document.getElementsByTagName(tag || &quot;*&quot;);
	   if ( !els[0] ) return false;

	   for ( len = els.length; i &lt; len; i++ ) {
	      if ( els[i].className.match(regex) ) {
	         matches.push( els[i]);
	      }
	   }
	   return matches; // an array of elements that have the desired classname
	};
}
 
// Very simple implementation. We're only checking for an id, class, or tag name.
// Does not accept CSS selectors in pre-querySelector browsers.
var $ = function(el, tag) {
   var firstChar = el.charAt(0);
 
   if ( document.querySelectorAll ) return document.querySelectorAll(el);
 
   switch ( firstChar ) {
      case &quot;#&quot;:
         return document.getElementById( el.slice(1) );
      case &quot;.&quot;:
         return document.getElementsByClassName( el.slice(1), tag );
      default:
         return document.getElementsByTagName(el);
   }
};

// Usage
$('#container');
$('.box'); // any element with a class of box
$('.box', 'div'); // look for divs with a class of box
$('p'); // get all p elements
</pre>
<p>Unfortunately, the legacy method isn&#8217;t quite so minimal. Honestly, at this point, you should use a library. jQuery is highly optimized for working with the DOM, which is why it&#8217;s so popular! The example above will certainly work, however, it doesn&#8217;t support complex CSS selectors in older browsers; that task is just a wee-bit more complicated!
</p>
<hr />
<h2>Summary</h2>
<p>It&#8217;s important for me to note that that I&#8217;m not encouraging you to abandon jQuery. I use it in nearly all of my projects. That said, don&#8217;t always be willing to embrace abstractions without taking a bit of time to research the underlying code. </p>
<p>I&#8217;d like this posting to serve as a living document, of sorts. If you have any of your own (or improvements/clarifications for my examples), leave a comment below, and I&#8217;ll sporadically update this posting with new items. Bookmark this page now! Lastly, I&#8217;d like to send a hat-tip to <a href="http://sharedfil.es/js-48hIfQE4XK.html">this set of examples</a>, which served as the impetus for this post.</p>
<p><a href="http://feedads.g.doubleclick.net/~a/keJiHaDRtmi6rCn2QfrThd7x2JY/0/da"><img src="http://feedads.g.doubleclick.net/~a/keJiHaDRtmi6rCn2QfrThd7x2JY/0/di" border="0"></img></a><br />
<a href="http://feedads.g.doubleclick.net/~a/keJiHaDRtmi6rCn2QfrThd7x2JY/1/da"><img src="http://feedads.g.doubleclick.net/~a/keJiHaDRtmi6rCn2QfrThd7x2JY/1/di" border="0"></img></a></p>
<div>
<a href="http://feeds.feedburner.com/~ff/nettuts?a=7WlqzndfiXk:5GnZ7NtSfn4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=7WlqzndfiXk:5GnZ7NtSfn4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=7WlqzndfiXk:5GnZ7NtSfn4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=7WlqzndfiXk:5GnZ7NtSfn4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=7WlqzndfiXk:5GnZ7NtSfn4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=7WlqzndfiXk:5GnZ7NtSfn4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=7WlqzndfiXk:5GnZ7NtSfn4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=7WlqzndfiXk:5GnZ7NtSfn4:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div>
<p><img src="http://feeds.feedburner.com/~r/nettuts/~4/7WlqzndfiXk" height="1" width="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://terrytoledo.com/2012/01/from-jquery-to-javascript-a-reference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

