<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Nettuts+</title>
	
	<link>http://net.tutsplus.com</link>
	<description>Web Development &amp; Design Tutorials</description>
	<lastBuildDate>Fri, 27 Nov 2009 10:30:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<image><link>http://nettuts.com</link><url>http://envato.s3.amazonaws.com/rss_images/nettuts.jpg</url><title>NETTUTS</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/nettuts" type="application/rss+xml" /><feedburner:emailServiceId>nettuts</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>10 Templates that Solve Problems for Web Developers</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/N_enMJLGFa0/</link>
		<comments>http://net.tutsplus.com/articles/web-roundups/10-templates-that-solve-problems-for-web-developers/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 10:30:29 +0000</pubDate>
		<dc:creator>Jarel Remick</dc:creator>
				<category><![CDATA[Web Roundups]]></category>
		<category><![CDATA[site template]]></category>
		<category><![CDATA[templates]]></category>
		<category><![CDATA[themeforest]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=7928</guid>
		<description><![CDATA[<img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/200x200.jpg" alt="10 Templates that Solve Problems for Web Developers" />]]></description>
			<content:encoded><![CDATA[<p>We live in a web centric world right now, and if you haven&#8217;t already, you&#8217;ll most likely be facing website related dilemma(s). For example, maybe you need an email template to send out your company newsletter(s) but you don&#8217;t have the first clue as to how to create one let alone create one that works with all major clients, looks outstanding and is easy to customize and reuse.</p>
<p>Or maybe you need a stylish but functional admin panel for a client whom you&#8217;ve just built a complex CMS for, but you aren&#8217;t a designer. There are an infinite number of possible problems you could be facing and fortunately, there are solutions.</p>
<p><span id="more-7928"></span></p>
<h3>1. <a href="http://themeforest.net/item/airmail-customizable-email-template/70841">Airmail! &#8211; Customizable Email Template</a></h3>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/airmail-customizable-email-template/70841"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/Airmail.jpg" alt="Airmail" width="590" height="300"/></a>
</div>
<p>&ldquo;Airmail is a professionally built and designed custom HTML email template! Perfect for just about anyone – usable for everything from newsletters to eFlyers to whitepapers.&rdquo;</p>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/airmail-customizable-email-template/70841"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/AirmailFullView.jpg" alt="Airmail" width="600" height="411"/></a>
</div>
<h3>2. <a href="http://themeforest.net/item/simpla-admin-flexible-user-friendly-admin-skin/46073">Simpla Admin &#8211; Flexible &#038; User Friendly Admin skin</a></h3>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/simpla-admin-flexible-user-friendly-admin-skin/46073"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/SimplaAdmin.jpg" alt="Simpla Admin" width="590" height="300"/></a>
</div>
<p>&ldquo;Simpla Admin is a professional template with a beautiful and user friendly interface. With various smart and intuitive jQuery functions, navigating the interface is a breeze.&rdquo;</p>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/simpla-admin-flexible-user-friendly-admin-skin/46073"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/SimplaAdminFullView.jpg" alt="Simpla Admin" width="600" height="448"/></a>
</div>
<h3>3. <a href="http://themeforest.net/item/cleanmail-email-template-package-5-colors/70735">CleanMail &#8211; Email Template Package &#8211; 5 Colors!</a></h3>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/cleanmail-email-template-package-5-colors/70735"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/CleanMail.jpg" alt="CleanMail" width="590" height="300"/></a>
</div>
<p>&ldquo;CleanMail is a simple yet sexy email template package with 5 different color schemes!&rdquo;</p>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/cleanmail-email-template-package-5-colors/70735"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/CleanMailFullView.jpg" alt="CleanMail" width="600" height="409"/></a>
</div>
<h3>4. <a href="http://themeforest.net/item/wordpress-wiki-theme/29479">WordPress Wiki Theme</a></h3>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/wordpress-wiki-theme/29479"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/WordPressWiki.jpg" alt="WordPress Wiki" width="590" height="300"/></a>
</div>
<p>&ldquo;If you’re looking for a Knowledge Base or Wiki for your company but don’t want or need a full blown Wiki Application. This is the theme for you. Built with a custom Frequently Asked Questions plugin to help extend the functionality of your web site. The plugin acts as a custom write panel that displays in essence short FAQs below posts in their respective categories. The FAQs are searchable and paginate and are not required.&rdquo;</p>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/wordpress-wiki-theme/29479"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/WordPressWikiFullView.jpg" alt="WordPressWiki" width="600" height="444"/></a>
</div>
<h3>5. <a href="http://themeforest.net/item/marketplace-community-wordpress-theme/68073">Marketplace Community WordPress Theme</a></h3>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/marketplace-community-wordpress-theme/68073"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/MarketplaceCommunity.jpg" alt="Marketplace Community" width="590" height="300"/></a>
</div>
<p>&ldquo;Marketplace is a both clean and stylish WordPress theme with the intent and focus on creating a community site for industry news, tutorials, etc. This theme includes many popular built in features seen in today’s industry leading community sites. This themes comes with 5 different color options to choose from.&rdquo;</p>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/marketplace-community-wordpress-theme/68073"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/MarketplaceCommunityFullView.jpg" alt="Marketplace Community" width="600" height="424"/></a>
</div>
<h3>6. <a href="http://themeforest.net/item/vcard-professional-portfolio/64207">vCard Professional Portfolio</a></h3>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/vcard-professional-portfolio/64207"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/vCardProfessionalPortfolio.jpg" alt="vCard Professional Portfolio" width="590" height="300"/></a>
</div>
<p>&ldquo;This is a professional and clean vCard based on Tim Van Damme’s website. With this design you can use almost any background.&rdquo;</p>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/vcard-professional-portfolio/64207v"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/vCardFullView.jpg" alt="vCard Professional Portfolio" width="600" height="444"/></a>
</div>
<h3>7. <a href="http://themeforest.net/item/sleek-server-error-pages-404-403-500-more/55012">Sleek Server Error Pages</a></h3>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/sleek-server-error-pages-404-403-500-more/55012"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/SleekServer.jpg" alt="Sleek Server Error Pages" width="590" height="300"/></a>
</div>
<p>&ldquo;This is a clean, web 2.0 design for website / server error pages. It is flexible and very easy to customize. It comes with 5 of the most common error pages (404, 403, 401, 500 and 503) but it’s very easy to add more if needed. All text is real text so adding more pages is a breeze, no image editing required.&rdquo;</p>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/sleek-server-error-pages-404-403-500-more/55012"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/SleekServerFullView.jpg" alt="Sleek Server Error Pages" width="600" height="455"/></a>
</div>
<h3>8. <a href="http://themeforest.net/item/neotericthe-ultimate-under-construction-page/67920">NEOTERIC—The Ultimate Under Construction Page!</a></h3>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/neotericthe-ultimate-under-construction-page/67920"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/Neoteric.jpg" alt="Neoteric" width="590" height="300"/></a>
</div>
<p>&ldquo;NEOTERIC is a clean single page &lsquo;Under Construction/Coming Soon&rsquo; template in 10 SKINS designed to keep your users up to date on your site’s progress.&rdquo;</p>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/neotericthe-ultimate-under-construction-page/67920"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/NeotericFullView.jpg" alt="Neoteric" width="600" height="288"/></a>
</div>
<h3>9. <a href="http://themeforest.net/item/under-construction-page-with-twitter-pie-graph/55525">Under Construction Page with Twitter &#038; Pie Graph!</a></h3>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/under-construction-page-with-twitter-pie-graph/55525"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/UnderConstruction.jpg" alt="Under Construction" width="590" height="300"/></a>
</div>
<p>&ldquo;Make sure your visitors know whats going on with this Under construction site template that features a feed of your latest tweets (which can be easily removed if you dont use twitter) and a pie chart that is easy to change to reflect your progress!&rdquo;</p>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/under-construction-page-with-twitter-pie-graph/55525"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/UnderConstructionFullView.jpg" alt="Under Construction" width="600" height="369"/></a>
</div>
<h3>10. <a href="http://themeforest.net/item/minimo-a-minimal-one-page-portfolio-theme/49798">Minimo &#8211; A minimal one page portfolio theme</a></h3>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/minimo-a-minimal-one-page-portfolio-theme/49798"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/Minimo.png" alt="Minimo" width="590" height="300"/></a>
</div>
<p>&ldquo;Minimo is a simple and attractive one page portfolio showcase theme. This theme is built using the 960.gs grid system framework, giving it a structured and professional look and features custom designed icons. Included is a form mail script, so the entire site works out of the box, simply add your destination email address.&rdquo;</p>
<div class="tutorial_image">
	<a href="http://themeforest.net/item/minimo-a-minimal-one-page-portfolio-theme/49798"><img src="http://nettuts.s3.amazonaws.com/504_solveProblems/images/MinimoFullView.jpg" alt="Minimo" width="600" height="386"/></a>
</div>
<h3>Conclusion</h3>
<p>When working on projects for your clients, what kinds of templates do you find yourself most in need of? Thanks for reading! </p>
<ul class="webroundup">
<li>Follow us on <a href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li>
</ul>
<p>
<script type="text/javascript"><!--digg_url = "post permalink (not digg url)"; // -->
</script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>

<p><a href="http://feedads.g.doubleclick.net/~a/T_dJOYQ6W94WIwv51t26UJCeV8U/0/da"><img src="http://feedads.g.doubleclick.net/~a/T_dJOYQ6W94WIwv51t26UJCeV8U/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/T_dJOYQ6W94WIwv51t26UJCeV8U/1/da"><img src="http://feedads.g.doubleclick.net/~a/T_dJOYQ6W94WIwv51t26UJCeV8U/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=N_enMJLGFa0:wWy4rPjq61Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=N_enMJLGFa0:wWy4rPjq61Y:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=N_enMJLGFa0:wWy4rPjq61Y:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=N_enMJLGFa0:wWy4rPjq61Y:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=N_enMJLGFa0:wWy4rPjq61Y:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=N_enMJLGFa0:wWy4rPjq61Y:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=N_enMJLGFa0:wWy4rPjq61Y:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=N_enMJLGFa0:wWy4rPjq61Y:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/N_enMJLGFa0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/articles/web-roundups/10-templates-that-solve-problems-for-web-developers/feed/</wfw:commentRss>
		<slash:comments>56</slash:comments>
		<feedburner:origLink>http://net.tutsplus.com/articles/web-roundups/10-templates-that-solve-problems-for-web-developers/</feedburner:origLink></item>
		<item>
		<title>You Don’t Know Anything About Regular Expressions: A Complete Guide</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/l6afNawrBb4/</link>
		<comments>http://net.tutsplus.com/tutorials/javascript-ajax/you-dont-know-anything-about-regular-expressions/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 10:30:28 +0000</pubDate>
		<dc:creator>Jeffrey Way</dc:creator>
				<category><![CDATA[JavaScript & AJAX]]></category>
		<category><![CDATA[Screencasts]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[regular expressions]]></category>
		<category><![CDATA[video tutorial]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=7869</guid>
		<description><![CDATA[<img src="http://nettuts.s3.amazonaws.com/503_regex/200x200.png" alt="You Don't Know Anything About Regular Expressions" />]]></description>
			<content:encoded><![CDATA[<p>
Regular expressions can be scary&#8230;really scary. Fortunately, once you memorize what each symbol represents, the fear quickly subsides. If you fit the title of this article, there&#8217;s much to learn! Let&#8217;s get started.
</p>
<p><span id="more-7869"></span></p>
<h3>Section 1: Learning the Basics</h3>
<p>
The key to learning how to effectively use regular expressions is to just take a day and memorize all of the symbols. This is the best advice I can possibly offer. Sit down, create some flash cards, and just memorize them! Here are the most common:
</p>
<ul>
<li><strong>. </strong> &#8211; Matches any character, except for line breaks if dotall is false. </li>
<li><strong> * </strong> &#8211; Matches 0 or more of the preceding character. </li>
<li><strong> + </strong> &#8211; Matches 1 or more of the preceding character. </li>
<li><strong> ? </strong> &#8211; Preceding character is optional. Matches 0 or 1 occurrence. </li>
<li><strong> \d </strong> &#8211; Matches any single digit </li>
<li><strong> \w </strong> &#8211; Matches any word character (alphanumeric &#038; underscore). </li>
<li><strong> [XYZ] </strong> &#8211; Matches any single character from the character class. </li>
<li><strong> [XYZ]+ </strong> &#8211; Matches one or more of any of the characters in the set.  </li>
<li><strong> $ </strong> &#8211; Matches the end of the string. </li>
<li><strong> ^ </strong> &#8211; Matches the beginning of a string. </li>
<li><strong> [^a-z] </strong> &#8211; When inside of a character class, the ^ means NOT; in this case, match anything that is NOT a lowercase letter. </li>
<li>
</ul>
<p>Yep &#8211; it&#8217;s not fun, but just memorize them. You&#8217;ll be thankful if you do! </p>
<h4>Tools </h4>
<p>
You can be certain that you&#8217;ll want to rip your hair out at one point or another when an expression doesn&#8217;t work, no matter how much it should &#8211; or you think it should! Downloading the <a href="http://gskinner.com/RegExr/">RegExr Desktop app</a> is essential, and is really quite fun to fool around with. In addition to real-time checking, it also offers a sidebar which details the definition and usage of every symbol. <a href="http://gskinner.com/RegExr/">Download it!</a>.
</p>
<div class="tutorial_image">
<a href="http://gskinner.com/RegExr/"><br />
   <img src="http://nettuts.s3.amazonaws.com/503_regex/regexr.jpg" alt="Regexr" /><br />
</a>
</div>
<h3>Section 2: Regular Expressions for Dummies: Screencast Series </h3>
<p>
The next step is to learn how to actually use these symbols! If video is your preference, you&#8217;re in luck! Watch the five lesson video series, <a href="http://net.tutsplus.com/videos/screencasts/regular-expressions-for-dummies-screencast-series/">&#8220;Regular Expressions for Dummies.&#8221;</a>
</p>
<div class="tutorial_image">
<a href="http://nettuts.s3.amazonaws.com/503_regex/dummies.png"><br />
   <img src="http://nettuts.s3.amazonaws.com/503_regex/dummies.png" alt="Regular Expressions for Dummies" /><br />
</a>
</div>
<h3>Section 3: Regular Expressions and JavaScript </h3>
<div class="tutorial_image">
<a href="http://nettuts.s3.amazonaws.com/503_regex/regex.zip"><img src="http://nettuts.com/wp-content/themes/nettuts/site_images/button_src_nm.jpg"></a>
</div>
<p>
In this final section, we&#8217;ll review a handful of the most important JavaScript methods for working with regular expressions.
</p>
<h3> 1. Test() </h3>
<p>
This one accepts a single string parameter and returns a boolean indicating whether or not a match has been found. If you don&#8217;t necessarily need to perform an operation with the a specific matched result &#8211; for instance, when validating a username &#8211; &#8220;test&#8221; will do the job just fine.
</p>
<h4>Example </h4>
<pre name="code" class="js">
var username = 'JohnSmith';
alert(/[A-Za-z_-]+/.test(username)); // returns true
</pre>
<p>Above, we begin by declaring a regular expression which only allows upper and lower case letters, an underscore, and a dash. We wrap these accepted characters within brackets, which designates a <strong>character class</strong>. The &#8220;+&#8221; symbol, which proceeds it, signifies that we&#8217;re looking for one or more of any of the preceding characters. We then test that pattern against our variable, &#8220;JohnSmith.&#8221; Because there was a match, the browser will display an alert box with the value, &#8220;true.&#8221;
</p>
<h3> 2. Split() </h3>
<p>
You&#8217;re most likely already familiar with the split method. It accepts a single regular expression which represents where the &#8220;split&#8221; should occur. <em>Please note that we can also use a string if we&#8217;d prefer.</em>
</p>
<pre name="code" class="js">
var str = 'this is my string';
alert(str.split(/\s/)); // alerts "this, is, my, string"
</pre>
<p>
By passing &#8220;\s&#8221; &#8211; representing a single space &#8211; we&#8217;ve now split our string into an array. If you need to access one particular value, just append the desired index.
</p>
<pre name="code" class="js">
var str = 'this is my this string';
alert(str.split(/\s/)[3]); // alerts "string"
</pre>
<h3>3.  Replace() </h3>
<p>
As you might expect, the &#8220;replace&#8221; method allows you to replace a certain block of text, represented by a string or regular expression, with a different string.
</p>
<h4>Example </h4>
<p> If we wanted to change the string &#8220;Hello, World&#8221; to &#8220;Hello, Universe,&#8221; we could do the following: </p>
<pre name="code" class="js">
var someString = 'Hello, World';
someString = someString.replace(/World/, 'Universe');
alert(someString); // alerts "Hello, Universe"
</pre>
<p>It should be noted that, for this simple example, we could have simply used .replace(&#8217;World&#8217;, &#8216;Universe&#8217;). Also, using the replace method does not automatically overwrite the value the variable, we must reassign the returned value back to the variable, someString.  </p>
<h4>Example 2</h4>
<p>For another example, let&#8217;s imagine that we wish to perform some elementary security precautions when a user signs up for our fictional site. Perhaps we want to take their username and remove any symbols, quotation marks, semi-colons, etc. Performing such a task is trivial with JavaScript and regular expressions.
</p>
<pre name="code" class="js">
var username = 'J;ohnSmith;@%';
username = username.replace(/[^A-Za-z\d_-]+/, '');
alert(username); // JohnSmith;@%
</pre>
<p>
Given the produced alert value, one might assume that there was an error in our code (which we&#8217;ll review shortly). However, this is not the case. If you&#8217;ll notice, the semi-colon immediately after the &#8220;J&#8221; was removed as expected. To tell the engine to continue searching the string for more matches, we add a &#8220;g&#8221; directly after our closing forward-slash; this modifier, or <strong>flag</strong>, stands for &#8220;global.&#8221; Our revised code should now look like so:
</p>
<pre name="code" class="js">
var username = 'J;ohnSmith;@%';
username = username.replace(/[^A-Za-z\d_-]+/g, '');
alert(username); // alerts JohnSmith
</pre>
<p>Now, the regular expression searches the ENTIRE string and replaces all necessary characters. To review the actual expression &#8211; <strong> .replace(/[^A-Za-z\d_-]+/g, &#8221;); </strong> &#8211; it&#8217;s important to notice the carot symbol inside of the brackets. When placed within a character class, this means &#8220;find anything that IS NOT&#8230;&#8221; Now, if we re-read, it says, find anything that is NOT a letter, number (represented by \d), an underscore, or a dash; if you find a match, replace it with nothing, or, in effect, delete the character entirely.
</p>
<h3> 4. Match() </h3>
<p>
Unlike the &#8220;test&#8221; method, &#8220;match()&#8221; will return an array containing each match found.
</p>
<h4>Example </h4>
<pre name="code" class="js">
var name = 'JeffreyWay';
alert(name.match(/e/)); // alerts "e"
</pre>
<p>
The code above will alert a single &#8220;e.&#8221; However, notice that there are actually two e&#8217;s in the string &#8220;JeffreyWay.&#8221; We, once again, must use the &#8220;g&#8221; modifier to declare a &#8220;<strong>g</strong>lobal search. </p>
<pre name="code" class="js">
var name = 'JeffreyWay';
alert(name.match(/e/g)); // alerts "e,e"
</pre>
<p>If we then want to alert one of those specific values with the array, we can reference the desired index after the parentheses. </p>
<pre name="code" class="js">
var name = 'JeffreyWay';
alert(name.match(/e/g)[1]); // alerts "e"
</pre>
<h4>Example 2</h4>
<p>Let&#8217;s review another example to ensure that we understand it correctly. </p>
<pre name="code" class="js">
var string = 'This is just a string with some 12345 and some !@#$ mixed in.';
alert(string.match(/[a-z]+/gi)); // alerts "This,is,just,a,string,with,some,and,some,mixed,in"
</pre>
<p>
Within the regular expression, we created a pattern which matches one or more upper or lowercase letters &#8211; thanks to the &#8220;i&#8221; modifier. We also are appending the &#8220;g&#8221; to declare a global search. The code above will alert &#8220;This,is,just,a,string,with,some,and,some,mixed,in.&#8221; If we then wanted to trap one of these values within the array inside of a variable, we just reference the correct index.
</p>
<pre name="code" class="js">
var string = 'This is just a string with some 12345 and some !@#$ mixed in.';
var matches = string.match(/[a-z]+/gi);
alert(matches[2]); // alerts "just"
</pre>
<h3>Splitting an Email Address</h3>
<p>
Just for practice, let&#8217;s try to split an email address &#8211; nettuts@tutsplus.com &#8211; into its respective username and domain name: &#8220;nettuts,&#8221; and &#8220;tutsplus.&#8221;
</p>
<pre name="code" class="js">
var email = 'nettuts@tutsplus.com';
alert(email.replace(/([a-z\d_-]+)@([a-z\d_-]+)\.[a-z]{2,4}/ig, '$1, $2')); // alerts "nettuts, tutsplus"
</pre>
<p>
If you&#8217;re brand new to regular expressions, the code above might look a bit daunting. Don&#8217;t worry, it did for all of us when we first started. Once you break it down into subsets though, it&#8217;s really quite simple. Let&#8217;s take it piece by piece. </p>
<pre name="code" class="js">
.replace(/([a-z\d_-]+)
</pre>
<p>
Starting from the middle, we search for any letter, number, underscore, or dash, and match one ore more of them (+). We&#8217;d like to access the value of whatever is matched here, so we wrap it within parentheses. That way, we can reference this matched set later! </p>
<pre name="code" class="js">
@([a-z\d_-]+)
</pre>
<p>
Immediately following the preceding match, find the @ symbol, and then another set of one or more letters, numbers, underscore, and dashes. Once again, we wrap that set within parentheses in order to access it later. </p>
<pre name="code" class="js">
\.[a-z]{2,4}/ig,
</pre>
<p>Continuing on, we find a single period (we must escape it with &#8220;\&#8221; due to the fact that, in regular expressions, it matches any character (sometimes excluding a line break). The last part is to find the &#8220;.com.&#8221; We know that the majority, if not all, domains will have a suffix range of two &#8211; four characters (com, edu, net, name, etc.). If we&#8217;re aware of that specific range, we can forego using a more generic symbol like * or +, and instead wrap the two numbers within curly braces, representing the minimum and maximum, respectively.
</p>
<pre name="code" class="js">
 '$1, $2')
</pre>
<p>This last part represents the second parameter of the replace method, or what we&#8217;d like to replace the matched sets with. Here, we&#8217;re using $1 and $2 to refer to what was stored within the first and second sets of parentheses, respectively. In this particular instances, $1 refers to &#8220;nettuts,&#8221; and $2 refers to &#8220;tutsplus.&#8221;  </p>
<h3>Creating our Own Location Object </h3>
<p>
For our final project, we&#8217;ll replicate the location object. For those unfamiliar, the location object provides you with information about the current page: the href, host, port, protocol, etc. Please note that this is purely for practice&#8217;s sake. In a real world site, just use the preexisting location object!
</p>
<p>We first begin by creating our location function, which accepts a single parameter representing the url that we wish to &#8220;decode;&#8221; we&#8217;ll call it &#8220;loc.&#8221; </p>
<pre name="code" class="js">
function loc(url) { }
</pre>
<p> Now, we can call it like so, and pass in a gibberish url : </p>
<pre name="code" class="js">
var l = loc('http://www.somesite.com?somekey=somevalue&#038;anotherkey=anothervalue#theHashGoesHere');
</pre>
<p>Next, we need to return an object which contains a handful of methods. </p>
<pre name="code" class="js">
function loc(url) {
	return {

	}
}
</pre>
<h4>Search</h4>
<p>Though we won&#8217;t create all of them, we&#8217;ll mimic a handful or so. The first one will be &#8220;search.&#8221; Using regular expressions, we&#8217;ll need to search the url and return everything within the querystring. </p>
<pre name="code" class="js">
return {
	search : function() {
		return url.match(/\?(.+)/i)[1];
               // returns "somekey=somevalue&#038;anotherkey=anothervalue#theHashGoesHere"
	}
}
</pre>
<p>Above, we take the passed in url, and try to match our regular expressions against it. This expression searches through the string for the question mark, representing the beginning of our querystring. At this point, we need to trap the remaining characters, which is why the <em>(.+)</em> is wrapped within parentheses. Finally, we need to return only that block of characters, so we use [1] to target it.</p>
<h4>Hash </h4>
<p>
Now we&#8217;ll create another method which returns the hash of the url, or anything after the pound sign.
</p>
<pre name="code" class="js">
hash : function() {
	return url.match(/#(.+)/i)[1]; // returns "theHashGoesHere"
},
</pre>
<p>This time, we search for the pound sign, and, once again, trap the following characters within parentheses so that we can refer to only that specific subset &#8211; with [1]. </p>
<h4>Protocol</h4>
<p>The protocol method should return, as you would guess, the protocol used by the page &#8211; which is generally &#8220;http&#8221; or &#8220;https.&#8221; </p>
<pre name="code" class="js">
protocol : function() {
	return url.match(/(ht|f)tps?:/i)[0]; // returns 'http:'
},
</pre>
<p>This one is slightly more tricky, only because there are a few choices to compensate for: http, https, and ftp. Though we could do something like &#8211; <em>(http|https|ftp)</em> &#8211; it would be cleaner to do: <em>(ht|f)tps?</em> <br />
This designates that we should first find either an &#8220;ht&#8221; or the &#8220;f&#8221; character. Next, we match the &#8220;tp&#8221; characters. The final &#8220;s&#8221; should be optional, so we append a question mark, which signifies that there may be zero or one instance of the preceding character. Much nicer. </p>
<h4>Href </h4>
<p>
For the sake of brevity, this will be our last one. It will simply return the url of the page.
</p>
<pre name="code" class="js">
href : function() {
	return url.match(/(.+\.[a-z]{2,4})/ig); // returns "http://www.somesite.com"
}
</pre>
<p>Here we&#8217;re matching all characters up to the point where we find a period followed by two-four characters (representing com, au, edu, name, etc.). It&#8217;s important to realize that we can make these expressions as complicated or as simple as we&#8217;d like. It all depends on how strict we must be. </p>
<h4> Our Final Simple Function: </h4>
<pre name="code" class="js">
function loc(url) {
	return {
		search : function() {
			return url.match(/\?(.+)/i)[1];
		},

		hash : function() {
			return url.match(/#(.+)/i)[1];
		},

		protocol : function() {
			return url.match(/(ht|f)tps?:/)[0];
		},

		href : function() {
			return url.match(/(.+\.[a-z]{2,4})/ig);
		}
	}
}
</pre>
<p>With that function created, we can easily alert each subsection by doing: </p>
<pre name="code" class="js">
var l = loc('http://www.net.tutsplus.edu?key=value#hash');

alert(l.href()); // http://www.net.tutsplus.com
alert(l.protocol()); // http:

...etc.
</pre>
<h3>Conclusion</h3>
<p>
Thanks for reading! I&#8217;m <a href="http://www.jeffrey-way.com">Jeffrey Way</a>&#8230;signing off.
</p>
<ul class="webroundup">
<li>Follow us on <a href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li>
</ul>
<p>
<script type="text/javascript"><!--digg_url = "post permalink (not digg url)"; // -->
</script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>

<p><a href="http://feedads.g.doubleclick.net/~a/PkQOTBpcg_BNbbNoi8mhIuUbpKE/0/da"><img src="http://feedads.g.doubleclick.net/~a/PkQOTBpcg_BNbbNoi8mhIuUbpKE/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/PkQOTBpcg_BNbbNoi8mhIuUbpKE/1/da"><img src="http://feedads.g.doubleclick.net/~a/PkQOTBpcg_BNbbNoi8mhIuUbpKE/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=l6afNawrBb4:KvzhwHgqyR4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=l6afNawrBb4:KvzhwHgqyR4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=l6afNawrBb4:KvzhwHgqyR4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=l6afNawrBb4:KvzhwHgqyR4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=l6afNawrBb4:KvzhwHgqyR4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=l6afNawrBb4:KvzhwHgqyR4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=l6afNawrBb4:KvzhwHgqyR4:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=l6afNawrBb4:KvzhwHgqyR4:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/l6afNawrBb4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/tutorials/javascript-ajax/you-dont-know-anything-about-regular-expressions/feed/</wfw:commentRss>
		<slash:comments>44</slash:comments>
		<feedburner:origLink>http://net.tutsplus.com/tutorials/javascript-ajax/you-dont-know-anything-about-regular-expressions/</feedburner:origLink></item>
		<item>
		<title>Build an RSS Feed Reader with jQuery and jGFeed: New Plus Tutorial</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/IX7WY0tcJ4o/</link>
		<comments>http://net.tutsplus.com/tutorials/plus-tutorials-2/build-an-rss-feed-reader-with-jquery-and-jgfeed-new-plus-tutorial/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 16:30:51 +0000</pubDate>
		<dc:creator>Luis Montero</dc:creator>
				<category><![CDATA[Plus]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jqfeed]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery plugin]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=7941</guid>
		<description><![CDATA[<img src="http://nettutsplus.s3.amazonaws.com/41_jqfeed/preview.jpg" alt="Build an RSS Feed Reader with jQuery and jGFeed: New Plus Tutorial" />]]></description>
			<content:encoded><![CDATA[<p>
This PLUS tutorial and screencast will demonstrate how to use jQuery and the jGFeed plugin to fetch news feeds remotely and write the results into the existing markup. jGFeed is a jQuery plugin that allows you to retrieve &#8216;any&#8217; RSS feed from &#8216;any&#8217; host and return a JSON object for easy usage. <a href="http://net.tutsplus.com/about/join-plus/">Become a PLUS member.</a>
</p>
<p><span id="more-7941"></span></p>
<div class="tutorial_image">
<a href="http://net.tutsplus.com/about/join-plus/"><br />
   <img src="http://nettutsplus.s3.amazonaws.com/41_jqfeed/4.png" alt="Example" /><br />
</a>
</div>
<div class="tutorial_image">
<a href="http://net.tutsplus.com/about/join-plus/"><br />
   <img src="http://nettutsplus.s3.amazonaws.com/41_jqfeed/6.png" alt="Example" /><br />
</a>
</div>
<div class="tutorial_image">
<a href="http://net.tutsplus.com/about/join-plus/"><br />
   <img src="http://nettutsplus.s3.amazonaws.com/41_jqfeed/7.png" alt="Example" /><br />
</a>
</div>
<h3>Join Tuts Plus</h3>
<div class="tutorial_image"><img src="http://miscfiles.s3.amazonaws.com/banners/nettuts_468x60.jpg" border=0 alt="NETTUTS+ Screencasts and Bonus Tutorials" width=468 height=60></div>
<p>
For those unfamiliar, the family of TUTS sites runs a premium membership service called <a href="http://www.tutsplus.com">&#8220;TUTSPLUS&#8221;</a>. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from <a href="http://net.tutsplus.com">Nettuts+</a>, <a href="psd.tutsplus.com">Psdtuts+</a>, <a href="ae.tutsplus.com">Aetuts+</a>, <a href="audio.tutsplus.com">Audiotuts+</a>, and <a href="vector.tutsplus.com">Vectortuts+!</a> For the price of a pizza, you&#8217;ll learn from some of the best minds in the business. <a href="http://net.tutsplus.com/about/join-plus/">Join today!</a> </p>
<ul class="webroundup">
<li>Subscribe to the <a href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for more daily web development tuts and articles.</li>
</ul>
<p>
<script type="text/javascript"><!--digg_url = "post permalink (not digg url)"; // -->
</script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>

<p><a href="http://feedads.g.doubleclick.net/~a/9s7WJGU-vTnr7INEtLs_sCPcBdc/0/da"><img src="http://feedads.g.doubleclick.net/~a/9s7WJGU-vTnr7INEtLs_sCPcBdc/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/9s7WJGU-vTnr7INEtLs_sCPcBdc/1/da"><img src="http://feedads.g.doubleclick.net/~a/9s7WJGU-vTnr7INEtLs_sCPcBdc/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=IX7WY0tcJ4o:_LOG561l0D8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=IX7WY0tcJ4o:_LOG561l0D8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=IX7WY0tcJ4o:_LOG561l0D8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=IX7WY0tcJ4o:_LOG561l0D8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=IX7WY0tcJ4o:_LOG561l0D8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=IX7WY0tcJ4o:_LOG561l0D8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=IX7WY0tcJ4o:_LOG561l0D8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=IX7WY0tcJ4o:_LOG561l0D8:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/IX7WY0tcJ4o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/tutorials/plus-tutorials-2/build-an-rss-feed-reader-with-jquery-and-jgfeed-new-plus-tutorial/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://net.tutsplus.com/tutorials/plus-tutorials-2/build-an-rss-feed-reader-with-jquery-and-jgfeed-new-plus-tutorial/</feedburner:origLink></item>
		<item>
		<title>Top 20+ MySQL Best Practices</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/8k9IPLbvIjg/</link>
		<comments>http://net.tutsplus.com/tutorials/other/top-20-mysql-best-practices/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 10:30:47 +0000</pubDate>
		<dc:creator>Burak Guzel</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[my sql]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=7855</guid>
		<description><![CDATA[<img src="http://nettuts.s3.amazonaws.com/500_mysql/preview.jpg" alt="20 MySQL Best Practices for Beginners" width="200" height="200"/>]]></description>
			<content:encoded><![CDATA[<p>Database operations often tend to be the main bottleneck for most web applications today. It&#8217;s not only the DBA&#8217;s (database administrators) that have to worry about these performance issues. We as programmers need to do our part by structuring tables properly, writing optimized queries and better code. Here are some MySQL optimization techniques for programmers.</p>
<p><span id="more-7855"></span></p>
<h3>1. Optimize Your Queries For the Query Cache</h3>
<p>Most MySQL servers have query caching enabled. It&#8217;s one of the most effective methods of improving performance, that is quietly handled by the database engine. When the same query is executed multiple times, the result is fetched from the cache, which is quite fast.</p>
<p>The main problem is, it is so easy and hidden from the programmer, most of us tend to ignore it. Some things we do can actually prevent the query cache from performing its task.</p>
<pre name="code" class="php">
// query cache does NOT work
$r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()");

// query cache works!
$today = date("Y-m-d");
$r = mysql_query("SELECT username FROM user WHERE signup_date >= '$today'");
</pre>
<p>The reason query cache does not work in the first line is the usage of the CURDATE() function. This applies to all non-deterministic functions like NOW() and RAND() etc&#8230; Since the return result of the function can change, MySQL decides to disable query caching for that query. All we needed to do is to add an extra line of PHP before the query to prevent this from happening.</p>
<h3>2. EXPLAIN Your SELECT Queries</h3>
<p>Using the <a href="http://dev.mysql.com/doc/refman/5.0/en/explain.html">EXPLAIN</a> keyword can give you insight on what MySQL is doing to execute your query. This can help you spot the bottlenecks and other problems with your query or table structures.</p>
<p>The results of an EXPLAIN query will show you which indexes are being utilized, how the table is being scanned and sorted etc&#8230; </p>
<p>Take a SELECT query (preferably a complex one, with joins), and add the keyword EXPLAIN in front of it. You can just use phpmyadmin for this. It will show you the results in a nice table. For example, let&#8217;s say I forgot to add an index to a column, which I perform joins on:</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/500_mysql/unoptimized_explain.jpg" border="0" /></div>
<p>After adding the index to the group_id field:</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/500_mysql/optimized_explain.jpg" border="0" /></div>
<p>Now instead of scanning 7883 rows, it will only scan 9 and 16 rows from the 2 tables. A good rule of thumb is to multiply all numbers under the &#8220;rows&#8221; column, and your query performance will be somewhat proportional to the resulting number.</p>
<h3>3. LIMIT 1 When Getting a Unique Row</h3>
<p>Sometimes when you are querying your tables, you already know you are looking for just one row. You might be fetching a unique record, or you might just be just checking the existence of any number of records that satisfy your WHERE clause.</p>
<p>In such cases, adding LIMIT 1 to your query can increase performance. This way the database engine will stop scanning for records after it finds just 1, instead of going thru the whole table or index.</p>
<pre name="code" class="php">
// do I have any users from Alabama?

// what NOT to do:
$r = mysql_query("SELECT * FROM user WHERE state = 'Alabama'");
if (mysql_num_rows($r) > 0) {
	// ...
}

// much better:
$r = mysql_query("SELECT 1 FROM user WHERE state = 'Alabama' LIMIT 1");
if (mysql_num_rows($r) > 0) {
	// ...
}
</pre>
<h3>4. Index the Search Fields</h3>
<p>Indexes are not just for the primary keys or the unique keys. If there are any columns in your table that you will search by, you should almost always index them.</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/500_mysql/search_index.jpg" border="0" /></div>
<p>As you can see, this rule also applies on a partial string search like &#8220;last_name LIKE &#8216;a%&#8217;&#8221;. When searching from the beginning of the string, MySQL is able to utilize the index on that column.</p>
<p>You should also understand which kinds of searches can not use the regular indexes. For instance, when searching for a word (e.g. &#8220;WHERE post_content LIKE &#8216;%apple%&#8217;&#8221;), you will not see a benefit from a normal index. You will be better off using <a href="http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html">mysql fulltext search</a> or building your own indexing solution.</p>
<h3>5. Index and Use Same Column Types for Joins</h3>
<p>If your application contains many JOIN queries, you need to make sure that the columns you join by are indexed on both tables. This affects how MySQL internally optimizes the join operation.</p>
<p>Also, the columns that are joined, need to be the same type. For instance, if you join a DECIMAL column, to an INT column from another table, MySQL will be unable to use at least one of the indexes. Even the character encodings need to be the same type for string type columns.</p>
<pre name="code" class="php">
// looking for companies in my state
$r = mysql_query("SELECT company_name FROM users
	LEFT JOIN companies ON (users.state = companies.state)
	WHERE users.id = $user_id");

// both state columns should be indexed
// and they both should be the same type and character encoding
// or MySQL might do full table scans
</pre>
<h3>6. Do Not ORDER BY RAND()</h3>
<p>This is one of those tricks that sound cool at first, and many rookie programmers fall for this trap. You may not realize what kind of terrible bottleneck you can create once you start using this in your queries.</p>
<p>If you really need random rows out of your results, there are much better ways of doing it. Granted it takes additional code, but you will prevent a bottleneck that gets exponentially worse as your data grows. The problem is, MySQL will have to perform RAND() operation (which takes processing power) for every single row in the table before sorting it and giving you just 1 row.</p>
<pre name="code" class="php">
// what NOT to do:
$r = mysql_query("SELECT username FROM user ORDER BY RAND() LIMIT 1");

// much better:

$r = mysql_query("SELECT count(*) FROM user");
$d = mysql_fetch_row($r);
$rand = mt_rand(0,$d[0] - 1);

$r = mysql_query("SELECT username FROM user LIMIT $rand, 1");
</pre>
<p>So you pick a random number less than the number of results and use that as the offset in your LIMIT clause.</p>
<h3>7. Avoid SELECT *</h3>
<p>The more data is read from the tables, the slower the query will become. It increases the time it takes for the disk operations. Also when the database server is separate from the web server, you will have longer network delays due to the data having to be transferred between the servers.</p>
<p>It is a good habit to always specify which columns you need when you are doing your SELECT&#8217;s.</p>
<pre name="code" class="php">
// not preferred
$r = mysql_query("SELECT * FROM user WHERE user_id = 1");
$d = mysql_fetch_assoc($r);
echo "Welcome {$d['username']}";

// better:
$r = mysql_query("SELECT username FROM user WHERE user_id = 1");
$d = mysql_fetch_assoc($r);
echo "Welcome {$d['username']}";

// the differences are more significant with bigger result sets
</pre>
<h3>8. Almost Always Have an id Field</h3>
<p>In every table have an id column that is the PRIMARY KEY, AUTO_INCREMENT and one of the flavors of INT. Also preferably UNSIGNED, since the value can not be negative.</p>
<p>Even if you have a users table that has a unique username field, do not make that your primary key. VARCHAR fields as primary keys are slower. And you will have a better structure in your code by referring to all users with their id&#8217;s internally.</p>
<p>There are also behind the scenes operations done by the MySQL engine itself, that uses the primary key field internally. Which become even more important, the more complicated the database setup is. (clusters, partitioning etc&#8230;).</p>
<p>One possible exception to the rule are the &#8220;association tables&#8221;, used for the many-to-many type of associations between 2 tables. For example a &#8220;posts_tags&#8221; table that contains 2 columns: post_id, tag_id, that is used for the relations between two tables named &#8220;post&#8221; and &#8220;tags&#8221;. These tables can have a PRIMARY key that contains both id fields.</p>
<h3>9. Use ENUM over VARCHAR</h3>
<p><a href="http://dev.mysql.com/doc/refman/5.0/en/enum.html">ENUM</a> type columns are very fast and compact. Internally they are stored like TINYINT, yet they can contain and display string values. This makes them a perfect candidate for certain fields.</p>
<p>If you have a field, which will contain only a few different kinds of values, use ENUM instead of VARCHAR. For example, it could be a column named &#8220;status&#8221;, and only contain values such as &#8220;active&#8221;, &#8220;inactive&#8221;, &#8220;pending&#8221;, &#8220;expired&#8221; etc&#8230;</p>
<p>There is even a way to get a &#8220;suggestion&#8221; from MySQL itself on how to restructure your table. When you do have a VARCHAR field, it can actually suggest you to change that column type to ENUM instead. This done using the PROCEDURE ANALYSE() call. Which brings us to:</p>
<h3>10. Get Suggestions with PROCEDURE ANALYSE()</h3>
<p><a href="http://dev.mysql.com/doc/refman/5.0/en/procedure-analyse.html">PROCEDURE ANALYSE()</a> will let MySQL analyze the columns structures and the actual data in your table to come up with certain suggestions for you. It is only useful if there is actual data in your tables because that plays a big role in the decision making.</p>
<p>For example, if you created an INT field for your primary key, however do not have too many rows, it might suggest you to use a MEDIUMINT instead. Or if you are using a VARCHAR field, you might get a suggestion to convert it to ENUM, if there are only few unique values.</p>
<p>You can also run this by clicking the &#8220;Propose table structure&#8221; link in phpmyadmin, in one of your table views.</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/500_mysql/suggestions.jpg" border="0" /></div>
<p>Keep in mind these are only suggestions. And if your table is going to grow bigger, they may not even be the right suggestions to follow. The decision is ultimately yours.</p>
<h3>11. Use NOT NULL If You Can</h3>
<p>Unless you have a very specific reason to use a NULL value, you should always set your columns as NOT NULL.</p>
<p>First of all, ask yourself if there is any difference between having an empty string value vs. a NULL value (for INT fields: 0 vs. NULL). If there is no reason to have both, you do not need a NULL field. (Did you know that Oracle considers NULL and empty string as being the same?)</p>
<p>NULL columns require additional space and they can add complexity to your comparison statements. Just avoid them when you can. However, I understand some people might have very specific reasons to have NULL values, which is not always a bad thing.</p>
<p>From MySQL docs:</p>
<blockquote><p>&#8220;NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.&#8221;</p></blockquote>
<h3>12. Prepared Statements</h3>
<p>There are multiple benefits to using prepared statements, both for performance and security reasons.</p>
<p>Prepared Statements will filter the variables you bind to them by default, which is great for protecting your application against SQL injection attacks. You can of course filter your variables manually too, but those methods are more prone to human error and forgetfulness by the programmer. This is less of an issue when using some kind of framework or ORM.</p>
<p>Since our focus is on performance, I should also mention the benefits in that area. These benefits are more significant when the same query is being used multiple times in your application. You can assign different values to the same prepared statement, yet MySQL will only have to parse it once.</p>
<p>Also latest versions of MySQL transmits prepared statements in a native binary form, which are more efficient and can also help reduce network delays.</p>
<p>There was a time when many programmers used to avoid prepared statements on purpose, for a single important reason. They were not being cached by the MySQL query cache. But since sometime around version 5.1, query caching is supported too.</p>
<p>To use prepared statements in PHP you check out the <a href="http://php.net/manual/en/book.mysqli.php">mysqli extension</a> or use a database abstraction layer like <a href="http://us.php.net/manual/en/book.pdo.php">PDO</a>.</p>
<pre name="code" class="php">
// create a prepared statement
if ($stmt = $mysqli->prepare("SELECT username FROM user WHERE state=?")) {

	// bind parameters
    $stmt->bind_param("s", $state);

	// execute
    $stmt->execute();

	// bind result variables
    $stmt->bind_result($username);

	// fetch value
    $stmt->fetch();

    printf("%s is from %s\n", $username, $state);

    $stmt->close();
}
</pre>
<h3>13. Unbuffered Queries</h3>
<p>Normally when you perform a query from a script, it will wait for the execution of that query to finish before it can continue. You can change that by using unbuffered queries.</p>
<p>There is a great explanation in the PHP docs for the <a href="http://php.net/manual/en/function.mysql-unbuffered-query.php">mysql_unbuffered_query()</a> function:</p>
<blockquote><p>&#8220;mysql_unbuffered_query() sends the SQL query query to MySQL without automatically fetching and buffering the result rows as mysql_query() does. This saves a considerable amount of memory with SQL queries that produce large result sets, and you can start working on the result set immediately after the first row has been retrieved as you don&#8217;t have to wait until the complete SQL query has been performed.&#8221;</p></blockquote>
<p>However, it comes with certain limitations. You have to either read all the rows or call <a href="http://us2.php.net/manual/en/function.mysql-free-result.php">mysql_free_result()</a> before you can perform another query. Also you are not allowed to use <a href="http://us2.php.net/manual/en/function.mysql-num-rows.php">mysql_num_rows()</a> or <a href="http://us2.php.net/manual/en/function.mysql-data-seek.php">mysql_data_seek()</a> on the result set.</p>
<h3>14. Store IP Addresses as UNSIGNED INT</h3>
<p>Many programmers will create a VARCHAR(15) field without realizing they can actually store IP addresses as integer values. With an INT you go down to only 4 bytes of space, and have a fixed size field instead.</p>
<p>You have to make sure your column is an UNSIGNED INT, because IP Addresses use the whole range of a 32 bit unsigned integer.</p>
<p>In your queries you can use the <a href="http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-aton">INET_ATON()</a> to convert and IP to an integer, and <a href="http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-ntoa">INET_NTOA()</a> for vice versa. There are also similar functions in PHP called <a href="http://php.net/manual/en/function.ip2long.php">ip2long()</a> and <a href="http://us.php.net/manual/en/function.long2ip.php">long2ip()</a>.</p>
<pre name="code" class="php">
$r = "UPDATE users SET ip = INET_ATON('{$_SERVER['REMOTE_ADDR']}') WHERE user_id = $user_id";
</pre>
<h3>15. Fixed-length (Static) Tables are Faster</h3>
<p>When every single column in a table is &#8220;fixed-length&#8221;, the table is also considered <a href="http://dev.mysql.com/doc/refman/5.1/en/static-format.html">&#8220;static&#8221; or &#8220;fixed-length&#8221;</a>. Examples of column types that are NOT fixed-length are: VARCHAR, TEXT, BLOB. If you include even just 1 of these types of columns, the table ceases to be fixed-length and has to be handled differently by the MySQL engine.</p>
<p>Fixed-length tables can improve performance because it is faster for MySQL engine to seek through the records. When it wants to read a specific row in a table, it can quickly calculate the position of it. If the row size is not fixed, every time it needs to do a seek, it has to consult the primary key index.</p>
<p>They are also easier to cache and easier to reconstruct after a crash. But they also can take more space. For instance, if you convert a VARCHAR(20) field to a CHAR(20) field, it will always take 20 bytes of space regardless of what is it in.</p>
<p>By using &#8220;Vertical Partitioning&#8221; techniques, you can separate the variable-length columns to a separate table. Which brings us to:</p>
<h3>16. Vertical Partitioning</h3>
<p>Vertical Partitioning is the act of splitting your table structure in a vertical manner for optimization reasons.</p>
<p><strong>Example 1</strong>: You might have a users table that contains home addresses, that do not get read often. You can choose to split your table and store the address info on a separate table. This way your main users table will shrink in size. As you know, smaller tables perform faster.</p>
<p><strong>Example 2</strong>: You have a &#8220;last_login&#8221; field in your table. It updates every time a user logs in to the website. But every update on a table causes the query cache for that table to be flushed. You can put that field into another table to keep updates to your users table to a minimum.</p>
<p>But you also need to make sure you don&#8217;t constantly need to join these 2 tables after the partitioning or you might actually suffer performance decline.</p>
<h3>17. Split the Big DELETE or INSERT Queries</h3>
<p>If you need to perform a big DELETE or INSERT query on a live website, you need to be careful not to disturb the web traffic. When a big query like that is performed, it can lock your tables and bring your web application to a halt.</p>
<p>Apache runs many parallel processes/threads. Therefore it works most efficiently when scripts finish executing as soon as possible, so the servers do not experience too many open connections and processes at once that consume resources, especially the memory.</p>
<p>If you end up locking your tables for any extended period of time (like 30 seconds or more), on a high traffic web site, you will cause a process and query pileup, which might take a long time to clear or even crash your web server.</p>
<p>If you have some kind of maintenance script that needs to delete large numbers of rows, just use the LIMIT clause to do it in smaller batches to avoid this congestion.</p>
<pre name="code" class="php">
while (1) {
	mysql_query("DELETE FROM logs WHERE log_date <= '2009-10-01' LIMIT 10000");
	if (mysql_affected_rows() == 0) {
		// done deleting
		break;
	}
	// you can even pause a bit
	usleep(50000);
}
</pre>
<h3>18. Smaller Columns Are Faster</h3>
<p>With database engines, disk is perhaps the most significant bottleneck. Keeping things smaller and more compact is usually helpful in terms of performance, to reduce the amount of disk transfer.</p>
<p>MySQL docs have a list of <a href="http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html">Storage Requirements</a> for all data types.</p>
<p>If a table is expected to have very few rows, there is no reason to make the primary key an INT, instead of MEDIUMINT, SMALLINT or even in some cases TINYINT. If you do not need the time component, use DATE instead of DATETIME.</p>
<p>Just make sure you leave reasonable room to grow or you might end up like <a href="http://news.slashdot.org/article.pl?sid=06/11/09/1534204">Slashdot</a>.</p>
<h3>19. Choose the Right Storage Engine</h3>
<p>The two main storage engines in MySQL are MyISAM and InnoDB. Each have their own pros and cons.</p>
<p>MyISAM is good for read-heavy applications, but it doesn't scale very well when there are a lot of writes. Even if you are updating one field of one row, the whole table gets locked, and no other process can even read from it until that query is finished. MyISAM is very fast at calculating SELECT COUNT(*) types of queries.</p>
<p>InnoDB tends to be a more complicated storage engine and can be slower than MyISAM for most small applications. But it supports row-based locking, which scales better. It also supports some more advanced features such as transactions.</p>
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/myisam-storage-engine.html">MyISAM Storage Engine</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/innodb.html">InnoDB Storage Engine</a></li>
</ul>
<h3>20. Use an Object Relational Mapper</h3>
<p>By using an ORM (Object Relational Mapper), you can gain certain performance benefits. Everything an ORM can do, can be coded manually too. But this can mean too much extra work and require a high level of expertise.</p>
<p>ORM's are great for "Lazy Loading". It means that they can fetch values only as they are needed. But you need to be careful with them or you can end up creating to many mini-queries that can reduce performance.</p>
<p>ORM's can also batch your queries into transactions, which operate much faster than sending individual queries to the database.</p>
<p>Currently my favorite ORM for PHP is <a href="http://www.doctrine-project.org">Doctrine</a>. I wrote an article on how to <a href="http://www.phpandstuff.com/articles/codeigniter-doctrine-from-scratch-day-1-install-and-setup">install Doctrine with CodeIgniter</a>.</p>
<h3>21. Be Careful with Persistent Connections</h3>
<p>Persistent Connections are meant to reduce the overhead of recreating connections to MySQL. When a persistent connection is created, it will stay open even after the script finishes running. Since Apache reuses it's child processes, next time the process runs for a new script, it will reuse the same MySQL connection.</p>
<ul>
<li><a href="http://php.net/manual/en/function.mysql-pconnect.php">mysql_pconnect() in PHP</a></li>
</ul>
<p>It sounds great in theory. But from my personal experience (and many others), this features turns out to be not worth the trouble. You can have serious problems with connection limits, memory issues and so on.</p>
<p>Apache runs extremely parallel, and creates many child processes. This is the main reason that persistent connections do not work very well in this environment. Before you consider using the mysql_pconnect() function, consult your system admin.</p>
<ul class="webroundup">
<li>Follow us on <a href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li>
</ul>
<p>
<script type="text/javascript"><!--digg_url = "post permalink (not digg url)"; // -->
</script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>

<p><a href="http://feedads.g.doubleclick.net/~a/JDyD14sRHgLdTEtLwfSaKibOJao/0/da"><img src="http://feedads.g.doubleclick.net/~a/JDyD14sRHgLdTEtLwfSaKibOJao/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/JDyD14sRHgLdTEtLwfSaKibOJao/1/da"><img src="http://feedads.g.doubleclick.net/~a/JDyD14sRHgLdTEtLwfSaKibOJao/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=8k9IPLbvIjg:LpFqX5ucY7c:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=8k9IPLbvIjg:LpFqX5ucY7c:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=8k9IPLbvIjg:LpFqX5ucY7c:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=8k9IPLbvIjg:LpFqX5ucY7c:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=8k9IPLbvIjg:LpFqX5ucY7c:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=8k9IPLbvIjg:LpFqX5ucY7c:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=8k9IPLbvIjg:LpFqX5ucY7c:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=8k9IPLbvIjg:LpFqX5ucY7c:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/8k9IPLbvIjg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/tutorials/other/top-20-mysql-best-practices/feed/</wfw:commentRss>
		<slash:comments>114</slash:comments>
		<feedburner:origLink>http://net.tutsplus.com/tutorials/other/top-20-mysql-best-practices/</feedburner:origLink></item>
		<item>
		<title>Building an Image Gallery with Progressive Enhancement</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/6TMLfCr1QDM/</link>
		<comments>http://net.tutsplus.com/tutorials/javascript-ajax/building-an-image-gallery-with-progressive-enhancement/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 10:30:18 +0000</pubDate>
		<dc:creator>Andrew Burgess</dc:creator>
				<category><![CDATA[JavaScript & AJAX]]></category>
		<category><![CDATA[image gallery]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[progressive enhancement]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=7860</guid>
		<description><![CDATA[<img src="http://nettuts.s3.amazonaws.com/501_imagegallery/200.jpg" alt="Building an Image Gallery with Progressive Enhancement" />]]></description>
			<content:encoded><![CDATA[<p>Who doesn&#8217;t love to completely trick out their website with neat features? But what happens when your viewers aren&#8217;t using the latest browser, or they have JavaScript turned off? In today&#8217;s tutorial, you&#8217;ll learn how to create a image gallery that will work in almost all environments, using progressive enhancement techniques.</p>
<p><span id="more-7860"></span></p>
<div class="tutorial_image">
<a href="http://nettuts.s3.amazonaws.com/501_imagegallery/gallery.zip"><img src="http://nettuts.com/wp-content/themes/nettuts/site_images/button_src_nm.jpg"></a><br />
<a href="http://nettuts.s3.amazonaws.com/501_imagegallery/gallery/index.htm"><img src="http://nettuts.com/wp-content/themes/nettuts/site_images/button_demo_nm.jpg"></a>
</div>
<h3 id='introduction'>Introduction</h3>
<div class="tutorial_image">
   <img src="http://nettuts.s3.amazonaws.com/501_imagegallery/scatter.png" alt="Final Product" />
</div>
<p>So what exactly is progressive enhancement? Formally, it is this:</p>
<blockquote>
<p>Progressive enhancement is a strategy for web design that emphasizes accessibility, semantic markup, and external stylesheet and scripting technologies. Progressive enhancement uses web technologies in a layered fashion that allows everyone to access the basic content and functionality of a web page, using any browser or Internet connection, while also providing those with better bandwidth or more advanced browser software an enhanced version of the page. (<a href='http://en.wikipedia.org/wiki/Progressive_enhancement'>Wikipedia</a>).</p>
</blockquote>
<p>Progressive enhancement is the opposite of graceful degradation, where you build your site/app with all the features, and then make sure it looks good and functions decently in older browsers. With progressive enhancement, we&#8217;ll lay a solid foundation for our image gallery that will work no matter where you view it. Then, we&#8217;ll layer on eye-candy and functionality until we&#8217;ve got a good-looking, well-functioning image gallery. Let&#8217;s begin!</p>
<h3 id='what_were_after'>What we&#8217;re After</h3>
<p>Here&#8217;s what we want to end up with: if all the bells and whistles are turned on, we&#8217;ll be able to drag our images around to view them; it will be a very basic simulation of a stack of photos on your coffee table. When you click on one, it will slide open to reveal some details about the image. If JavaScript is turned off, we&#8217;ll have a nice grid of image to choose from; clicking them will take us to a page with a larger version of the image and the details. If there&#8217;s no CSS support, we&#8217;ll get an ugly (but working) list of the images.</p>
<p>Here&#8217;s a screen-shot of our final product:</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/501_imagegallery/final.png" alt="Screenshot of finished gallery"/></div>
<h3 id='laying_the_foundation_posh'>Laying the Foundation: POSH</h3>
<p>We start with some plain old semantic HTML. This is our foundation, since every browser out there is good at parsing HTML.</p>
<h4 id='indexhtm'>index.htm</h4>
<pre name="code" class="html">
&lt;!DOCTYPE html>
&lt;html>
&lt;head>
	&lt;meta charset='utf-8' />
	&lt;title>Progressively Enhanced Image Gallery&lt;/title>
&lt;/head>
&lt;body>
	&lt;div id="container">
			&lt;h1>Click on an image below to view it!&lt;/h1>

		&lt;ul id="images">
			&lt;li>&lt;div>
				&lt;a href="3dOcean.htm">&lt;img alt="3dOcean" src="images/thumbnails/3dOcean_tn.jpg"/>&lt;/a>
			&lt;/div>&lt;/li>
			&lt;li>&lt;div>
				&lt;a href="AudioJungle.htm">&lt;img alt="AudioJungle" src="images/thumbnails/AudioJungle_tn.jpg"/>&lt;/a>
			&lt;/div>&lt;/li>
			&lt;li>&lt;div>
			&lt;a href="ActiveDen.htm">&lt;img alt="ActiveDen" src="images/thumbnails/ActiveDen_tn.jpg"/>&lt;/a>
			&lt;/div>&lt;/li>
			&lt;li>&lt;div>
				&lt;a href="GraphicRiver.htm">&lt;img alt="GraphicRiver" src="images/thumbnails/GraphicRiver_tn.jpg"/>&lt;/a>
			&lt;/div>&lt;/li>
			&lt;li>&lt;div>
				&lt;a href="ThemeForest.htm">&lt;img alt="ThemeForest" src="images/thumbnails/ThemeForest_tn.jpg"/>&lt;/a>
			&lt;/div>&lt;/li>
			&lt;li>&lt;div>
				&lt;a href="VideoHive.htm">&lt;img alt="VideoHive" src="images/thumbnails/VideoHive_tn.jpg"/>&lt;/a>
			&lt;/div>&lt;/li>
		&lt;/ul>

	&lt;/div>
&lt;/body>
&lt;/html>
</pre>
<p>That&#8217;s it; pretty basic stuff, eh? No browser worth that title should have a problem with it. And this is our finished first layer. No, it&#8217;s not pretty, but that wasn&#8217;t our goal: we wanted something that will work everywhere, no matter what. A few things to notice about this code: firstly, it&#8217;s semantic, as we said it should be. You might wonder about the divs inside the list items. What&#8217;s up with them? Even though we&#8217;re starting with the bare bones, we are anticipating that most of our viewers will have JavaScript enabled, in which case we&#8217;ll need those divs. We could insert them with jQuery, but since we <em>do</em> expect them to be used most of the time, it&#8217;s easier to hard-code it in. The other thing to notice is that it&#8217;s usable. Try viewing it in Lynx, or another text-only browser:</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/501_imagegallery/lynx.png" alt="Gallery in Lynx"/></div>
<p>By the way, the pages linked to in the HTML above will be available in the downloadable source; they&#8217;re all similar to this:
<pre name='code' class='html'>
&lt;!DOCTYPE html>
&lt;html>
&lt;head>
	&lt;meta charset='utf-8' />
	&lt;title>Themeforest MarketPlace by Envato&lt;/title>
&lt;/head>
&lt;body>
&lt;h1>ThemeForest&lt;/h1>
&lt;img src="images/ThemeForest.jpg" alt="ThemeForest" />
&lt;p>Themeforest offers: HTML Templates, WordPress,
Joomla, Flash Sites, PSD Templates, Javascript, PHP Scripts&lt;/p>
&lt;/body>
&lt;/html>
</pre>
</p>
<p>On a real site, you&#8217;d surround this with your site template, but it&#8217;s just fine for our purposes.</p>
<h3 id='dressing_the_structure_css'>Dressing the Structure: CSS</h3>
<p>Although semantic HTML is nice, it looks a bit bare. Let&#8217;s dress it up with some CSS. Of course, we first have to reference the stylesheet:
<pre name='code' class='html'>
&lt;link type="text/css" rel="stylesheet" href="styles/default.css" media="screen" />
</pre>
</p>
<p>We&#8217;ll level the playing field first with a stripped-down Meyer reset:
<pre name='code' class='css'>
/* Meyer's Reset */
html, body, div, h1, h2, h4, p, a, img, ul, li
{ margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; }
/* remember to define focus styles! */
:focus { outline: 0; }
body { line-height: 1; color: black; background: white; }
ol, ul { list-style: none; }
/* END Meyer's Reset */
</pre>
</p>
<p>Now we have to style our gallery for use without JavaScript. We&#8217;ll start with some general elements and background styling: </p>
<pre class="css" name="code">
body{
	font:13px/1.5 &apos;Helvetica Neue&apos;,Arial,&apos;Liberation Sans&apos;,FreeSans,sans-serif; /* &lt;-- from 960.gs text.css */
	background: #36b4dd;
}
h1 { font-size: 30px; }
#container > h1 { padding: 10px;}
h4 { font-size: 20px; padding-bottom:10px;}
</pre>
<p>Now we&#8217;ll take care of our heading and list items.</p>
<pre name='code' class='css'>
#container h1 {
	padding: 10px;
}
#images li {
	float:left;
	background:#ececec;
	border:1px solid #ccc;
	margin:10px;
	width: 256px;
	padding: 10px;
	overflow: hidden;
}
#images li div {
	width: 512px;
	overflow:hidden;
}
#images li a {
	float:left;
}
#images li div.info {
	width: 246px;
	padding:0 0 0 10px;
	float:left;
}
</pre>
<p>You&#8217;ll notice that we&#8217;ve set a width on our list elements. We need to do that for our JavaScript functionality; that&#8217;s also why overflow:hidden is set. This is easy in our case, because I&#8217;ve made all the images the same width. If yours are different widths, you&#8217;ll probably have to set the width for each list item with JavaScript. That will work because the CSS only version doesn&#8217;t require the width. The div directly inside our list item (that wraps all the content) is 512px wide, with overflow hidden. We&#8217;ve floated our anchor to the left so we can float the div.info to the left beside it, as you see further on.</p>
<p>So, here are the fruits of our labours so far:</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/501_imagegallery/css.png" alt="Our Gallery with CSS only" /></div>
<p>We&#8217;ll come back to CSS in a bit; but now, let&#8217;s turn to the JavaScript!</p>
<h3 id='adding_the_functionality_javascript'>Adding the Functionality: JavaScript</h3>
<p>We&#8217;ll be using jQuery here; so start by importing that from Google&#8217;s CDN. We&#8217;ll also need the jQueryUI library. We could get that from Google as well, but we don&#8217;t need the whole library. I&#8217;ve downloaded a copy from the <a href='http://jqueryui.com'>jQueryUI site</a>, with just the core and the draggable components, which is all we&#8217;ll need. You can do whichever you prefer.
<pre name='code' class='html'>
&lt;script src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js'>&lt;/script>
&lt;script src='js/jqueryui-core-drag.js'>&lt;/script>
</pre>
</p>
<p>Before we start coding, let&#8217;s determine what we need to do.</p>
<ul>
<li>The h1 we&#8217;ve hard-coded provides instruction for the non-JavaScript version. We&#8217;ll remove this and add different instructions.</li>
<li>We need to configure the dragging on the list elements; we&#8217;ll add a splash of fun: when the user releases the list item, it will slide a bit further and slow down (sounds like an iEffect). Like we said earlier, it&#8217;s supposed to be somewhat like a stack of photos on a table.</li>
<li>When a list item is clicked, it should &#8216;slide open,&#8217; doubling in width. Before it does, however, we&#8217;ll send an Ajax call to get the page that the user would go to if JavaScript wasn&#8217;t enabled. Then, we&#8217;ll get the values we want from that page and plug them into our list item in a div. We&#8217;ll check for this div before making the call, though, so if the user has already clicked on it, we won&#8217;t send another request.</li>
</ul>
<p>Alright, open up a script tag and let&#8217;s code! </p>
<pre class="js" name="code">
var imgs;

$(document).ready(function () {

});

$(window).load(function () {

});
</pre>
<p>We&#8217;ll start by creating a global variable: an array of the list items (well, it will be an array soon). Then, we set up event handlers for a) when the DOM is ready, and b) when the window is finished loading. The effect we&#8217;ll do when the window loads (which I haven&#8217;t told you about yet) doesn&#8217;t require that we wait until then, but I think it will be nicer when the images have been loaded.</p>
<p>Now, this code goes in our document.ready function:</p>
<pre name='code' class='js'>
var  drag = {};
$('h1').remove();
$('#images').append('&lt;li id='instructions'>&lt;h2>Toss the images around; if you see one you like, click on it!&lt;/h2>&lt;/li>');

imgs = $('#images li');
</pre>
<p>Should be straightforward: we create an object that will hold some details about out dragging; then we remove the h1, append a list item with new instructions to our list, and put all the list items in our imgs variable.</p>
<p>Now we&#8217;ll build our dragging functionality. Really it&#8217;s as simple as this:
<pre name='code' class='js'>
imgs.draggable();
</pre>
</p>
<p>But we&#8217;re going to add a few options. Here&#8217;s the code; persue it yourself and then we&#8217;ll stroll through it. </p>
<pre class='js' name="code">
imgs.draggable({
			stack : { group : &apos;#images li&apos;, min : 1},
			start : function () {
				$this = $(this);
				if($this.attr(&quot;id&quot;) === &apos;instructions&apos;) { $this.fadeOut().remove(); }

				imgs.each(function () {
				var $this = $(this);
				if($this.width() !== 256) {
					$this.stop().animate({width : 256 }).removeClass(&#39;top&#39;);
				}
			});

			drag.startTime = new Date();
			drag.startPos = $this.position();
		},
		stop : function () {
			var $this = $(this), top, left, time;
			drag.endTime = new Date();
			drag.endPos = $this.position();
			drag.leftOffset = drag.endPos.left - drag.startPos.left;
			drag.topOffset  = drag.endPos.top  - drag.startPos.top;

			time = (drag.endTime.getTime() - drag.startTime.getTime()) /60;

			top  = (drag.topOffset / time).toString();
			left = (drag.leftOffset / time).toString();

			$this.animate({
				top : &#39;+=&#39; + top,
				left: &#39;+=&#39; + left
			});
		}

});
</pre>
<p>We&#8217;ve added three properties to our draggable options object: stack, start, and stop. Stack controls the z-index of a group of objects, and takes an object with two properties of its own: group and min. Group is a jQuery selector; in our case, it&#8217;s the list items. Min is the minimum z-index any items in the group can take. So now, when you drag an item, it comes to the top of the pile. </p>
<p>The start function is run when you begin to drag an item. We start by caching $(this). Then, we check to see if the list item we grabbed has an id of &#8216;instructions.&#8217; If it does, we fade it out and remove it. Then, we loop over each list item and if we find any that aren&#8217;t 256px wide, we animate the width to 256px and remove the class of &#8216;top.&#8217; What&#8217;s &#8216;top&#8217; do? We&#8217;ll style it in a few minutes, but it just gives the user some visual feedback when they click an item. After that, we do something very important: we set two properties on our drag object. One (startTime) is the time the dragging started, and the other (startPos) is the position the item started at. We&#8217;ll use this information to create our effect when the dragging stops.</p>
<p>Lastly, we have the stop function, which predicably runs when user stops dragging. Again, we start by caching $(this), as well as creating a few other variables we&#8217;ll give values to in a moment. Next, we put our end time and position into drag.endTime and drag.endPosition. Then we calculate our left and top offset by subtracting where we were from where we are; we can do this with the top and left properties that the position object has. Now for the slowing down animate logic: you could get very complicated with this algorithm, but we&#8217;re just going to keep it simple. We&#8217;ll find the time the drag took by subtracting our startTime from our endTime; the getTime method returns the number of milleseconds since 1970/01/01, so the difference is in milleseconds Then, we divide that value by 60, which I came up with through trial and error. On an average drag, this sets our time variable somewhere between 2 and 3. Then we divide our top and left offset by time, and convert those values to string, saving them in top and left. Finally, we animate the dragged list item, incrementing (that&#8217;s what &#8216;+=&#8217; does) the value by top or left. At this point, you should be able to drag the images around and get our effect.</p>
<p>However, clicking the images will bring you to a new page. So let&#8217;s set up our click event handler. </p>
<pre class='js' name='code'>
imgs.click(function () {
			var $this = $(this);

		if ($this.attr(&#39;id&#39;) === &#39;instructions&#39;) {
			$this.fadeOut().remove();
		}
		else {
			if($this.width() !== 256) {
				$this.stop().animate({width : 256 }).removeClass(&#39;top&#39;);
			}
			else {
				if (!($this.find(&#39;.info&#39;).length)) {
					$.ajax({
						url : $this.find(&#39;a&#39;).attr(&#39;href&#39;),
						dataType : &#39;html&#39;,
						success : function (data) {
							var $d = $(data),
								head = $d.filter(&#39;h1&#39;),
								para = $d.filter(&#39;p&#39;);

							$this.children(&#39;div&#39;).append(&#39;&lt;div class=&quot;info&quot;&gt;&lt;/div&gt;&#39;).find(&quot;.info&quot;).append(head, para);
						},
						error : function () {
							var msg = &#39;&lt;h1&gt;Oops!&lt;/h1&gt;&lt;p&gt;It looks like there been a problem; we can\&#39;t get this info right now.&lt;/p&gt;&#39;;
							$this.children(&#39;div&#39;).append(&#39;&lt;div class=&quot;info&quot;&gt;&lt;/div&gt;&#39;).find(&quot;.info&quot;).html(msg);
						}
					});
				}
				$this.css({&#39;zIndex&#39; : 8 })
					 .stop()
					 .animate({ width : 512})
					 .addClass(&#39;top&#39;)
						.siblings().removeClass(&#39;top&#39;)
								   .stop()
								   .animate({width : 256})
										.filter(function () { return $(this).css(&#39;zIndex&#39;) === &#39;8&#39; }).css({&#39;zIndex&#39; : 7});
			}
		}
		return false;
	});
</pre>
<p>Standard operating procedure today: begin by caching $(this). Once again, we check for the id of instructions; if it&#8217;s there, we fadeOut and remove the item. If its not there, we check the width of the element: if it isn&#8217;t 256px, that means this item has already been clicked, so we animate the width down to 256 and remove our top class (yes, we&#8217;ll get there). If the element is 256px wide, we check for a child element with the class of info. We can do this my calling the find method on the element, pass in the selector we&#8217;re looking for, and get the length property. If this element doesn&#8217;t exist, the result will be 0, which is a false value, so we wrap that in parentheses and use a ! to switch the boolean. Now, if there aren&#8217;t any child elements with a class of info, we&#8217;ll step into this block, which is our ajax call.</p>
<p> $.ajax() takes an object parameter, and we&#8217;ll use four properties: url, datatype, success, and error. Url and datatype are obvious: we simply find the anchor in our list item and set url to its href; our datatype is html. If our ajax call is successful, we&#8217;ll take the data we get, which is the entire HTML contents of the page, and turn it into a jQuery object. Then, we can filter out the heading and paragraph that we know we have there. Then we simply get the div inside our list item, append a div.info, and append the heading and paragraph to that. If our request fails, we&#8217;ll show an error message by a similar process, using the error function. After our ajax call, we want to perform some styling and animation on our list item. First, we want to set the z-index to 8, or any number higher than the number of draggable items we have. Then we want to stop all current animations on this list item and animate the width to 512px. Lastly, we&#8217;ll add that top class. Next, we get all the siblings, which are the other list items. We&#8217;ll stop any animation on them and then animate them to 256px wide. Finally, we&#8217;ll filter out only the elements with a z-index of 8 and change their z-index to 7. This allows the currently cliked list item to come ot the top. Right at the end, we return false, so we stay on our current page (because even though this is a click function on a list item, the users will most likely click our anchor-wrapped image inside the list item). </p>
<p>So that&#8217;s our click handler; only one piece of JavaScript left. If you give our example a try now, you&#8217;ll see it works &#8230; kind of. Whenever you click a list item to open it, it opens, but you&#8217;ll notice a rather shifty problem. It&#8217;s because the list items are floated to the left; let&#8217;s take care of that in our window ready handler.</p>
<pre name='code' class='js'>
$(window).load(function () {
	var $w = $(window);
	imgs.css({	position : 'absolute',
			left : $w.width() / 2 - imgs.width(),
			top  : $w.height() / 2- imgs.height() });
	for(var i = 0; imgs[i]; i++ ) {
		$(imgs[i]).animate({	left : '+=' + Math.random()*150,
						top  : '+=' + Math.random()*150 });
	}
});
</pre>
<p>If you&#8217;ve followed pretty well so far, you won&#8217;t flinch here: we simply use the jQuery&#8217;s css method to set the positioning to absolute and stack all the images so their right edges are aligned to the middle of the viewport, and their bottom edges are aligned to the vertical middle. Then we use a for loop to recurse over each list item and randomly animate it right and down. This creates the effect of a stack of images being scattered. </p>
<p>So that&#8217;s it for the JavaScript! Now, when a user loads the page, they should see something like this (after animation) :</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/501_imagegallery/scatter.png" alt="Images scattered" /></div>
<h3 id='final_touches_css3'>Final Touches: CSS3</h3>
<p>We could end there, but we want to reward those who use forward-thinking browsers, so it&#8217;s back to the CSS for a few minutes. And, yes, we&#8217;ll look at the top class.</p>
<p>The first thing we&#8217;ll do is add rounded corners to the selector #images li.
<pre name='code' class='css'>
border-radius:5px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
</pre>
</p>
<p>Then the top class, which list items only have when they are &#8216;open,&#8217; looks like this:
<pre name='code' class='css'>
.top {
	box-shadow:0 0 10px #000;
	-moz-box-shadow:0 0 10px #000;
	-webkit-box-shadow:0 0 30px #000;
}
</pre>
</p>
<p>Nothing incredibly fancy, but a few nice refinements nonetheless.</p>
<h3 id='closing_comments'>Closing Comments</h3>
<p>Well, that&#8217;s it. We should now have an image gallery that works decently without CSS or JavaScript, but takes full advantage of them where those technologies are available. So, how would you improve our gallery? Let&#8217;s hear it in the comments!</p>

<p><a href="http://feedads.g.doubleclick.net/~a/EVLTQqe31UTVALGCRWoCnp5I2m8/0/da"><img src="http://feedads.g.doubleclick.net/~a/EVLTQqe31UTVALGCRWoCnp5I2m8/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/EVLTQqe31UTVALGCRWoCnp5I2m8/1/da"><img src="http://feedads.g.doubleclick.net/~a/EVLTQqe31UTVALGCRWoCnp5I2m8/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=6TMLfCr1QDM:d82R04UkPFo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=6TMLfCr1QDM:d82R04UkPFo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=6TMLfCr1QDM:d82R04UkPFo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=6TMLfCr1QDM:d82R04UkPFo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=6TMLfCr1QDM:d82R04UkPFo:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=6TMLfCr1QDM:d82R04UkPFo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=6TMLfCr1QDM:d82R04UkPFo:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=6TMLfCr1QDM:d82R04UkPFo:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/6TMLfCr1QDM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/tutorials/javascript-ajax/building-an-image-gallery-with-progressive-enhancement/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		<feedburner:origLink>http://net.tutsplus.com/tutorials/javascript-ajax/building-an-image-gallery-with-progressive-enhancement/</feedburner:origLink></item>
		<item>
		<title>20+ Brand New and Incredibly Useful WordPress Plugins</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/e7b70dF9jKM/</link>
		<comments>http://net.tutsplus.com/articles/web-roundups/20-brand-new-and-incredibly-useful-wordpress-plugins/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 19:41:14 +0000</pubDate>
		<dc:creator>Ivor Padilla</dc:creator>
				<category><![CDATA[Web Roundups]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[wordpress plugin]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=7863</guid>
		<description><![CDATA[<img src="http://nettuts.s3.amazonaws.com/502_wp/preview.jpg" alt="21 Brand New and Incredibly Useful WordPress Plugins" width="200" height="200"/>]]></description>
			<content:encoded><![CDATA[<p>With more than 7000+ plugins, WordPress is the most extendable Content Management System available; in fact, &#8220;WordPress is infinitely extensible&#8221; as Matt Mullenweg says. In this post, we&#8217;ll examine twenty-one really useful plugins to take your blog to the next level.</p>
<p><span id="more-7863"></span></p>
<h3>1. Drag To Share</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/1.jpg" border="0" /></div>
<p>&#8220;<strong>Drag to share</strong> is the newest trend in social sharing. Just drag an image and drop it into any social website to share the whole page in real time. Most notably, this effect is being used by Mashable. The plugin was developed with the source files created by Dan Wellman. Read more <a href="http://net.tutsplus.com/tutorials/javascript-ajax/drag-to-share">here </a>&#8221; </p>
<p><a href="http://wordpress.org/extend/plugins/drag-to-share/">Download the plugin</a></p>
<h3>2. Paginator</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/2.jpg" border="0" /></div>
<p>&#8220;<strong>Paginator</strong> is a pagination technique based on the idea of scrolling.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/paginator/">Download the plugin</a></p>
<h3>3. TypeKit Plugin for WordPress</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/3.jpg" border="0" /></div>
<p>&#8220;This is a convenient way for WordPress users to use the Typekit font service in WordPress web sites. This will enable users to quickly change the fonts on their sites. Further this plugin provides the ability to designate where TypeKit will be used in their site.&#8221;</p>
<p><a href="http://net.tutsplus.com/videos/screencasts/typekit-removing-the-wrapping-paper/">Want to learn more about TypeKit? Watch our screencast.</a></p>
<p><a href="http://wordpress.org/extend/plugins/typekit/">Download the plugin</a></p>
<h3>4. Custom Coming Soon Page</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/4.jpg" border="0" /></div>
<p>The &#8220;Custom Coming Soon Pages&#8221; WordPress plugin allows you to display a  &#8220;Coming Soon&#8221; or &#8220;Under Construction&#8221; page to normal visitors or regular members of your WordPress site,  while the site administrators continue to see the fully functional website.</p>
<p>This will enable you to perform upgrades, fix nasty bugs or preview jazzy enhancements to your design live on your WordPress based website or blog without letting your users and normal visitors see crappy error messages or changes to the design until you really want them to.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/custom-coming-soon-page/">Download the plugin</a></p>
<h3>5. Custom Class Selector</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/5.jpg" border="0" /></div>
<p>&#8220;The Custom Class Selector plugin allows users to style their post content using custom classes made available by the active theme. Theme developers can make custom style classes available within the visual editor by adding a simple function to the functions.php file included with their theme.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/custom-class-selector/">Download the plugin</a></p>
<h3>6. PHP-Widgetify</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/6.jpg" border="0" /></div>
<p>&#8220;Like a normal text widget, this allows you to easily post text and HTML, but now you can execute PHP too! This makes merging with other themes easier.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/php-widgetify/">Download the plugin</a></p>
<h3>7. Pretty Comments</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/7.jpg" border="0" /></div>
<p>&#8220;Add some formatting capabilities to the comments textareas.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/pretty-comments/screenshots/">Download the plugin</a></p>
<h3>8. Custom Login Page</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/8.jpg" border="0" /></div>
<p>&#8220;With the Custom Login Page, you can change the background image of your login page, the background image/colo of your login form div, the main logo image of your login page, and add custom CSS &#8211; all through a simple interface. Remember to view the Help tab at the top of the settings page for the plugin.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/wp-custom-login-page/">Download the plugin</a></p>
<h3>9. eCSStender for WordPress</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/9.jpg" border="0" /></div>
<p>&#8220;This plugin uses the eCSStender javascript Library. This library is a parser that takes your CSS after the browser.</p>
<p>The library re-interprets the css using the plugins and adds new abilities to the browsers. You can for example add CSS3 Selectors support to IE6. </p>
<p><a href="http://wordpress.org/extend/plugins/ecsstender-take-control-of-your-css/">Download the plugin</a></p>
<h3>10. Freebie Images: Free Stock Images Plugin</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/10.jpg" border="0" /></div>
<p>&#8220;Spice up your blog with high quality free stock photos &#038; images created by professional photographers and illustrators: Easy to use search interface with advanced filtering and Drag &#038; Drop functionality.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/freebie-images-free-stock-images-plugin/screenshots/">Download the plugin</a></p>
<h3>11. SecurePress Website Security Analyzer</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/11.jpg" border="0" /></div>
<p>&#8220;SecurePress is a &#8220;Live&#8221; patent pending security system for WordPress.<br />
With the introduction of SecurePress, WordPress owners now have a clear choice in website protection. No more piece-meal security patches and plugins. The SecurePress widget installs enough free features to get you started towards securing your site. The ability to see and record your attacks is an excellent starting point. The free reports and statistics available within the dashboard help you to better understand the level and magnitude of these attacks. The free price tag is another excellent reason to download! When you&#8217;re ready, and after familiarizing yourself with the dashboard, you may want to upgrade to the full version to enable the vast blocking capabilities of SecurePress Pro and turn this application into a monster security shield.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/securepress-plugin/">Download the plugin</a></p>
<h3>12. Prev-Next Keyboard Navigation</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/12.jpg" border="0" /></div>
<p>&#8220;Prev-Next Keyboard Navigation adds JavaScript to allow moving through postings on index and archive pages using the J/K keys to skip to the next or previous post.&#8221;</p>
<h4>Features</h4>
<ol>
<li>Scrolls the current post to the top</li>
<li>View next post with &#8220;J&#8221;, previous post with &#8220;K&#8221;</li>
<li>After the last post on a page, continues to the next page</li>
</ol>
<p><small>Photo by <a href="http://openphoto.net/gallery/image.html?image_id=17560">John Khan</a></small></p>
<p><a href="#">Download the plugin</a></p>
<h3>13. oEmbed Provider</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/13.jpg" border="0" /></div>
<p>&#8220;The oEmbed provider plugin makes WordPress an oEmbed provider, compliant with the XML and JSON specification at <a href="http://www.oembed.com">http://www.oembed.com</a>.</p>
<p>oEmbed is a format for allowing an embedded representation of a URL on third party sites. The simple API allows a website to display embedded content (such as photos or videos) when a user posts a link to that resource, without having to parse the resource directly.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/oembed-provider/">Download the plugin</a></p>
<h3>14. My WordPress Secure</h3>
<p>&#8220;This plugin is very simple: it removes the WP-Version from the head of the document &#8211; thus, avoiding bad-intentioned people from knowing what version of WordPress you&#8217;re currently running. &#8220;</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/14.jpg" border="0" /></div>
<p><a href="http://wordpress.org/extend/plugins/my-wordpress-secure/">Download the plugin</a></p>
<h3>15. Private Messages For WordPress</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/15.jpg" border="0" /></div>
<p>&#8220;This plugin allows users of your blog to send private messages (PM) to each other. The number of PMs can be controlled via the plugin&#8217;s option page.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/private-messages-for-wordpress/screenshots/">Download the plugin</a></p>
<h3>16. Simple WordPress Framework for Plugins Development</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/16.jpg" border="0" /></div>
<p>&#8220;Simple WordPress Framework is a Plugin to help you create new Plugins. Even though this is the first version (Beta), it is fully functional. It was designed using the standards and requirements specified in the WordPress Plugin API Manual and follows the correct programming structure, functions and procedures that are required to build a plugin in WordPress. In every PHP file, you will find notes and urls referring to the WordPress API articles that are relevant.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/simple-wordpress-framework/">Download the plugin</a></p>
<h3>17. No IE6</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/17.jpg" border="0" /></div>
<p>&#8220;You can install this plugin to inform your users that they are running an old browser.</p>
<p>This is using the jReject jQuery plugin. The WordPress plugin simply uses hooks to insert the jQuery plugin into your theme.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/reject-ie6/">Download the plugin</a></p>
<h3>18. S3Vault</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/18.jpg" border="0" /></div>
<p>&#8220;S3Vault is a WordPress Plugin to protect your Amazon S3 files by generating expiration links. You can post your S3 files for download, or play videos inline without worrying about others sharing your S3 file links.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/s3vault/">Download the plugin</a></p>
<h3>19. Envato Marketplace Items</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/19.jpg" border="0" /></div>
<p>&#8220;The Envato Marketplace Items plugin retrieves items from an Envato Marketplace and API set of your choice, then caches and shows the results as a gallery of 80px square thumbnails.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/envato-marketplace-items/">Download the plugin</a></p>
<h3>20. WordPress Admin Bar Improved</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/20.jpg" border="0" /></div>
<p>&#8220;This Plugin replicates all of the menu links in your normal admin area at the top of your main site for logged in users (i.e. you). You can go right to the &#8220;Write Post&#8221; or manage options pages in one click from anywhere on your blog. No more having to go to your dashboard first. You can even have it replace your admin area menus if you want.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/wordpress-admin-bar-improved/">Download the plugin</a></p>
<h3>21. Excerpt Tools</h3>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/502_wp/21.jpg" border="0" /></div>
<p>&#8220;If you require a specific excerpt length for each post, this is the right plugin for you. It adds an excerpt box to pages and shows a customizable jQuery character counter with the ability to limit the amount of characters.&#8221;</p>
<p><a href="http://wordpress.org/extend/plugins/excerpt-tools/">Download the plugin</a></p>
<ul class="webroundup">
<li>Follow us on <a href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li>
</ul>
<p>
<script type="text/javascript"><!--digg_url = "post permalink (not digg url)"; // -->
</script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>

<p><a href="http://feedads.g.doubleclick.net/~a/KgR2SBtiM969QfWw2-8GIOmuirw/0/da"><img src="http://feedads.g.doubleclick.net/~a/KgR2SBtiM969QfWw2-8GIOmuirw/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/KgR2SBtiM969QfWw2-8GIOmuirw/1/da"><img src="http://feedads.g.doubleclick.net/~a/KgR2SBtiM969QfWw2-8GIOmuirw/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=e7b70dF9jKM:mDBw_GEbhHo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=e7b70dF9jKM:mDBw_GEbhHo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=e7b70dF9jKM:mDBw_GEbhHo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=e7b70dF9jKM:mDBw_GEbhHo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=e7b70dF9jKM:mDBw_GEbhHo:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=e7b70dF9jKM:mDBw_GEbhHo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=e7b70dF9jKM:mDBw_GEbhHo:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=e7b70dF9jKM:mDBw_GEbhHo:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/e7b70dF9jKM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/articles/web-roundups/20-brand-new-and-incredibly-useful-wordpress-plugins/feed/</wfw:commentRss>
		<slash:comments>104</slash:comments>
		<feedburner:origLink>http://net.tutsplus.com/articles/web-roundups/20-brand-new-and-incredibly-useful-wordpress-plugins/</feedburner:origLink></item>
		<item>
		<title>5 More Helpful Video Quick Tips</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/N8ECwldZcIQ/</link>
		<comments>http://net.tutsplus.com/videos/screencasts/5-more-helpful-video-quick-tips/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 19:56:34 +0000</pubDate>
		<dc:creator>Jeffrey Way</dc:creator>
				<category><![CDATA[Screencasts]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[quick tip]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=7844</guid>
		<description><![CDATA[<img src="http://nettuts.s3.amazonaws.com/499_quicktips/200x200.jpg" alt="5 More Helpful Video Quick Tips" />]]></description>
			<content:encoded><![CDATA[<p>
As many of you might know, I post a sporadic video quick tip on <a href="http://www.twitter.com/nettuts">Twitter</a> once a week or so. For those of you who don&#8217;t <a href="http://www.twitter.com/nettuts">follow us</a>, here are the latest five.</p>
<p>
You&#8217;ll learn how to select anything and everything with jQuery, how to log PHP errors to a text file, how to change your website&#8217;s background with each WordPress post, and more. Each video does not exceed five minutes.
</p>
<p><span id="more-7844"></span></p>
<h3><a href="http://screenr.com/o12">How to Change your Website&#8217;s Background with Each WordPress Blog Post</a></h3>
<div class="tutorial_image">
<a href="http://screenr.com/o12"><br />
<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=27577' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=27577' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object><br />
</a>
</div>
<ul>
<li><a href="http://screenr.com/o12">Watch on your iPhone</a></li>
<li><a href="http://screenr.com/download.aspx?ScreencastId=27577">Download the Mp4</a></li>
<li><a href="http://www.8164.org/wordpress-custom-field/">Further Reading on this Subject</a></li>
</ul>
<h3><a href="http://screenr.com/n1B">How to Rename the jQuery &#8220;$&#8221; Symbol</a></h3>
<div class="tutorial_image">
<a href="http://screenr.com/n1B"><br />
<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=23711' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=23711' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object><br />
</a>
</div>
<ul>
<li><a href="http://screenr.com/n1B">Watch on your iPhone</a></li>
<li><a href="http://screenr.com/download.aspx?ScreencastId=23711">Download the Mp4</a></li>
</ul>
<h3><a href="http://screenr.com/IdB">How to Select Anything and Everything with jQuery</a></h3>
<div class="tutorial_image">
<a href="http://screenr.com/IdB"><br />
<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=23807' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=23807' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object><br />
</a>
</div>
<ul>
<li><a href="http://screenr.com/IdB">Watch on your iPhone</a></li>
<li><a href="http://screenr.com/download.aspx?ScreencastId=23807">Download the Mp4</a></li>
</ul>
<h3><a href="http://screenr.com/PON">Log Errors to a Text File with PHP</a></h3>
<div class="tutorial_image">
<a href="http://screenr.com/PON"><br />
<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=20759' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=20759' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object><br />
</a>
</div>
<ul>
<li><a href="http://screenr.com/PON">Watch on your iPhone</a></li>
<li><a href="http://screenr.com/download.aspx?ScreencastId=20759">Download the Mp4</a></li>
</ul>
<p><!-- 5--></p>
<h3><a href="http://screenr.com/IIN">Stay Up to Date on the Latest Nettuts+ Screencasts with Boxee</a></h3>
<div class="tutorial_image">
<a href="http://screenr.com/IIN"><br />
<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=23063' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=23063' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object><br />
</a>
</div>
<ul>
<li><a href="http://screenr.com/IIN">Watch on your iPhone</a></li>
<li><a href="http://screenr.com/download.aspx?ScreencastId=23063">Download the Mp4</a></li>
</ul>
<ul class="webroundup">
<li>Follow us on <a href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li>
</ul>
<p>
<script type="text/javascript"><!--digg_url = "post permalink (not digg url)"; // -->
</script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>

<p><a href="http://feedads.g.doubleclick.net/~a/KYHMBXA1YGig5Y4W9vB-5bWcGO0/0/da"><img src="http://feedads.g.doubleclick.net/~a/KYHMBXA1YGig5Y4W9vB-5bWcGO0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/KYHMBXA1YGig5Y4W9vB-5bWcGO0/1/da"><img src="http://feedads.g.doubleclick.net/~a/KYHMBXA1YGig5Y4W9vB-5bWcGO0/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=N8ECwldZcIQ:d6xc6zCfPfI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=N8ECwldZcIQ:d6xc6zCfPfI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=N8ECwldZcIQ:d6xc6zCfPfI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=N8ECwldZcIQ:d6xc6zCfPfI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=N8ECwldZcIQ:d6xc6zCfPfI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=N8ECwldZcIQ:d6xc6zCfPfI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=N8ECwldZcIQ:d6xc6zCfPfI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=N8ECwldZcIQ:d6xc6zCfPfI:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/N8ECwldZcIQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/videos/screencasts/5-more-helpful-video-quick-tips/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		<feedburner:origLink>http://net.tutsplus.com/videos/screencasts/5-more-helpful-video-quick-tips/</feedburner:origLink></item>
		<item>
		<title>Sorting Values with JavaScript</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/XvOdxEU1pFY/</link>
		<comments>http://net.tutsplus.com/tutorials/javascript-ajax/sorting-values-with-javascript/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 19:29:06 +0000</pubDate>
		<dc:creator>Andrew Burgess</dc:creator>
				<category><![CDATA[JavaScript & AJAX]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[sort]]></category>
		<category><![CDATA[sorting]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=7837</guid>
		<description><![CDATA[<img src="http://nettuts.s3.amazonaws.com/498_js/200.jpg" />]]></description>
			<content:encoded><![CDATA[<p>Lists and tables are often the best way to display data on the web; but you shouldn&#8217;t have to worry about sorting that information manually. In today&#8217;s tutorial, you&#8217;re going to make a jQuery plugin that will put all your ducks in a row with JavaScript ease!</p>
<p><span id="more-7837"></span></p>
<div class="tutorial_image">
<a href="http://nettuts.s3.amazonaws.com/498_js/demo.zip"><img src="http://nettuts.com/wp-content/themes/nettuts/site_images/button_src_nm.jpg"></a><br />
<a href="http://nettuts.s3.amazonaws.com/498_js/demo/sort.htm"><img src="http://nettuts.com/wp-content/themes/nettuts/site_images/button_demo_nm.jpg"></a>
</div>
<h2>Preface</h2>
<p>So, how exactly does sorting work in JavaScript? It&#8217;s not too complicated: any array object has a sort method. If you don&#8217;t pass it any parameters, it will convert the objects in the array to strings, sort them pseudo-alphabetically, and return them. Usually, this is terrible; consider sorting the numbers 0 &#8211; 10 alphabetically. You would get this: [0, 1, 10, 2, 3, 4, 5, 6, 7, 8, 9]. Fortunately, we can pass a function to the sort method. That function should take two parameters (the two items to be compared): then, it will return 0 if they are equal, a negative number if the first parameter takes precedence, or a positive number of the second parameter should come first. So numbers are actually the simplest thing to sort &#8220;manually&#8221;: </p>
<pre class="js" name="code">
numberArray.sort(function(a, b) {
    return a - b
});
</pre>
<p>Obviously, this will return 0 if the numbers are equal, a negative number if <code>a</code> should be first, and a positive number if <code>b</code> should be first. </p>
<p>We&#8217;re going to look at sorting several different types of data, a few in multiple formats; but this will all be much more useful if we wrap it in a jQuery plugin, so let&#8217;s start by setting up that shell!</p>
<h2>The Plugin Shell</h2>
<div class="tutorial_image"><img alt="You still can't crate a jQuery Plugin" src="http://nettuts.s3.amazonaws.com/498_js/plugin.png" /></div>
<p>If you&#8217;re not familiar with writing jQuery plugins, check out Jeffrey Way&#8217;s Screencast &#8220;<a href="http://net.tutsplus.com/videos/screencasts/you-still-cant-create-a-jquery-plugin/">You still can&#8217;t create a jQuery Plugin?</a>&#8221; It&#8217;ll get you up to speed in no time if you&#8217;re comfortable with jQuery! (true confession: I&#8217;d actually never written a plugin until I made this one). </p>
<p>We&#8217;ll set up our plugin, called datasort, this way: we&#8217;ll pass it an array of items to sort; we can specify four parameters.</p>
<ul>
<li>datatype (the type of data you&#8217;re sorting)</li>
<li>sortElement (the child element you want to sort by, if desired)</li>
<li>sortAttr (the attribute you want to sort by, if desired)</li>
<li>reverse (the direction they should sort in)</li>
</ul>
<p>So a fully-modified call to our plugin might look like this:</p>
<pre class="js" name="code">
$('ul.names li).datasort({
    		datatype    : 'alpha',
    		sortElement : 'span.first',
    		sortAttr    : 'rel',
    		reverse     : true
    	});
</pre>
<p>Here&#8217;s the plugin shell:</p>
<pre class="js" name="code">
(function ($) {
  $.fn.datasort = function(options) {
    var defaults = {
    	//set the default parameter values
          datatype    : 'alpha',
          sortElement : false,
          sortAttr    : false,
          reverse     : false
          },
    // combine the default and user's parameters, overriding defaults
        settings = $.extend({}, defaults, options),
        datatypes = {},
        base = {},
        that = this;

    if (typeof settings.datatype === 'string') {
      that.sort(datatypes[settings.datatype]);
    }
    if (typeof settings.datatype === 'function') {
      that.sort(settings.datatype);
    }
    if(settings.reverse) {
      that = $($.makeArray(this).reverse());
    }
    $.each(that, function(index, element) { that.parent().append(element); });
  };
})(jQuery);
</pre>
<p>So here&#8217;s how it&#8217;ll work: we&#8217;ll set up all the variables at the beginning. Then, if the datatype parameter is a string, we&#8217;ll find the corresponding sort function in the datatypes object and sort with it; if the datatype parameter is a function, we&#8217;ll sort with it. Finally, if the reverse setting is set to true, we&#8217;ll reverse the order of the sorted items (since jQuery objects aren&#8217;t true JavaScript arrays, the reverse function won&#8217;t work on them; so we can use $.makeArray() to turn it into one; then, once it&#8217;s reversed, we re-jquery-fy it!).</p>
<h2>Laying a Bit More Groundwork</h2>
<p>At the very lowest level, you can sort almost any type of data in one of two ways: we&#8217;ll be calling them alphabetically and numerically. Let&#8217;s create these two functions as properties of your base object.</p>
<pre class="js" name="code">
base = {
  alpha : function(a, b) {
    a = a.toUpperCase();
    b = b.toUpperCase();
    return (a < b) ? -1 : (a > b) : 1 : 0;
    //ternary operator: condition ? returnIfTrue : returnIfFalse
  },
  number : function(a, b) {
    a = parseFloat(a);
    b = parseFloat(b);
    return a - b;
  }
},
</pre>
<p>Pretty simple, eh? Simply normalize the two values, compare and return. The tricky part is parsing the data that we want to send to these functions; that&#8217;s what we&#8217;ll do now. However, there&#8217;s one more thing.</p>
<p>When sorting items in the array, we might not want to sort simply by the text of the element itself. The sortElement and sortAttr parameters of our plugin are to this end. For example, we will likely want to sort table rows based on a certain column of table cells. In that case, we&#8217;d use $(&#8217;table tr&#8217;).datasort({ sortElement : &#8216;td.price&#8217; }). Or perhaps we want to sort a list of images by their alt attributes: $(&#8217;ul li&#8217;).datasort({sortElement : &#8216;img&#8217;, sortAttr : &#8216;alt&#8217;}). Because of all this, we need to add one more function to our base object:</p>
<pre class="js" name="code">
base = {
  alpha : function (a, b) { ... },
  number : function (a, b) { ... },
  extract : function (a, b) {
  	var get = function (i) {
      var o = $(i);
      if (settings.sortElement) {
        o = o.children(settings.sortElement);
      }
      if (settings.sortAttr) {
        o = o.attr(settings.sortAttr);
      } else {
        o = o.text();
      }
      return o;
    };
    return {
      a : get(a),
      b : get(b)
    };
  }
},
</pre>
<p>It may look complicated, but it&#8217;s not. We just create a jQuery object with each item; if sortElement is set, we use the children() method to get the right elements. Then, if a sortAttr is set, we get its value; if not, we get the element&#8217;s text. We&#8217;ve set all this to an inner function, and return an object with two properites; these properties are the values we must parse and send to the appropriate base sorting function.</p>
<p>This probably seemed like a lot of prep work, but what we were really doing is abstracting as much code as possible. This way, they&#8217;ll be much less repeat code, because the important actions have been bundled away as functions.</p>
<h2>Sorting Words and Numbers</h2>
<p>We&#8217;re finally here: the fun part! We&#8217;ll start by building two simple functions for our datatypes object. These will simple pass values to base.extract() and then pass those return values to the appropriate sorting class.</p>
<pre class="js" name="code">
datatypes = {
  alpha : function (a, b) {
    var o = base.extract(a, b);
    return base.alpha(o.a, o.b);
  },
  number : function(a, b) {
    var o = base.extract(a, b);
    for (var e in o) {
      o[e] = o[e].replace(/[$]?(-?\d+.?\d+)/, '\$1');
    }
    return base.number(o.a, o.b);
  },
},
</pre>
<p>Our alphabetic sorter should be obvious. The number sorter does a bit more: before passing the extracted values on, it strips out a dollar sign at the front. I&#8217;ve kept this regular expression simple, but you could parse a lot of different number formats here if you wanted to get complex. Let&#8217;s give our evolving plugin a try; create a basic html page:</p>
<pre class="html" name="code">
&lt;!DOCTYPE html>
&lt;html>
&lt;head>
  &lt;meta charset='utf-8' />
  &lt;title>Data Sorting&lt;/title>
  &lt;style type='text/css'>
  ul, table {
    display:table;
    float:left;
    background:#ececec;
    margin:10px;
    padding:0;
    border:1px solid #ccc;
  }
  li, tr {
    margin:0;
    padding:8px;
    border-top:1px solid #fff;
    border-bottom:1px solid #ccc;
    list-style-type:none;
  }
  li:first-child { border-top:0 }
  li:last-child { border-bottom:0 }
  &lt;/style>
&lt;/head>
&lt;body>
  &lt;table class='a'>
    &lt;thead>
      &lt;tr>
        &lt;th rel='alpha' class='first'>First Name&lt;/th>
        &lt;th rel='alpha' class='last'>Last Name&lt;/th>
      &lt;/tr>
    &lt;/thead>
    &lt;tbody>
      &lt;tr>&lt;td class="first">Jeffrey&lt;/td> &lt;td class="last">Way&lt;/td>&lt;/tr>
      &lt;tr>&lt;td class="first">Sean&lt;/td> &lt;td class="last">Hodge&lt;/td>&lt;/tr>
      &lt;tr>&lt;td class="first">Adam&lt;/td> &lt;td class="last">Miller&lt;/td>&lt;/tr>
      &lt;tr>&lt;td class="first">Ian&lt;/td> &lt;td class="last">Yates&lt;/td>&lt;/tr>
      &lt;tr>&lt;td class="first">Adrian&lt;/td> &lt;td class="last">Try&lt;/td>&lt;/tr>
      &lt;tr>&lt;td class="first">Caleb&lt;/td> &lt;td class="last">Aylsworth&lt;/td>&lt;/tr>
    &lt;/tbody>
  &lt;/table>

  &lt;ul class='n'>
  &lt;li>4.09&lt;/li>
  &lt;li>4.10&lt;/li>
  &lt;li>67.8&lt;/li>
  &lt;li>100&lt;/li>
  &lt;li>-98&lt;/li>
  &lt;li>67.7&lt;/li>
  &lt;li>23&lt;/li>
  &lt;/ul> 

  &lt;ul class="curr">
    &lt;li>$299.66&lt;/li>
    &lt;li>$299.57&lt;/li>
    &lt;li>$0.14&lt;/li>
    &lt;li>$80.00&lt;/li>
  &lt;/ul>

  &lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" />&lt;/script>
  &lt;script src="jquery.datasort.js" />&lt;/script>
  &lt;script type="text/javascript">
    $('table.a tbody tr').datasort({sortElement : 'td.last'});
    $('ul.n li').datasort({datatype: 'number', reverse: true});
    $('ul.curr li').datasort({ datatype: 'number' });
  &lt;/script>
&lt;/body>
&lt;/html>
</pre>
<p>I&#8217;ve included a table and two lists (and I&#8217;ve styled them briefly). Take note of our plugin calls: we&#8217;re using the default datatype for the table, but sorting by the table cells with a class of last; try changing this to &#8216;td.first.&#8217; Then, we sort the lists numerically, and reverse one of them. Here&#8217;s the proof of our labours:</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/498_js/alphaNumber.png" alt="Sorting Alphabetically and Numerically" /></div>
<p>Pretty nice, but those were relatively simple values; what if we want to be able to sort multiple formats for one type?</p>
<h2>Sorting Dates</h2>
<p>There are a number of different ways to write dates, which makes it pretty tricky to parse them for sorting. However, we can cover most of them with this:</p>
<pre class='js' name='code'>
date : function(a, b) {
  var o = base.extract(a, b);
  for (var e in o) {
  o[e] = o[e].replace(/-/g, '')
             .replace(/january|jan/i, '01')
             .replace(/february|feb/i, '02')
             .replace(/march|mar/i, '03')
             .replace(/april|apr/i, '04')
             .replace(/may/i, '05')
             .replace(/june|jun/i, '06')
             .replace(/july|jul/i, '07')
             .replace(/august|aug/i, '08')
             .replace(/september|sept|sep/i, '09')
             .replace(/october|oct/i, '10')
             .replace(/november|nov/i, '11')
             .replace(/december|dec/i, '12')
             .replace(/(\d{2}) (\d{2}), (\d{4})/, '\$3\$1\$2')
             .replace(/(\d{2})\/(\d{2})\/(\d{4})/, '\$3\$2\$1');
  }
  return base.number(o.a, o.b);
},
</pre>
<p>So what are we doing here? First, here&#8217;s the logic: if all the dates are formatted YYYYMMDD, they will sort correctly with numerical sorting. Our parser can sort the following date formats:</p>
<ul>
<li>YYYY-MM-DD</li>
<li>YYYYMMDD</li>
<li>DD/MM/YYYY</li>
<li>month DD, YYYY</li>
</ul>
<p>First we strip our dashes, which will leave YYYY-MM-DD ready for parsing. Then, we replace every month name or abbreviation with its number value. Finally, we have to rearrange the numbers for DD/MM/YYY and month DD, YYYY. That&#8217;s what the last two expressions do. To give this a try, paste this list into our HTML:</p>
<pre class="html" name="code">
&lt;ul class='date'>
  &lt;li>2009-10-06&lt;/li>
  &lt;li>sept 25, 1995&lt;/li>
  &lt;li>1990-06-18&lt;/li>
  &lt;li>20100131&lt;/li>
  &lt;li>June 18, 2009&lt;/li>
  &lt;li>02/11/1993&lt;/li>
  &lt;li>15941219&lt;/li>
  &lt;li>1965-08-05&lt;/li>
  &lt;li>1425-12-25&lt;/li>
&lt;/ul>
</pre>
<p>And call it with this:</p>
<pre class="js" name="code">
    $('ul.date li').datasort({datatype: 'date'});
</pre>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/498_js/date.png" alt="Sorting Dates" /></div>
<p>Is this a perfect date parser? Not by any means; we can&#8217;t sort DD/MM/YY, because there&#8217;s no way to know what century this is in. Also, we can&#8217;t tell the difference between DD/MM/YY and MM/DD/YY, so we just have to choose one. </p>
<h2>Sorting Time</h2>
<p>Sorting time values must be one of the most difficult values to sort: we need to be able to accept 12-hour time, 24-hour time, and values with or without AM/PM tags and seconds. I think it&#8217;s easiest to sort time alphabetically, even though its all numbers. Why? Consider these two timestamps: 00:15:37 and 12:15. The first one should come first, but if we sort them by number they&#8217;ll be parsed as floats, and end up like 1537 and 1215. Now, the second value will come first. Also, when sorting alphabetically, we don&#8217;t have to take out the colons (parseFloat() would choke on them). So here&#8217;s how it&#8217;s done.</p>
<pre class="js" name="code">
time : function(a, b) {
  var o = base.extract(a, b),
      afternoon = /^(.+) PM$/i;
  for (var e in o) {
    o[e] = o[e].split(':');
    var last = o[e].length - 1;

    if(afternoon.test(o[e][last])) {
      o[e][0] = (parseInt(o[e][0]) + 12).toString();
      o[e][last] = o[e][last].replace(afternoon, '\$1');
    }
    if(parseInt(o[e][0]) < 10 &#038;&#038; o[e][0].length === 1) {
      o[e][0] = '0' + o[e][0];
    }
    o[e][last] = o[e][last].replace(/^(.+) AM$/i, '\$1');

    o[e] = o[e].join('');
  }
  return base.alpha(o.a, o.b);
}
</pre>
<p>Let's go through this line by line. </p>
<pre class="js" name="code">
  var o = base.extract(a, b),
      afternoon = /^(.+) PM$/i;
</pre>
<p>We start with our variables: our extracted values and a regular expression to check for PM label. </p>
<pre class="js" name="code">
  for (var e in o) {
    o[e] = o[e].split(':');
    var last = o[e].length - 1;

    if(afternoon.test(o[e][last])) {
      o[e][0] = (parseInt(o[e][0]) + 12).toString();
      o[e][last] = o[e][last].replace(afternoon, '\$1');
    }
</pre>
<p>Next, we'll start a for loop, going through each of the values we're sorting; first, we split it into an array at the colons. We create an easy way to get to the last items of the array: our 'last' variable. Then, we test our PM regex on the last item in our array; if it returns true, this value has the PM tag. Therefore, we'll add 12 to the first item in our array, which will be the hour value; we do this because we need all the values to be formatted in  24-hour time. (Note that to do this, we must convert it to a number, add 12, and then turn it back into a string). Finally, we use the PM regex again to remove that label from the last item in the array.</p>
<pre class="js" name="code">
    if(parseInt(o[e][0]) < 10 &#038;&#038; o[e][0].length === 1) {
      o[e][0] = '0' + o[e][0];
    }
   o[e][last] = o[e][last].replace(/^(.+) AM$/i, '\$1');

    o[e] = o[e].join('');
}
return base.alpha(o.a, o.b);
</pre>
<p>In this last chunk, we check the hour value for two conditions: is it less than 10? and does the string have only one character? This is important because a value like 08 will parse as 8 and be less than 10; but we're trying to see if we need to add a zero to the front. If the string has only one character, then we add the zero, so 3 becomes 03. This will keep things in order!</p>
<p>Before joining the array, we remove any AM labels. So now this . . .</p>
<pre class="html" name="code">
&lt;ul class='time'>
  &lt;li>1:15:47&lt;/li>
  &lt;li>3:45 PM&lt;/li>
  &lt;li>12:00:17&lt;/li>
  &lt;li>06:56&lt;/li>
  &lt;li>19:39&lt;/li>
  &lt;li>4:32 AM&lt;/li>
  &lt;li>00:15:36&lt;/li>
&lt;/ul>
</pre>
<p>. . . can be sorted with this . . . </p>
<pre class='js' name='code'>
$('ul.time li').datasort({datatype: 'time'});
</pre>
<p>And we're done! Behold the fruits of our labour:</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/498_js/time.png" alt="Sorting Time" /></div>
<h2>More Random Values</h2>
<p>We've set up our jQuery plugin so that users can pass sorting functions as the datatype parameter. This allows us to easily extend the plugin, although we don't have access to the base 'class' from the plugin call. We can easily write a function to sort psudeo-ratings:</p>
<pre class="js" name="code">
$('ul.rating li').datasort({datatype: function(a, b) {
      var o  = {
      a : $(a).text(),
      b : $(b).text()
      }
      for (var e in o) {
        o[e] = o[e].replace(/poor/i, 0)
                   .replace(/satisfactory/i, 1)
                   .replace(/good/i, 2)
                   .replace(/excellent/i, 3);
      }
      return o.a - o.b;
    }
});
</pre>
<p>This uses the simplest regular expressions possible to sort a list like this:</p>
<pre class="html" name="code">
&lt;ul class="rating">
  &lt;li>Good&lt;/li>
  &lt;li>Excellent&lt;/li>
  &lt;li>Poor&lt;/li>
  &lt;li>Satisfactory&lt;/li>
&lt;/ul>
</pre>
<h2>That's a Wrap!</h2>
<p>Now you're in the know: sorting values in JavaScript really isn't as hard as you might have thought. You can imagine this being useful to sort a table, with something like this:</p>
<pre class='js' name='code'>
$('table#myTable thead th').toggle(
  function() {
    var $this = $(this);
    $('table#myTable tbody tr').datasort({
      datatype: $this.attr('rel'),
      sortElement: 'td.' + $this.attr('class')
    });
  },
  function() {
    var $this = $(this);
    $('table#myTable tbody tr').datasort({
      datatype: $this.attr('rel'),
      sortElement: 'td.' + $this.attr('class'),
      reverse: true
      });
  }
);
</pre>
<p>(Try replacing the jQuery code for the table in the first example with this!)</p>
<p>Of course, we could improve this plugin a lot; for example, we could have it check the <code>rel</code> atttribute for a datatype if one isn't given as a parameter, and default to alpha if there is no <code>rel</code>. But that's aside from the sorting. </p>
<p>In sum, to sort with JavaScipt, we follow these steps:</p>
<ol>
<li>Determine the different formats you want to sort.</li>
<li>Decide what format you want to sort in.</li>
<li>Sort the array of items with the sort() method, passing in a function that will convert the two items to your desired format before comparing them</li>
</ol>
<p>Have a datatype to add to our plugin? Have a better way of sorting one of these? Let's hear it in the comments!</p>
<ul class="webroundup">
<li>Follow us on <a href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li>
</ul>
<p>
<script type="text/javascript"><!--digg_url = "post permalink (not digg url)"; // -->
</script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>

<p><a href="http://feedads.g.doubleclick.net/~a/ty7smmc_YUaC4a5CZVrX6OswVqM/0/da"><img src="http://feedads.g.doubleclick.net/~a/ty7smmc_YUaC4a5CZVrX6OswVqM/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/ty7smmc_YUaC4a5CZVrX6OswVqM/1/da"><img src="http://feedads.g.doubleclick.net/~a/ty7smmc_YUaC4a5CZVrX6OswVqM/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=XvOdxEU1pFY:Y3NEUHylKQI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=XvOdxEU1pFY:Y3NEUHylKQI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=XvOdxEU1pFY:Y3NEUHylKQI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=XvOdxEU1pFY:Y3NEUHylKQI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=XvOdxEU1pFY:Y3NEUHylKQI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=XvOdxEU1pFY:Y3NEUHylKQI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=XvOdxEU1pFY:Y3NEUHylKQI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=XvOdxEU1pFY:Y3NEUHylKQI:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/XvOdxEU1pFY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/tutorials/javascript-ajax/sorting-values-with-javascript/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		<feedburner:origLink>http://net.tutsplus.com/tutorials/javascript-ajax/sorting-values-with-javascript/</feedburner:origLink></item>
		<item>
		<title>How to Build a Custom jQuery Tabs Plugin: New Plus Tutorial</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/HZeUVNSMq2g/</link>
		<comments>http://net.tutsplus.com/tutorials/plus-tutorials-2/how-to-build-a-custom-jquery-tabs-plugin-new-plus-tutorial/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 23:00:14 +0000</pubDate>
		<dc:creator>Jeffrey Way</dc:creator>
				<category><![CDATA[Plus]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery plugin]]></category>
		<category><![CDATA[plus]]></category>
		<category><![CDATA[screecast]]></category>
		<category><![CDATA[video tutorial]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=7825</guid>
		<description><![CDATA[<img src="http://nettutsplus.s3.amazonaws.com/40_tabs/200x200.jpg" alt="" />]]></description>
			<content:encoded><![CDATA[<p>
In this week&#8217;s <strong>45 minute Plus video tutorial</strong>, I&#8217;ll personally teach you how to build a flexible jQuery tabs plugin. This plugin will automatically create the individual tabs, allow for auto-switching, fading, and plenty more &#8211; without being bloated. Why create a tabs plugin when there are plenty of them already available? Because too much abstraction is never a good thing. <a href="http://net.tutsplus.com/about/join-plus/">Become a Plus member.</a>
</p>
<p><span id="more-7825"></span></p>
<div class="tutorial_image">
   <img src="http://nettutsplus.s3.amazonaws.com/40_tabs/example1.jpg" alt="Unstyled" />
</div>
<div class="tutorial_image">
   <img src="http://nettutsplus.s3.amazonaws.com/40_tabs/jwTabs.jpg" alt="Final Product" />
</div>
<h3>Join Tuts Plus</h3>
<div class="tutorial_image"><img src="http://miscfiles.s3.amazonaws.com/banners/nettuts_468x60.jpg" border=0 alt="NETTUTS+ Screencasts and Bonus Tutorials" width=468 height=60></div>
<p>
For those unfamiliar, the family of TUTS sites runs a premium membership service called <a href="http://www.tutsplus.com">&#8220;TUTSPLUS&#8221;</a>. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from <a href="http://net.tutsplus.com">Nettuts+</a>, <a href="psd.tutsplus.com">Psdtuts+</a>, <a href="ae.tutsplus.com">Aetuts+</a>, <a href="audio.tutsplus.com">Audiotuts+</a>, and <a href="vector.tutsplus.com">Vectortuts+!</a> For the price of a pizza, you&#8217;ll learn from some of the best minds in the business. <a href="http://net.tutsplus.com/about/join-plus/">Join today!</a> </p>
<ul class="webroundup">
<li>Subscribe to the <a href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for more daily web development tuts and articles.</li>
</ul>
<p>
<script type="text/javascript"><!--digg_url = "post permalink (not digg url)"; // -->
</script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>

<p><a href="http://feedads.g.doubleclick.net/~a/JC1xkCKrNFJwebmsz5wTuTqY1xs/0/da"><img src="http://feedads.g.doubleclick.net/~a/JC1xkCKrNFJwebmsz5wTuTqY1xs/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/JC1xkCKrNFJwebmsz5wTuTqY1xs/1/da"><img src="http://feedads.g.doubleclick.net/~a/JC1xkCKrNFJwebmsz5wTuTqY1xs/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=HZeUVNSMq2g:_t7hlCoSEEQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=HZeUVNSMq2g:_t7hlCoSEEQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=HZeUVNSMq2g:_t7hlCoSEEQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=HZeUVNSMq2g:_t7hlCoSEEQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=HZeUVNSMq2g:_t7hlCoSEEQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=HZeUVNSMq2g:_t7hlCoSEEQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=HZeUVNSMq2g:_t7hlCoSEEQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=HZeUVNSMq2g:_t7hlCoSEEQ:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/HZeUVNSMq2g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/tutorials/plus-tutorials-2/how-to-build-a-custom-jquery-tabs-plugin-new-plus-tutorial/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		<feedburner:origLink>http://net.tutsplus.com/tutorials/plus-tutorials-2/how-to-build-a-custom-jquery-tabs-plugin-new-plus-tutorial/</feedburner:origLink></item>
		<item>
		<title>Build an RSS 2.0 Feed with CodeIgniter</title>
		<link>http://feedproxy.google.com/~r/nettuts/~3/TLOrO9psFlE/</link>
		<comments>http://net.tutsplus.com/tutorials/php/building-an-rss-2-0-feed-with-codeigniter/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 19:19:04 +0000</pubDate>
		<dc:creator>Drazen Mokic</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[code igniter]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[framework]]></category>

		<guid isPermaLink="false">http://net.tutsplus.com/?p=7811</guid>
		<description><![CDATA[<img src="http://nettuts.s3.amazonaws.com/496_ci/ci.jpg" alt="Build an RSS 2.0 Feed with CodeIgniter" width="200" height="200"/>]]></description>
			<content:encoded><![CDATA[<p>
	In this tutorial, we will build a RSS 2.0 Feed with the PHP framework <a href="http://www.codeigniter.com">CodeIgniter</a>. After this tutorial, you will be able to build a feed for any custom website in no time at all.
</p>
<p><span id="more-7811"></span></p>
<h3>Tutorial Details</h3>
<ul>
<li><b>Program</b>: CodeIgniter PHP Framework</li>
<li><b>Version</b>: 1.7.1</li>
<li><b>Difficulty:</b> Easy</li>
<li><b>Estimated Completion Time:</b> 30 minutes</li>
</ul>
<h3>Step 1: What we Need</h3>
<div class="tutorial_image">
   <img src="http://nettuts.s3.amazonaws.com/496_ci/img7.jpg" alt="Finished Product" />
</div>
<p>
	First, we&#8217;ll take a look at the tools needed to get started. Besides an installation of <a href="http://codeigniter.com/">CodeIgniter</a>, we need a running MySQL database with some content from which we can build our feed.
</p>
<p>
	For this purpose, here are some dummy entries you can import. Create a database called <b>tut_feeds</b>. Then,  copy the following code, and import it into your MySQL database.
</p>
<pre name="code" class="sql">
    CREATE TABLE IF NOT EXISTS `posts` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `title` varchar(120) NOT NULL,
      `text` text NOT NULL,
      `date` date NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM;

    INSERT INTO `posts` (`id`, `title`, `text`, `date`) VALUES
    (1, 'Some great article', 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using ''Content here, content here'', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for ''lorem ipsum'' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).', '2009-08-10'),
    (2, 'Another great article', 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using ''Content here, content here'', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for ''lorem ipsum'' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).', '2009-08-10'),
    (3, 'News from myfeed', 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using ''Content here, content here'', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for ''lorem ipsum'' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).', '2009-08-10');
</pre>
<p>This is how it should appear in phpmyadmin. After you have pasted the code in, press the <b>Ok</b> button on the right side.</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/496_ci/img1.jpg" border="0" /></div>
<p>If everything works correctly, you should see have something like this:</p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/496_ci/img2.jpg" border="0" /></div>
<p><!-- Step 2 --></p>
<h3>Step 2: Setting up CodeIgniter</h3>
<p>Before we start writing code, we need to configure CodeIgniter.</p>
<p>Browse to your CI folder, and then into <b>system/application/config</b>. We will need to edit the following files:</p>
<ul>
<li>autoload.php</li>
<li>config.php</li>
<li>database.php</li>
<li>routes.php</li>
</ul>
<p><strong>Edit the autoload.php like so:</strong></p>
<pre name="code" class="php">
	$autoload['libraries'] = array('database');
</pre>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/496_ci/img3.jpg" border="0" /></div>
<p>This will tell CI to load the database automatically; so we don&#8217;t need to load it every time.</p>
<p><strong>Edit the config.php like so:</strong></p>
<pre name="code" class="php">
	$config['base_url'] = "http://localhost/YOUR DIRECTORY";
</pre>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/496_ci/img4.jpg" border="0" /></div>
<p>You need to replace <b>tutorials/ci_feeds</b> with your directory and CI folder.</p>
<p><strong>Edit the database.php like so:</strong></p>
<pre name="code" class="php">
	$db['default']['hostname'] = "localhost"; // your host
    $db['default']['username'] = "root";
    $db['default']['password'] = "";
    $db['default']['database'] = "tut_feeds";
</pre>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/496_ci/img5.jpg" border="0" /></div>
<p>
	With these settings, we tell CI which database to use. Here you also have to replace <i>hostname</i>, <i>username</i> and<br />
	<i>password</i> with your personal database info.
</p>
<p><strong>Edit the routes.php like this:</strong></p>
<pre name="code" class="php">
	$route['default_controller'] = "Feed";
</pre>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/496_ci/img6.jpg" border="0" /></div>
<p>
	The default controller is the <i>&#8220;index&#8221;</i> controller for your application. Every time you open<br />
    <i>localhost/YOUR DIRECTORY</i>, this default controller will be loaded first. We&#8217;ll create the <i>feed</i> in the next step.
</p>
<p><!-- Step 3 --></p>
<h3>Step 3: Creating the Feed Controller</h3>
<p>
	In this controller, all the magic happens. Browse to <b>system/application/controllers</b> and create a new file<br />
	called <b>feed.php</b>. Next, create the <i>Feed</i> controller and have it extend the parent CI Controller.
</p>
<pre name="code" class="php">
	class Feed extends Controller {

      function Feed()
      {
		parent::Controller();
      }
}
</pre>
<p>
	If you are already confused please have a look at Jeffrey&#8217;s<br />
    <a href="http://net.tutsplus.com/videos/screencasts/easy-development-with-codeigniter/">Easy Development with CodeIgniter</a> tutorial.<br />
    After you&#8217;ve learned the basics, return to continue this tutorial! <img src='http://net.tutsplus.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
</p>
<p>
	Before the next step, we&#8217;ll make use of CI&#8217;s great helpers. Load the <i>xml</i> and <i>text</i> helper.
</p>
<pre name="code" class="php">
class Feed extends Controller {

      function Feed()
      {
        parent::Controller();

        $this->load->helper('xml');
		$this->load->helper('text');
      }
}
</pre>
<p><!-- Step 4 --></p>
<h3>Step 4: Creating the Model</h3>
<p>
	Next, will create a model to receive data from the database. If you don&#8217;t know what models are, have a look at the CI<br />
	<a href="http://codeigniter.com/user_guide/general/models.html">userguide</a>. Browse to <b>system/application/models</b><br />
    and create a file called <b>posts_model.php</b>.
</p>
<pre name="code" class="php">
class Posts_model extends Model {

	// get all postings
	function getPosts($limit = NULL)
	{
		return $this->db->get('posts', $limit);
	}
}
</pre>
<p>
	We are using <a href="http://codeigniter.com/user_guide/database/active_record.html">active records</a> to receive data<br />
    from the database. The first parameter declares the table we want to use and with the second we can set a limit &#8211; so we<br />
    can tell CI how many records we want to retrieve.
</p>
<p>
	Perhaps you&#8217;ve noticed that <i>$limit</i> is set to NULL by default. This makes it possible to set a limit, but <b>you don&#8217;t have to</b>.<br />
    If you don&#8217;t set a second parameter, this function will simply return all records.
</p>
<p><!-- Step 5 --></p>
<h3>Step 5: Back to the Feed Controller</h3>
<p>
	Now that we&#8217;ve created our model, we can continue with our <i>feed controller</i>. We&#8217;ll load the <i>posts_model</i> that we just created.
</p>
<pre name="code" class="php">
class Feed extends Controller {

      function Feed()
      {
        parent::Controller();

        $this->load->helper('xml');
		$this->load->helper('text');
        $this->load->model('posts_model', 'posts');
      }
}
</pre>
<p>
	With the second parameter, we assign our model to a different object name &#8211; so we have less to type <img src='http://net.tutsplus.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> . Now we create the <i>index</i><br />
    method which is the method called by default. Let&#8217;s set up some information for the feed view later too.
</p>
<pre name="code" class="php">
	function index()
	{
		$data['feed_name'] = 'MyWebsite.com'; // your website
		$data['encoding'] = 'utf-8'; // the encoding
        $data['feed_url'] = 'http://www.MyWebsite.com/feed'; // the url to your feed
        $data['page_description'] = 'What my site is about comes here'; // some description
        $data['page_language'] = 'en-en'; // the language
        $data['creator_email'] = 'mail@me.com'; // your email
        $data['posts'] = $this->posts->getPosts(10);
        header("Content-Type: application/rss+xml"); // important!
	}
</pre>
<p>
	While the majority of the information above is easy to understand, we will have a look at two of them.<br />
    <i>header(&#8221;Content-Type: application/rss+xml&#8221;);</i> is a very important part. This tells the browser to parse it as<br />
     an RSS Feed. Otherwise the browser will try to parse it as plain text or html.
</p>
<p>
	With <i>$data['posts'] = $this->posts->getPosts(10);</i> we are using our model and are storing all records in the <i>$posts</i> array.<br />
    I set the limit to 10; so it will return, at most, 10 records. You can set this value higher or lower if you want. If we leave it<br />
    blank, like <i>$data['posts'] = $this->posts->getPosts();</i>, it would return all records.
</p>
<p>
	Finally, we need to load the <i>view</i> which we will create in the next step.
</p>
<pre name="code" class="php">
	function index()
	{
		$data['feed_name'] = 'MyWebsite.com';
		$data['encoding'] = 'utf-8'; // the encoding
        $data['feed_url'] = 'http://www.MyWebsite.com/feed';
        $data['page_description'] = 'What my site is about comes here';
        $data['page_language'] = 'en-en';
        $data['creator_email'] = 'mail@me.com';
        $data['posts'] = $this->posts->getPosts(10);
        header("Content-Type: application/rss+xml"); 

        $this->load->view('rss', $data);
	}
</pre>
<p>
	Our <i>$data</i> array is passed as the second parameter to the view file, so we can access it in the view.<br />
    Your feed controller should now look like this:
</p>
<pre name="code" class="php">
class Feed extends Controller {

	function Feed()
	{
		parent::Controller();

		$this->load->helper('xml');
		$this->load->helper('text');
        $this->load->model('posts_model', 'posts');
	}

	function index()
	{
		$data['feed_name'] = 'MyWebsite.com';
		$data['encoding'] = 'utf-8';
        $data['feed_url'] = 'http://www.MyWebsite.com/feed';
        $data['page_description'] = 'What my site is about comes here';
        $data['page_language'] = 'en-en';
        $data['creator_email'] = 'mail@me.com';
        $data['posts'] = $this->posts->getPosts(10);
        header("Content-Type: application/rss+xml");

		$this->load->view('rss', $data);
	}

}
</pre>
<p><!-- Step 6 --></p>
<h3>Step 6: Creating the View</h3>
<p>
	Finally we have to create the view file &#8211; our output. Browse to <b>system/application/views</b> and crate a file called<br />
    <b>rss.php</b>.
</p>
<p>
	First we set the <i>xml version</i> and the <i>encoding</i> within the head.
</p>
<pre name="code" class="php">
	&lt;?php  echo '&lt;?xml version="1.0" encoding="' . $encoding . '"?>' . "\n"; ?>
</pre>
<p>
	Followed by some rss meta information.
</p>
<pre name="code" class="php">
    <rss version="2.0"
        xmlns:dc="http://purl.org/dc/elements/1.1/"
        xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
        xmlns:admin="http://webns.net/mvcb/"
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:content="http://purl.org/rss/1.0/modules/content/">

        <channel>
</pre>
<p>
	Now we will access the array <i>$data</i> from the previous step. We can access this data via the array keys, like so:
</p>
<pre name="code" class="php">
<link><?php echo $feed_url; ?></link>
    <description><?php echo $page_description; ?></description>
    <dc:language><?php echo $page_language; ?></dc:language>
    <dc:creator><?php echo $creator_email; ?></dc:creator>

    <dc:rights>Copyright <?php echo gmdate("Y", time()); ?></dc:rights>
    <admin:generatorAgent rdf:resource="http://www.codeigniter.com/" />
</pre>
<p>
	Now we need to loop, with <i>foreach</i>, to get all records.
</p>
<pre name="code" class="php">
    <?php foreach($posts->result() as $post): ?>

       <item>
<link><?php echo site_url('YOUR URL' . $post->id) ?></link>
          <guid><?php echo site_url('YOUR URL' . $post->id) ?></guid>

          	<description><![CDATA[ <?php echo character_limiter($post->text, 200); ?> ]]&gt;</description>
<pubDate><?php echo $post->date; ?></pubDate>
        </item>

    <?php endforeach; ?>

    	</channel>
	<</rss>
</pre>
<p>
	For <i>link</i> and <i>guide</i>, you have to set a link to your controller where the posts are fetched. For example: <i>my/posts/$post->id</i>.
</p>
<p>
	I hope you noticed CDATA. This is used for text-output (content). Remember how we learned in the head that this is <i>xml</i>;<br />
    so it has to be xml valid. If we don&#8217;t set CDATA we&#8217;ll potentially end up with invalid markup.</p>
<p><!-- Step 7 --></p>
<h3>Step 7: Overview</h3>
<p>
	Now your files should look like this:
</p>
<p><b>system/application/controllers/feed.php</b></p>
<pre name="code" class="php">
class Feed extends Controller {

	function Feed()
	{
		parent::Controller();

		$this->load->helper('xml');
		$this->load->helper('text');
        $this->load->model('posts_model', 'posts');
	}

	function index()
	{
		$data['feed_name'] = 'MyWebsite.com';
		$data['encoding'] = 'utf-8';
        $data['feed_url'] = 'http://www.MyWebsite.com/feed';
        $data['page_description'] = 'What my site is about comes here';
        $data['page_language'] = 'en-en';
        $data['creator_email'] = 'mail@me.com';
        $data['posts'] = $this->posts->getPosts(10);
        header("Content-Type: application/rss+xml");

		$this->load->view('rss', $data);
	}

}
</pre>
<p><b>system/application/models/posts_model.php</b></p>
<pre name="code" class="php">
class Posts_model extends Model {

	// get all postings
	function getPosts($limit = NULL)
	{
		return $this->db->get('posts', $limit);
	}
}
</pre>
<p><b>system/application/views/rss.php</b></p>
<pre name="code" class="php">
	<?php  echo '<?xml version="1.0" encoding="' . $encoding . '"?>' . "\n"; ?>
    <rss version="2.0"
        xmlns:dc="http://purl.org/dc/elements/1.1/"
        xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
        xmlns:admin="http://webns.net/mvcb/"
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:content="http://purl.org/rss/1.0/modules/content/">

        <channel>
<link><?php echo $feed_url; ?></link>
        <description><?php echo $page_description; ?></description>
        <dc:language><?php echo $page_language; ?></dc:language>
        <dc:creator><?php echo $creator_email; ?></dc:creator>

        <dc:rights>Copyright <?php echo gmdate("Y", time()); ?></dc:rights>
        <admin:generatorAgent rdf:resource="http://www.codeigniter.com/" />

        <?php foreach($posts->result() as $post): ?>

            <item>
<link><?php echo site_url('blog/posting/' . $post->id) ?></link>
              <guid><?php echo site_url('blog/posting/' . $post->id) ?></guid>

                <description><![CDATA[ <?php echo character_limiter($post->text, 200); ?> ]]&gt;</description>
<pubDate><?php echo $post->date; ?></pubDate>
            </item>

        <?php endforeach; ?>

        </channel>
    </rss>
</pre>
<p>And our feed looks like this, just with other content <img src='http://net.tutsplus.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="tutorial_image"><img src="http://nettuts.s3.amazonaws.com/496_ci/img7.jpg" border="0" /></div>
<p><!-- Step 7 --></p>
<h3>Conclusion</h3>
<p>
	I hope you&#8217;ve learned how easy it is to build an RSS 2.0 Feed with the power of CodeIgniter. For more tutorials and screencasts on CodeIgniter, check out Jeffrey`s <a href="http://net.tutsplus.com/videos/screencasts/codeigniter-from-scratch-day-7-pagination/">CodeIgniter from Scratch</a> series.
</p>
<ul class="webroundup">
<li>Follow us on <a href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li>
</ul>
<p>
<script type="text/javascript"><!--digg_url = "post permalink (not digg url)"; // -->
</script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></p>

<p><a href="http://feedads.g.doubleclick.net/~a/w_Y-OlFBnQNKL15koDQiOvqH3ao/0/da"><img src="http://feedads.g.doubleclick.net/~a/w_Y-OlFBnQNKL15koDQiOvqH3ao/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/w_Y-OlFBnQNKL15koDQiOvqH3ao/1/da"><img src="http://feedads.g.doubleclick.net/~a/w_Y-OlFBnQNKL15koDQiOvqH3ao/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nettuts?a=TLOrO9psFlE:fw-qvnfOtIw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TLOrO9psFlE:fw-qvnfOtIw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TLOrO9psFlE:fw-qvnfOtIw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TLOrO9psFlE:fw-qvnfOtIw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TLOrO9psFlE:fw-qvnfOtIw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TLOrO9psFlE:fw-qvnfOtIw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/nettuts?i=TLOrO9psFlE:fw-qvnfOtIw:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nettuts?a=TLOrO9psFlE:fw-qvnfOtIw:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/nettuts/~4/TLOrO9psFlE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://net.tutsplus.com/tutorials/php/building-an-rss-2-0-feed-with-codeigniter/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		<feedburner:origLink>http://net.tutsplus.com/tutorials/php/building-an-rss-2-0-feed-with-codeigniter/</feedburner:origLink></item>
	</channel>
</rss><!--
This site's performance optimized by W3 Total Cache:

W3 Total Cache improves the user experience of your blog by caching
frequent operations, reducing the weight of various files and providing
transparent content delivery network integration.

Learn more about our WordPress Plugins: http://www.w3-edge.com/wordpress-plugins/

Page Caching using memcached
Database Caching 18/25 queries in 0.008 seconds using memcached
Content Delivery Network via 

Served from: psdtutsplus.com @ 2009-11-28 20:30:41 -->
