<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss1full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:mn="http://usefulinc.com/rss/manifest/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

  <channel rdf:about="http://realm3.com/posts/feed">
    <title>realm3</title>
    <link>http://realm3.com/</link>
    <description>Web application development for the masses.</description>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://realm3.com/articles/command_line_kung_fu_at_ruby_on_rails_october_meeting" />
        <rdf:li rdf:resource="http://realm3.com/articles/web_security_101_at_barcamp_nashville_2009" />
        <rdf:li rdf:resource="http://realm3.com/articles/ubuntu_9.04_on_asus_k40in-a1" />
        <rdf:li rdf:resource="http://realm3.com/articles/lightning_fast_cakephp" />
        <rdf:li rdf:resource="http://realm3.com/articles/nyphp_presentation_-_become_a_bash_ninja" />
        <rdf:li rdf:resource="http://realm3.com/articles/craiglist_hall_of_shame_version_4" />
        <rdf:li rdf:resource="http://realm3.com/articles/tips_for_finding_great_freelance_developers" />
        <rdf:li rdf:resource="http://realm3.com/articles/exhuberant_ctags_in_vim_for_php_on_ubuntu_8.10" />
        <rdf:li rdf:resource="http://realm3.com/articles/compiling_and_using_jsmin_on_ubuntu" />
        <rdf:li rdf:resource="http://realm3.com/articles/installing_django_from_source_on_ubuntu_8.10" />
      </rdf:Seq>
    </items>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/r3articles" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /></channel>

  <item rdf:about="http://realm3.com/articles/command_line_kung_fu_at_ruby_on_rails_october_meeting">
    <link>http://feedproxy.google.com/~r/r3articles/~3/7KEpn3fuBmI/command_line_kung_fu_at_ruby_on_rails_october_meeting</link>
    <title>Command Line Kung Fu at Ruby on Rails October Meeting</title>
    <description>&lt;div style="margin: 0 10px 10px 0; float: left;"&gt;
&lt;a href="http://www.flickr.com/photos/kungfoofool/4036612921/"&gt;&lt;img src="http://farm3.static.flickr.com/2600/4036612921_70f6990e0d_m.jpg" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;A lot of the material I went over was from the &lt;a href="http://realm3.com/articles/nyphp_presentation_-_become_a_bash_ninja"&gt;NYPHP presentation&lt;/a&gt; that I gave earlier this year, but I did spend a little more time on functionality specific to the bash prompt.&lt;/p&gt;
&lt;br style="clear: left;" /&gt;
&lt;p&gt;A couple of the things that seemed to generate the most enthusiasm:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using "cd -" to toggle between the most recently viewed directories.&lt;/li&gt;
&lt;li&gt;The use of GNU screen.&lt;/li&gt;
&lt;li&gt;Using aliases, especially for aliasing mysql --safe-updates&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
&lt;div style="margin: 0 10px 10px 0; float: left;"&gt;
&lt;a href="http://www.flickr.com/photos/kungfoofool/4037364700/"&gt;&lt;img src="http://farm3.static.flickr.com/2685/4037364700_bb3ce72afd_m.jpg" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;Some of the attendees had their own useful suggestions. Daniel Nelson pointed out that Ctrl+N and Ctrl+P is faster than using arrow keys to navigate through your command history. He also pointed out that you could pass command output into arguments using parenthesis. For example:&lt;/p&gt;
&lt;pre&gt;$ diff &amp;lt;(ls -l) &amp;lt;(ls ../ -l)&lt;/pre&gt;
&lt;p&gt;That's pretty slick if you ask me!&lt;/p&gt;
&lt;p&gt;A lot of PHP guys showed up, so there was some interest in a small function I wrote to parse out information from the php.net information pages. Here it is in it's full glory:&lt;/p&gt;
&lt;pre class="code"&gt;
phpargs() {
    curl -s http://us3.php.net/$1 | \
    sed -n '/&amp;lt;div class="methodsynopsis dc-description"&amp;gt;/,/&amp;lt;\/div&amp;gt;/p' | \
    sed 's/&amp;lt;[^&amp;gt;]*&amp;gt;//g' | tr -d "\n"
    echo
}
&lt;/pre&gt;
&lt;p&gt;It's pretty basic, but if you add this to your bash profile you can run it by passing a function name.&lt;/p&gt;
&lt;pre&gt;
$ phpargs strpos
&lt;strong&gt;     int strpos    ( string $haystack   , mixed $needle   [, int $offset = 0  ] )&lt;/strong&gt;
&lt;/pre&gt;
&lt;p&gt;Again, if you're reading this and you're not checking out your local user groups, then I encourage you to do so! Even smaller cities often have user groups and they are a valuable place to both learn things and share what you know.&lt;/p&gt;
&lt;h3&gt;Related Links&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.meetup.com/nashvilleruby/"&gt;Nashville Ruby on Rails Meetup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/r3articles/~4/7KEpn3fuBmI" height="1" width="1"/&gt;</description>
    <dc:date>2009-10-23 09:00:08</dc:date>
  <feedburner:origLink>http://realm3.com/articles/command_line_kung_fu_at_ruby_on_rails_october_meeting</feedburner:origLink></item>

  <item rdf:about="http://realm3.com/articles/web_security_101_at_barcamp_nashville_2009">
    <link>http://feedproxy.google.com/~r/r3articles/~3/bXTI14fwYK4/web_security_101_at_barcamp_nashville_2009</link>
    <title>Web Security 101 at BarCamp Nashville 2009</title>
    <description>&lt;strong&gt;Edit: 10/18/2009&lt;/strong&gt; - Here's the video and slides. The audio on the video doesn't kick in until about 9 minutes in (as I start going over framework security issues).&lt;/p&gt;

&lt;center&gt;
&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="386" id="utv648594" name="utv_n_610676"&gt;&lt;param name="flashvars" value="loc=%2F&amp;amp;autoplay=false&amp;amp;vid=2369801" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="src" value="http://www.ustream.tv/flash/video/2369801" /&gt;&lt;embed flashvars="loc=%2F&amp;amp;autoplay=false&amp;amp;vid=2369801" width="480" height="386" allowfullscreen="true" allowscriptaccess="always" id="utv648594" name="utv_n_610676" src="http://www.ustream.tv/flash/video/2369801" type="application/x-shockwave-flash" /&gt;&lt;/object&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;div style="width:425px;text-align:left" id="__ss_2269233"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/brian_dailey/2009-barcamp-nashville-web-security-101" title="2009 Barcamp Nashville   Web Security 101"&gt;2009 Barcamp Nashville   Web Security 101&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=2009barcampnashville-websecurity101-091018190232-phpapp02&amp;stripped_title=2009-barcamp-nashville-web-security-101" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=2009barcampnashville-websecurity101-091018190232-phpapp02&amp;stripped_title=2009-barcamp-nashville-web-security-101" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/brian_dailey"&gt;brian_dailey&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;

