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

<channel>
	<title>Snipe.Net &#187; best practices</title>
	<atom:link href="http://www.snipe.net/tags/best-practices/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.snipe.net</link>
	<description>Bitterness never tasted so sweet</description>
	<lastBuildDate>Thu, 29 Jul 2010 05:03:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Sexy, Cheap and Easy: Not Your Mom, Your Wireframes</title>
		<link>http://www.snipe.net/2010/02/wireframes/</link>
		<comments>http://www.snipe.net/2010/02/wireframes/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 20:51:22 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[application development]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[iplotz]]></category>
		<category><![CDATA[planning]]></category>
		<category><![CDATA[prototyping]]></category>
		<category><![CDATA[wireframes]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=2867</guid>
		<description><![CDATA[I&#8217;m a planning whore. It&#8217;s true. I&#8217;m one of those weirdos that really enjoys creating data flows, use cases, wireframes, and functional requirements documents. My bizarre predalictions aside, wireframes are a critical part of planning any website or web based application. Spending the time to plan your project out well at the very beginning may [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F02%2Fwireframes%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2010%2F02%2Fwireframes%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;m a planning whore. It&#8217;s true. I&#8217;m one of those weirdos that really enjoys creating data flows, use cases, wireframes, and functional requirements documents. My bizarre predalictions aside, wireframes are a critical part of planning any website or web based application.<br />
<span id="more-2867"></span></p>
<p>Spending the time to plan your project out well at the very beginning may seem like a luxury your timeline and budget can&#8217;t allow, but most people realize pretty quickly that failing to do so often ends up costing exponentially more time and money towards the end of the project, when you have exactly <em>none</em> of either to spare.</p>
<p>Scope starts to creep, or features and interface challenges that hadn&#8217;t been thought through before are suddenly at the center of a series of critical and rushed decisions that have to be made. This means that you (and/or your crew) are stressed, and because you&#8217;ve run out of time and money, you end up having to cobble something together that works as a compromise, but doesn&#8217;t stand up to the caliber of work you pride yourself on creating.</p>
<p>For those of you who have been reading this blog for many years, you&#8217;ll recognize the tune I&#8217;m singing. I constantly harp about planning and documenting. My love affair with planning and documentation isn&#8217;t just because of that head injury I suffered as a kid &#8211; its because I&#8217;ve been fucked over so many times and on such a grand scale in the past when I (or my client/manager) have decided to cut corners and just &#8220;crank it out&#8221;. While the &#8220;crank it out&#8221; method may work sometimes, the times that it fails, it fails hard, at the expense of time, money, quality and developer sanity.</p>
<p>Okay, I&#8217;ll get off my soapbox. For now. &lt;/rant&gt;</p>
<p>So, wireframes. I&#8217;ve done them in just about every application you can imagine. Visio, Smartdraw, Omnigraffle, even hand-drawn &#8211; you name it, I&#8217;ve probably tried it. I&#8217;ve been on the eternal quest for the perfect wireframing solution,  but I&#8217;ve always been left wanting.</p>
<h3>But What ARE Wireframes?</h3>
<p><strong>Wireframes are a graphical representation of a website or application that help illustrate the user interface without the clutter of stylized design elements. </strong>If you skip the wireframe process and go right to Photoshop comps, the client can often get so hung up on the fact that they want that button to be blue with rounded corners instead of green with a square corners that critical elements in the UI can be forgotten altogether. Wireframes let you plan through the user interface elements that are required for each screen in a barebones, no-frills manner.</p>
<p><img class="aligncenter size-full wp-image-2872" title="sketchy" src="http://www.snipe.net/wp-content/uploads/2010/02/sketchy.gif" alt="" width="525" height="413" /></p>
<p><strong>I&#8217;m a big fan of sketchy wireframes, especially in the beginning of a project.</strong> I find that if you go to a client with something too polished, they perceive it as a structure that has been decided upon, even when that&#8217;s the furthest thing from the truth. The sketchy styled wireframes have a hand-drawn, loose feel to them that seems to better communicate that it&#8217;s a <em>discussion</em>, not a <em>decision</em>. By avoiding a polished, rigid wireframe, I have found that clients are more able to understand that what they&#8217;re looking at isn&#8217;t meant to represent the finished design.</p>
<p>I used to hand-draw my wireframes &#8211; but the obvious challenges there is that if a change is made to an element that appears on many pages of the site, you now have to re-do all of those drawings. Another disadvantage to pen and paper wireframes is that you have to write a crapload of code if you want to extend the drawing into an interactive format where the client can actually click on elements and see how they behave.</p>
<h3>Evolution: Easy Prototyping</h3>
<p><strong>More recently, I had found a few apps that were a lot closer to what I was looking for. <a href="http://www.balsamiq.com/products/mockups" target="_blank">Balsamiq Mockups</a></strong> is a great application that has a gorgeous sketchy style and a <a href="http://mockupstogo.net/" target="_blank">great library of user-contributed downloadable interface elements</a>, so just about every imaginable interface element is available for free download once you&#8217;ve purchased the product. More interestingly, <strong><a href="http://www.napkee.com/" target="_blank">Napkee</a></strong> is a commercial addon for Balsamiq that allows you to export your wireframes into HTML (with jQuery) or a Flex file, turning static wireframes into a prototyping tool with very little additional work. Neat!</p>
<p><strong>Unfortunately, Napkee ended up being a little buggy sometimes, and perhaps more importantly, Balsamiq doesn&#8217;t natively support Master templates yet.</strong> So once again, when a change was made to the main site navigation, I&#8217;d have to go in and edit 30 files instead of being able to update a Master template and have those changes reflected across the boards.</p>
<p><strong>Another drawback is that Balsamiq does not support the ability to switch back and forth from sketchy style to straight lines. </strong>In my workflow process, what I wanted was to be able to do the rough sketchy style wireframes in the beginning, update them as needed, and then be able to click a button and convert them into a more polished, final-looking set of wireframes that I could hand over to the graphic designers with a client sign-off.</p>
<p>A later contender, <strong><a href="http://www.flairbuilder.com/home/viewer/" target="_blank">Flairbuilder</a></strong>, looked like it might be the answer. It does support the ability to toggle back and forth between sketchy and regular line styles, however the sketchy-style lines somehow didn&#8217;t look as nice as Balsamiq&#8217;s, and (<em>this is the big one</em>) in order to show the client a working prototype that was created with the desktop version, you had to export the file and then <em>ask them to download a proprietary viewer</em>. Fuck that noise. Half my clients are still on IE6 for chrissakes. I&#8217;m not asking them to download anything. So back to Balsamiq I went. Until now.</p>
<h3>The Next Generation</h3>
<p>Enter <strong><a href="http://iplotz.com/" target="_blank">iPlotz</a></strong>. I like it already because the name makes me think of a pixelated rabbi pitching a fit. What are their next product lines going to be, the <em>iKibitz</em> and the <em>iSchmaltz</em>? HAH! I&#8217;m hilarious. But probably more importantly, it fills in the gaps that Balsamiq+Napkee and Flairbuilder couldn&#8217;t &#8211; and even adds some great project organization, management and collaboration tools in to boot.</p>
<p>The interface is pretty intuitive, and they have a nice library of elements from which to choose &#8211; plus, like Balsamiq, they have a <a href="http://iplotz.com/projects.php" target="_blank">public repository of snippets and projects</a> available for download to fill in the gaps. Like Balsamiq, iPlotz has both a web-based version and a desktop version. The desktop version is a must-have for me, since I spend a hideous amount of time (4.5 hours a day) commuting through mountains where I have no connectivity.</p>
<h3>What&#8217;s Awesome</h3>
<ul>
<li>Works on PC, Mac and Linux. (I normally despise AIR applications &#8211; but it works here. Nicely executed.)</li>
<li>Support for Master template files. If our main app nav or layout changes, change it once and it automagically updates on all the pages using that Master. HUGE time saver.</li>
<li>Send work you created in desktop client to your web account, so you can do a lot of the work wherever you want and then upload it  when you&#8217;re ready to use the collaboration tools.</li>
<li>Toggle between sketchy-style, Mac skin and PC skin, great for rough mockups and then converting to polished final versions with just a click.</li>
<li>Export PDF list with thumbnail of annotated elements an annotations, perfect for an organized breakdown of more specific details on each element. LOVE this &#8211; didn&#8217;t know I wanted this feature until I found it here.</li>
<li>Online collaboration with others, allowing clients and co-workers to add notes and comments right into the file.</li>
<li>Detailed version history.</li>
<li>Built-in task management system with milestone, great for organizing work on large projects where tasks can get lost.</li>
<li>Export wireframe pages as PNG.</li>
<li>Share the HTML prototype on their server, or export to ZIP file and upload it to your own.</li>
<li>One-click grid overlay.</li>
<li>Easily embed the prototype in your own websites.</li>
<li>Easily create or import additional UI elements from user contributed snippets.</li>
<li>Properties menu lets you specify exact pixel dimensions for every element if needed.</li>
<li>Separate menu of iPhone UI elements (Android coming soon).</li>
<li>Automatic site map generation.</li>
</ul>
<h3>What Needs Work</h3>
<p>Of course nothing is going to be perfect, and iPlotz is no exception. Here are a few of the things that bug me, <em>none</em> of which are even close to being deal-breakers in my world.</p>
<ul>
<li>Hotkey mapping is a little wonky in some browsers, but that is more an artifact of AIR/Flash than it is iPlotz, I think.</li>
<li>Some elements do not maintain the same sketch style. For example, the module-style widget has rounded corners, which is inconsistent with the rest of the sketchy style&#8217;s squared corners. I also feel it is introduces a level of graphic design that I specifically wish to avoid by using sketchy frames. I have only noticed this on a handful of elements, however, and I spoke to iPlotz founder Mark Vernon today and he assures me that properties like that will be customizable in the near future. </li>
<li>Element library isn&#8217;t as extensive as Balsamiq, but user-contributed snippets seem to be on the rise</li>
<li>I didn&#8217;t see any way to save a frequently used imported snippet to your element library so you can get to the easily for future projects. <strong>UPDATE: </strong>Mark informed me that they&#8217;re going to be pushing out this functionality in one of their next releases. I&#8217;ll be checking it out on their staging server.</li>
</ul>
<h3>My Demo</h3>
<p>In order to give it a fair review, I decided to whip up a small set of mockups, both to give me an idea of what the UI is like, and to be able to show you some &#8220;finished&#8221; products. </p>
<p>Below is the embeddable widget that I could easily stick into a branded HTML page to show my client. Click around in it, and you&#8217;ll see it&#8217;s fully functional. The size was dictated by my blog size, not a iPlotz limitation. You can display it at whatever size you&#8217;d like in your own sire.</p>
<div style="text-align: center; padding-bottom: 15px;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="450" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><param name="src" value="http://iplotz.com/app/viewer.swf?k=bb21379aab442e40608a3121ab798e97&amp;project_name=Snipe test&amp;project_id=31845&amp;page_id=31845_7&amp;e=1&amp;a=19791" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="550" height="450" src="http://iplotz.com/app/viewer.swf?k=bb21379aab442e40608a3121ab798e97&amp;project_name=Snipe test&amp;project_id=31845&amp;page_id=31845_7&amp;e=1&amp;a=19791" allowfullscreen="true" allowscriptaccess="always"></embed></object></div>
<p>Check out my <strong><a href="http://iplotz.com/app/viewer.php?k=9ec5982af4082394ffc8070e86bd4f3b&#038;pr=31845&#038;pg=31845_10&#038;a=19791&#038;sitemap=true#">sitemap demo version here</a></strong>. You can set your wireframes to public or private &#8211; I&#8217;ve got mine set to public so that you can see them, but I probably would keep them private and just assign roles to team members on a real project.</p>
<p>Take a few minutes and click around in the protoype. The nav menus, homepage accordian box, contact form, etc all work, and it required no extra work on my part other than to specify a link in the element&#8217;s properties. (If you&#8217;ve used Balsamiq+Napkee before, the process is basically identical.)</p>
<p>For client deliverables, in addition to the fancy shmancy working protoype, I can easily export single wireframes (using the sketchy style, the Mac OS style or the PC style):</p>
<p><a href="http://www.snipe.net/wp-content/uploads/2010/02/homepage.png"><img src="http://www.snipe.net/wp-content/uploads/2010/02/homepage-560x471.png" alt="" title="homepage" width="560" height="471" class="aligncenter size-large wp-image-2883" /></a></p>
<p><a href="http://www.snipe.net/wp-content/uploads/2010/02/contact.png"><img src="http://www.snipe.net/wp-content/uploads/2010/02/contact-560x471.png" alt="" title="contact" width="560" height="471" class="aligncenter size-large wp-image-2884" /></a></p>
<p>Or I can export them all into one PDF [<a href="http://www.snipe.net/wp-content/uploads/2010/02/mockups.pdf">PDF link</a>]. And this is my favorite part &#8211; the bit I didn&#8217;t realize I needed until I had it &#8211; I can generate a PDF that contains only the elements in the pages that have annotations [<a href="http://www.snipe.net/wp-content/uploads/2010/02/annotations.pdf">PDF link</a>]. This is fantastic because it allows me to explain any special considerations around specific elements in great detail without cluttering up the wireframe itself. I normally have to manually create this documentation, so <strong>this feature alone has just saved me <em>hours</em> of repetitive work</strong>.</p>
<h3>Another Potential Option. Sorta.</h3>
<p><strong>Another interesting contender is <a href="http://www.protoshare.com/" target="_blank">ProtoShare</a></strong>. It looks to have a lot of the same functionality as iPlotz, with online collaboration, version history, project management elements and easy prototyping, however their product is web-only, which I&#8217;m not crazy about, and their free demo required a credit card, which I can&#8217;t stand on principle. </p>
<p><strong><em>Protip: </em></strong>The free trial is supposed to woo new clients and get them on-board and buying as quickly as possible &#8211; asking for a credit card number just so someone can try out your software is a little sleazy, as if you&#8217;re hoping I&#8217;m going to forget to cancel and you can suck me for at least a few bucks before I get around to it. If your product is good and brings value, I will buy it. Don&#8217;t force me. Dick.</p>
<p>For me, web collaboration might work fine for my personal web clients,  but some of the clients we have at the agency I work for have strict  rules about online collaboration in apps that do not live on our server  or theirs, so my particular circumstance might limit the times I can use the collaboration in a practical situation.</p>
<p><strong>The price points on ProtoShare is also a little higher.</strong> iPlotz starts at exactly free, albeit with a very limited plan, only 1 project, max 5 pages. The next plan is $15 a month (although the best value seems to be the yearly plan of $99 which comes with a license for the desktop version), whereas ProtoShare starts at $29/month with restrictions on how many people can review/collaborate. Who knows &#8211; it might be worth the extra scratch, but I <em>hate</em> using web-only tools, and I&#8217;m not going to give them my credit card information just to try out a demo. You can compare their prices in more detail here: <a href="http://www.protoshare.com/cgi-bin/WebObjects/Protoshare.woa/3/nobkmark/pRKey5fwWtE3SvtVvtychM/18.0" target="_blank">ProtoShare</a> vs <a href="http://iplotz.com/price.php" target="_blank">iPlotz</a>. When they come out with a desktop version, I might be willing to check it out. I don&#8217;t see any option for the sketchy-style mockups in ProtoShare either though, which is another negative in their column.</p>
<p>But hey, don&#8217;t take my word for it &#8211; check out the video demos on both sites and download iPlotz. I&#8217;m curious to know what you think.</p>
<p><strong>Note:</strong> The title of this article refers to &#8220;cheap&#8221;. While to many people, &#8220;cheap&#8221; might mean &#8220;free&#8221;, I consider ~$99 a year a reasonable price for such a flexible tool that is such an important part of my job, especially since Balsamiq is $79 and Napkee is $49, so you&#8217;re spending that much even if you go the &#8220;cheaper&#8221; route. Seriously, you spend more than $100 on Starbucks (or whatever corporate coffee swill you&#8217;re into) a month, and I spend more than that on hookers and blow in a single week. You can also buy the iPlotz software outright without the web collaboration, which ends up being about $80 for a one-time purchase. </p>
<p>So that&#8217;s iPlotz. I&#8217;m a now paid member, and I&#8217;m very happy with what they provide. Plus, in talking to Mark today, it sounds like they&#8217;ve got more very cool features coming down the line soon.</p>
<p>What prototyping/wireframing tool do you use? Let me know in the comments!</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2009/01/cheap-or-free-website-status-monitoring/' rel='bookmark' title='Permanent Link: Cheap or Free Website Status Monitoring'>Cheap or Free Website Status Monitoring</a> <small>Its a call you never, ever want to get. &#8220;My...</small></li>
<li><a href='http://www.snipe.net/2008/07/generate-lists-of-banned-words-for-forums-and-other-applications/' rel='bookmark' title='Permanent Link: Generate lists of banned words for forums and other applications'>Generate lists of banned words for forums and other applications</a> <small>If you develop software for a living, or if you...</small></li>
<li><a href='http://www.snipe.net/2009/10/mini-site-facebook-static-fbml/' rel='bookmark' title='Permanent Link: Extending Facebook Static FBML Tabs with Dynamic Content'>Extending Facebook Static FBML Tabs with Dynamic Content</a> <small>This tutorial walks you through how to use DynamicFBML to...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2010/02/wireframes/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>SVN Working Copies and Repository Locations</title>
		<link>http://www.snipe.net/2009/03/getting-started-with-subversion-part-two/</link>
		<comments>http://www.snipe.net/2009/03/getting-started-with-subversion-part-two/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 09:11:35 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[version control]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=1641</guid>
		<description><![CDATA[In part one of this series, you learned what Subversion is and how it can help you, in addition to the terms you&#8217;ll need to become familiar with in order to use Subversion in your development process. Part two of this series goes into more specific detail about potential development environments that may work for [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2009%2F03%2Fgetting-started-with-subversion-part-two%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2009%2F03%2Fgetting-started-with-subversion-part-two%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>In part one of this series, you learned what Subversion is and how it can help you, in addition to the terms you&#8217;ll need to become familiar with in order to use Subversion in your development process. Part two of this series goes into more specific detail about potential development environments that may work for you.<span id="more-1641"></span></p>
<p><strong>Subversion creates a bunch of hidden files and folders inside of every directory in your Working Copy that&#8217;s checked into SVN. </strong>If your Working Copy is on your local computer, you&#8217;ll see these as .svn directories if your system preferences allow you to see hidden files and folders. You don&#8217;t need to worry about these, and you never really need to look at them, but as a result, it is not recommended that your Working Copy be on your live production box. If you decide not to listen to me, you should at least consider <a href="http://claudio.cicali.name/post/2005/08/protecting-svn-entries/" target="_blank">adding a few lines to your .htaccess</a> to deny prying eyes access to your .svn directories.</p>
<h2>Working Copy &amp; Repository on your local machine</h2>
<p><strong>Create a Working Copy on your local machine, create the Repository on your local machine, and FTP/SFTP the files once they&#8217;re committed.</strong> This will really only work if you are the only developer, or your local machine is the only machine changing files. (Okay, that&#8217;s not entirely true &#8211; you can set up the Repository on a network drive and have multiple developers Check Out their own Working Copies to their own computers, but I have run into issues running Subversion over a network.)</p>
<p><img class="aligncenter" style="margin: auto;" title="config1" src="http://www.snipe.net/wp-content/uploads/2009/03/config1.png" alt="config1" width="334" height="491" /></p>
<p>If you&#8217;re running OSX on your local machine, see this <strong><a href="http://www.wikihow.com/Install-Subversion-on-Mac-OS-X" target="_blank">tutorial on WikiHow on how to set up Subversion locally</a></strong>. If you&#8217;re running Windows, there is <strong><a href="http://www.thewebsqueeze.com/web-design-articles/an-introduction-to-subversion.html" target="_blank">an exceptional walkthrough on The WebSqueeze</a></strong> written by Christopher Hyne that is a must-read. Setting up Subversion on Mac or PC is really quite painless, and this is a perfectly valid way to go.</p>
<p><strong>Pros:</strong> Easy, local setup. No external services to set up, your workflow doesn&#8217;t change that much, and you don&#8217;t need an internet connection to commit things to your repository.</p>
<p><strong>Cons:</strong> Possible challenges with running Subversion over a network, you still have to upload your files manually, and you don&#8217;t get the benefit of a slick gui with which to view revision history, as you would using <a href="http://www.beanstalkapp.com" target="_blank">Beanstalk</a> or <a href="http://www.unfuddle.com" target="_blank">Unfuddle</a> for hosted solutions, or by setting up <a href="http://trac.edgewall.org/" target="_blank">Trac</a> (a gui reporting interface/wiki/ticket system) on your server. You can set up Trac on your local machine with Python and some extra work, but that&#8217;s always been too much trouble for me. Just MHO though &#8211; it works great for some people.</p>
<h2>Working Copy on your local machine, remote Repository</h2>
<p><strong>For my personal stuff, since I use <a href="http://www.snipe.net/series/moving-to-mosso/" target="_blank">Mosso</a> as my web host, which does not currently provide Subversion (though I hear they&#8217;re working on it), I use a third party Subversion host, like <a href="http://www.beanstalkapp.com" target="_blank">Beanstalk</a> or <a href="http://www.unfuddle.com" target="_blank">Unfuddle</a>.</strong> I create my Repository on Beanstalk or Unfuddle, Import whatever files I may have created for the project already, Check Out a Working Copy to my laptop, and I&#8217;m all set. I work on files on my laptop, test them on my local installation of Apache/PHP using <a href="http://www.apachefriends.org/en/xampp.html" target="_blank">XAMPP</a>, Commit them to Beanstalk or Unfuddle (depending which service I&#8217;m using to host my Repository), and upload them via FTP/SFTP to the development server area.</p>
<p>The result is a little extra work &#8211; I have to deal with SVN on top of FTP/SFTP, but the security of knowing my ass is covered and I have a detailed revision history makes it entirely worth it to me.</p>
<p><strong>One benefit to using a third-party SVN host, such as <a href="http://www.beanstalkapp.com" target="_blank">Beanstalk</a> or <a href="http://www.unfuddle.com" target="_blank">Unfuddle</a> (besides the fact that it gives you SVN capabilities if your server doesn&#8217;t support it) is that you get a shmancy web interface with which to view your revisions.</strong> Below is a screenshot of the Unfuddle web interface. You can see that it gives me a nice, organized view of all of the history, including revisions messages, numbers and person committing. (This is a project for JPM Morgan that I worked on with my friend <a href="http://www.phpcult.com/blog/" target="_blank">Vidyut Luther</a>.)</p>
<p><img class="aligncenter" style="margin: auto;" title="picture-5" src="http://www.snipe.net/wp-content/uploads/2009/03/picture-5-560x354.png" alt="picture-5" width="560" height="354" /></p>
<p>In getting Vidyut&#8217;s blog url, I see his latest blog posts states that he can, in fact, use Subversion on Mosso, by using Expandrive. I haven&#8217;t tried it yet, and he has, so if you&#8217;re interested in exploring that as an option, <a href="http://www.phpcult.com/blog/using-subversion-with-mosso/" target="_blank">check out his blog post about it</a>. I may give it a shot at some point, but I do like the simplicity of working with a third-party SVN host. I don&#8217;t have to administer anything, just create the Repository and go.</p>
<h2>Remote Branches on dev, remote Repository, rsync to live</h2>
<p>One way of handling your development environment is to set up a Repository on the remote server, Check Out a Working Copy on a dev area on the remote server, such as dev.example.com, and set up individual <em>Branches</em> for each developer. An SVN Branch is simply a copy of the filesystem separate from the main version, called the <em>Trunk</em>. Using Branches allows you to save your half-broken work frequently without interfering with others, yet you can still selectively share information with your collaborators.</p>
<p><a href="http://www.snipe.net/wp-content/uploads/2009/03/config4.png"><img class="aligncenter size-full wp-image-1679" title="config4" src="http://www.snipe.net/wp-content/uploads/2009/03/config4.png" alt="config4" width="550" height="600" /></a></p>
<p><strong>In this scenario, no one ever touches the live files directly, ever. Ever ever.</strong> Everything gets pushed to dev for review, and once it&#8217;s approved, you run the rsync script and rsync is the <em>only</em> utility that ever moves stuff over to live.  It may sound confusing, but <a href="http://www.robsearles.co.uk/2008/12/05/want-to-svn-but-cant-rsync-to-the-rescue/" target="_blank">check out this simple blog post that explains how it can be done</a>.</p>
<p>This can be daunting to set up, since there will be directories on live you may want to skip during the rsync (uploaded images, cache files, etc), but once it&#8217;s set up, it generally works like a charm, and it insures that no one ever screws up the live server, since no one is ever touching the live server.</p>
<p>Creating Branches is incredibly easy &#8211; check out the section on Branches in the free <em><a href="http://svnbook.red-bean.com/en/1.0/ch04s02.html" target="_blank">Version Control with Subversion book</a></em>. They cover this concept and process very well. To give you an idea of what Branches look like, we&#8217;ll use their example structure, with a project named <em>calc</em><em></em>. This is what the original directory structure looks like:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-1683" title="svn-struct" src="http://www.snipe.net/wp-content/uploads/2009/03/svn-struct.png" alt="svn-struct" width="258" height="232" /></p>
<p>You can see in this example, the &#8216;branches&#8217; directory is currently empty, since we haven&#8217;t created any branches yet. The three file icons represent the total files in the project, which live in the Trunk.</p>
<p>Once we create a Branch, named &#8216;my calc branch&#8217; (since it&#8217;s a Branch within the &#8216;calc&#8217; project), you can see that a new directory is shown in the &#8216;branches&#8217; directory, and a copy of the files from the Trunk live there:</p>
<p><img class="aligncenter size-full wp-image-1684" title="svn-struct-branches" src="http://www.snipe.net/wp-content/uploads/2009/03/svn-struct-branches.png" alt="svn-struct-branches" width="323" height="340" /></p>
<p>Parts of each Branch can be selectively merged into the Trunk, so each developer can work on their tasks within their own Branch, break (and hopefully fix) as many things as they need to, Committing their work as they go, without affecting the main Trunk until the revisions are merged.</p>
<p><strong>If you didn&#8217;t want to use Branches, you could add a staging server in this process. </strong>At a place I used to work, we had a development version that was actively worked on, a staging server, and a live server. We would Commit changes to the development server, rsync over to the staging server, and the staging server would automagically rsync every 10 minutes to live. Nothing was synced to staging unless we had kicked the tires and done QA on it on the development box, and if we couldn&#8217;t wait the 10 minutes, we could do a manual push to live by running the rsync script directly from the command line.</p>
<p>These are just a few of the possibilities. How are you using Subversion? Leave your configuration in the comments! And keep your eyes out for the next section that deals with the basic Subversion commands you&#8217;ll need to get started and optional gui applications you can use to make your Subversion experience easier.</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2009/03/getting-started-with-subversion/' rel='bookmark' title='Permanent Link: Getting Started with Subversion'>Getting Started with Subversion</a> <small>As a web developer, hopefully you&#8217;re already using subversion, and...</small></li>
<li><a href='http://www.snipe.net/2008/07/dropbox-versus-foldershare-for-syncing-files-between-computers/' rel='bookmark' title='Permanent Link: Dropbox versus FolderShare for Syncing Files Between Computers'>Dropbox versus FolderShare for Syncing Files Between Computers</a> <small>In my eternal quest to sync up all of the...</small></li>
<li><a href='http://www.snipe.net/2009/02/questions-to-ask-before-starting-a-project/' rel='bookmark' title='Permanent Link: Questions to Ask Before Starting a Project'>Questions to Ask Before Starting a Project</a> <small>We&#8217;re all human, and we all make mistakes and overlook...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2009/03/getting-started-with-subversion-part-two/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Getting Started with Subversion</title>
		<link>http://www.snipe.net/2009/03/getting-started-with-subversion/</link>
		<comments>http://www.snipe.net/2009/03/getting-started-with-subversion/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 08:14:09 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[version control]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=1620</guid>
		<description><![CDATA[As a web developer, hopefully you&#8217;re already using subversion, and this tutorial is utterly useless to you. If so, good job, and carry on! If you&#8217;re a web developer (or web designer, or web programmer, or are in any way creating files that display or do something on the internet) and you&#8217;re not using subversion [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2009%2F03%2Fgetting-started-with-subversion%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2009%2F03%2Fgetting-started-with-subversion%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>As a web developer, hopefully you&#8217;re already using subversion, and this tutorial is utterly useless to you. If so, good job, and carry on! If you&#8217;re a web developer (or web designer, or web programmer, or are in any way creating files that display or do something on the internet) and you&#8217;re not using subversion (or any other version control), this tutorial is for you.<span id="more-1620"></span></p>
<p>Since this is a question that comes up a lot, I&#8217;ve scoured the web for a really basic subversion primer, and although many come close (including the outstanding free online book, <em><a href="http://svnbook.red-bean.com" target="_blank">Version Control with Subversion</a></em>), some people may feel overwhelmed at such an immense amount of information. Truly, I believe the only flaw in the <em>Version Control with Subversion</em> book is that they don&#8217;t include any real life set-up examples when discussing the <a href="http://svnbook.red-bean.com/en/1.1/ch01s04.html" target="_blank">Subversion Architecture</a>.</p>
<p>There are many different ways you can set up your development environment, so I can understand why they would be hesitant to give specific examples, however some people learn best by seeing examples that relate to their lives, so that&#8217;s what I&#8217;m going to attempt to do.</p>
<p>The example set-up we&#8217;ll be looking at is one in which the developer is currently working either locally or remotely, and using FTP/SFTP to move files to the remote development environment webserver. For example, you either:</p>
<ul>
<li>Have a copy of Apache running on your desktop/laptop computer. You store and work on the files on your desktop/laptop, test them locally, and then upload them to your server  -<em> or you</em> -</li>
<li>Make changes to the files locally on your desktop/laptop and test directly in the development space of the webserver (no local webserver) -<em> or you</em> -</li>
<li>Use a text editor that allows you to pull files from FTP directly. You open them from FTP, make your changes, and save to FTP (no local copy stored at all)</li>
</ul>
<p><strong>I should mention that the third option here is absolutely the least recommended, especially since you&#8217;re not using version control.</strong> If your FTP process konks out mid-way through and the file isn&#8217;t saved completely, closing your application could mean losing that file forever. (Yeah, I&#8217;m looking at you, UltraEdit.) Regardless, if you&#8217;re using any of the above scenarios, or something fairly similar, this is aimed at you.</p>
<p>Because the <em>Version Control with Subversion</em> book is so good at explaining so much of this, I&#8217;ll be linking to it liberally, and just filing in the blanks where some people may get a little lost.</p>
<p><strong>Disclaimer: </strong>This article is a <em>very basic</em> overview of subversion. There are many ways you might have your system and repository set up, and I won&#8217;t try to list them all, or even most. I&#8217;m going to use what many web developers would consider a &#8220;real world&#8221; example. You will not walk away from this a subversion guru, or able to deftly administer a subversion server. You will hopefully walk away knowing how to set up a simple repository, connect to it, and begin using svn in your day to day development. If you fuck something up, it is not my fault. Start on a test environment until you get your svn legs and feel pretty comfortable with basic commands.</p>
<p>This article is not a replacement for <em>Version Control with Subversion</em> &#8211; more of a supplement for newbies. <strong>As you begin to delve further into using subversion, that book will become your bible.</strong></p>
<h2>What is Subversion?</h2>
<p>According to the <em>Version Control with Subversion</em> book:</p>
<blockquote><p>Subversion (SVN) is a free/open-source version control system.       That is, Subversion manages files and directories, and the       changes made to them, over time.  This allows you to recover       older versions of your data, or examine the history of how your       data changed.</p>
<p>Subversion can operate across networks, which allows it to       be used by people on different computers.  At some level, the       ability for various people to modify and manage the same set of       data from their respective locations fosters collaboration.       Progress can occur more quickly without a single conduit through       which all modifications must occur.  And because the work is       versioned, you need not fear that quality is the trade-off for       losing that conduit—if some incorrect change is made to       the data, just undo that change. (<a href="http://svnbook.red-bean.com/en/1.4/svn.intro.whatis.html" target="_blank">more</a>)</p></blockquote>
<p>This is a pretty good explanation of what it is, but it can be hard to imagine what that actually looks like or how you&#8217;d use it in practical terms.</p>
<h2>So what can Subversion actually do for <em>you</em>?</h2>
<p><strong>It means you can have multiple developers working on a project without fear of one overwriting the other one&#8217;s work.</strong> Have you ever worked on a project with multiple developers, where everyone is working on the same codebase?</p>
<blockquote><p>&#8220;Hey Bob &#8211; I&#8217;m working on index.php &#8211; don&#8217;t touch it for now. I&#8217;ll let you know when I&#8217;m done, okay?&#8221;</p></blockquote>
<p>or how about</p>
<blockquote><p>&#8220;CRAP! Did you make changes to view.php? You blew out my work! I spent half a day working on that frakking function!&#8221;</p></blockquote>
<p>All of that goes away. Each developer can have their own version of the application or website (called <em>branches</em>), where the changes they make will not impact the other developers, and the changes can then be selectively merged into the main development area, or <em>trunk</em>.</p>
<p><strong>It also means that you have a method by which to track all of the changes you&#8217;ve made to any given file.</strong> Each time you commit changes to the file, subversion assigns that change a unique revision number. This means that if you ever need to roll a file back to a specific revision, you can easily do so with a simple command.</p>
<p><strong>A good example of where you might need to do this is where you&#8217;ve &#8220;fixed&#8221; a bug that broke something else on the site</strong> (and really, who hasn&#8217;t done that?). If you know the now-broken functionality was working before, you can roll back to a previous version of the changed file (or any version before that, if needed) to the point where the functionality wasn&#8217;t broken.</p>
<p><strong>You can also compare revisions side by side, so if you don&#8217;t want to do a full rollback, you can see what changed from one revision to the next </strong>to figure out what you (or they) did to break it so you can undo just that part or find a new solution. Plus, since each developer has their own subversion username, you can see who did what (so you know who to fire/berate/pummel/defenestrate).</p>
<p><strong>In short &#8211; whether you&#8217;re flying solo or working with a team, Subversion can help keep you sane, and bail your ass out when you need it most.</strong></p>
<h2>Sounds awesome, right? Let&#8217;s get started!</h2>
<p>Before we go any further, there are some terms that you&#8217;ll need to understand in order to grok Subversion. Don&#8217;t worry too much if they are hard to remember &#8211; we&#8217;ll be using them a lot, and they&#8217;ll become second nature to you.</p>
<blockquote><p><strong>Repository </strong>- this is the central location where Subversion keeps all of the information about your files, folders, and revisions. The repository can live on the same server as your development environment if your hosting setup has Subversion installed, or it can live somewhere completely separate.</p>
<p>If your hosting company does not have Subversion installed, you can even use a third-party Subversion host like Beanstalk or Unfuddle, whose sole purpose is to store your repository, and only your repository. Your local files are still on your hard drive, and your development files are still on your webserver.</p>
<p><strong>Working Copy </strong>- this is the set of files you work with to make changes to your code, build your application, etc. The working copy usually lives on your hard drive, and would replace the directory you upload from and download to if you were using FTP. Simply put, this is the <em>copy</em> of the files you are meant to be <em>working</em> with. You can have multiple working copies of a site for any single repository, and in fact, you would have multiple versions if you have multiple developers. Each developer would have their own working copy.</p>
<p><strong>Import</strong> &#8211; Importing in Subversion allows you to pull your existing files into a new repository. So, for example, if you have a site that&#8217;s already halfway built before you have the epiphany to use version control, you&#8217;d import your existing stuff into the repository.</p>
<p><strong>Check Out</strong> &#8211; If you already have files in a repository and need to create a new Working Copy, you&#8217;d use Check Out.</p>
<p><strong>Update </strong>- Using the Update command pulls the most recent version from the repository. If you had multiple developers working on the same files, or if you&#8217;re working from multiple computers, you&#8217;d want to make sure you update before you start making any edits to the files. If you fail to update before you make changes, you risk running into a Conflict when you Commit. (see below)</p>
<p><strong>Commit</strong> &#8211; When you&#8217;ve made changes to a file or files in your Working Copy and you&#8217;re ready to push those changes into the repository, you Commit them.</p>
<p><strong>Conflict</strong> &#8211; A Conflict occurs when there are changes on both your local version (Working Copy) of a file and the Repository of that file. For example, Sally makes changes to the file         <tt class="filename">sandwich.txt</tt> in the repository.  Harry has         just changed the file in his working copy and commits it.         Sally doesn&#8217;t update her working copy before committing it and she gets         a conflict (since Harry committed his version <em>after</em> Sally&#8217;s last Update, and Subversion therefore sees Sally&#8217;s version as out of date). More on predicting and resolving conflicts later.</p>
<p><strong>Trunk </strong>- the location within your Working Copy where your main project files live.</p>
<p><strong>Branches</strong> &#8211; individual copies of the project that allow each developer to have their own working version. Changes can be Committed without breaking the Trunk, and are then merged into the Trunk when they are deemed worthy. (More on this in the bonus section of <a href="http://www.snipe.net/2009/03/getting-started-with-subversion-part-two/" target="_blank">part two</a>.)</p></blockquote>
<p>The image below gives a very high level view of how Subversion works.</p>
<p><img class="aligncenter size-full wp-image-1653" title="svn" src="http://www.snipe.net/wp-content/uploads/2009/03/svn.png" alt="svn" width="550" height="500" /></p>
<p>The Repository is your gatekeeper. It is the part of Subversion that makes sure files don&#8217;t get over-written with outdated versions, and allows you to work in tandem with other developers without risking stepping on each others toes. Other than through the command line (to execute import, update, commit, and status commands) or through whatever gui application you prefer using, you never access the Repository directly.</p>
<h2>How often to Commit?</h2>
<p>This is largely a matter of preference. Some developers wait until entire classes or functions are added/edited/etc before committing a file. I personally tend to commit more often, since it gives me a more granular way of seeing what broke something else and rolling it back, etc &#8211; but <strong>the only wrong way to Commit is to not Commit at all</strong>. You do not need to commit every time you change every tiny thing, though. For example, if I had to do some copy changes, I wouldn&#8217;t Commit after changing each word. The revisions would be so broken down, it would be hard to find important changes in the sea of revisions.</p>
<p>You (and your team, if you&#8217;re working in a group) will find a Commit frequency that works for you, as you become more comfortable using Subversion, so don&#8217;t sweat it too much in the beginning.</p>
<p>Now that you know the lingo and what it <em>does</em>, you need to decide how you&#8217;re going to set up your subversion workflow. <strong><a href="http://www.snipe.net/2009/03/getting-started-with-subversion-part-two/">Check out the second part in this series</a></strong>!</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2009/03/getting-started-with-subversion-part-two/' rel='bookmark' title='Permanent Link: SVN Working Copies and Repository Locations'>SVN Working Copies and Repository Locations</a> <small>In part one of this series, you learned what Subversion...</small></li>
<li><a href='http://www.snipe.net/2010/07/introducing-fbmhell-com/' rel='bookmark' title='Permanent Link: Introducing FBMHell.Com'>Introducing FBMHell.Com</a> <small>Good news, everyone! My compulsive need to make websites and...</small></li>
<li><a href='http://www.snipe.net/2008/07/dropbox-versus-foldershare-for-syncing-files-between-computers/' rel='bookmark' title='Permanent Link: Dropbox versus FolderShare for Syncing Files Between Computers'>Dropbox versus FolderShare for Syncing Files Between Computers</a> <small>In my eternal quest to sync up all of the...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2009/03/getting-started-with-subversion/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Practical Mod_Rewrite for Web Developers</title>
		<link>http://www.snipe.net/2009/02/practical-mod_rewrite/</link>
		<comments>http://www.snipe.net/2009/02/practical-mod_rewrite/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 23:44:53 +0000</pubDate>
		<dc:creator>snipe</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://www.snipe.net/?p=1481</guid>
		<description><![CDATA[On *nix-based servers, mod_rewrite can be a powerful tool in any web monkey&#8217;s arsenal, however it still voodoo to many, while others may not even be aware that it can help them at all. What is Mod_Rewrite? Simply put, mod_rewrite is an Apache module that let&#8217;s you rewrite urls based on rules you define. That&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.snipe.net%2F2009%2F02%2Fpractical-mod_rewrite%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.snipe.net%2F2009%2F02%2Fpractical-mod_rewrite%2F&amp;source=snipeyhead&amp;style=normal&amp;service=bit.ly&amp;service_api=R_92bd97f4f8b9fa8a40675b36ea291223" height="61" width="50" /><br />
			</a>
		</div>
<p>On *nix-based servers, mod_rewrite can be a powerful tool in any web monkey&#8217;s arsenal, however it still voodoo to many, while others may not even be aware that it can help them at all.</p>
<h2><span id="more-1481"></span>What is Mod_Rewrite?</h2>
<p><strong>Simply put, mod_rewrite is an Apache module that let&#8217;s you rewrite urls based on rules you define.</strong> That&#8217;s it. Seriously.</p>
<p>Regardless of how confusing some of the rules you may have come across appear to be, all they are doing is taking one url and rewriting as a different url. This rewriting happens at the server level, before the user&#8217;s browser sees anything, so the end result is seamless to them.</p>
<p><strong>When you hear about &#8220;search engine friendly&#8221; urls, you&#8217;re most often seeing mod_rewrite in action.</strong> Mod_rewrite is the Apache module that let&#8217;s you turn a url like:</p>
<p><a class="linkification-ext" title="Linkification: http://www.example.com/shop.php?category=Books&amp;Title=Foo" href="http://www.example.com/shop.php?category=Books&amp;Title=Foo">http://www.example.com/shop.php?category=Books&amp;Title=Foo</a></p>
<p>into:</p>
<p><a class="linkification-ext" title="Linkification: http://www.example.com/shop/books/foo.html" href="http://www.example.com/shop/books/foo.html">http://www.example.com/shop/books/foo.html</a></p>
<p><strong>Some other common uses for mod_rewrite:</strong></p>
<ul>
<li>Directing all traffic from multiple domain names to one domain</li>
<li>Directing all traffic from www and non-www to one location</li>
<li>Blocking traffic from specific websites</li>
<li>Blocking spammy searchbots and offline browsers from spidering your site and eating your bandwidth</li>
<li>Mask file extensions</li>
<li>Preventing image hotlinking (other web pages linking to images on your server)</li>
</ul>
<p>Apache&#8217;s mod_rewrite can be intimidating if you start where you&#8217;re supposed to start &#8211; <a href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html" target="_blank">the Apache documentation</a>, however there are some very useful, common &#8211; and <em>simple</em> rewrite rules that you may wish to consider implementing into your site development plan, if you&#8217;re not doing so already.</p>
<p><strong>Note: If you&#8217;re using Microsoft IIS, you have a few options</strong>, but I don&#8217;t use IIS, so I&#8217;m afraid I won&#8217;t be of much help to you beyond telling you where to look. <a href="http://www.isapirewrite.com/" target="_blank">ISAPI ReWrite</a> seems to be very popular, and there is a free &#8220;lite&#8221; version available.</p>
<h2>Getting Started</h2>
<p>Your mod_rewrite rules typically live in an .htaccess file in your web root. You can only have one .htaccess per directory, but you can have individual .htaccess files in sub-directories under the web root. I generally do not recommend doing this. If mod_rewrite rules from one .htaccess conflict with the rules from the .htaccess in a sub-directory, it can be a real pain in the ass to troubleshoot. Try to avoid it.</p>
<p>When you&#8217;re adding mod_rewrite rules to your .htaccess file, you&#8217;ll want to start by using a conditional that checks to see if mod_rewrite is installed on your server. This can prevent getting a 500 Internal Server Error if you don&#8217;t.</p>
<pre class="brush: c#">&lt;ifmodule mod_rewrite.c&gt;
# Start your (rewrite) engines...
RewriteEngine On

# rules and conditions go here...
&lt;/ifmodule&gt;</pre>
<h2>Directing Multiple Domain Names to a Single Domain Url</h2>
<p>If you have multiple domain names pointing to the same site, mod_rewrite can also help you direct all traffic to a single domain url, to improve your search engine rankings. Search engines don&#8217;t take too kindly to the same content living at multiple urls &#8211; they usually think its an attempt to spam the search engine &#8211; and you can actually be penalized for it. To redirect all traffic to one specific domain name,</p>
<pre class="brush: css">RewriteCond %{HTTP_HOST} !^www\.snipe\.net$ [NC]
RewriteRule ^(.*)$ http://www.snipe.net/$1 [R=301]</pre>
<p>This basically says &#8220;if the domain requested (the HTTP_HOST) does not match <em><a class="linkification-ext" title="Linkification: http://www.snipe.net" href="http://www.snipe.net">www.snipe.net</a></em> then rewrite the url as <em><a class="linkification-ext" title="Linkification: http://www.snipe.net" href="http://www.snipe.net">www.snipe.net</a></em>&#8220;. (Note the escaping slashes after the www and before the .net in the condition.)  The R=301 specifies that the redirect should be a 301 redirect, meaning that the address has moved permanently and search engines should use the new url instead of the old one.</p>
<h2>To www or not to www</h2>
<p>Even if you have only one domain name, if you&#8217;re not redirecting traffic from the &#8220;www&#8221; version to the &#8220;non-www&#8221; version (or vice versa), you may encounter this problem. Whether or not you choose to use the www in your url is largely a branding decision more than anything else (i.e. it doesn&#8217;t really matter in most cases) &#8211; but you should pick one and stick with it.</p>
<p><strong>Require (force) the www</strong></p>
<pre class="brush: css">RewriteCond %{HTTP_HOST} !^www\.snipe\.net$ [NC]
RewriteRule ^(.*)$ http://www.snipe.net/$1 [R=301,L]</pre>
<p><strong>Remove the www</strong></p>
<pre class="brush: css">RewriteCond %{HTTP_HOST} !^snipe\.net$ [NC]
RewriteRule ^(.*)$ http://snipe.net/$1 [R=301,L]</pre>
<h2>Deny traffic by referrer</h2>
<p>There may be a few reasons why you want to block traffic by referrer. Maybe you&#8217;re getting a lot of bandwidth-sucking hits from a spammy website &#8211; or maybe someone is linking to you that you feel does not represent you very well, and you want to pull the plug on traffic from coming their site.</p>
<pre class="brush: css">RewriteCond %{HTTP_REFERER} onebadsite\.com [NC,OR]
RewriteCond %{HTTP_REFERER} anotherbadsite\.com [NC]
RewriteRule .* - [F,L]</pre>
<p>In this snippet, the rule is saying &#8220;If the referring url is onebadsite.com OR anotherbadsite.com, redirect the user to an HTTP Forbidden error.&#8221; The NC specifies that the condition is <em>not</em> case-sensitive, and the OR flag is&#8230; well&#8230; an &#8220;or&#8221;. OR is used with multiple RewriteCond directives to combine them with OR instead of the implicit AND.</p>
<p><img class="aligncenter size-large wp-image-1501" title="snipe-sucks" src="http://www.snipe.net/wp-content/uploads/2009/02/snipe-sucks-560x509.png" alt="snipe-sucks" width="560" height="509" /></p>
<p><strong>Keep in mind &#8211; this method of blocking traffic is hardly foolproof, at least in the latter of the two scenarios above. </strong>If the webmaster of onebadsite.com is linking to you in a way or context you do not want (and you&#8217;ve asked them to remove the link), the above method will cause a user on onebadsite.com&#8217;s website who has clicked on the link to you from onebadsite.com to hit a Forbidden error. If that user has half a brain, they may very well just google your site name or try to access it later from a bookmark &#8211; but it&#8217;s a simple measure you can take to keep the idjits out.</p>
<h2>Blocking Bad Bots and Spiders</h2>
<p>While there is some potential debate as to what is a &#8220;bad&#8221; bot or spider, the consensus seems to that a bot is bad if they do more harm than good, such as e-mail harvesters, site rippers that download entire websites for offline browsing, etc. Even if bandwidth isn&#8217;t so much an issue, I like to block these just on principle.</p>
<p>Please note &#8211; this list is not mine &#8211; it was <a href="http://www.javascriptkit.com/howto/htaccess13.shtml" target="_blank">directly nicked from a list on JavascriptKit</a>.</p>
<pre class="brush: css">RewriteCond %{HTTP_USER_AGENT} ^BlackWidow [OR]
RewriteCond %{HTTP_USER_AGENT} ^Bot\ mailto:craftbot@yahoo.com [OR]
RewriteCond %{HTTP_USER_AGENT} ^ChinaClaw [OR]
RewriteCond %{HTTP_USER_AGENT} ^Custo [OR]
RewriteCond %{HTTP_USER_AGENT} ^DISCo [OR]
RewriteCond %{HTTP_USER_AGENT} ^Download\ Demon [OR]
RewriteCond %{HTTP_USER_AGENT} ^eCatch [OR]
RewriteCond %{HTTP_USER_AGENT} ^EirGrabber [OR]
RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon [OR]
RewriteCond %{HTTP_USER_AGENT} ^EmailWolf [OR]
RewriteCond %{HTTP_USER_AGENT} ^Express\ WebPictures [OR]
RewriteCond %{HTTP_USER_AGENT} ^ExtractorPro [OR]
RewriteCond %{HTTP_USER_AGENT} ^EyeNetIE [OR]
RewriteCond %{HTTP_USER_AGENT} ^FlashGet [OR]
RewriteCond %{HTTP_USER_AGENT} ^GetRight [OR]
RewriteCond %{HTTP_USER_AGENT} ^GetWeb! [OR]
RewriteCond %{HTTP_USER_AGENT} ^Go!Zilla [OR]
RewriteCond %{HTTP_USER_AGENT} ^Go-Ahead-Got-It [OR]
RewriteCond %{HTTP_USER_AGENT} ^GrabNet [OR]
RewriteCond %{HTTP_USER_AGENT} ^Grafula [OR]
RewriteCond %{HTTP_USER_AGENT} ^HMView [OR]
RewriteCond %{HTTP_USER_AGENT} HTTrack [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Image\ Stripper [OR]
RewriteCond %{HTTP_USER_AGENT} ^Image\ Sucker [OR]
RewriteCond %{HTTP_USER_AGENT} Indy\ Library [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^InterGET [OR]
RewriteCond %{HTTP_USER_AGENT} ^Internet\ Ninja [OR]
RewriteCond %{HTTP_USER_AGENT} ^JetCar [OR]
RewriteCond %{HTTP_USER_AGENT} ^JOC\ Web\ Spider [OR]
RewriteCond %{HTTP_USER_AGENT} ^larbin [OR]
RewriteCond %{HTTP_USER_AGENT} ^LeechFTP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mass\ Downloader [OR]
RewriteCond %{HTTP_USER_AGENT} ^MIDown\ tool [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mister\ PiX [OR]
RewriteCond %{HTTP_USER_AGENT} ^Navroad [OR]
RewriteCond %{HTTP_USER_AGENT} ^NearSite [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetAnts [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetSpider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Net\ Vampire [OR]
RewriteCond %{HTTP_USER_AGENT} ^NetZIP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Octopus [OR]
RewriteCond %{HTTP_USER_AGENT} ^Offline\ Explorer [OR]
RewriteCond %{HTTP_USER_AGENT} ^Offline\ Navigator [OR]
RewriteCond %{HTTP_USER_AGENT} ^PageGrabber [OR]
RewriteCond %{HTTP_USER_AGENT} ^Papa\ Foto [OR]
RewriteCond %{HTTP_USER_AGENT} ^pavuk [OR]
RewriteCond %{HTTP_USER_AGENT} ^pcBrowser [OR]
RewriteCond %{HTTP_USER_AGENT} ^RealDownload [OR]
RewriteCond %{HTTP_USER_AGENT} ^ReGet [OR]
RewriteCond %{HTTP_USER_AGENT} ^SiteSnagger [OR]
RewriteCond %{HTTP_USER_AGENT} ^SmartDownload [OR]
RewriteCond %{HTTP_USER_AGENT} ^SuperBot [OR]
RewriteCond %{HTTP_USER_AGENT} ^SuperHTTP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Surfbot [OR]
RewriteCond %{HTTP_USER_AGENT} ^tAkeOut [OR]
RewriteCond %{HTTP_USER_AGENT} ^Teleport\ Pro [OR]
RewriteCond %{HTTP_USER_AGENT} ^VoidEYE [OR]
RewriteCond %{HTTP_USER_AGENT} ^Web\ Image\ Collector [OR]
RewriteCond %{HTTP_USER_AGENT} ^Web\ Sucker [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebAuto [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebCopier [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebFetch [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebGo\ IS [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebLeacher [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebReaper [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebSauger [OR]
RewriteCond %{HTTP_USER_AGENT} ^Website\ eXtractor [OR]
RewriteCond %{HTTP_USER_AGENT} ^Website\ Quester [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebStripper [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebWhacker [OR]
RewriteCond %{HTTP_USER_AGENT} ^WebZIP [OR]
RewriteCond %{HTTP_USER_AGENT} ^Wget [OR]
RewriteCond %{HTTP_USER_AGENT} ^Widow [OR]
RewriteCond %{HTTP_USER_AGENT} ^WWWOFFLE [OR]
RewriteCond %{HTTP_USER_AGENT} ^Xaldon\ WebSpider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus
RewriteRule ^.* - [F,L]</pre>
<p><strong>Once again, this method isn&#8217;t foolproof. </strong>The HTTP_USER_AGENT is quite easily spoofed, and some site ripping applications even allow you to specify what user agent you want to appear as. But if your site is large, implementing this list may make a significant impact on your monthly bandwidth bill.</p>
<h2>Mask File Extensions</h2>
<p>If for some reason you want to hide the fact that you&#8217;re using PHP (or Perl, or whatever), all it takes is a simple line in your .htaccess to have your .php files look like .html files:</p>
<pre class="brush: css">RewriteRule ^(.*)\.html$ $1.php [R=301,L] </pre>
<p>You could even completely obfuscate it if you wanted to, for example serving files that end in .snipe that are really .php files:</p>
<pre class="brush: css">RewriteRule ^(.*)\.snipe$ $1.php [R=301,L] </pre>
<p>In these examples, redirects all files that end in .html (or .snipe) to be served from <em>filename.php</em> so it looks like all your pages are .html (or .snipe) but really they are .php. Notice again that we&#8217;re using a 301 redirect.</p>
<h2>Prevent Image/File Hotlinking</h2>
<p>This snippets prevents people from hotlinking to your files &#8211; that is, linking directly to files hosted on your server from their website, thus sucking your bandwidth. It should be noted that in my experience, this rewrite rule seems somewhat spotty, and doesn&#8217;t always work, so be sure to test thoroughly.</p>
<pre class="brush: css">RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?snipe.net/.*$ [NC]
RewriteRule \.(gif|jpg|swf|flv|png)$ /images/dont_steal_bandwidth_jackass.png [R=302,L] </pre>
<p>This rule basically says &#8220;If the request&#8217;s referrer is not blank (meaning the file was accessed directly in a browser) AND is not snipe.net (case insensitive), rewrite any files that end in .gif, .jpg, .swf, .flv or .png to display the file /images/dont_steal_bandwidth_jackass.png.</p>
<p>I have a friend who was trolling through their server logs (as he tended to do) and he realized that someone was using an image from his server, a Debian logo, if I recall correctly &#8211; as their MySpace background image. My friend spicyjack, being of the snarky persuasion, set up a leech=prevention mod_rewrite that directed all requests for that image that were not coming FROM his server to an image that was&#8230; shall we say&#8230;. not something you&#8217;d want as the background image of your MySpace page. (Google &#8220;hotcurry.jpg&#8221; if you&#8217;re really curious. It&#8217;s NSFW. Or anything, or that matter.)</p>
<h2>Search Engine Friendly URLS &#8211; Make Dynamic Pages appear Static</h2>
<p>To turn site.com/index.php?category=foo&amp;subcat=bar into site.com/category-foo/bar.html, just use:</p>
<pre class="brush: css">RewriteRule ^category-([0-9]+)/([0-9A-Za-z]+).html index.php?category=$1&amp;amp;subcat=$2 </pre>
<p>The category number and the subcategory name are variables, these are now represented by $1 and $2. The round brackets and the stuff inside them will be replaced by the variables. The things inside the round brackets are the regex rules for what the variable can contain. Example [0-9] means that it can contain any number from 0 to 9 and the + sign means that the number can be repeated 1 or more times.</p>
<h2>The [L]ast Word</h2>
<p>The [L] flag tells mod-rewrite that no more rules should be processed after that. Also remember that the order these rules are in DOES matter, so you&#8217;ll want to consider their intended behavior carefully when you&#8217;re planning your .htaccess. If at all possible, have your Apache error logs accessible while experimenting. when mod_rewrite goes wrong, it very often gives you a generic (and infuriating) &#8220;500 Internal Server Error&#8221; instead of anything actually useful to you &#8211; the Apache error logs may help shed some light on things.</p>
<p>Also be sure to test thoroughly whenever using mod_rewrite, since you can seriously break stuff if you&#8217;re not careful.</p>
<h2>More Resources</h2>
<p>Can&#8217;t get enough mod_rewrite? Check out these links for additional information and tips.</p>
<ul>
<li><a href="http://www.htaccesselite.com/mod-rewrite-flags-vt101.html" target="_blank">Mod_Rewrite flags</a></li>
<li><a href="http://www.askapache.com/htaccess/mod_rewrite-tips-and-tricks.html" target="_blank">Mod_rewrite Tips &amp; Tricks</a></li>
<li><a href="http://www.askapache.com/htaccess/mod_rewrite-variables-cheatsheet.html" target="_blank">Mod_Rewrite Cheat Sheet</a></li>
</ul>
<p>And if you&#8217;ve got a handy mod_rewrite rule you can&#8217;t live without, let us know in the comments.</p>


<p>Possibly related posts:<ol><li><a href='http://www.snipe.net/2010/06/upgrading-to-wordpress-3/' rel='bookmark' title='Permanent Link: Upgrading to WordPress 3.0 and Adding Multi-Site'>Upgrading to WordPress 3.0 and Adding Multi-Site</a> <small>WordPress 3.0, code name “Thelonious”, has been released, and it...</small></li>
<li><a href='http://www.snipe.net/2009/03/and-still-more-notes-on-mosso/' rel='bookmark' title='Permanent Link: And Still More Notes on Mosso'>And Still More Notes on Mosso</a> <small>Continuing in the Moving to Mosso series, I&#8217;ve come across...</small></li>
<li><a href='http://www.snipe.net/2005/06/more-about-register_globals/' rel='bookmark' title='Permanent Link: More About register_globals'>More About register_globals</a> <small>If you&#8217;ve been directed to this page, that means that...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.snipe.net/2009/02/practical-mod_rewrite/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>