&lt;br/&gt;&lt;br/&gt;&lt;a href="http://barcampnashville.com/session/web-security-101"&gt;&lt;img src="/img/articles/barcamp.png" border="0" style="border: 1px solid #000;" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br/&gt;
&lt;p&gt;I'll be speaking at the Nashville BarCamp 2009, giving a brief talk on application-layer security. You can read more details on the &lt;a href="http://barcampnashville.com/session/web-security-101"&gt;BarCamp information page&lt;/a&gt;.&lt;img src="http://feeds.feedburner.com/~r/r3articles/~4/bXTI14fwYK4" height="1" width="1"/&gt;</description>
    <dc:date>2009-10-02 11:11:44</dc:date>
  <feedburner:origLink>http://realm3.com/articles/web_security_101_at_barcamp_nashville_2009</feedburner:origLink></item>

  <item rdf:about="http://realm3.com/articles/ubuntu_9.04_on_asus_k40in-a1">
    <link>http://feedproxy.google.com/~r/r3articles/~3/s-hWbeU-m94/ubuntu_9.04_on_asus_k40in-a1</link>
    <title>Ubuntu 9.04 on Asus K40IN-A1</title>
    <description>&lt;p&gt;&lt;i&gt;I'll be updating this periodically as I resolve driver problems.&lt;br/&gt;
&lt;b&gt;Updated July 11, 2009:&lt;/b&gt; Got Nvidia driver running, also fixed issues with trackpad scroll.&lt;br/&gt;

&lt;b&gt;Last updated August 9, 2009:&lt;/b&gt;  BIOS 213 upgrade from ASUS fixed external speakers.
&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;The laptop I just purchased is an &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16834220542"&gt;ASUS K40&lt;/a&gt;. By default, it's running Windows Vista, so of course the first thing I do when I get it is set it up as a dual boot with Ubuntu.&lt;/p&gt;
&lt;h3&gt;Default Install&lt;/h3&gt;
What works:
&lt;ul&gt;
&lt;li&gt;Wireless&lt;/li&gt;
&lt;li&gt;Function keys for brightness, volume, play/stop/next/previous&lt;/li&gt;
&lt;li&gt;Mouse&lt;/li&gt;
&lt;/ul&gt;http://news.cincinnati.com/article/20090727/EDIT02/907270353/1019/EDIT/New+rule+on+appraisers+burdens+home+buyer
What doesn't:
&lt;ul&gt;
&lt;li&gt;Native resolution is 1366x768, but it's set to 1280x720 and doesn't recognize Nvidia. Attempted to install Nvidia drivers but so far no luck.&lt;/li&gt;
&lt;li&gt;Speakers do not appear to be working (listed under volume controls as 'HDA NVidia (Alsa Mixer)', but I am getting audio through the headsets.&lt;/li&gt;
&lt;li&gt;Mouse scroll doesn't work&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;July 11, Mostly Fixed&lt;/h3&gt;
&lt;p&gt;I got most of the functionality working by installing the latest Nvidia Linux driver, version 185.18.14, from Nvidia.com (&lt;a href="http://www.nvidia.com/object/linux_display_archive.html"&gt;listed here&lt;/a&gt;). To do what I did, do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download the Nvidia.run file to your desktop.&lt;/li&gt;
&lt;li&gt;Press Ctrl+Alt+F6 and log in. Navigate to the desktop directory...&lt;br/&gt;
&lt;pre&gt;
cd Desktop
chmod +x NVIDIA*
sudo sh NVIDIA[press Tab to auto-complete the filename]
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In my case, it ran the necessary compile routines, rebooted, and I found that the resolution is now native, Compiz works well, and now even the two-fingered mouse scroll function works as it should. The wireless on/off toggle switch works, but I'm not sure if that worked before or not.&lt;/p&gt;

&lt;h3&gt;August 9, BIOS Fixes Front Speakers&lt;/h3&gt;
&lt;p&gt;Updating the BIOS to the 213 release from ASUS fixed the external laptop speakers.&lt;/p&gt;
&lt;p&gt;I'm still having period problems with the &lt;a href="http://ubuntuforums.org/showpost.php?p=7693435&amp;postcount=22"&gt;Atheros wireless card&lt;/a&gt; staying connected. While it's annoying, it's not annoying enough to keep using Vista.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/r3articles/~4/s-hWbeU-m94" height="1" width="1"/&gt;</description>
    <dc:date>2009-07-08 21:01:32</dc:date>
  <feedburner:origLink>http://realm3.com/articles/ubuntu_9.04_on_asus_k40in-a1</feedburner:origLink></item>

  <item rdf:about="http://realm3.com/articles/lightning_fast_cakephp">
    <link>http://feedproxy.google.com/~r/r3articles/~3/dcQCbp_O5Mo/lightning_fast_cakephp</link>
    <title>Lightning Fast CakePHP</title>
    <description>&lt;h1&gt;Lightning Fast Caching for CakePHP&lt;/h1&gt;
&lt;h3&gt;Frameworks: Benefits Come At A Cost&lt;/h3&gt;
&lt;p&gt;It is well known that CakePHP is not the fastest gun in the west. &lt;a href="http://paul-m-jones.com/blog/?p=238"&gt;Paul Jones&lt;/a&gt; has published some great benchmark tests that compare the various frameworks against straight up PHP and HTML. I know that there are a lot of objections to this sort of test:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strike&gt;The benchmarks are somewhat dated: some of these frameworks have improved their performance.&lt;/strike&gt; &lt;b&gt;Edit:&lt;/b&gt; Paul tells me that the frameworks have &lt;i&gt;not&lt;/i&gt; improved and in fact some of have gotten worse. He's working on a new round of tests but doesn't know when it'll be out yet.&lt;/li&gt;
	&lt;li&gt;Comparing the complicated tasks that frameworks routinely do against &amp;lt;?php echo 'Hello, world!'; ?&amp;gt; isn't really fair.&lt;/li&gt;

&lt;/ul&gt;
&lt;p&gt;Despite numerous objections, the maxim still stands: frameworks come with a performance hit.&lt;/p&gt;
&lt;p&gt;It boils down to this:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Spend more time (and time equals money) on development.&lt;/li&gt;
	&lt;li&gt;Spend more money on scaling hardware to meet demands&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It's been pointed out by much smarter engineers than yours truly that development time is, generally speaking, much more expensive than scaling hardware. Therefore, many companies wisely choose to use a framework and enjoy the many advantages that come with it.&lt;/p&gt;

&lt;h3&gt;A Simultaneous Stroke Of Luck And Misfortune&lt;/h3&gt;

&lt;p&gt;You build a site on CakePHP, you launch it, and you hope the world beats a path to your door. Lets assume they do just that, but alas, you underestimated server capacity, the firehose of end-users, and the time it takes to migrate to a more robust environment. You need a quick fix.&lt;/p&gt;
&lt;p&gt;If you have dynamic content, then you want to still give it to your users. Caching some pages for a few seconds or even minutes means that users may get information that is slightly dated, but in this case you don't care.&lt;/p&gt;
&lt;p&gt;Here are the requirements for our caching mechanism:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Do not cache pages for logged in users.&lt;/li&gt;
	&lt;li&gt;Serve a cached page if available.&lt;/li&gt;
	&lt;li&gt;Create a whitelist of pages that are not cached (search results, etc).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Have Your CakePHP And Eat It, Too&lt;/h3&gt;
&lt;p&gt;CakePHP works by routing all of your requests through webroot/index.php. The slowdown doesn't really occur until you launch the CakePHP Dispatcher. You can spend a lot of time tracking down performance hits in the CakePHP router, your own application code, or in some third-party code, but that takes time. The fastest way to make your application quicker is to skip all of that completely.&lt;/p&gt;
&lt;p&gt;If you're familiar with CakePHP, you'll know that it already has a lot of caching built right in. You can cache views, queries, or other components, but maybe that's just not enough. We need &lt;i&gt;lightning&lt;/i&gt; fast results with minimal server impact.&lt;/p&gt;
&lt;p&gt;Therefore, our flow is as follows:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Check to see if a user is logged in.&lt;/li&gt;
	&lt;ul&gt;

		&lt;li&gt;If yes, then go ahead and dispatch. (This modification works best if most of your traffic isn't going to be logged in. )&lt;/li&gt;
		&lt;li&gt;If no, then check and see if we have a non-expired cached version of the page.&lt;/li&gt;
		&lt;ul&gt;
			&lt;li&gt;If a cached version is available, render it.&lt;/li&gt;
			&lt;li&gt;If not, dispatch, capture the dispatch, and write it to a cache.&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/ul&gt;

&lt;/ul&gt;
&lt;p&gt;We'll actually be making modifications to webroot/index.php underneath the dreaded comment by CakePHP:&lt;/p&gt;
&lt;pre class="code"&gt;
/**
 * Editing below this line should not be necessary.
 * Change at your own risk.
 *
*/
&lt;/pre&gt;

&lt;h3&gt;Decide Where To Cache&lt;/h3&gt;
&lt;p&gt;In this example I'm going to use a file system cache. It's easier to set up, but just remember that caching in memory is faster than caching on the disk. You can easily take this example and use Memcache instead.&lt;/p&gt;
&lt;p&gt;To cache each page, we're going to need to create a key for each page. For this example, we're going to use the actual page URL, which is passed as $_GET['url'] (if you have .htaccess set up properly).&lt;/p&gt;
&lt;pre class="code"&gt;
	$cache_key = md5($_GET['url']);
&lt;/pre&gt;

&lt;p&gt;You could also create a human-readable key by replacing slashes with underscores, but simply creating a hash of the URL is a pretty quick solution.&lt;/p&gt;
&lt;p&gt;I'm going to save this to the tmp/cache directory, but as I mentioned, memcache is a far better solution.&lt;/p&gt;
&lt;pre class="code"&gt;
    $cached_file_name = CAKE_CORE_INCLUDE_PATH . 'app/tmp/cache/view_cache_' . $cache_key;
&lt;/pre&gt;

&lt;h3&gt;Detecting User Login&lt;/h3&gt;
&lt;p&gt;CakePHP uses it's own session name, so the first thing to do is grab session information. If your using a default install, it's probably named CAKEPHP.&lt;/p&gt;
&lt;pre&gt;
	session_name('CAKEPHP');
	session_start();
&lt;/pre&gt;

&lt;p&gt;You can leave the line checking for a favicon.ico request (I believe this is probably there because a lot of users do not have a favicon, so each request for that non-existant file would require a costly CakePHP dispatch call).&lt;/p&gt;
&lt;p&gt;Just before $Dispatcher is called, we can see if this user is logged in.&lt;/p&gt;
&lt;pre class="code"&gt;
	if (isset($_GET['url']) &amp;&amp; $_GET['url'] === 'favicon.ico') {
		return;
	} else {
		if (
			// Do not show cache if user is logged in
			isset($_SESSION['User'])
		) {
			// Dispatch as normal.
			if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) {
				trigger_error("CakePHP core could not be found.  Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
			}
			$Dispatcher = new Dispatcher();
			$Dispatcher-&gt;dispatch($url);
		} else {
			// Do nothing.
		}
	}
&lt;/pre&gt;
&lt;p&gt;At this point, we're dispatching if the user has a session, otherwise, the user gets nothing. The next thing on our list is to check and see if a cached version of the page is available.&lt;/p&gt;
&lt;pre class="code"&gt;
		if (
			// User logged in
		) {
			// Dispatch 
&lt;span style="color: red;"&gt;
		} else if (file_exists($cached_file_name) &amp;&amp; filemtime($cached_file_name) &gt; (time()-300)) {
			readfile($cached_file_name);
			// echo '&lt;!-- cached version from ' . (time() - filemtime($cached_file_name)) . ' seconds ago --&gt;';

&lt;/span&gt;
		} else {
			// Do nothing.
		}
&lt;/pre&gt;
&lt;p&gt;In the above, we're first checking to see if the cache exists, and since we're using a file cache, we also have to see how old the file is (in this case five minutes). If we were using Memcache, we could configure the cache to expire automatically.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;readfile&lt;/i&gt; is a quick method to read the contents of the file and spit it straight out to the browser.&lt;/p&gt;
&lt;p&gt;The next step is to handle a request from a user with no session when the cache is expired or unavailable.&lt;/p&gt;
&lt;pre class="code"&gt;
		if ( /* User logged in */ ) {
			// Dispatch
		} else if ( /* Cache available */ ) {
			// Render cache.
		} else {
&lt;span style="color: red;"&gt;
			// Dispatch, regenerate catch.
			if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) {
				trigger_error("CakePHP core could not be found.  Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
			}
			$Dispatcher = new Dispatcher();
			$output = $Dispatcher-&gt;dispatch($url, array('return' =&gt; 1));
			file_put_contents($cached_file_name, $output);
			echo $output;

&lt;/span&gt;
		}
&lt;/pre&gt;
&lt;p&gt;The important part here are the parameters we're passing to the $Dispatcher-&amp;gt;dispatch() method. The second parameter tells the dispatcher that we don't want it to write output directly to the browser, instead, we want it returned so we can capture it in $output.&lt;/p&gt;
&lt;p&gt;The next line simply writes the contents of $output to our cache file, and then echo it all out to the browser. Obviously, you'll want to add error-handling here in case the write to cache fails.&lt;/p&gt;

&lt;p&gt;At this point, you should have a working cache, but this means *every* page is going to be fetched from cache. That includes dynamic pages like search results, a login page... everything. Obviously, that means no users can log in, and your application is effectively broken. Great job, padawan! Let's get to fixing it.&lt;/p&gt;

&lt;h3&gt;White Listing Pages&lt;/h3&gt;
&lt;p&gt;In the first logic test we checked to see if the user was logged in, and dispatched the page if they were. We're going to add these additional tests there.&lt;/p&gt;

&lt;pre class="code"&gt;
		if (
			// Do not show cache if user is logged in
			isset($_SESSION['User'])
&lt;span style="color: red;"&gt;
			// Do not cache the login or signup page.
			|| (isset($_GET['url']) &amp;&amp; strpos($_GET['url'], 'users/login') !== FALSE)
			// Do not cache messages page 
			|| (isset($_GET['url']) &amp;&amp; preg_match('/messages\/index$/', $_GET['url']) !== 0)
			// Do not cache search results
			|| (isset($_GET['url']) &amp;&amp; preg_match('/search\/index$/', $_GET['url']) !== 0)
&lt;/span&gt;
		) {
&lt;/pre&gt;
&lt;p&gt;You can use &lt;a href="http://php.net/strpos"&gt;strpos&lt;/a&gt; (faster) or &lt;a href="http://php.net/preg_match"&gt;preg_match&lt;/a&gt; (a little slower) to match URLs that you do not want to cache.&lt;/p&gt;

&lt;h3&gt;Hooray! Uber-Fast CakePHP!&lt;/h3&gt;
&lt;p&gt;The final code placed after your CORE_PATH should look something like this:&lt;/p&gt;
&lt;pre class="code"&gt;

	$cached_file_name = CAKE_CORE_INCLUDE_PATH . 'app/tmp/cache/view_cache';
	// url is not set for root path.
	if (isset($_GET['url'])) {
		$cached_file_name .= md5($_GET['url']);
	}

	session_name('CAKEPHP');
	session_start();

	if (isset($_GET['url']) &amp;&amp; $_GET['url'] === 'favicon.ico') {
		return;
	} else {
		if (
			// Do not show cache if user is logged in
			// This session name might vary by your application.
			isset($_SESSION['User'])
			// Do not cache the login or signup page.
			|| (isset($_GET['url']) &amp;&amp; strpos($_GET['url'], 'users/login') !== FALSE)
			// Do not cache messages page 
			|| (isset($_GET['url']) &amp;&amp; preg_match('/messages\/index$/', $_GET['url']) !== 0)
			// Do not cache search results
			|| (isset($_GET['url']) &amp;&amp; preg_match('/search\/index$/', $_GET['url']) !== 0)
		) {
			if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) {
				trigger_error("CakePHP core could not be found.  Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
			}
			$Dispatcher = new Dispatcher();
			$Dispatcher-&gt;dispatch($url);
		} else if (file_exists($cached_file_name) &amp;&amp; filemtime($cached_file_name) &gt; (time()-300)) {
			// Check for non-expired cached version.
			readfile($cached_file_name);
			// For debugging speed, you can uncomment this.
			// echo '&lt;!-- cached version from ' . (time() - filemtime($cached_file_name)) . ' seconds ago --&gt;';
		} else {
			// Dispatch, regenerate catch.
			if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) {
				trigger_error("CakePHP core could not be found.  Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
			}
			$Dispatcher = new Dispatcher();
			$output = $Dispatcher-&gt;dispatch($url, array('return' =&gt; 1));
			file_put_contents($cached_file_name, $output);
			echo $output;
		}
	}

&lt;/pre&gt;
&lt;p&gt;If this approach was helpful to you, or on the otherhand, it seems terribly wrong-headed, just let me know via the comments. You can also shoot me an email, my first name at this domain name.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/r3articles/~4/dcQCbp_O5Mo" height="1" width="1"/&gt;</description>
    <dc:date>2009-06-19 15:33:29</dc:date>
  <feedburner:origLink>http://realm3.com/articles/lightning_fast_cakephp</feedburner:origLink></item>

  <item rdf:about="http://realm3.com/articles/nyphp_presentation_-_become_a_bash_ninja">
    <link>http://feedproxy.google.com/~r/r3articles/~3/8xsUYvBU9nU/nyphp_presentation_-_become_a_bash_ninja</link>
    <title>NYPHP Presentation - Become A Bash Ninja</title>
    <description>&lt;p&gt;The objective of this presentation was to gently introduce GUI users to shell usage, and hopefully to teach some new tricks to seasoned developers.&lt;/p&gt;
&lt;p&gt;I mentioned &lt;a href="http://dotfiles.org"&gt;DotFiles.org&lt;/a&gt; as a place to get familiar with more advanced configuration. Also check out &lt;a href="http://commandlinefu.com/"&gt;Command Line Fu&lt;/a&gt;.&lt;p&gt;
&lt;p&gt;I highly recommend participating in your local (insert programming preference here) user group. It's a great opportunity to learn new things or perhaps share things you've learned with others.&lt;/p&gt;
&lt;p&gt;The presentation was filmed and then edited by my good friend (and excellent photographer) &lt;a href="http://www.jamesallenwalker.com"&gt;James Allen Walker&lt;/a&gt;. James is also working on a project for WORLD magazine called &lt;a href="http://worldontheroad.tumblr.com/"&gt;World On The Road&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Video - Part 1&lt;/h3&gt;
&lt;center&gt;
&lt;object width="400" height="300"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=3887943&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=3887943&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;h3&gt;Video - Part 2&lt;/h3&gt;
&lt;object width="400" height="300"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=6049500&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=6049500&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;br /&gt;Video by &lt;a href="http://vimeo.com/user1445026"&gt;James Allen Walker&lt;/a&gt;.
&lt;/center&gt;
&lt;h3&gt;Slides&lt;/h3&gt;
&lt;center&gt;
&lt;div style="width:425px;text-align:left" id="__ss_1195990"&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=nyphppresentation-090325090250-phpapp01&amp;stripped_title=nyphp-march-2009-presentation" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=nyphppresentation-090325090250-phpapp01&amp;stripped_title=nyphp-march-2009-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;/center&gt;

&lt;p&gt;My dot files are available here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://dotfiles.org/~brian_dailey/.vimrc"&gt;Vim Configuration File&lt;/a&gt; - There are a lot of additional plugins that I use, in addition to this.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dotfiles.org/~brian_dailey/.bashrc"&gt;Bash Aliases &amp;amp; Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dotfiles.org/~brian_dailey/.screenrc"&gt;GNU Screen Config&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is a copy of the NYPHP blurb:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
It's March. Not much happens in March. Except, of course, for the March General Meeting, where we're pleased to have karate kid Brian Dailey show us how to slice through the original IDE - the command line. Even if you're an avid GUI user, these techniques are always useful - and great at impressing your friends - so join Brian and step up to get your own black belt.
&lt;/p&gt;&lt;p&gt;
The command line environment can be a powerful tool in a developer's toolkit. Learning to use it well can make you a more productive and more versatile developer.
&lt;/p&gt;&lt;p&gt;
This presentation is an introduction to the use of the shell as a development environment. The talk will go over the basics of shell navigation, including shortcuts that even seasoned CLI users may find useful.
&lt;/p&gt;&lt;p&gt;
The presentation will also briefly cover some of the most useful tools available to PHP developers: GNU screen for your multitasking needs, using vim as and IDE, and automated deployment with Phing.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Links&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.nyphp.org"&gt;New York PHP Users Group Community&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jamesallenwalker.com"&gt;James Allen Walker, Photographer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/r3articles/~4/8xsUYvBU9nU" height="1" width="1"/&gt;</description>
    <dc:date>2009-03-25 10:09:28</dc:date>
  <feedburner:origLink>http://realm3.com/articles/nyphp_presentation_-_become_a_bash_ninja</feedburner:origLink></item>

  <item rdf:about="http://realm3.com/articles/craiglist_hall_of_shame_version_4">
    <link>http://feedproxy.google.com/~r/r3articles/~3/KEEvPmkUDeA/craiglist_hall_of_shame_version_4</link>
    <title>Craiglist Hall Of Shame Version 4</title>
    <description>&lt;p&gt;It's time for another list of horrible job postings gone wrong, brought to you by Craigslist!&lt;/p&gt;
&lt;p&gt;My advice? If you're looking for a developer, I &lt;a href="/articles/tips_for_finding_great_freelance_developers"&gt;have some basic suggestions&lt;/a&gt;.&lt;/p&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;p&gt;Throwing new developers at a project (even "talented" ones) doesn't miraculously make it meet your deadline. I can't help but wonder what happened to this guy, given that this was posted on a Thursday at 9pm, and the project is due on a Friday at 11am. Did a talented Java developer miraculously pull this off? Somehow I doubt it. The desperation here is almost palpable. (I obscured the phone number on this one.)&lt;/p&gt;
&lt;div class="craigslist" style="background-color: #eee; font-family: serif;"&gt;
&lt;h2&gt;talented Java/php web expert needed ASAP&lt;/h2&gt;
&lt;hr&gt;
Reply to: &lt;a href="mailto:&amp;#103;&amp;#105;&amp;#103;&amp;#115;&amp;#45;&amp;#55;&amp;#53;&amp;#48;&amp;#51;&amp;#51;&amp;#57;&amp;#57;&amp;#48;&amp;#50;&amp;#64;&amp;#99;&amp;#114;&amp;#97;&amp;#105;&amp;#103;&amp;#115;&amp;#108;&amp;#105;&amp;#115;&amp;#116;&amp;#46;&amp;#111;&amp;#114;&amp;#103;?subject=talented%20Java/php%20web%20expert%20needed%20ASAP"&gt;&amp;#103;&amp;#105;&amp;#103;&amp;#115;&amp;#45;&amp;#55;&amp;#53;&amp;#48;&amp;#51;&amp;#51;&amp;#57;&amp;#57;&amp;#48;&amp;#50;&amp;#64;&amp;#99;&amp;#114;&amp;#97;&amp;#105;&amp;#103;&amp;#115;&amp;#108;&amp;#105;&amp;#115;&amp;#116;&amp;#46;&amp;#111;&amp;#114;&amp;#103;&lt;/a&gt;&lt;br&gt;
Date: 2008-07-10,  9:52PM EDT&lt;br&gt;

&lt;br&gt;
&lt;br&gt;
Work right now Tonight, Pay is cash.
&lt;br&gt;
My office is downtown fulton street closer to wall street.
&lt;br&gt;
call 917-555-1234 If you want to work ASAP.
&lt;br&gt;

&lt;br&gt;
We need to get the site completed by 11am Friday
&lt;br&gt;
a)calender installation- php
&lt;br&gt;
b)new page to load listings- Ajax
&lt;br&gt;
c)new page to include flash vedio reel

&lt;br&gt;

&lt;br&gt;
That's it. 
&lt;br&gt;
more job opportunity if you can be effective
&lt;/div&gt;

&lt;p&gt;At least with this guy you get an office with a window, right?&lt;/p&gt;
&lt;div class="craigslist" style="background-color: #eee; font-family: serif;"&gt;
&lt;h2&gt;PHP/MySQL/JavaScript - PT 9a-1p M-F @ Starrbucks (Park Slope)&lt;/h2&gt;
&lt;hr&gt;
Reply to: &lt;a href="mailto:gigs-863212828@craigslist.org?subject=PHP/MySQL/JavaScript%20-%20PT%209a-1p%20M-F%20@%20Starrbucks%20%28Park%20Slope%29"&gt;gigs-863212828@craigslist.org&lt;/a&gt; &lt;sup&gt;[&lt;a href="http://www.craigslist.org/about/help/replying_to_posts" target="_blank" title="How do I reply?"&gt;?&lt;/a&gt;]&lt;/sup&gt;&lt;br&gt;

Date: 2008-10-02, 12:27AM EDT&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
I work out of Starbucks. I'm looking for another programmer to join me.
I have a lot of work to do. And I start early every day. You must be
able to work the same hours, the same location.
&lt;ul&gt;
&lt;li&gt; Location: Park Slope
&lt;/li&gt;&lt;li&gt;it's NOT ok to contact this poster with services or other commercial interests
&lt;/li&gt;&lt;li&gt; Compensation: $20 per hour &lt;/li&gt;&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;At least he's honest about the pay.&lt;/p&gt;

&lt;div class="craigslist" style="background-color: #eee; font-family: serif;"&gt;
&lt;h2&gt;Adult Webcam PHP site (New York)&lt;/h2&gt;
&lt;hr&gt;
Reply to: &lt;a href="mailto:&amp;#103;&amp;#105;&amp;#103;&amp;#115;&amp;#45;&amp;#49;&amp;#48;&amp;#49;&amp;#49;&amp;#53;&amp;#57;&amp;#48;&amp;#54;&amp;#49;&amp;#50;&amp;#64;&amp;#99;&amp;#114;&amp;#97;&amp;#105;&amp;#103;&amp;#115;&amp;#108;&amp;#105;&amp;#115;&amp;#116;&amp;#46;&amp;#111;&amp;#114;&amp;#103;?subject=Adult%20Webcam%20PHP%20site%20(New%20York)"&gt;&amp;#103;&amp;#105;&amp;#103;&amp;#115;&amp;#45;&amp;#49;&amp;#48;&amp;#49;&amp;#49;&amp;#53;&amp;#57;&amp;#48;&amp;#54;&amp;#49;&amp;#50;&amp;#64;&amp;#99;&amp;#114;&amp;#97;&amp;#105;&amp;#103;&amp;#115;&amp;#108;&amp;#105;&amp;#115;&amp;#116;&amp;#46;&amp;#111;&amp;#114;&amp;#103;&lt;/a&gt; &lt;sup&gt;[&lt;a href="http://www.craigslist.org/about/help/replying_to_posts" target="_blank" title="How do I reply?"&gt;?&lt;/a&gt;]&lt;/sup&gt;&lt;br&gt;

Date: 2009-01-28,  4:40PM EST&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;div id="userbody"&gt;
Looking for a PHP programer who can put together a PHP adult live webcam site together. If the designer likes he can present a template and simply tweak it as well. There is pay.. but low.

&lt;br&gt;

&lt;br&gt;
Thanks
&lt;br&gt;&lt;br&gt;&lt;ul&gt;
&lt;li&gt; Location: New York

&lt;li&gt;it's NOT ok to contact this poster with services or other commercial interests
&lt;li&gt; Compensation: low budget &lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This one's honest, but also &lt;a href="http://www.eeoc.gov/policy/adea.html"&gt;most likely illegal&lt;/a&gt;.&lt;/p&gt;

&lt;div class="craigslist" style="background-color: #eee; font-family: serif;"&gt;
&lt;h2&gt;Hungry College Coder needed for startup&lt;/h2&gt;
&lt;hr&gt;
Reply to: &lt;a href="mailto:&amp;#103;&amp;#105;&amp;#103;&amp;#115;&amp;#45;&amp;#49;&amp;#48;&amp;#50;&amp;#49;&amp;#48;&amp;#54;&amp;#54;&amp;#52;&amp;#49;&amp;#56;&amp;#64;&amp;#99;&amp;#114;&amp;#97;&amp;#105;&amp;#103;&amp;#115;&amp;#108;&amp;#105;&amp;#115;&amp;#116;&amp;#46;&amp;#111;&amp;#114;&amp;#103;?subject=Hungry%20College%20Coder%20needed%20for%20startup"&gt;&amp;#103;&amp;#105;&amp;#103;&amp;#115;&amp;#45;&amp;#49;&amp;#48;&amp;#50;&amp;#49;&amp;#48;&amp;#54;&amp;#54;&amp;#52;&amp;#49;&amp;#56;&amp;#64;&amp;#99;&amp;#114;&amp;#97;&amp;#105;&amp;#103;&amp;#115;&amp;#108;&amp;#105;&amp;#115;&amp;#116;&amp;#46;&amp;#111;&amp;#114;&amp;#103;&lt;/a&gt; &lt;sup&gt;[&lt;a href="http://www.craigslist.org/about/help/replying_to_posts" target="_blank" title="How do I reply?"&gt;?&lt;/a&gt;]&lt;/sup&gt;&lt;br&gt;

Date: 2009-02-04,  5:42PM EST&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;div id="userbody"&gt;
Startup seeking college student/demon coder for work on a php/mysql app.  

&lt;br&gt;

&lt;br&gt;
You:  a college student based in NYC, probably in a CS program.  You can code PHP in your sleep.  AJAX is your only friend (possibly excluding xbox).  Large databases don't scare you.  You hack APIs just to see what they can't do.  
&lt;br&gt;

&lt;br&gt;
The project:  a large-scale consumer-facing web app that will literally change the way we think about information.  Sounds big and ballsy - it is big and ballsy.  This is the kind of project you will skip classes for.  That said, it's not rocket science and a working prototype can probably be built in a month.
&lt;br&gt;

&lt;br&gt;

Why college students?  Because times are tight and we can't pay monster salaries.  This project is going to have to be built by people who believe in it.  
&lt;br&gt;

&lt;br&gt;
Send links to things you've built, and a note explaining why you're so great.

&lt;br&gt;&lt;br&gt;&lt;ul&gt;
&lt;li&gt;it's NOT ok to contact this poster with services or other commercial interests
&lt;li&gt; Compensation: a little cash, a little less equity &lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;One more to round it up.&lt;/p&gt;
&lt;div class="craigslist" style="background-color: #eee; font-family: serif;"&gt;
&lt;h2&gt;Need PHP/MySQL Developer to Create Mafia Wars type Game (Nationwide)&lt;/h2&gt;
&lt;hr&gt;
Reply to: &lt;a href="mailto:&amp;#103;&amp;#105;&amp;#103;&amp;#115;&amp;#45;&amp;#49;&amp;#48;&amp;#50;&amp;#56;&amp;#57;&amp;#56;&amp;#56;&amp;#54;&amp;#50;&amp;#51;&amp;#64;&amp;#99;&amp;#114;&amp;#97;&amp;#105;&amp;#103;&amp;#115;&amp;#108;&amp;#105;&amp;#115;&amp;#116;&amp;#46;&amp;#111;&amp;#114;&amp;#103;?subject=Need%20PHP/MySQL%20Developer%20to%20Create%20Mafia%20Wars%20type%20Game%20(Nationwide)"&gt;&amp;#103;&amp;#105;&amp;#103;&amp;#115;&amp;#45;&amp;#49;&amp;#48;&amp;#50;&amp;#56;&amp;#57;&amp;#56;&amp;#56;&amp;#54;&amp;#50;&amp;#51;&amp;#64;&amp;#99;&amp;#114;&amp;#97;&amp;#105;&amp;#103;&amp;#115;&amp;#108;&amp;#105;&amp;#115;&amp;#116;&amp;#46;&amp;#111;&amp;#114;&amp;#103;&lt;/a&gt; &lt;sup&gt;[&lt;a href="http://www.craigslist.org/about/help/replying_to_posts" target="_blank" title="How do I reply?"&gt;?&lt;/a&gt;]&lt;/sup&gt;&lt;br&gt;

Date: 2009-02-10, 12:38PM EST&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;div id="userbody"&gt;
Need an Advanced PHP/MySQL Developer to re-create a Mafia wars type game platform. Must have experience.
&lt;br&gt;

&lt;br&gt;
Pay is $900 for completion of platform. 

&lt;br&gt;&lt;br&gt;&lt;ul&gt;
&lt;li&gt; Location: Nationwide

&lt;li&gt;it's NOT ok to contact this poster with services or other commercial interests
&lt;li&gt; Compensation: 900 &lt;/ul&gt;

&lt;/div&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/r3articles/~4/KEEvPmkUDeA" height="1" width="1"/&gt;</description>
    <dc:date>2009-03-03 16:57:42</dc:date>
  <feedburner:origLink>http://realm3.com/articles/craiglist_hall_of_shame_version_4</feedburner:origLink></item>

  <item rdf:about="http://realm3.com/articles/tips_for_finding_great_freelance_developers">
    <link>http://feedproxy.google.com/~r/r3articles/~3/UVBvX42dJwo/tips_for_finding_great_freelance_developers</link>
    <title>Tips For Finding Great Freelance Developers</title>
    <description>&lt;br&gt;
As with most things, there are a lot of ways to do something wrong and only a few ways to do it correctly. Looking for a good freelance developer is one of those things. I am not an avid proponent of sites like Elance, oDesk, or similar sites that attempt to aggregate freelancers based on low bids. These sites are also not conducive to finding local developers. In my experience, going local is often worth the premium. (I get to "clean up" after a lot of "outsourcing gone bad" stories, so I don't feel they encroach on my territory: just that it rarely works well.) While online relationships (via Twitter, LinkedIn, Facebook, etc) are useful, they are nearly worthless unless paired up with good old-fashioned face-to-face networking.&lt;br&gt;
&lt;br&gt;
Why try to find a good developer versus a mediocre developer? If you're serious about developing a software product, it's going to save you money in the long run. If you hire a moonlighter that suddenly finds himself swamped with "real" work, then you're left scrambling to find a replacement. If you hire a bad developer that "makes it work" but later you have issues, you may find yourself faced with an expensive total rewrite of the project by a qualified developer.&lt;br&gt;
&lt;br&gt;
Here are some practical tips on finding great developers.&lt;br&gt;
&lt;br&gt;

&lt;h3&gt;
Finding Candidates: Go Offline
&lt;/h3&gt;
Don't look for developers on Craigslist. The signal-to-noise ratio is so high that good job posts are hard to find, making it the last place to find well-qualified applicants. The same rule can apply to most generalized job-boards. Just like any other business arrangement, the most successful partnerships begin with personal relationships. Good developers are often active in local technical or entrepreneurial groups. This can vary from structured "referral generation" networks like &lt;a href="http://www.bni.com/" id="jyaj" title="Business Networking International"&gt;Business Networking International&lt;/a&gt; to user groups specific to a particular technology. Some of the groups in New York include New York Tech, NextNY, nycruby, and NYPHP. If you're running a business, getting involved in groups like NextNY or New York Tech can be beneficial in far more than just finding a good developer. Even if you don't find a developer immediately, enlarging your business network will perhaps lead to someone who can recommend a developer. Likewise, you may find a good developer that isn't available for immediate work, but may be willing to help you qualify another candidate.&lt;br&gt;

A relationship bound by face-to-face contact is going to be far stronger than a message posted on a job board, Craigslist, or on an email list. Both you and a developer can feel out potential problems in personality differences (yes, that absolutely can affect a working relationship) or job qualifications.&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;
If You Must Go Online, Be Specific
&lt;/h3&gt;
If you absolutely &lt;i&gt;must&lt;/i&gt; post it online, then at least be specific about both your company and your company's needs. One of the problems with "Developer wanted" posts on Craigslist or on email lists like NextNY are that they are too broad. Web "designer" and web "developer" get lumped into the same category, preferred languages or technologies aren't specified, and company information is not given on the pretext that if you get in touch and we like you, we'll tell you more.&lt;br&gt;

&lt;br&gt;
First, be as specific as you can. If you don't &lt;i&gt;know&lt;/i&gt; what technology you are planning on using then it's a good idea to mention this. The more specific you are about the project requirements, the more qualified your responses will be. Developers often work in specific technologies (for myself, it's PHP). Most developers aren't even going to bother to answer something like this:&lt;br&gt;

&lt;br&gt;
&lt;div class="testimonial"&gt;
&lt;p&gt;"Seeking developer. Please email for details with rates and resume."&lt;/p&gt;
&lt;div class="author"&gt;Random Individual&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
That sort of resume fishing isn't worth our time unless we're just absolutely desperate. Good developers are rarely desperate, even in these crazy economic times.&lt;br&gt;

&lt;br&gt;
Second, not offering information about yourself or your company assumes that you're going to receive dozens of resumes, pick the qualified candidates, and then tell them about your company. There are a few problems with this assumption. First, resumes don't tell you everything about a developer. It takes a real-time discussion via phone or in-person to determine whether or not a candidate is truly qualified, so by gathering more responses you're wasting both your time and your candidates'. It's understandable that you may not want to divulge information if you're a startup still in stealth mode, but even then some generalized information can be helpful. What industry does the company serve? What are they doing that makes the work exciting?&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;
Screening Candidates
&lt;/h3&gt;
&lt;b&gt;Look for familiarity with best practices.&lt;/b&gt; There are a few things that nearly all developers should be familiar with. If you are absolutely not a "techie," then it may be difficult to determine who's a qualified candidate. The best thing to do is find someone that has the knowledge to help you screen candidates. Otherwise, you may know the proper words to look for, but you're still going to be shooting in the dark. Here are some basics to start with:&lt;br&gt;

&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;
Source code control. This allows developers to track changes to code and roll back to previous changes if necessary. You won't find many developers willing to argue that source code control is "unnecessary."&lt;br&gt;
&lt;/li&gt;

&lt;li&gt;
Automated testing. You don't have to be a huge fan of test-driven development to realize that automated testing is a useful way to ensure higher-quality software. Even if a developer doesn't do this for every project, they should know what it is and have an opinion on how to use it.
&lt;/li&gt;
&lt;li&gt;
Avoid reinventing the wheel. For most software development tasks out there, especially the web-based kind, there are frameworks to help move work along. For example, using an MVC framework like Code Igniter, CakePHP, Ruby on Rails, or others, ensures that if a developer drops off the planet, someone else can take over. Of course, a bad developer can't be saved by using a framework, but in most cases if you have to get another developer involved at least the framework has publicly available documentation. I've learned to be very wary of companies or freelancers who claim to use a proprietary framework of their own making. It's usually a very, very bad sign.
&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
References are often more revealing than resumes. Most serious freelance developers will be able to hand you a list of past clients who were happy with their work.&lt;br&gt;

&lt;br&gt;
&lt;h3&gt;
In Summary
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
Go offline
&lt;/li&gt;
&lt;li&gt;
Be specific
&lt;/li&gt;
&lt;li&gt;
Look for familiarity with "Best Practices"
&lt;/li&gt;
&lt;li&gt;
The more output is standardized, the better.

&lt;/li&gt;
&lt;li&gt;
Get past references (for freelance projects) if at all possible.
&lt;/li&gt;

&lt;li&gt;
Realize that most good developers are busy, most bad developers are applying to multiple jobs in desperation.
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
Further Resources
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
Joel on Software: &lt;a href="http://www.joelonsoftware.com/articles/FindingGreatDevelopers.html" id="zh-3" title="Finding Great Developers"&gt;Finding Great Developers&lt;/a&gt;&lt;br&gt;

&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/r3articles/~4/UVBvX42dJwo" height="1" width="1"/&gt;</description>
    <dc:date>2009-02-24 14:50:32</dc:date>
  <feedburner:origLink>http://realm3.com/articles/tips_for_finding_great_freelance_developers</feedburner:origLink></item>

  <item rdf:about="http://realm3.com/articles/exhuberant_ctags_in_vim_for_php_on_ubuntu_8.10">
    <link>http://feedproxy.google.com/~r/r3articles/~3/9n1dwiqiQEA/exhuberant_ctags_in_vim_for_php_on_ubuntu_8.10</link>
    <title>Exhuberant Ctags in Vim for PHP on Ubuntu 8.10</title>
    <description>&lt;p&gt;Function auto-completion in vim is ordinarily limited to the files that you have loaded into tabs or buffers. This is usually sufficient for me, but lately I've decided to set up &lt;strong&gt;exuberant ctags&lt;/strong&gt; so auto-completion can be used project-wide. I also use CakePHP for most LAMP-stack projects that I work on, and I figured it would be nice to jump straight to a function to check arguments rather than relying on the online documentation.&lt;/p&gt;
&lt;p&gt;Installing exhuberant-ctags on Ubuntu is easy as usual:&lt;/p&gt;
&lt;pre class="code"&gt;
$ sudo apt-get install exhuberant-ctags
&lt;/pre&gt;
&lt;p&gt;Next, create a directory in your vim settings directory to store your tag files for different projects:&lt;/p&gt;
&lt;pre class="code"&gt;
$ mkdir ~/.vim/mytags 
&lt;/pre&gt;
&lt;p&gt;Now you can jump to your project base directory and compile a tags file. In this case, we're going to generate a tags file for CakePHP. Your installation directory will, of    course, vary. We're also going to use a command that &lt;a href="http://weierophinney.net/matthew/archives/134-exuberant-ctags-with-PHP-in-Vim.html"&gt;Matthew Weier O'Phinney&lt;/a&gt;      helpfully fleshed out to make sure we include all PHP functions. I suggest creating a shell script file so you can automate this task for multiple projects.&lt;/p&gt;
&lt;pre class="code"&gt;
$ cd /opt/cakephp-1.2/
$ ctags-exuberant -f ~/.vim/mytags/cake -h ".php" \
    -R --exclude="\.svn" --totals=yes --tag-relative=yes \
    --PHP-kinds=+cf --regex-PHP='/abstract class ([^ ]*)/\1/c/' \
    --regex-PHP='/interface ([^ ]*)/\1/c/' \
    --regex-PHP='/(public |static |abstract |protected |private )+function ([^ (]*)/\2/f/' 
&lt;/pre&gt;
&lt;p&gt;Now when you are inside a CakePHP project you can type this into vim to access CakePHP's ctags file.&lt;/p&gt;
&lt;pre class="code"&gt;
:set tags=~/.vim/mytags/cake
&lt;/pre&gt;
&lt;p&gt;You can now auto-complete CakePHP functions and variables, as well as jump to them directly. For example, if you're in a controller and you're using &lt;span class="code"&gt;$this-&gt;Session-&gt;setFlash&lt;/span&gt;, move the cursor over "setFlash" and press Ctrl + ]. This will open /cake/libs/session.php and put you in function setFlash. You can use Ctrl + T to jump back.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/r3articles/~4/9n1dwiqiQEA" height="1" width="1"/&gt;</description>
    <dc:date>2009-02-22 21:14:39</dc:date>
  <feedburner:origLink>http://realm3.com/articles/exhuberant_ctags_in_vim_for_php_on_ubuntu_8.10</feedburner:origLink></item>

  <item rdf:about="http://realm3.com/articles/compiling_and_using_jsmin_on_ubuntu">
    <link>http://feedproxy.google.com/~r/r3articles/~3/YmerVrxqCdk/compiling_and_using_jsmin_on_ubuntu</link>
    <title>Compiling and Using JSMin on Ubuntu</title>
    <description>&lt;p&gt;&lt;a href="http://www.crockford.com/javascript/jsmin.html"&gt;JSMin&lt;/a&gt; is a popular &lt;a href="http://en.wikipedia.org/wiki/Minify"&gt;Javascript minifier&lt;/a&gt; that you will need to compile from the C source code on Ubuntu to use. (An executable is already available for Windows). I use it often for compressing jQuery extensions.&lt;/p&gt;
&lt;p&gt;First, download the jsmin.c file into a directory.&lt;/p&gt;
&lt;pre class="code"&gt;
$ cd
$ mkdir jsmin
$ cd !$
$ wget http://www.crockford.com/javascript/jsmin.c
&lt;/pre&gt;
&lt;p&gt;For the next step you'll need to make sure you install the gcc compilers for Ubuntu, if you have not already done this.&lt;/p&gt;
&lt;pre class="code"&gt;
$ sudo apt-get install gcc
&lt;/pre&gt;
&lt;p&gt;Compile the file.&lt;/p&gt;
&lt;pre class="code"&gt;
$ cc jsmin.c -o jsmin
&lt;/pre&gt;
&lt;p&gt;You can leave the compiled file in your home directory, but if you think you're going to keep it around I suggest moving it to /usr/local/lib/jsmin/ and creating a symbolic link from /usr/local/bin/&lt;/p&gt;
&lt;pre class="code"&gt;
$ sudo mv ~/jsmin/ /usr/local/lib/jsmin/ &amp;&amp; \
    sudo ln -s /usr/local/lib/jsmin/jsmin /usr/local/bin/jsmin
&lt;/pre&gt;
&lt;p&gt;Now, to use it! The below assumes you haven't moved it from your home directory. If you have, then the ~/jsmin/ path is unnecessary.&lt;/p&gt;
&lt;pre class="code"&gt;
$ ~/jsmin/jsmin &lt; my_javascript.src.js &gt; my_javascript.min.js
&lt;/pre&gt;
&lt;p&gt;That's pretty much all there is to it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/r3articles/~4/YmerVrxqCdk" height="1" width="1"/&gt;</description>
    <dc:date>2009-01-07 12:21:32</dc:date>
  <feedburner:origLink>http://realm3.com/articles/compiling_and_using_jsmin_on_ubuntu</feedburner:origLink></item>

  <item rdf:about="http://realm3.com/articles/installing_django_from_source_on_ubuntu_8.10">
    <link>http://feedproxy.google.com/~r/r3articles/~3/ni16YjHlyjI/installing_django_from_source_on_ubuntu_8.10</link>
    <title>Installing Django From Source on Ubuntu 8.10</title>
    <description>&lt;p&gt;First you'll need to install python.&lt;/p&gt;
&lt;pre class="code"&gt;
sudo apt-get install python
&lt;/pre&gt;
&lt;p&gt;Once Python is installed, download the tarball from the Django Project website. For this example I used &lt;a href="http://www.djangoproject.com/download/1.0.2/tarball/"&gt;version 1.0.2&lt;/a&gt;. You can download this file to your home directory.&lt;/p&gt;
&lt;pre class="code"&gt;
cd
wget http://www.djangoproject.com/download/1.0.2/tarball/
tar xzvf Django-1.0.2-final.tar.gz
&lt;/pre&gt;
&lt;p&gt;Now we can just move this entire package to somewhere logical.&lt;/p&gt;
&lt;pre class="code"&gt;
sudo mv Django-1.0.2-final /usr/local/lib/django-1.0.2/
&lt;/pre&gt;
&lt;p&gt;Link to it from the Python site-packages directory, and create a link to the django-admin.py executable.&lt;/p&gt;
&lt;pre class="code"&gt;
cd /usr/local/lib/django-1.0.2/
sudo ln -s `pwd`/django /usr/lib/python2.5/site-packages/django
sudo ln -s `pwd`/django/bin/django-admin.py /usr/local/bin/
&lt;/pre&gt;
&lt;p&gt;Test it by changing to your home directory and running django-admin!&lt;/p&gt;
&lt;pre class="code"&gt;
$ django-admin.py --version
1.0.2 final
&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/r3articles/~4/ni16YjHlyjI" height="1" width="1"/&gt;</description>
    <dc:date>2008-12-24 14:30:45</dc:date>
  <feedburner:origLink>http://realm3.com/articles/installing_django_from_source_on_ubuntu_8.10</feedburner:origLink></item>

  <rdf:Description rdf:ID="manifest">
    <mn:channels>
      <rdf:Seq>
        <rdf:li rdf:resource="http://realm3.com/posts/feed" />
      </rdf:Seq>
    </mn:channels>
  </rdf:Description>

</rdf:RDF>
