<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss version="2.0">
  <channel>
    <title>ThinkRefresh Articles</title>
    <description>Articles and screencasts on ruby, rails, business and start-ups.</description>
    <link>http://thinkrefresh.com/posts.rss</link>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/thinkrefresh" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>BDD and The Big Rewrite</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/rewrite.jpg" title="-" alt="-" /&gt;&lt;/p&gt;
&lt;p&gt;Rewriting your &lt;em&gt;whole&lt;/em&gt; application is no easy task (as demonstrated by the lack of news about Textmate 2 &lt;a href="http://blog.macromates.com/2009/working-on-it/"&gt;until recently&lt;/a&gt;), but after some research and a little experimentation, I&amp;#8217;ve realised it&amp;#8217;s made easier if you&amp;#8217;ve written user stories &amp;#8211; an integration testing method used in &lt;acronym title="Behavior Driven Development"&gt;&lt;span class="caps"&gt;BDD&lt;/span&gt;&lt;/acronym&gt;.&lt;/p&gt;
&lt;h2&gt;Why bother rewrite?&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://scotland-on-rails.s3.amazonaws.com/2B12_StevenBaker-SOR.mp4"&gt;Steven Baker&lt;/a&gt; spoke at Scotland on Rails about this very topic, and his points were very clear:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;It&amp;#8217;s a blank slate, a fresh start, an empty canvas &amp;#8211; nothing bad has happened, you don&amp;#8217;t need to learn what some other developer&amp;#8217;s code means, or worse: your own from years ago!&lt;/li&gt;
	&lt;li&gt;It&amp;#8217;s a green field &amp;#8211; no edge cases, integration bugs or many problems you may have run into in the past.&lt;/li&gt;
	&lt;li&gt;No technical debt &amp;#8211; there is no lack of tests or documentation in the new project.&lt;/li&gt;
	&lt;li&gt;You can avoid making the same mistakes.&lt;/li&gt;
	&lt;li&gt;You get to use sexy, bleeding-edge, new technologies.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My excuses fall into #3 and #4 &amp;#8211; when the application I am rewriting was first developed I hadn&amp;#8217;t learned about &lt;acronym title="Test Driven Development"&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt;&lt;/acronym&gt; and the whole architecture is totally wrong. One file even has 1000 lines of code in it, it gives me nightmares&amp;#8230;&lt;/p&gt;
&lt;h2&gt;So why not rewrite?&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://chadfowler.com/2006/12/27/the-big-rewrite"&gt;Some&lt;/a&gt; &lt;a href="http://www.joelonsoftware.com/articles/fog0000000069.html"&gt;people&lt;/a&gt; argue that rewriting a system from scratch is usually by no means the best idea due to the risks involved. Steven continues in his talk to mention the following problems:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;It costs money, lots of money.&lt;/li&gt;
	&lt;li&gt;It might fail again (i.e. no/low acceptance).&lt;/li&gt;
	&lt;li&gt;Lack of bug fixes.&lt;/li&gt;
	&lt;li&gt;Could make same mistakes.&lt;/li&gt;
	&lt;li&gt;You could run into the same problems.&lt;/li&gt;
	&lt;li&gt;You probably won&amp;#8217;t know how to use these new technologies.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Thankfully I can justify pretty much all of the above points because it is (or rather, should be) a small application, and I am confident will improve sales, besides, there are more bugs caused by just upgrading Rails than I can foresee in the development of a new application.&lt;/p&gt;
&lt;h2&gt;How user stories can help.&lt;/h2&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/user-stories.jpg" title="Very Important User Stories" alt="Very Important User Stories" /&gt; &lt;span class="caption"&gt;&amp;#8220;Very Important User Stories&amp;#8221;&lt;br /&gt;
Source: &lt;a href="http://flic.kr/p/GWcKr"&gt;SweatPantsNinja @ Flickr&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;User stories explicitly define the goals of the system, so provided they pass, the system contains all the functions that it is required to provide. So if you take these as a basis for your new application: once they all pass, you&amp;#8217;re back to where you left of with the previous iteration.&lt;/p&gt;
&lt;p&gt;Of course your new UI might differ, but usually you can just copy over the view files and &lt;span class="caps"&gt;CSS&lt;/span&gt; from your old application, if you are tempted by something like &lt;span class="caps"&gt;HAML&lt;/span&gt; or &lt;span class="caps"&gt;SASS&lt;/span&gt;, I&amp;#8217;d make the switch as part of refactoring once the application is back up to it&amp;#8217;s previous state.&lt;/p&gt;
&lt;p&gt;So what should change? Well since the stories were first introduced, your client&amp;#8217;s requirements (whether they are a business, or the general public) may have changed &amp;#8211; so you should look for stories that can be cut or altered, however, make sure the stakeholders are involved in this process otherwise you might finish up with people not accepting the update (read: Vista).&lt;/p&gt;
&lt;p&gt;You may also have new features that you&amp;#8217;re gagging to dig your teeth into, but you should avoid temptation to add these into the initial build &amp;#8211; the reasons for this being:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;You will probably dive in head first into those features without thinking about the differences in the new base code.&lt;/li&gt;
	&lt;li&gt;You should be able to provide your client with a preview of the update, especially if there have been feature cut-backs, and they should be perfectly happy using it &amp;#8211; as they (hopefully) were with the previous system.&lt;/li&gt;
	&lt;li&gt;Over-complicating releases with hundreds of new features all in one go will send users running for the hills and also releasing over time will make your client feel like they are getting more for their money &amp;#8211; as they can see the time involved in each release.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That said, you should keep the new updates in the back of your head so you don&amp;#8217;t end up throwing away &lt;em&gt;too much&lt;/em&gt; code when you get round to implementing them, just doing get caught up with &amp;#8220;I&amp;#8217;ll code this in because it might be useful in future&amp;#8221;.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re not already using &lt;acronym title="Behavior Driven Development"&gt;&lt;span class="caps"&gt;BDD&lt;/span&gt;&lt;/acronym&gt; through user stories, you should seriously consider implementing them sooner rather than later &amp;#8211; because they&amp;#8217;ll not only help any rewrites, but will also reduce the need for a rewrite in the first place!&lt;/p&gt;
&lt;p&gt;To get started, I suggest you check out &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt;, Ryan Bates (of &lt;a href="http://railscasts.com"&gt;Railscasts&lt;/a&gt;) has produced a &lt;a href="http://railscasts.com/episodes/155-beginning-with-cucumber"&gt;video introduction&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As a closing warning, note that you should always still consider modifying current applications over the &amp;#8216;big rewrite&amp;#8217;, user stories simply aid in redevelopment if that&amp;#8217;s what you &lt;strong&gt;must&lt;/strong&gt; resort to. If you are simply looking to refactor and improve your code &amp;#8211; a rewrite is most likely not for you &amp;#8211; if you don&amp;#8217;t have tests in place to aid in refactoring, I suggest you &lt;a href="http://scotland-on-rails.s3.amazonaws.com/2A08_JoeOBrianJimWeirich-SOR.mp4"&gt;view the Ruby Code Review video&lt;/a&gt; from Scotland on Rails, where Joe O&amp;#8217;Brien and Jim Weirich discuss retrofitting tests.&lt;/p&gt;
&lt;p&gt;This article&amp;#8217;s photo: I&amp;#8217;m afraid I lost the &lt;span class="caps"&gt;URL&lt;/span&gt;, if you are/know the author, fire me a &lt;a href="http://twitter.com/ryantownsend"&gt;tweet&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Mon, 29 Jun 2009 22:20:04 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/21-bdd-and-the-big-rewrite</link>
      <guid>http://thinkrefresh.com/posts/21-bdd-and-the-big-rewrite</guid>
    </item>
    <item>
      <title>Maintenance Pages: VirtualHost Configuration</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/soindustry_maintenance.png" title="The SoIndustry maintenance page" alt="The SoIndustry maintenance page" /&gt;&lt;/p&gt;
&lt;p&gt;Are you running a Rails app in production and making regular updates to the codebase? If so, you probably already appreciate the need for an easily deployed maintenance page for handling all requests during significant code updates, particularly those running migrations and altering the DB schema. Luckily, existing tutorials on this topic (&lt;a href="http://clarkware.com/cgi/blosxom/2007/01/05"&gt;Custom Maintenance Pages&lt;/a&gt;, &lt;a href="http://bjhess.com/blog/2007/08/06/rails-maintenance-page-with-images-and-styles/"&gt;Rails maintenance page with images and styles&lt;/a&gt;) make Capistrano-powered maintenance pages look pretty straight-forward.&lt;/p&gt;
&lt;p&gt;Unfortunately, this wasn&amp;#8217;t my experience with the Ubuntu + Apache2 + Passenger stack on the &lt;a href="http://notipal.com"&gt;Notipal&lt;/a&gt; production slice on &lt;a href="http://slicehost.com"&gt;SliceHost&lt;/a&gt;; I followed the Mike Clark tutorial, but the rewrite conditions just didn&amp;#8217;t appear to do anything whatsoever.&lt;/p&gt;
&lt;p&gt;After a bit of trial &amp;amp; error, it was all figured out; these are the additional steps that I had to take to get our stack &amp;amp; Apache configuration to work with VirtualHosts and Rewrite Conditions:&lt;/p&gt;
&lt;h2&gt;1. Install mod_rewrite&lt;/h2&gt;
&lt;p&gt;Apache 2 comes bundled with mod_rewrite, but it isn&amp;#8217;t always enabled by default, so run the command below to enable it:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo a2enmod rewrite&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;2. Include RewriteCond conditions &lt;span class="caps"&gt;WITHIN&lt;/span&gt; your VirtualHost blocks&lt;/h2&gt;
&lt;p&gt;In my experience, you have to put these commands &lt;strong&gt;within&lt;/strong&gt; the VirtualHost blocks nested in the Apache conf files to get rewrites to spring in to action once your maintenance page has been deployed by Capistrano (including them globally in the apache2.conf just didn&amp;#8217;t seem to work):&lt;/p&gt;
&lt;script type="text/javascript" src="http://gist.github.com/108725.js"&gt;&lt;/script&gt;&lt;h2&gt;3. Restart Apache&lt;/h2&gt;
&lt;p&gt;The code below will restart Apache 2 in a graceful manner, so you won&amp;#8217;t cut off any visitors currently loading a page from your website:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;apache2ctl -k graceful&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;4. Check It Works&lt;/h2&gt;
&lt;p&gt;Hit &lt;code&gt;cap deploy:web:disable&lt;/code&gt; to put your site in to maintenance. Hit &lt;code&gt;cap deploy:web:enable&lt;/code&gt; to take your site out of maintenance.&lt;/p&gt;
&lt;p&gt;And that should be it. Your .com should now be showing a completely unstyled Capistrano maintenance page when ever you use the capistrano web:disable command.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/capistrano_maintenance.png" title="Unstyled Capistrano maintenance page" alt="Unstyled Capistrano maintenance page" /&gt;&lt;/p&gt;
&lt;p&gt;In a follow-up post we&amp;#8217;ll be styling your maintenance page and making it far more user/visitor/customer friendly.&lt;/p&gt;</description>
      <pubDate>Fri, 08 May 2009 14:59:32 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/18-maintenance-pages-virtualhost-configuration</link>
      <guid>http://thinkrefresh.com/posts/18-maintenance-pages-virtualhost-configuration</guid>
    </item>
    <item>
      <title>Staying on-track with side projects</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/todos.jpg" title="ToDo List In LessProjects" alt="ToDo List In LessProjects" /&gt;&lt;/p&gt;
&lt;p&gt;Recently I have been so busy with my main projects, &lt;a href="http://notipal.com/"&gt;Notipal&lt;/a&gt; became left untouched. This wasn&amp;#8217;t because I wasn&amp;#8217;t excited about the project, but just that I couldn&amp;#8217;t commit any particular dates to the 3 or so days it needs to become launch-ready.&lt;/p&gt;
&lt;p&gt;When speaking to Neil about the issue of not knowing when I will find these 3 days, he came up with idea of spending an hour, or even half an hour, every evening and pre-assigning all the leftover to-dos to their own date &amp;#8211; rather than trying to tackle them all in 3 sessions.&lt;/p&gt;
&lt;p&gt;In the past I have always tried to avoid working on different things for a small amount of time each because of the cost (in time) associated with figuring out where you were and what needs to be done next, but as Notipal is not a complicated application, I thought I&amp;#8217;d give it a try&amp;#8230;&lt;/p&gt;
&lt;p&gt;I cannot stress enough how much of a difference assigning these days has made, I&amp;#8217;ve found that most of the to-dos are taking 20-30mins to complete, and the feeling of getting something done has often spurred me on to complete a second item, so in terms of the schedule I&amp;#8217;ve quickly become ahead.&lt;/p&gt;
&lt;p&gt;Giving yourself small goals that are easily achievable (even if they seem trivial) can really aid overall development and you&amp;#8217;ll soon find yourself anticipating those 30 minutes of your day where you can get a kick out of something as simple as ticking a box. Everyone can find 30 minutes &amp;#8211; I&amp;#8217;ll leave you with a well-known phrase:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The busiest people have the most time.&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <pubDate>Sun, 08 Mar 2009 17:04:29 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/17-staying-on-track-with-side-projects</link>
      <guid>http://thinkrefresh.com/posts/17-staying-on-track-with-side-projects</guid>
    </item>
    <item>
      <title>Agile is not an excuse for an absence of design processes</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/mess.jpg" title="A lack of order" alt="A lack of order" /&gt;&lt;/p&gt;
&lt;p&gt;With the economic climate in such an awful state, project management skills are becoming increasingly important as businesses strive to minimise wasted money.&lt;/p&gt;
&lt;p&gt;You have probably heard the phrase:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Work smarter, not harder&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This idea is ever so important, however the trouble faced by Rails developers is that Rails has helped us work &lt;em&gt;faster&lt;/em&gt; not smarter. Agile has become the latest cool development model, however many of us are simply avoiding the design phase because of it&amp;#8217;s potential to slow us down &amp;#8211; using agile as our excuse.&lt;/p&gt;
&lt;h2&gt;Design doesn&amp;#8217;t slow you down&lt;/h2&gt;
&lt;p&gt;&amp;#8230;bad organisation of a design process does, or rather a lack of a design process altogether, either of which lead to inaccurate or useless plans.&lt;/p&gt;
&lt;p&gt;As a human being, we naturally construct solutions all the time, so what we do as developers is simply an extension of this on a greater level. The problem brews when we don&amp;#8217;t formalise our process. In our brain we can formulate solutions on the fly, which is fine for problems such as &amp;#8216;what should I have for dinner this evening?&amp;#8217;, but when there are multiple dependancies on the solution, things tend to go a bit haywire &amp;#8211; how many times have you been to the supermarket and forgotten to purchase an ingredient you needed for your dinner?&lt;/p&gt;
&lt;p&gt;How do we cope with our dependancies? Well in the case of shopping, we tend to make a list &amp;#8211; our documentation if you will. Not documenting your design can waste an incredible amount of time if you are constantly referring back to the application or even the code behind it.&lt;/p&gt;
&lt;p&gt;So, we need a process to manage the choices we are making, and their evolution as solutions.&lt;/p&gt;
&lt;h2&gt;Developing a process&lt;/h2&gt;
&lt;p&gt;If you&amp;#8217;re going to be doing something day-in-day-out, you need it to be as streamlined and natural as possible, hence why I won&amp;#8217;t be telling you exactly what tools to use, or how you should be documenting. To make things natural, it&amp;#8217;s best to base them on something common to yourself, everybody has to eat and most people go shopping, so I&amp;#8217;ll take that as an example.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/process-diagram.png" class="diagram" title="Process Diagram" alt="Process Diagram" /&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s pretty easy to see how this relates to developing web applications, however taking on an iterative approach it&amp;#8217;s important to note that this process should be cyclic &amp;#8211; your &amp;#8216;&lt;em&gt;select solutions&lt;/em&gt;&amp;#8217; phase should actually contain a set of cycles itself, reviewing each solution one by one.&lt;/p&gt;
&lt;h2&gt;How to document&lt;/h2&gt;
&lt;p&gt;As I mentioned earlier, I can&amp;#8217;t tell you what tools to document this process will work best for you, but if you want to get your foot in the door, then you can&amp;#8217;t go wrong with a ToDo list, provided it has categorisation and descriptions for each task, &lt;a href="http://lessprojects.com/"&gt;LessProjects&lt;/a&gt; is a good example of this.&lt;/p&gt;
&lt;p&gt;Each problem can start it&amp;#8217;s life as a task, in the &amp;#8216;Gather Requirements&amp;#8217; phase (part 2 in the diagram above), and progress through the following 5 sections as you continue to work on the application.&lt;/p&gt;
&lt;p&gt;Documenting all the proposed solutions is by no means necessary, but you should at the very least give a short explanation for why each one was chosen / denied, so looking back at things you can see why you avoided one thing or another. Some problems might not actually have a suitable solution, so it&amp;#8217;s worth having a &amp;#8216;denied&amp;#8217; status for when you reject functionality &amp;#8211; but remember to always explain why you denied it.&lt;/p&gt;
&lt;p&gt;You could also skip documenting the pre-conditions and actions, as you&amp;#8217;ll probably be calculating them in realtime, and are unlikely to be referenced in the future &amp;#8211; we want to keep this process as lean as possible so you actually follow it!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;There is no excuse for not following a process in your work, even a bad process will help you in the long run &amp;#8211; perfection cannot be achieved without failure. Your process should be very streamlined &amp;#8211; don&amp;#8217;t pack it full of unnecessary planning because you&amp;#8217;ll just end up avoiding following it. It&amp;#8217;s also worth reviewing your process over time too, maybe after each big project, your habits, team and environment will change, and so should your design process.&lt;/p&gt;
&lt;p&gt;This article&amp;#8217;s photo: &amp;#8220;Snakes&amp;#8221; by &lt;a href="http://www.flickr.com/photos/_boris/2796908072/"&gt;_boris @ Flickr&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Thu, 26 Feb 2009 18:27:06 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/16-agile-is-not-an-excuse-for-an-absence-of-design-pro</link>
      <guid>http://thinkrefresh.com/posts/16-agile-is-not-an-excuse-for-an-absence-of-design-pro</guid>
    </item>
    <item>
      <title>A Simple Spam Solution</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/spam.jpg" title="Spam" alt="Spam" /&gt;&lt;/p&gt;
&lt;p&gt;After updating the ThinkRefresh blog, for a while there was no spam which was nice, but the bots quickly returned and were back at it. My old anti-spam solution didn&amp;#8217;t work particularly well, I was using &lt;a href="http://snook.ca/archives/other/effective_blog_comment_spam_blocker/"&gt;Jonathan Snook&amp;#8217;s method&lt;/a&gt; of building up a score from various criteria, however this still required me to check my email notifications for people who&amp;#8217;d been wrongly marked as spam.&lt;/p&gt;
&lt;p&gt;An ideal spam solution places no &lt;em&gt;visible&lt;/em&gt; limitations on a visitor, but also doesn&amp;#8217;t involve any work by the site&amp;#8217;s owner, hence why I am against using &lt;acronym title="Completely Automated Public Turing test to tell Computers and Humans Apart"&gt;&lt;span class="caps"&gt;CAPTCHA&lt;/span&gt;&lt;/acronym&gt;. From this I &lt;em&gt;think&lt;/em&gt; I may have come up with a pretty good solution &amp;#8211; the blog certainly hasn&amp;#8217;t had any spam since I installed it.&lt;/p&gt;
&lt;h2&gt;What&amp;#8217;s the plan?&lt;/h2&gt;
&lt;p&gt;A typical bot will do either of two things:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Load your form once, process the fields and then use the command line to send &lt;span class="caps"&gt;POST&lt;/span&gt; requests adding comments on a daily basis.&lt;/li&gt;
	&lt;li&gt;On a daily basis, load random posts in a browser on your site, fill the comment fields and hit submit.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;One might think you can prevent the first method of spamming by checking referrer variables, but those can be spoofed, so we need some way of checking they are human without the humans knowing they are being checked.&lt;/p&gt;
&lt;p&gt;This is where it hit me &amp;#8211; if an automated bot is submitting spam, it probably won&amp;#8217;t be hanging around to do so&amp;#8230; so lets add a timer. If you mark any comments within a few seconds of loading a blog page as spam, visitors don&amp;#8217;t have time to type a comment in that time, and spam bots won&amp;#8217;t be waiting.&lt;/p&gt;
&lt;p&gt;I have quite long blog posts, so I opted for 15 seconds, it&amp;#8217;s unlikely anyone with anything useful to say will have typed it in 15 seconds and most people won&amp;#8217;t even notice!&lt;/p&gt;
&lt;h2&gt;What&amp;#8217;s the code?&lt;/h2&gt;
&lt;p&gt;My blog engine is coded in Ruby On Rails (of course), but it should be pretty simple to convert this to &lt;span class="caps"&gt;PHP&lt;/span&gt; or other languages. First we need to setup a session on any page that has a comment form, all this needs to carry is a timestamp:&lt;/p&gt;
&lt;script src="http://gist.github.com/55843.js"&gt;&lt;/script&gt;&lt;noscript&gt;
&lt;p&gt;View the code on &lt;a href="http://gist.github.com/55843"&gt;GitHub Gists&lt;/a&gt;&lt;/p&gt;
&lt;/noscript&gt;
&lt;p&gt;Then on our &amp;#8216;add comment&amp;#8217; page (in my case comments controller &amp;#8594; create action), we need to check this session value is present and whether it&amp;#8217;s after the limit (in this case 15 seconds):&lt;/p&gt;
&lt;script src="http://gist.github.com/55844.js"&gt;&lt;/script&gt;&lt;noscript&gt;
&lt;p&gt;View the code on &lt;a href="http://gist.github.com/55844"&gt;GitHub Gists&lt;/a&gt;&lt;/p&gt;
&lt;/noscript&gt;
&lt;p&gt;That&amp;#8217;s all you need functionality-wise, but you should really let your user know about the limit, so I went a little further and added some JavaScript (using &lt;a href="http://www.prototypejs.org/"&gt;Prototype&lt;/a&gt;) to disable the submit button on my forms:&lt;/p&gt;
&lt;script src="http://gist.github.com/55845.js"&gt;&lt;/script&gt;&lt;noscript&gt;
&lt;p&gt;View the code on &lt;a href="http://gist.github.com/55845"&gt;GitHub Gists&lt;/a&gt;&lt;/p&gt;
&lt;/noscript&gt;
&lt;p&gt;Hope this is useful to you, and there is a live demo on this site! You may need to reload to see it in action below. If you use this solution on your site, please let me know how it works out for you.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This article&amp;#8217;s photo: &amp;#8220;Spam Wall&amp;#8221; by &lt;a href="http://www.flickr.com/photos/63056612@N00/155554663/"&gt;FreezeLight @ Flickr&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 01 Feb 2009 11:02:02 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/15-a-simple-spam-solution</link>
      <guid>http://thinkrefresh.com/posts/15-a-simple-spam-solution</guid>
    </item>
    <item>
      <title>Web Development &amp; Education</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/lecture-seating.jpg" title="Lecture Seating" alt="Lecture Seating" /&gt;&lt;/p&gt;
&lt;p&gt;I have a few peers who are intending to go into web design / development, but are planning on going to university first, and others who are looking at the same career path, but already at university. Based on the experience of myself and my coursemates, I&amp;#8217;d like to share an insight into what university can provide young web designers, and what you need to be doing to prepare yourself for the exciting world of work.&lt;/p&gt;
&lt;h2&gt;Where am I heading?&lt;/h2&gt;
&lt;p&gt;This is the most important question you should be asking yourself. Most students leaving 6th form make the mistake of asking themselves, &amp;#8216;do I want to go to university?&amp;#8217;, and &amp;#8216;what should I study?&amp;#8217;, probably because, in many schools &amp;amp; colleges, going to university is regarded as &amp;#8216;the done thing&amp;#8217;.&lt;/p&gt;
&lt;p&gt;There aren’t too many enterprise-sized businesses involved in public-facing web design &amp;amp; development, which is a shame, because in my view that&amp;#8217;s where all the excitement lies. However, if a big corporation is where you want to be, the choice is simple; university is probably for you because they are unlikely to hire you without a degree.&lt;/p&gt;
&lt;p&gt;Smaller businesses are often much more flexible in who they&amp;#8217;ll accept, looking for an excellence in actual skills rather than qualifications. At the age of 18, it&amp;#8217;s unlikely you&amp;#8217;ll have the skills necessary to command a good salary in web design, so you have 3 options, firstly, try to get a job and build up your skills (and salary) over time, get an internship where you will get training with work promised at the end, or go to university and gain your skills there.&lt;/p&gt;
&lt;p&gt;The final option is, of course, setting up your own business, again this still doesn&amp;#8217;t mean you should forget the idea of going to university. You have a lot of spare time when studying an I.T course, so you can use that to work on developing your business without having the risk of not being able to pay your rent/mortgage/bills if your business goes under. I have pretty seamlessly worked part-time for &lt;a href="http://agincourttech.com/"&gt;Agincourt&lt;/a&gt; over the 3 years I have been at university, so there is no reason why you couldn&amp;#8217;t be running a business of your own in that time.&lt;/p&gt;
&lt;p&gt;For those who are mind-boggled by all the choices thrown at them for post-6th form education/employment and cannot decide at all; university is a safe bet. You can always decide what you want to do for a job during your time there, and there is little worry about getting on the right course, you can usually swap pretty easily. Neil was studying a business degree, but got interested in the web, and managed to mould his degree around his interest.&lt;/p&gt;
&lt;h2&gt;So what is university like?&lt;/h2&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/lecture-theatre.jpg" title="A typical lecture theatre" alt="A typical lecture theatre" /&gt; &lt;span class="caption"&gt;&amp;#8220;Today&amp;#8217;s Lecture&amp;#8221;&lt;br /&gt;
Source: &lt;a href="http://flickr.com/photos/andrewscott/2330212397/"&gt;Andrew Scott @ Flickr&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I have always maintained that I.T. should not be taught above a very basic level &amp;#8211; those who are going to be successful will learn the required expertise off their own back. You can’t float through university, grab your degree certificate, and walk into a well paid, exciting job because you will be up against those who’ve used their free time wisely to develop a portfolio of design and development work and network with the head honchos of the industry.&lt;/p&gt;
&lt;p&gt;Universities try to teach skills that will still be useful in 20 years time, which is why many courses have very generic units. The trouble is, the web won’t be the same in 2 years, let alone 20! My course, &amp;#8216;Internet Computing&amp;#8217;, is &lt;em&gt;by name&lt;/em&gt; pretty specific to web technologies, and yet we’ve never studied &lt;span class="caps"&gt;CSS&lt;/span&gt;, Javascript or any scripting language &amp;#8211; we only created a small &lt;span class="caps"&gt;HTML&lt;/span&gt;-only website in first year&amp;#8230; using framesets (I feel dirty just mentioning them). To counter-balance this, radically new ideas are taught as well (hence my post on the Semantic Web), however, these ideas are not yet applicable to real life. So, you come out with knowledge that’s too basic and too bleeding-edge to be of much use&amp;#8230; unless you supplement it yourself.&lt;/p&gt;
&lt;p&gt;A degree will only prove that you are capable of learning if provided with teaching. To take the next step, learning has to be off your own back, you must always have a desire to learn more.&lt;/p&gt;
&lt;p&gt;You may have heard the phrase:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Learn a new [programming / scripting / markup] language every year&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Your 3 years at university is the best time to really take that on-board. If you really want to succeed in web design, University is great for those who want to &lt;em&gt;learn&lt;/em&gt;, but not so great for those who want to be &lt;em&gt;taught&lt;/em&gt; &amp;#8211; it&amp;#8217;s up to you how much you get out of it.&lt;/p&gt;
&lt;h2&gt;How can I make the most of my time?&lt;/h2&gt;
&lt;p&gt;I cannot stress the importance of learning, it doesn&amp;#8217;t have to be from books, most people learn web technologies best through practical use, so here are a few ideas and tips:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Design as many websites as possible &amp;#8211; if you can&amp;#8217;t find clients give them away for free.&lt;/li&gt;
	&lt;li&gt;Develop/run your own blog&lt;/li&gt;
	&lt;li&gt;Create some screencasts / write some tutorials&lt;/li&gt;
	&lt;li&gt;Develop some open-source applications / plugins (&lt;a href="http://github.com"&gt;GitHub&lt;/a&gt; will host the repositories for free)&lt;/li&gt;
	&lt;li&gt;Network with industry leaders (get on &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt; right away!)&lt;/li&gt;
	&lt;li&gt;Do some &lt;a href="http://en.wikipedia.org/wiki/Pair_programming"&gt;pair programming&lt;/a&gt; with a follow web developer&lt;/li&gt;
	&lt;li&gt;Give some talks on what you&amp;#8217;ve learnt from the above ideas&lt;/li&gt;
	&lt;li&gt;The above ideas will hopefully help you learn some the following:
	&lt;ul&gt;
		&lt;li&gt;&lt;em&gt;Markup &amp;amp; design:&lt;/em&gt; &lt;a href="http://www.w3schools.com/xhtml/" class="X"&gt;&lt;acronym title="eXtensible Hypertext Markup Language"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/acronym&gt;&lt;/a&gt;, &lt;a href="http://www.w3schools.com/css/"&gt;&lt;acronym title="Cascading Stylesheets"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/acronym&gt;&lt;/a&gt;, &lt;a href="http://www.w3schools.com/xml/"&gt;&lt;acronym title="eXtensible Markup Language"&gt;&lt;span class="caps"&gt;XML&lt;/span&gt;&lt;/acronym&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;Scripting:&lt;/em&gt; &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt;, &lt;a href="http://www.php.net"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/JavaScript"&gt;JavaScript&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;Frameworks:&lt;/em&gt; &lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt;, &lt;a href="http://cakephp.org/"&gt;CakePHP&lt;/a&gt;, &lt;a href="http://rubyonrails.org/"&gt;Ruby On Rails&lt;/a&gt;, &lt;a href="http://prototypejs.org/"&gt;Prototype&lt;/a&gt;, &lt;a href="http://jsquery.com/"&gt;jQuery&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;Paradigms:&lt;/em&gt; &lt;acronym title="Object Oriented Programming"&gt;&lt;span class="caps"&gt;OOP&lt;/span&gt;&lt;/acronym&gt;, &lt;acronym title="Don&amp;#39;t Repeat Yourself"&gt;&lt;span class="caps"&gt;DRY&lt;/span&gt;&lt;/acronym&gt;, &lt;acronym title="Test-Driven Development"&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt;&lt;/acronym&gt;, &lt;acronym title="Test All The Fucking Time"&gt;&lt;span class="caps"&gt;TATFT&lt;/span&gt;&lt;/acronym&gt;, &lt;a href="http://microformats.org/"&gt;Microformats&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;Marketing:&lt;/em&gt; Social Networking, &lt;acronym title="Search Engine Optimisation"&gt;&lt;span class="caps"&gt;SEO&lt;/span&gt;&lt;/acronym&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, please please please: decide on what you&amp;#8217;re going to implement and only follow tutorials for the bits you can&amp;#8217;t figure out &amp;#8211; don&amp;#8217;t just follow tutorials blindly, hoping to learn something &amp;#8211; you&amp;#8217;ll just end up cut &amp;amp; pasting and not really understanding.&lt;/p&gt;
&lt;p&gt;A chap I know on Twitter, &lt;a href="http://twitter.com/jamespadolsey"&gt;James Padolsey&lt;/a&gt;, is already using many of these tips (before my recommendation), so I really recommend you check out &lt;a href="http://james.padolsey.com/"&gt;his blog&lt;/a&gt; where he often posts his open-source &lt;a href="http://james.padolsey.com/category/javascript/"&gt;jQuery Plugins&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve used my time to learn Ruby On Rails, Git, *nix server administration, considerably built on my &lt;span class="caps"&gt;CSS&lt;/span&gt;, Javascript and general design skills, designed numerous websites and develop a few web applications, and I&amp;#8217;ve loved every minute of it. Do you have any suggestions to upcoming students?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This article&amp;#8217;s photo: &amp;#8220;Lecture Pattern&amp;#8221; by &lt;a href="http://flickr.com/photos/foreby/3205159276/"&gt;Foreby @ Flickr&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 29 Jan 2009 13:21:57 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/14-web-development-education</link>
      <guid>http://thinkrefresh.com/posts/14-web-development-education</guid>
    </item>
    <item>
      <title>Concepts, Benefits and Problems of the Semantic Web</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/made-in-taiwan.jpg" title="Made in Taiwan - Semantics describe objects and properties" alt="Made in Taiwan - Semantics describe objects and properties" /&gt;&lt;/p&gt;
&lt;h2&gt;Prologue&lt;/h2&gt;
&lt;p&gt;Multiple people have requested that I post my latest essay on &amp;#8216;The adoption of the Semantic Web&amp;#8217; publicly, however I don&amp;#8217;t feel it accurately represents my views. Funnily enough, when you express a negative opinion of something, you don&amp;#8217;t stand yourself in good stead for getting a top grade when the marker has dedicated much of his/her life researching the topic.&lt;/p&gt;
&lt;p&gt;So rather than a simple cut-and-paste, I have opted to write an article from scratch about the Semantic Web to provide an insight into the ideas and technologies for those who know little or nothing about it, and my views on where it&amp;#8217;s heading.&lt;/p&gt;
&lt;h2&gt;What is the Semantic Web?&lt;/h2&gt;
&lt;p&gt;The Web, as we know it, is &lt;a href="http://en.wikipedia.org/wiki/Syntactic_web"&gt;Syntactic&lt;/a&gt;, or rather it contains information in a language which computers can display to users. However, the computers don&amp;#8217;t &lt;em&gt;understand&lt;/em&gt; the information; if you have a page about cars, only humans can understand what it&amp;#8217;s about &amp;#8211; and while that&amp;#8217;s not so much a problem as such, it isn&amp;#8217;t ideal.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/Semantic_Web" title="SW herein"&gt;Semantic Web&lt;/a&gt; adds meaning to information, so you can essentially tell a computer that a car may be left or right hand drive, it might have air conditioning and whatever else the computer might need to know.&lt;/p&gt;
&lt;h2&gt;Why is it important?&lt;/h2&gt;
&lt;p&gt;So you&amp;#8217;re probably wondering, &amp;#8216;why does a computer need to understand information?&amp;#8217;, and the simple answer is: automation. To illustrate below is a case study from &lt;a href="http://www.sciam.com/article.cfm?id=the-semantic-web"&gt;an article by Tim Berners-Lee&lt;/a&gt; himself (edited for readability):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;At the doctor&amp;#8217;s office, Lucy&amp;#8217;s Semantic Web agent promptly retrieved information about her mother&amp;#8217;s prescribed treatment from the doctor&amp;#8217;s agent, looked up several lists of providers, and checked for the ones in-plan for her mother&amp;#8217;s insurance within a 20-mile radius of her home and with a rating of excellent or very good on trusted rating services. It then began trying to find a match between available appointment times and the busy schedules of her and her brother Pete.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Whilst this is technically possible using the current Syntactic Web, it requires a developer to code an application to run such a service. On the SW, however, no coding would be required. Pretty sweet, eh?&lt;/p&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/oranges.jpg" title="Oranges - a good source of vitamin C" alt="Oranges - a good source of vitamin C" /&gt; &lt;span class="caption"&gt;&amp;#8220;Good Morning!&amp;#8221;&lt;br /&gt;
Source: &lt;a href="http://www.flickr.com/photos/lalunanera/159909006/"&gt;Lolandese Volante @ Flickr&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Another great feature would be the ability to infer information by combining information as such:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;I have a vitamin C deficiency &lt;em&gt;(I don&amp;#8217;t, but roll with it for a minute)&lt;/em&gt;&lt;/li&gt;
	&lt;li&gt;Citrus fruits are good sources of vitamin C&lt;/li&gt;
	&lt;li&gt;Oranges are citrus fruits&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Which would allow a computer to calculate I need to eat oranges. This is only a very simple example, experts have suggested the spread of disease, cures for ailments, and a variety of life-changing information could be inferred.&lt;/p&gt;
&lt;h2&gt;How is this all possible?&lt;/h2&gt;
&lt;p&gt;The &lt;a href="http://w3.org"&gt;W3C&lt;/a&gt; has produced a couple of markup languages, based on &lt;span class="caps"&gt;XML&lt;/span&gt;, that allow for semantic description of objects.&lt;/p&gt;
&lt;p&gt;These work much like &lt;a href="http://www.w3.org/2001/sw/BestPractices/SE/ODSD/"&gt;Object Oriented Programming&lt;/a&gt;. You have:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;a class that describes an object (e.g a car)&lt;/li&gt;
	&lt;li&gt;properties or attributes of a class (e.g how many doors the car has)&lt;/li&gt;
	&lt;li&gt;instances of a class (e.g a Vauxhall Corsa)&lt;/li&gt;
	&lt;li&gt;relationships between instances (e.g the Corsa is owned by Ryan)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The classes (or ontologies) are defined using &lt;a href="http://www.w3.org/TR/owl-features/"&gt;&lt;acronym title="OWL Web Ontology Language"&gt;&lt;span class="caps"&gt;OWL&lt;/span&gt;&lt;/acronym&gt;&lt;/a&gt;, and the instances and their relationships use &lt;a href="http://www.w3.org/RDF/"&gt;&lt;acronym title="Resource Description Framework"&gt;&lt;span class="caps"&gt;RDF&lt;/span&gt;&lt;/acronym&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Sounds great! Why haven&amp;#8217;t I heard about this before?&lt;/h2&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/semantic-web-roadmap.png" title="Semantic Web Roadmap 2008" alt="Semantic Web Roadmap 2008" /&gt; &lt;span class="caption"&gt;&amp;#8220;Semantic Web Roadmap 2008&amp;#8221;&lt;br /&gt;
Source: &lt;a href="http://www.flickr.com/photos/inao/1757901166/"&gt;Ina Galway @ Flickr&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;There are quite a few problems with the SW which must be ironed out before it even has a leg to stand on in comparison to the uptake of the current Web. For typical users to adopt it they must be able to see real results; it&amp;#8217;s all very well explaining what they&amp;#8217;ll be able to do in the future, but what can they do now? Answer: &lt;strong&gt;not a lot&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Ontologies&lt;/h3&gt;
&lt;p&gt;First of all, there is little point in creating ontologies if everyone uses their own, there needs to be a central reserve for them, so when people ask themselves &amp;#8220;how would I define my page of cars?&amp;#8221;, they know where to look up the car ontology. However, this does pose the problem of who will decide what is a &amp;#8216;correct&amp;#8217; ontology? Different people perceive objects in different ways, even between experts there are multiple ways of looking at things &amp;#8211; look at how long specifications for &lt;span class="caps"&gt;HTML&lt;/span&gt; and other languages take to get W3C approval &amp;#8211; you can&amp;#8217;t expect people to wait years to find out how to define their cars in &lt;span class="caps"&gt;RDF&lt;/span&gt;! And even then, people still don&amp;#8217;t fully agree!&lt;/p&gt;
&lt;p&gt;Even if we assume the relevant parties come to a swift agreement on the definition of an object, there is limited scope for what can be included. &lt;span class="caps"&gt;OWL&lt;/span&gt; is split into 3 sub-languages; Full, DL (Description Logic), and Lite. In the full version you have unlimited expressive power, but the computational resources required are too vast to be feasible, hence why the latter two &lt;em&gt;compromises&lt;/em&gt; were created. On the Syntactic Web we have been compromising all along – search engines have been scraping information from &lt;span class="caps"&gt;HTML&lt;/span&gt; that web services can manually link together. So, one could adopt the view, &amp;#8216;If we&amp;#8217;re still going to be in roughly the same position, why change anything?&amp;#8217;.&lt;/p&gt;
&lt;h3&gt;Inference&lt;/h3&gt;
&lt;p&gt;Before I gave you an accurate example of inference but there are problems, take a look at this one from &lt;a href="http://www.shirky.com/writings/semantic_syllogism.html"&gt;Clay Shirky&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Count Dracula is a Vampire&lt;/li&gt;
	&lt;li&gt;Count Dracula lives in Transylvania&lt;/li&gt;
	&lt;li&gt;Transylvania is a region of Romania&lt;/li&gt;
	&lt;li&gt;Vampires are not real&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;You can draw only one non-clashing conclusion from such a set of assertions &amp;#8211; Romania isn&amp;#8217;t real. That&amp;#8217;s wrong, of course.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/burglar.jpg" title="Burglar" alt="Burglar" /&gt; &lt;span class="caption"&gt;&amp;#8220;Burglar&amp;#8221;&lt;br /&gt;
Source: &lt;a href="http://www.flickr.com/photos/all_in_perspective/2966050830/"&gt;Wellstone @ Flickr&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For the SW to take off in a public environment, the data produced needs to be publicly available &amp;#8211; but many companies will be reluctant to share their information because others could use it with their own data to infer information, which could lead to competitors having an advantage.&lt;/p&gt;
&lt;p&gt;Many of the public are already paranoid enough about what can be discovered about them on the web &amp;#8211; I have heard stories of burglars tracking people&amp;#8217;s movements on Facebook so they can accurately predict when their house is going to be empty.&lt;/p&gt;
&lt;p&gt;Also, in a private environment, it&amp;#8217;s not as if this &amp;#8216;artificial intelligence&amp;#8217; method of discovering data isn&amp;#8217;t already being employed; governmental security agencies don&amp;#8217;t sit there browsing the web to monitor terrorist activity, they have computers sat around doing the work for them.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;For developers to push the SW into business environments, it really needs to be a solid technology with obvious benefits (e.g. improving a company&amp;#8217;s bottom line). Otherwise, we will forever be stuck in the catch-22 of nobody creating data because there is no data to use it with, and nobody developing applications because there is no data to base them on.&lt;/p&gt;
&lt;p&gt;At the moment, there are no clear benefits which cannot be broken down by major pitfalls. If &lt;span class="caps"&gt;RDF&lt;/span&gt; and &lt;span class="caps"&gt;OWL&lt;/span&gt; had been around at the inception of the web, we would probably be using the SW now. But at this late stage, trying to introduce them into such a massive environment would be somewhat counter-revolutionary (counter-evolutionary?).&lt;/p&gt;
&lt;p&gt;To get most businesses on-board there has to be short term returns; only the biggest of companies can afford to invest in semantics and wait to yield the benefits. SW can only achieve in the long term.&lt;/p&gt;
&lt;p&gt;Of course, these are only my thoughts, what do you think? Do you think the Semantic Web is going anywhere soon?&lt;/p&gt;</description>
      <pubDate>Mon, 26 Jan 2009 17:57:33 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/13-concepts-benefits-and-problems-of-the-semantic-web</link>
      <guid>http://thinkrefresh.com/posts/13-concepts-benefits-and-problems-of-the-semantic-web</guid>
    </item>
    <item>
      <title>Fixing Paperclip's Alpha PNG to JPG Conversion</title>
      <description>&lt;p&gt;&lt;a href="http://www.thoughtbot.com/projects/paperclip"&gt;Paperclip&lt;/a&gt; has to be one of my favorite plugins for Rails, providing simple storage and validation for uploads, and thumbnailing of images.&lt;/p&gt;
&lt;p&gt;Whilst it isn&amp;#8217;t technically broken, for small image sizes many people want to convert 24-bit (semi-transparent capable) PNGs to &lt;span class="caps"&gt;JPG&lt;/span&gt; and sadly this creates images containing artifacts where the transparency is assumed to be black not white. Luckily the fix is very simple, but it took me a while to figure out, so as always I thought I&amp;#8217;d share it with you guys &amp;amp; gals.&lt;/p&gt;
&lt;p&gt;The important option is the &lt;code&gt;:convert_options&lt;/code&gt; which takes a hash of &lt;a href="http://www.imagemagick.org/"&gt;ImageMagick&lt;/a&gt; flags for each of your thumbnails. In the code below, I am converting the &lt;em&gt;large&lt;/em&gt; and &lt;em&gt;max&lt;/em&gt; sizes to &lt;span class="caps"&gt;JPG&lt;/span&gt;, so for those I need the ImageMagick options &lt;code&gt;-background white -flatten&lt;/code&gt; which specifies the transparency should be white. &lt;strong&gt;Note:&lt;/strong&gt; the -flatten flag is very important &amp;#8211; this is the sole reason I ended up spending hours searching for a solution.&lt;/p&gt;
&lt;script src="http://gist.github.com/46119.js"&gt;&lt;/script&gt;&lt;noscript&gt;
&lt;p&gt;View code on &lt;a href="http://gist.github.com/46119"&gt;GitHub Gist&lt;/a&gt;&lt;/p&gt;
&lt;/noscript&gt;</description>
      <pubDate>Mon, 12 Jan 2009 19:30:43 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/12-fixing-paperclip-s-alpha-png-to-jpg-conversion</link>
      <guid>http://thinkrefresh.com/posts/12-fixing-paperclip-s-alpha-png-to-jpg-conversion</guid>
    </item>
    <item>
      <title>Personal Projects: Keep 'Em Simple</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/simple.jpg" title="Simplicity" alt="Simplicity" /&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href="/posts/10-simple-specifications"&gt;last ThinkRefresh article&lt;/a&gt; covered simple specifications for client work. In this post, we&amp;#8217;re concentrating on simple ideas for personal projects and startups.&lt;/p&gt;
&lt;p&gt;Everyone has at least a couple of ideas which they&amp;#8217;d like to pursue; the problem is, which one should you work on? You only have so much time in the day, and even if you&amp;#8217;re the best developer out there, you&amp;#8217;re always going to be limited by what you can achieve around current commitments, be it to friends, family, existing employment, or client work. As we&amp;#8217;ve &lt;a href="/posts/8-developer-diet"&gt;previously discussed&lt;/a&gt;, working all hours of the day can negatively impact your productivity.&lt;/p&gt;
&lt;p&gt;Based on my limited experience with founding &amp;amp; developing start-ups, and nurturing them from the crazy ideas stage through to production, I&amp;#8217;m now hedging my bets on web apps that are geared towards solving simple, tangible problems. You know the ones I&amp;#8217;m talking about; they&amp;#8217;re the sort of ideas you don&amp;#8217;t need a rehearsed speech for because &amp;#8220;The Problem&amp;#8221; just rolls off your tongue, subsequently justifying the follow-up explanation of the potential solution whilst making it sound simple (potentially to the exclamation of, &amp;#8220;why hasn&amp;#8217;t somebody done this already?&amp;#8221;) and undeniably attainable. If you have a web app idea that fits the bill, &lt;strong&gt;drop everything, and start coding&lt;/strong&gt;. That&amp;#8217;s the idea you want to pursue.&lt;/p&gt;
&lt;h2&gt;Example&lt;/h2&gt;
&lt;p&gt;I really wanted to use someone else&amp;#8217;s project as an example of a simple idea (please post one in the comments if you have one of your own), but Notipal, an application that Ryan and I started hacking on just before Christmas, just works so well:&lt;/p&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/fail.jpg" title="Fail Whale" alt="Fail Whale" /&gt; &lt;span class="caption"&gt;&amp;#8220;Fail Whale&amp;#8221;&lt;br /&gt;
Source: &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;My dad was trying to access his online banking. I was sat next to him. The bank&amp;#8217;s website was unavailable. He kept clicking refresh in a vain attempt to access his bank account. This process quickly became tedious, and as soon as it did, I slapped my forehead and decided that there needed to be a web application that offered an email collection service for error pages. As a &amp;#8216;webmaster&amp;#8217; you copy/paste a line of code in to your website templates, and if your site goes down, an email form (as provided by the line of code) can collect the email addresses of the people that hit your website&amp;#8217;s error page during the outage. And when your website is back up again, the service emails all the people who left their email address for notification.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s the Notipal problem &amp;amp; solution in a nutshell.&lt;/p&gt;
&lt;h2&gt;Saying &amp;#8216;No&amp;#8217;&lt;/h2&gt;
&lt;p&gt;Aside from the fact that simple ideas sound great to other people, there&amp;#8217;s a second, albeit no less important benefit for building an application which solves a problem &amp;#8211; it&amp;#8217;s &lt;em&gt;much&lt;/em&gt; easier to say &lt;em&gt;&amp;#8216;no&amp;#8217; to anything but the core feature set&lt;/em&gt; required to solve the problem you&amp;#8217;ve diagnosed. This point is particularly topical for ThinkRefresh readers; along with naming things and cache invalidation, &lt;em&gt;feature creep&lt;/em&gt; is a programmers worst enemy. More info about feature creep is available on &lt;a href="http://sixrevisions.com/project-management/eight-tips-on-how-to-manage-feature-creep/"&gt;Six Revisions&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Creeping_featurism"&gt;Wikipedia&lt;/a&gt;. Simple ideas empower you to say &lt;em&gt;&amp;#8216;no&amp;#8217; to feature creep&lt;/em&gt;, unlike ideas which target a &amp;#8216;gap in the market&amp;#8217; &amp;#8211; if the feature doesn&amp;#8217;t help you to solve the original problem, it doesn&amp;#8217;t make it in to the spec.&lt;/p&gt;
&lt;p&gt;The later breed of idea, which target a &amp;#8216;gap in the market&amp;#8217;, are usually conjured up whilst observing existing players in the market place, deciding that their market share can be eroded by a product with a slightly different &amp;#8216;fit&amp;#8217;, and only then trying to work out the required feature set. If you&amp;#8217;re considering pursuing one of these &amp;#8216;opportunities&amp;#8217;, think very carefully about doing so, unless, once again, you have specific use cases of exactly how the product works/functions differently, or how it solves a problem in a different way. By now, though, this post should have convinced you that you just want to start with a small problem and to create a simple solution &amp;#8211; something which you&amp;#8217;re much more likely to launch within the time you have available for personal projects.&lt;/p&gt;
&lt;p&gt;Finally, as an aside, does anyone have a new year&amp;#8217;s resolution related to personal projects, or are you planning to launch a personal project in &amp;#8216;09? We&amp;#8217;d would love to have the scoop, especially if it&amp;#8217;s a Rails app, so please let us know in the comments.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This article&amp;#8217;s photo: &amp;#8220;Chair&amp;#8221; by &lt;a href="http://www.flickr.com/photos/deks/201524959/"&gt;Christopher Woo @ Flickr&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 08 Jan 2009 13:13:14 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/11-personal-projects-keep-em-simple</link>
      <guid>http://thinkrefresh.com/posts/11-personal-projects-keep-em-simple</guid>
    </item>
    <item>
      <title>Simple Specifications</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/write-proposal.jpg" title="Writing a specification" alt="Writing a specification" /&gt;&lt;/p&gt;
&lt;p&gt;Writing a specification for a website or web application can be difficult, what do you include? How much transparency should there be? What about pricing?&lt;/p&gt;
&lt;p&gt;Here are some tips to start you on your way in a simple &lt;em&gt;who, what, why, when &amp;amp; where&lt;/em&gt; format based on what I&amp;#8217;ve learnt over the past few years.&lt;/p&gt;
&lt;h2&gt;What&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;m afraid I can&amp;#8217;t really start with &lt;em&gt;who&lt;/em&gt;, because without the context of &lt;em&gt;what&lt;/em&gt; you are making for you&amp;#8217;re client, it would be pretty confusing. So how should you go about describing what you are making?&lt;/p&gt;
&lt;p&gt;You should start off with a quick paragraph or two on your objective i.e specify in layman&amp;#8217;s terms what you are producing for your client. If you are making a website it may be pretty obvious what one is, but what kind of features are possible (even if you aren&amp;#8217;t including them), however if you are making a web application, it&amp;#8217;s probably best to explain what the difference is to website and desktop applications. Either way, what are the obvious benefits to the client?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I can get a website for £50 on the net.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We hear this a lot, but you can pre-empt this by explaining why you&amp;#8217;re solution is more expensive, and suggesting in good-faith that you can look at more affordable, less extravagant solutions if they are looking for a cheaper presence.&lt;/p&gt;
&lt;h3&gt;Flexibility&lt;/h3&gt;
&lt;p&gt;Some projects don&amp;#8217;t have strict deliverables, so what process will you go through to manage the scope of the project and how it&amp;#8217;s designed? If you&amp;#8217;re relying on prewritten systems, they might be fixed in implementation so it&amp;#8217;s worth mentioning what you can and cannot do with them.&lt;/p&gt;
&lt;h3&gt;External Code&lt;/h3&gt;
&lt;p&gt;Are you going to be using open source systems like &lt;a href="http://wordpress.com/"&gt;Wordpress&lt;/a&gt; or external services such as an &lt;acronym title="Application Programming Interface"&gt;&lt;span class="caps"&gt;API&lt;/span&gt;&lt;/acronym&gt;, and how are you going to plan for updates / changes in the specification? What happens if such service / codebase becomes unavailable or no longer supported? While these questions might be of no interest to the client, they are important to cover your back in event of any issues.&lt;/p&gt;
&lt;h2&gt;Who&lt;/h2&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/office-workers.jpg" title="Your potential users" alt="Your potential users" /&gt; &lt;span class="caption"&gt;&amp;#8220;Office workers in downtown Singapore&amp;#8221;&lt;br /&gt;
Source: &lt;a href="http://flickr.com/photos/larrycarr/2792634475/"&gt;Larry Carr @ Flickr&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is section is very important for not just your client but yourself also, first start with explaining whether it&amp;#8217;s a public website, private intranet, or public/private web application and how that relates to the type of visitors to the website. The questions you should be asking yourself when looking at visitors are:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;How computer literate are they?&lt;/li&gt;
	&lt;li&gt;How patient will they be, &lt;em&gt;i.e are they broadband guzzling script-kiddies who must have everything immediately or they&amp;#8217;ll go elsewhere, or employees who don&amp;#8217;t mind waiting 10 seconds for a large page of data to load?&lt;/em&gt;&lt;/li&gt;
	&lt;li&gt;What functionality will they be using?&lt;/li&gt;
	&lt;li&gt;What data &lt;strong&gt;should&lt;/strong&gt; or &lt;strong&gt;shouldn&amp;#8217;t&lt;/strong&gt; they have access too (whichever is more appropriate)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Context&lt;/h3&gt;
&lt;p&gt;How these users access the website/webapp can radically change how you display it. With mobile browsing becoming more and more popular it may be worth developing a streamlined mobile-specific interface, but context doesn&amp;#8217;t just &lt;em&gt;what devices&lt;/em&gt; they&amp;#8217;ll be using, but the &lt;em&gt;situations of access&lt;/em&gt;, for example when printing orders, a user might just want a quick list to scan through, but when dispatching them, the warehouse staff might only need to see a single order in much greater detail.&lt;/p&gt;
&lt;h2&gt;When&lt;/h2&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/calendars.jpg" title="Calendars on wall" alt="Calendars on wall" /&gt; &lt;span class="caption"&gt;&amp;#8220;Minimal Stripes&amp;#8221;&lt;br /&gt;
Source: &lt;a href="http://flickr.com/photos/nathan_awesome/3061372301/"&gt;Alienate @ Flickr&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;If you are not particularly great at predicting when projects are going to be complete, discuss this with the client, and ask when their deadlines are &amp;#8211; it might turn out that they don&amp;#8217;t really need certain functionality until later down the line, so you can set a short deadline for the core functions and work from there. If you are following an agile development model, it&amp;#8217;s also hard to determine exact dates, but you can always set deadlines with get-out clauses providing you give at least a set amount of notice.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s a good idea to set deadlines for your client too, an idea I came across through &lt;a href="http://boagworld.com"&gt;Paul Boag&lt;/a&gt; [I can&amp;#8217;t find the exact article, sorry]. It may only be that you need sample content from a client to initially fill their website, but it keeps the relationship bi-directional, rather than the client just polling you for updates all the time.&lt;/p&gt;
&lt;p&gt;Clients like to see their projects in action, you might be including them in your acceptance testing of each iteration, but if you aren&amp;#8217;t planning on meeting with them to discuss the project details further, it&amp;#8217;s worth considering booking progress meetings where you can demonstrate features to the client. This also helps with you&amp;#8217;re project management as it helps define internal goals to be reached before these meetings. The meetings need not be set in stone, but nobody likes to repeatedly delay them so it&amp;#8217;s always in the back of your mind.&lt;/p&gt;
&lt;h2&gt;Why&lt;/h2&gt;
&lt;p&gt;It&amp;#8217;s always good to finish on a positive, so before providing a list of your costs which is likely to give the client a heart attack, tell them why they want this project to happen, why should they be excited, and also most importantly why use you? You may have some specialisms that will guarantee success, or a close relationship with the client which you feel you can use to both yours and your client&amp;#8217;s advantage.&lt;/p&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/traffic-light.jpg" title="get ready... go!" alt="get ready... go!" /&gt; &lt;span class="caption"&gt;&amp;#8220;Driving Dilemma (edited)&amp;#8221;&lt;br /&gt;
Source: &lt;a href="http://flickr.com/photos/sis/2635898654/"&gt;Sister72 @ Flickr&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Finish Up&lt;/h2&gt;
&lt;h3&gt;Pricing&lt;/h3&gt;
&lt;p&gt;Pricing is a difficult one because it not only depends on the type of client, but also the financial situation and various aspects of the project, for these reasons I won&amp;#8217;t suggest how to price your work (that&amp;#8217;s maybe one for another post), but here are a few tips that work for us at &lt;a href="http://agincourttech.com/"&gt;Agincourt Technologies Ltd&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Take a 50% deposit up-front, if you&amp;#8217;re clients question this then you haven&amp;#8217;t done you&amp;#8217;re job properly in creating trust in the relationship.
	&lt;ul&gt;
		&lt;li&gt;You might like to suggest a finance company to act as an intermediary providing you with the money, and the client with monthly bills rather than lump sums.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;Unless you are charging by the hour, don&amp;#8217;t indicate your hours. If you&amp;#8217;ve quoted £10,000 for X many hours and it only takes you half the allotted time, then that makes up for the next time when you under-quote. You&amp;#8217;re client is paying for a product, not the service of you coding it, so they should be prepared to pay the full amount.&lt;/li&gt;
	&lt;li&gt;Mention your pricing with regards changes to the specification after sign-off, it&amp;#8217;s sometimes worth including a few hours for this when creating your total.&lt;/li&gt;
	&lt;li&gt;Alert clients of monthly costs as early as possible, hitting them with unexpected bills will harm your relationship.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Sign Off&lt;/h3&gt;
&lt;p&gt;The final hurdle is sign-off, I&amp;#8217;ve big tip for this one, print off a couple of copies of your specification and sit down with the client to read through it all, explaining anything that crops up and do it on their turf. Don&amp;#8217;t force clients to trudge all the way to your office, take the initiative to visit their office so they feel 100% comfortable when they sign your specification &amp;#8211; as an added bonus on your part: &lt;strong&gt;you can walk away with a cheque!&lt;/strong&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 05 Jan 2009 23:12:12 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/10-simple-specifications</link>
      <guid>http://thinkrefresh.com/posts/10-simple-specifications</guid>
    </item>
    <item>
      <title>Starling &amp; Workling Capistrano Tasks</title>
      <description>&lt;p&gt;Just a quick slice of code for you, if you&amp;#8217;ve followed the &lt;a href="http://railscasts.com/episodes/128-starling-and-workling"&gt;Starling and Workling&lt;/a&gt; screencast on &lt;a href="http://railscasts.com/"&gt;Railscasts&lt;/a&gt; and you want to run them in production, then you&amp;#8217;ll probably want to manage them through &lt;a href="http://www.capify.org/"&gt;Capistrano&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I spent a large portion of yesterday getting the commands to work correctly, so here is my Capistrano tasks:&lt;/p&gt;
&lt;script src="http://gist.github.com/43055.js"&gt;&lt;/script&gt;&lt;noscript&gt;
&lt;p&gt;View the code on &lt;a href="http://gist.github.com/43055"&gt;Github Gist&lt;/a&gt;&lt;/p&gt;
&lt;/noscript&gt;</description>
      <pubDate>Sun, 04 Jan 2009 14:02:47 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/9-starling-workling-capistrano-tasks</link>
      <guid>http://thinkrefresh.com/posts/9-starling-workling-capistrano-tasks</guid>
    </item>
    <item>
      <title>Developer Diet</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/planning.jpg" title="Queue-card storyboard" alt="Queue-card storyboard" /&gt;&lt;/p&gt;
&lt;p&gt;We can all fall into the trap of hacking away until dawn, but it&amp;#8217;s just not healthy to be doing repeatedly, especially if you&amp;#8217;re like me and tend to drink more Red Bull than the yearly recommendation in one night.&lt;/p&gt;
&lt;p&gt;My developer diet isn&amp;#8217;t simply looking at the food and drink we consume but how we use our time, and how improving this can lead to not only a better lifestyle, but increased productivity also.&lt;/p&gt;
&lt;h2&gt;Have a decent breakfast&lt;/h2&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/breakfast.jpg" title="Breakfast" alt="Breakfast" /&gt; &lt;span class="caption"&gt;&amp;#8220;Healthy Breakfast&amp;#8221;&lt;br /&gt;
Source: &lt;a href="http://flickr.com/photos/seitti/393764095/"&gt;Seitti @ Flickr&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Starting the morning on an empty stomach is not just a bad idea for your health, but will also distract you and drain you of energy as the day progresses. Women especially need to have a really good breakfast as studies have shown they are more likely to snack throughout the day &amp;#8211; so remember not eating breakfast is not a slimming diet!&lt;/p&gt;
&lt;p&gt;If you can&amp;#8217;t stomach cereal or toast in the morning, try fruit salad or even just bananas in yogurt, it might seem rudimentary, but it&amp;#8217;s a start. Fruit juice is also a good way to wake you up in the morning without resorting to caffeine.&lt;/p&gt;
&lt;h2&gt;Don&amp;#8217;t start too early&lt;/h2&gt;
&lt;p&gt;You&amp;#8217;re brain isn&amp;#8217;t active in the first hour or two of the morning, so why force yourself to work when you can use the time to ease yourself into work. A lot of web work / interest in services is acquired by networking be it using a blog, &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt; or any &lt;a href="http://soindustry.com/"&gt;social network&lt;/a&gt;, so as Elliot Jay Stocks suggests: &lt;a href="http://elliotjaystocks.com/blog/archive/2008/write-off-that-first-hour/"&gt;write of that first hour&lt;/a&gt;, read you&amp;#8217;re emails, write a blog post and catch up on Twitter.&lt;/p&gt;
&lt;h2&gt;Planning&lt;/h2&gt;
&lt;p&gt;You can decide the fate of a project even before you have even put finger to key. Agile programming is often used as an excuse not to plan at all, when actually it&amp;#8217;s really about being fluid and adapting the plan as you go along.&lt;/p&gt;
&lt;p&gt;You don&amp;#8217;t have to spend hours drawing class diagrams or &lt;acronym title="Entity Relationship Diagrams"&gt;&lt;span class="caps"&gt;ERD&lt;/span&gt;&lt;/acronym&gt;s, find something that works for you and stick to it. When working on &lt;a href="http://notipal.com/"&gt;Notipal&lt;/a&gt;, myself and &lt;a href="/about-us"&gt;Neil&lt;/a&gt; simply used &lt;a href="http://twitpic.com/sfsu"&gt;queue-cards to storyboard our idea&lt;/a&gt; and it worked really well. Even if the plan changes, you aren&amp;#8217;t stressing about where it&amp;#8217;s going and the core functionality.&lt;/p&gt;
&lt;h2&gt;Work side-by-side with a co-worker&lt;/h2&gt;
&lt;p&gt;Recently I was joined by Neil up in Manchester to begin work on Notipal, all we had was a rough idea and a blank Rails project. Many companies may be adverse to the idea of &lt;a href="http://en.wikipedia.org/wiki/Pair_programming"&gt;pair programming&lt;/a&gt; as it may seem like cutting your resources in half, but you work much more productively because neither of you spend time on IM(Instant Messaging), reading your &lt;span class="caps"&gt;RSS&lt;/span&gt; feed midday, or in any other form of procrastination. You&amp;#8217;ll find that working with another person actually makes you feel much more happy, as, believe it or not, you can actually have a laugh whilst programming!&lt;/p&gt;
&lt;h2&gt;Breaks&lt;/h2&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/kitkat.jpg" title="Kitkat" alt="Kitkat" /&gt; &lt;span class="caption"&gt;&amp;#8220;Have a break, have a&amp;#8230;&amp;#8221;&lt;br /&gt;
Source: &lt;a href="http://flickr.com/photos/pommykiwi/262676064/"&gt;Pommykiwi @ Flickr&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Everyone&amp;#8217;s heard the idea of having a 15 minute break away from the computer every hour, and most of us laugh at the concept, we&amp;#8217;re too busy for that&amp;#8230; right? &lt;strong&gt;Wrong!&lt;/strong&gt; The 15 minutes doesn&amp;#8217;t need to be spent stood by the coffee machine, or staring out the window, just &lt;em&gt;not concentrating on your monitor&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Try using the break to update your to-do list on paper or a whiteboard. The time concentrating on what you&amp;#8217;re supposed to be doing rather than what you&amp;#8217;re actually doing can freshen you up and help you optimise your time, so you&amp;#8217;re not sat around wondering what needs to be done next.&lt;/p&gt;
&lt;h2&gt;Don&amp;#8217;t give up on problems&lt;/h2&gt;
&lt;p&gt;All too often we come to a tricky / boring section of work and we either avoid it altogether or give up when we hit the first problem and work on something else. Try discussing it with a colleague or friend, regardless of whether they are technically minded or not, just by explaining the problem you might realise a much more simple solution.&lt;/p&gt;
&lt;p&gt;If all else fails have a break, and then sit down to do some research, avoid rushing into it, but don&amp;#8217;t deviate to something else as the knowledge of this problem will disrupt the rest of your work.&lt;/p&gt;
&lt;h2&gt;Lunch&lt;/h2&gt;
&lt;p&gt;Everyone engine needs fuel to keep running, not getting the right vitamins and minerals in your diet can lower your immune system and actually cause problems from deficiencies and developers are known to be some of the worst eaters.&lt;/p&gt;
&lt;p&gt;A sandwich (preferably homemade), a bag of crisps, some fruit, and a cereal bar is a perfectly wholesome lunch, you push healthy eating as far as you want, but it&amp;#8217;s pointless diving in at the deep end as it will just make you hungry and depressed.&lt;/p&gt;
&lt;p style="float:right;"&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/green_and_blacks.jpg" title="Green&amp;amp;Blacks 70% cocoa chocolate" alt="Green&amp;amp;Blacks 70% cocoa chocolate" /&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re not a big fruit eater, try rewarding yourself with a small amount of something you really like. I enjoy chocolate, like most people, so chucking in a small bar of &lt;a href="http://www.greenandblacks.com/uk/home.html"&gt;Green &amp;amp; Blacks&lt;/a&gt; dark chocolate can really boost my motivation for other foods. On a side note, dark chocolate is significantly better for you than milk chocolate, there is much less fat and more antioxidants and yet it still releases serotonin, the &lt;em&gt;feel good&lt;/em&gt; chemical produced in your brain.&lt;/p&gt;
&lt;h2&gt;Wind down&lt;/h2&gt;
&lt;p&gt;Don&amp;#8217;t expect to be able to sleep moments after you hit shutdown, you&amp;#8217;re mind needs time to relax otherwise you&amp;#8217;ll be up all night thinking about what functionality can be added to your application &amp;#8211; and while that might seem like a good thing, you aren&amp;#8217;t in the right frame of mind to be making decisions on functionality in the early hours of the morning, it&amp;#8217;s an easy way to create scope-creep.&lt;/p&gt;
&lt;p&gt;My recommendation is to expect to sleep an hour after you finish working, in that hour you should be doing anything that doesn&amp;#8217;t require too much concentration, TV is perfect &amp;#8211; soaps may be mind-numbing to watch &amp;#8211; but that&amp;#8217;s the idea! If you have quite an active mind, or drinking copious quantities of energy drinks, you&amp;#8217;ll have to extend the hour to two or more.&lt;/p&gt;
&lt;p&gt;Routine is another aid for telling your body when it&amp;#8217;s time to sleep, if you watch an hour of TV, then have a wash and brush your teeth before bed for a week, you&amp;#8217;ll find you will sleep more promptly.&lt;/p&gt;
&lt;h2&gt;Don&amp;#8217;t start too late&lt;/h2&gt;
&lt;p&gt;So we&amp;#8217;re back round to the morning, make sure you&amp;#8217;ve not had such a late night, and get up fresh and early, you only need around 8 hours sleep, any over that and you&amp;#8217;ll feel lethargic, and most of all you&amp;#8217;ll lose that great feeling when you do lie-in on a weekend.&lt;/p&gt;</description>
      <pubDate>Fri, 02 Jan 2009 12:23:35 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/8-developer-diet</link>
      <guid>http://thinkrefresh.com/posts/8-developer-diet</guid>
    </item>
    <item>
      <title>Rails 101: Routing</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/rails-routes.jpg" title="Rails Routes" alt="Rails Routes" /&gt;&lt;/p&gt;
&lt;p&gt;Routes define what URLs are used to access different parts of your application.&lt;/p&gt;
&lt;p&gt;When you run the scaffold generator described in the &lt;a href="/posts/6-rails-101-generators"&gt;previous article&lt;/a&gt; routes are setup for you automatically but they only setup the default settings, sometimes you need something a little more complex.&lt;/p&gt;
&lt;p&gt;In this article, I will show you how routes work and how to set them up yourself. You can &lt;a href="http://videos.thinkrefresh.com/media/Rails-101-004-Routing.mov"&gt;download a video version of this article&lt;/a&gt;, however the article is more up-to-date.&lt;/p&gt;
&lt;h2&gt;How Routes Work&lt;/h2&gt;
&lt;p&gt;You might have heard the phrase &amp;#8216;&lt;acronym title="Representational State Transfer"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt;&lt;/acronym&gt;ful routes&amp;#8217;, &lt;span class="caps"&gt;REST&lt;/span&gt; stands for &lt;em&gt;Representational State Transfer&lt;/em&gt; and basically makes use of different methods of request to process different actions, this way applications can interact with one another very easily over the standard &lt;acronym title="HyperText Transfer Protocol"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt;&lt;/acronym&gt; protocol.&lt;/p&gt;
&lt;p&gt;So how does &lt;span class="caps"&gt;REST&lt;/span&gt; affect you? Well if you are familiar with &lt;span class="caps"&gt;HTML&lt;/span&gt; you will know that forms have a method attribute which is set to &lt;span class="caps"&gt;GET&lt;/span&gt; or &lt;span class="caps"&gt;POST&lt;/span&gt;, however there are actually a few more methods available to &lt;span class="caps"&gt;HTTP&lt;/span&gt; but not included in &lt;span class="caps"&gt;HTML&lt;/span&gt;, these include the &lt;span class="caps"&gt;PUT&lt;/span&gt; and &lt;span class="caps"&gt;DELETE&lt;/span&gt; methods, &lt;span class="caps"&gt;REST&lt;/span&gt; uses these to figure out whether you are trying to create, read, update or delete an item.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;POST /users		=&amp;gt; Create
GET /users/1		=&amp;gt; Read (show)
PUT /users/1		=&amp;gt; Update
DELETE /users/1		=&amp;gt; Delete (destroy)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The standard Rails setup needs a few more actions than these, for starters there is the index action which lists all the items in the collection, this can be accessed by GETing the collection &lt;span class="caps"&gt;URL&lt;/span&gt;, in this example at/users. Other methods by default suffix the collection &lt;span class="caps"&gt;URL&lt;/span&gt; or object &lt;span class="caps"&gt;URL&lt;/span&gt; with their name, however this behavior can be overridden &amp;#8211; but we&amp;#8217;ll look into that later.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
GET /users		=&amp;gt; Index
GET /users/new		=&amp;gt; New
GET /users/1/edit	=&amp;gt; Edit&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Putting The Magic To Work&lt;/h2&gt;
&lt;p&gt;The routes file is located within the &lt;em&gt;config&lt;/em&gt; directory, by default it contains just two routes, both of which aren&amp;#8217;t restful and simply act as catch all for non-nested URLs, personally I like to remove these as they let you get away with not setting up your routes properly.&lt;/p&gt;
&lt;p&gt;To make our RESTful users section, all you need to enter is &lt;code&gt;map.resources :users&lt;/code&gt;, pretty simple right? Rails uses this one command to produce a set of around 14 routes!&lt;/p&gt;
&lt;p&gt;You can now test this with a rake command: &lt;code&gt;rake routes&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you look carefully, you&amp;#8217;ll notice that each route has a name associated with it, such as &lt;code&gt;new_user&lt;/code&gt;, this becomes useful in our views and controllers where we need to reference the URLs dynamically. In views you suffix the name with &amp;#8216;_path&amp;#8217;, for example &lt;code&gt;new_user_path&lt;/code&gt; and in controllers you should use &amp;#8216;_url&amp;#8217;, for example &lt;code&gt;new_user_url&lt;/code&gt;, this is because we only want the path in the view (/something), but in controllers you want the full address for use in the &lt;span class="caps"&gt;API&lt;/span&gt; (http://&amp;#8230;).&lt;/p&gt;
&lt;p&gt;You can setup named routes manually by typing the name of your route after &lt;code&gt;map&lt;/code&gt;. When setting up routes manually this way you have to specify a string which is parsed for parameters, the parameters are words prefixed with a colon, like symbols in Ruby.&lt;/p&gt;
&lt;p&gt;For an example, here&amp;#8217;s a route to disable a user, the route will be called &lt;code&gt;disable_user&lt;/code&gt;, and the route will include the user&amp;#8217;s ID, and it will call the disable method of the users controller.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;map.disable_user 'users/:user_id/disable',
  :controller =&amp;gt; 'users',
  :action =&amp;gt; 'disable'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;As you can see, &amp;#8216;user_id&amp;#8217; prefixed with a colon, this means it&amp;#8217;s a parameter and can be reference using &lt;code&gt;params[:user_id]&lt;/code&gt;. You can also constrict the parameter using a regular expression, so if we only wanted to accept numbers:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;map.disable_user 'users/:user_id/disable',
  :controller =&amp;gt; 'users',
  :action =&amp;gt; 'disable',
  :user_id =&amp;gt; /\d/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Remember I mentioned those additional &lt;span class="caps"&gt;HTTP&lt;/span&gt; methods before? Well we can constrain by them too, by adding the conditions hash to the end containing only one key value pair, I&amp;#8217;ll choose &amp;#8220;&lt;span class="caps"&gt;PUT&lt;/span&gt;&amp;#8221; which describes updating a current record.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;map.disable_user 'users/:user_id/disable',
  :controller =&amp;gt; 'users',
  :action =&amp;gt; 'disable',
  :user_id =&amp;gt; /\d/,
  :conditions =&amp;gt; { :method =&amp;gt; :put }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you are going down the RESTful route (no pun intended), you generally won&amp;#8217;t be writing your own routes like this very often, most of the time you can add them to the map.resources, so if we return back to our users entry, we can add our disable method to the member hash, which means it acts on one object, not the whole collection. If we wanted a disabled action to list all disabled users we can add it to the collection hash.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;map.resources :user, :member =&amp;gt; { :disable =&amp;gt; :put }&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Nested Routes&lt;/h2&gt;
&lt;p&gt;Another bonus for using map.resources is you can easily nest resources, so for example if a user has a profile, I would nice to be able to have routes like &lt;em&gt;/users/1/profile&lt;/em&gt;, and to do this we can just change the current map.resources into a block and drop another map.resource within it, but you don&amp;#8217;t use map this time, you use the word between the goal posts, in this case &amp;#8216;users&amp;#8217;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;map.resources :user, :member =&amp;gt; { :disable =&amp;gt; :put } do |users|
  users.resource :profile
end&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We can even refactor this further using the :has_one option:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;map.resources :user, :member =&amp;gt; { :disable =&amp;gt; :put }, :has_one =&amp;gt; :profile&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;There is also a similar option for has_many.&lt;/p&gt;
&lt;p&gt;You can now access the profile using more route helpers such as: &lt;code&gt;edit_user_profile_path(user_id)&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Special Notes&lt;/h2&gt;
&lt;p&gt;There are a few special things to note about routes, and those are the root route (again, no pun intended), path prefixing, namespacing, route globbing and shallow routing.&lt;/p&gt;
&lt;h3&gt;Root URLs&lt;/h3&gt;
&lt;p&gt;When a user goes to the root &lt;span class="caps"&gt;URL&lt;/span&gt; of your site you often want users to be greeted with a homepage, or dashboard, so to do that simply create a named route called root without a &lt;span class="caps"&gt;URL&lt;/span&gt; string attached to it. In this example, I&amp;#8217;ll make it point to the index of the users controller.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;map.root :controller =&amp;gt; 'users', :action =&amp;gt; 'index'&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Path Prefixes&lt;/h3&gt;
&lt;p&gt;Path prefixing allows you to prefix resource URLs with a string such as &amp;#8216;account&amp;#8217;, to make &lt;em&gt;/account/users&lt;/em&gt;, this means that you can group various URLs under one section.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;map.resources :user, :member =&amp;gt; { :disable =&amp;gt; :put }, :path_prefix =&amp;gt; 'account'&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Namespacing&lt;/h3&gt;
&lt;p&gt;If you have a bunch of controllers that have duplicate names but differing functionality, for example having a front-end &amp;#8216;notes&amp;#8217; controller which only lists and displays notes, and a back-end one which is protected and has a different layout, then namespacing keeps things tidy.&lt;/p&gt;
&lt;p&gt;You will need to group your routes within a namespace block as below:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;namespace(:admin) do |admin|
  admin.resources :user
  # ...
end&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And your controller will have to be namespaced too:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Admin::NotesController &amp;lt; ApplicationController&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Route Globbing&lt;/h3&gt;
&lt;p&gt;For route globbing, or in other words catch all routes with an unlimited nesting depth (i.e /random/url/here), you can prefix the parameter with an splat (asterisk) instead of a colon and in your controller and view the parameter will return an array of the parts.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;map.page '*path', :controller =&amp;gt; 'users', :action =&amp;gt; 'page'&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Shallow Routing&lt;/h3&gt;
&lt;p&gt;Recently introduced into Rails is the &lt;code&gt;:shallow&lt;/code&gt; option, this allows you to access nested routes as if they were belonging to the root. For example the routes:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;map.resources :notes, :shallow =&amp;gt; true do |note|
  note.resources :comments
end&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Would allow you to use the routes &lt;code&gt;comments_path&lt;/code&gt; and &lt;code&gt;comment_path(1)&lt;/code&gt; rather than having to use the nested paths &lt;code&gt;note_comments_path(note_id)&lt;/code&gt; or &lt;code&gt;note_comment_path(note_id, 1)&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;To create RESTful routes, you can use &lt;em&gt;map.resources&lt;/em&gt; or &lt;em&gt;resource&lt;/em&gt;, depending on whether you want a collection, or singular resource respectively. You can use the :member or :collection options to map additional routes within the resource, :has_many or :has_one to specify sub-routes and :path_prefix to add string prefixes to your paths.&lt;/p&gt;
&lt;p&gt;For the homepage you should use &lt;em&gt;map.root&lt;/em&gt; which negates the &lt;span class="caps"&gt;URL&lt;/span&gt; option, as it defaults to an empty string.&lt;/p&gt;
&lt;p&gt;And for other named routes you simply type &lt;code&gt;map.&lt;/code&gt; followed by the name and the &lt;span class="caps"&gt;URL&lt;/span&gt; as a string, for example &lt;code&gt;map.user 'users/:id'&lt;/code&gt; then follow it with a hash of options for :controller, :action and any constraints.&lt;/p&gt;</description>
      <pubDate>Sun, 28 Dec 2008 19:55:42 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/7-rails-101-routing</link>
      <guid>http://thinkrefresh.com/posts/7-rails-101-routing</guid>
    </item>
    <item>
      <title>Rails 101: Generators</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/rails-generator.jpg" title="Rails Generators" alt="Rails Generators" /&gt;&lt;/p&gt;
&lt;p&gt;So you&amp;#8217;re just about to crack on and dive into that code, but wait, you don&amp;#8217;t even need to do that! Rails comes with generators for basic functionality so you can get going as quickly as possible.&lt;/p&gt;
&lt;p&gt;Because Rails follows the strict file structure we covered in the &lt;a href="/posts/6-rails-101-file-structure"&gt;previous article&lt;/a&gt;, you can have a large amount of files automatically generated for you, because it knows where to put them.&lt;/p&gt;
&lt;p&gt;You also can &lt;a href="http://videos.thinkrefresh.com/media/Rails-101-003-Generators.mov.mov"&gt;download a video version of this article&lt;/a&gt;, however the article is more in-depth.&lt;/p&gt;
&lt;h2&gt;How?&lt;/h2&gt;
&lt;p&gt;Now, as I&amp;#8217;ve mentioned before, these files aren&amp;#8217;t like what is common in Java development where each &lt;span class="caps"&gt;IDE&lt;/span&gt; has it&amp;#8217;s own set which can&amp;#8217;t be used in another, just plain and simple Ruby classes, modules, and view files.&lt;/p&gt;
&lt;p&gt;You &lt;em&gt;can&lt;/em&gt; create your own controllers and models etc, &lt;em&gt;but&lt;/em&gt; the beauty of generators is you get up and running quickly. The first, and most important thing to note is you can get help on generators at any time by typing &lt;code&gt;script/generate --help&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;All the generators are called by typing &lt;code&gt;script/generate&lt;/code&gt; followed by the generator type and any options.&lt;/p&gt;
&lt;h2&gt;Scaffolding&lt;/h2&gt;
&lt;p&gt;To setup your first applications, the easiest thing to do is use the &lt;em&gt;scaffold&lt;/em&gt; generator, this not only sets up your model and controller, but a set of view files, a migration, a routes entry and some tests too.&lt;/p&gt;
&lt;p&gt;To begin with lets create an application to store some notes. Each note will have a title and some content as &lt;em&gt;attributes&lt;/em&gt;, so the command to generate this is:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;script/generate scaffold note title:string body:text&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Upon running this command you can see it generates a whole bunch of files, but at this moment we don&amp;#8217;t need to worry about them, we&amp;#8217;ll just migrate the database and boot up our server.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;rake db:migrate
script/server&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We don&amp;#8217;t have anything setup for our root page at the moment, so when you navigate to &lt;em&gt;http://localhost:3000/&lt;/em&gt; you will get the default Rails page. But if you go to the notes path at &lt;em&gt;http://localhost:3000/notes&lt;/em&gt; you will see that a basic notes section with all the &lt;acronym title="Create Read Update Delete"&gt;&lt;span class="caps"&gt;CRUD&lt;/span&gt;&lt;/acronym&gt; functionality is available.&lt;/p&gt;
&lt;h2&gt;Others&lt;/h2&gt;
&lt;p&gt;You don&amp;#8217;t always need to create all these files, sometimes you might just want a model or a controller, in which case you can simply use the &lt;code&gt;script/generate&lt;/code&gt; command again, but you can pass &lt;em&gt;model&lt;/em&gt;, &lt;em&gt;controller&lt;/em&gt; or &lt;em&gt;migration&lt;/em&gt; instead depending on what you want.&lt;/p&gt;
&lt;p&gt;One thing to remember with generating controllers is that you don&amp;#8217;t actually specify the model name like in scaffold or model generations, you actually specify the controller name, which is plural, so &lt;code&gt;script/generate scaffold note&lt;/code&gt; becomes &lt;code&gt;script/generate controller notes&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Edit &amp;gt; Undo&lt;/h2&gt;
&lt;p&gt;Finally if you decide you did something you didn&amp;#8217;t want to, you can remove any changes by running the same generator but with &lt;code&gt;script/destroy&lt;/code&gt; instead of &lt;code&gt;script/generate&lt;/code&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 28 Dec 2008 17:25:21 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/6-rails-101-generators</link>
      <guid>http://thinkrefresh.com/posts/6-rails-101-generators</guid>
    </item>
    <item>
      <title>YAML Configuration Files</title>
      <description>&lt;p&gt;Sometimes it&amp;#8217;s nice to have an easy place you can update options without having them hard coded into files buried in your application.&lt;/p&gt;
&lt;p&gt;I find it somewhat bizarre that this is not included in the Rails framework, however it&amp;#8217;s probably to do with keeping the directory tree clean. Anyway, it&amp;#8217;s not difficult to implement yourself.&lt;/p&gt;
&lt;h2&gt;Creating the file&lt;/h2&gt;
&lt;p&gt;First we&amp;#8217;ll need to create our file. I find the most suitable place for it to be located is _RAILS_ROOT/config/config.yml_, but you can save it wherever. The file will be converted to a hash, with strings as keys so you can nest your configuration as such:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;uploads:
  timeout: 600
  max_size_mb: 100&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Loading the file&lt;/h2&gt;
&lt;p&gt;Rather than loading the file in for each request, we only need load it once when the application is booted up, so past the following code into an initializer or the bottom of your &lt;em&gt;config/environment.rb&lt;/em&gt; file:&lt;/p&gt;
&lt;script src="http://gist.github.com/40994.js"&gt;&lt;/script&gt;&lt;noscript&gt;View the code on &lt;a href="http://gist.github.com/40994"&gt;Github Gist&lt;/a&gt;&lt;/noscript&gt;
&lt;p&gt;Now you can reference your configuration settings using the constant &lt;code&gt;SETTINGS&lt;/code&gt;, e.g:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SETTINGS['uploads']['max_size_mb']&lt;/code&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 28 Dec 2008 17:08:44 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/5-yaml-configuration-files</link>
      <guid>http://thinkrefresh.com/posts/5-yaml-configuration-files</guid>
    </item>
    <item>
      <title>Rails 101: File Structure</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/rails-files.jpg" title="Rails File Structure" alt="Rails File Structure" /&gt;&lt;/p&gt;
&lt;p&gt;When starting a project Rails automatically creates a large tree structure of folders and files, so what are they all for?&lt;/p&gt;
&lt;p&gt;You can &lt;a href="http://videos.thinkrefresh.com/media/Rails-101-002-File-Structure.mov"&gt;download a video version&lt;/a&gt; of this article.&lt;/p&gt;
&lt;h2&gt;Creating a Project&lt;/h2&gt;
&lt;p&gt;To create a project in Rails you need to be in your command line interface. Find an appropriate place to store your applications, for example, if you&amp;#8217;re on a Mac, the &lt;em&gt;sites&lt;/em&gt; folder is probably your best bet.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cd sites&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You can then generate the project by simply using the &lt;code&gt;rails&lt;/code&gt; command followed by the name of your project, for example:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;rails store&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Once all these files have been created. You will want open them in your editor, I recommend &lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt; if you&amp;#8217;re a Mac user, but anything that has a tree structure for files and ruby syntax highlighting will do.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cd store
mate .&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now all these folders might be a little daunting to begin with but I&amp;#8217;ll explain them one by one.&lt;/p&gt;
&lt;h2&gt;app&lt;/h2&gt;
&lt;p&gt;At the top we have our &lt;em&gt;app&lt;/em&gt; folder, coincidently this is the folder which most of the logic behind your application will be put.&lt;/p&gt;
&lt;h3&gt;Model View Controller&lt;/h3&gt;
&lt;p&gt;As mentioned in the &lt;a href="/posts/3-rails-101-introduction"&gt;previous article&lt;/a&gt;, Rails uses a &lt;acronym title="Model View Controller"&gt;&lt;span class="caps"&gt;MVC&lt;/span&gt;&lt;/acronym&gt; format to keep your code organised by separating your code into a logical structure. Imagine a user navigates to a page on your website. Their request is first sent to the relevent &lt;strong&gt;controller&lt;/strong&gt;, which picks out an action, like viewing the index, or updating an item.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;The controller then loads the objects, or &lt;strong&gt;models&lt;/strong&gt; it needs and maybe performs some updates on them. Models are, by default, linked to the database via ActiveRecord which means you don&amp;#8217;t really need to write any database code (such as &lt;span class="caps"&gt;SQL&lt;/span&gt;) until you&amp;#8217;re getting into advanced applications, so that is one less worry.&lt;/p&gt;
&lt;p&gt;When the controller is finished detailing with the model it will pass on any information to the &lt;strong&gt;view&lt;/strong&gt;, which will create the &lt;span class="caps"&gt;HTML&lt;/span&gt;, &lt;span class="caps"&gt;XML&lt;/span&gt;, &lt;span class="caps"&gt;RSS&lt;/span&gt; or whatever file format you want, before passing it back to the browser.&lt;/p&gt;
&lt;p&gt;You might notice there is also a &lt;strong&gt;helpers&lt;/strong&gt; folder within the app directory, helpers are basically small functions you can write to save you time and tidy your code up in the views.&lt;/p&gt;
&lt;h2&gt;config&lt;/h2&gt;
&lt;p&gt;The config directory contains all the files that are used during booting your application. One of the most important files is your &lt;em&gt;database.yml&lt;/em&gt; file, which stores your database access details.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;environments&lt;/strong&gt; folder which stores the different settings your application can run in, the defaults are development, production and test, however some people make a fourth for staging to test performance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Initializers&lt;/strong&gt; are used to run pieces of code during boot up of the application, such as setting up an exception notifier like &lt;a href="http://hoptoadapp.com/"&gt;Hoptoad&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Introduced in Rails 2.2.2 was internationalisation or I18n, the &lt;strong&gt;locales&lt;/strong&gt; folder contains the yml configuration files for all your supported languages.&lt;/p&gt;
&lt;p&gt;And finally the &lt;em&gt;routes.rb&lt;/em&gt; file which basically decides what your URLs look like and maps them to the right controllers. You don&amp;#8217;t need to worry about the others.&lt;/p&gt;
&lt;h2&gt;db&lt;/h2&gt;
&lt;p&gt;Your db directory will store any file-based databases, such as those using SQLite and the migration files which are basically Ruby-based commands which alter the database as you develop your application, ready for deployment.&lt;/p&gt;
&lt;h2&gt;doc&lt;/h2&gt;
&lt;p&gt;You can use the doc directory to store any documentation you might have for your application, or use the &lt;code&gt;rake rdoc&lt;/code&gt; command to generate code documentation automatically.&lt;/p&gt;
&lt;h2&gt;lib&lt;/h2&gt;
&lt;p&gt;You will use the lib directory to store custom classes for repeat functionality you&amp;#8217;ve sliced out of models and controllers.&lt;/p&gt;
&lt;h2&gt;log&lt;/h2&gt;
&lt;p&gt;One of the most important features of Rails is the log, the files store all the information you need to know while developing such as what queries are running, the performance of each page etc.&lt;/p&gt;
&lt;h2&gt;public&lt;/h2&gt;
&lt;p&gt;Your public directory is mapped to the root &lt;span class="caps"&gt;URL&lt;/span&gt;, so that means that rather than using paths prefixed with /public you can just address the file within the public directory as such: &lt;em&gt;example.com/images/my-image.jpg&lt;/em&gt; (as apposed to example.com/public/images/my-image.jpg).&lt;/p&gt;&lt;/p&gt;
&lt;h2&gt;script&lt;/h2&gt;
&lt;p&gt;In the terminal you will run commands like &lt;code&gt;script/server&lt;/code&gt; to boot up the server, these are all stored in the script directory, so you can leave that one alone for the time being.&lt;/p&gt;
&lt;h2&gt;test&lt;/h2&gt;
&lt;p&gt;You may have come across the acroynms &lt;a href="http://assets.thinkrefresh.com/images/content/rails-101-002-tdd-bdd.png"&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt; and &lt;span class="caps"&gt;BDD&lt;/span&gt;&lt;/a&gt;, which translate to &lt;em&gt;test driven development&lt;/em&gt; and &lt;em&gt;behaviour driven development&lt;/em&gt;. What these basically mean is that rather than waiting until the end of your project to test it, you test as you go along, so you will instantly pick up on any issues that might occur when you update your code. Because &lt;span class="caps"&gt;TDD&lt;/span&gt; &amp;amp; &lt;span class="caps"&gt;BDD&lt;/span&gt; are big in the Rails community, the test directory is an important part of the framework.&lt;/p&gt;
&lt;h2&gt;tmp&lt;/h2&gt;
&lt;p&gt;Cache files, sessions and process identifiers are stored in here &amp;#8211; nothing to be bothered about really.&lt;/p&gt;
&lt;h2&gt;vendor&lt;/h2&gt;
&lt;p&gt;This stores any plugins you have installed, the edge version of Rails if you&amp;#8217;re using it and any gems you have bundled into your application.&lt;/p&gt;
&lt;p&gt;Read the next in the series: &lt;a href="/posts/6-rails-101-generators"&gt;Generators »&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 28 Dec 2008 16:38:26 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/4-rails-101-file-structure</link>
      <guid>http://thinkrefresh.com/posts/4-rails-101-file-structure</guid>
    </item>
    <item>
      <title>Rails 101: Introduction</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/rails.png" title="Your beginning to learn Ruby On Rails" alt="Your beginning to learn Ruby On Rails" /&gt;&lt;/p&gt;
&lt;p&gt;So you want to learn &lt;a href="http://rubyonrails.org"&gt;Ruby on Rails&lt;/a&gt;? Whether you are comfortable with programming or new to writing your own applications and websites &amp;#8211; this guide is for you. This is the first article of many where we will cover everything you need to know to get to grips with programming and building your own web applications with Rails.&lt;/p&gt;
&lt;p&gt;We won&amp;#8217;t be starting with building a fully blown social network application to rival &lt;a href="http://facebook.com/"&gt;Facebook&lt;/a&gt; or anything of that sort, so don&amp;#8217;t worry about being thrown in at the deep end &amp;#8211; we&amp;#8217;re taking this one slowly.&lt;/p&gt;
&lt;p&gt;You can &lt;a href="http://videos.thinkrefresh.com/media/Rails-101-001-Introduction.mov"&gt;download a video version of this article&lt;/a&gt;, however the article covers the topic in a greater depth.&lt;/p&gt;
&lt;h2&gt;Agenda&lt;/h2&gt;
&lt;p&gt;Getting started is always the hardest part, so we thought we&amp;#8217;d outline a little description of what this article, and subsequent articles, will cover before you commit your time to them.&lt;/p&gt;
&lt;p&gt;In this first article we will look at what Rails is, why it came to be, and some concepts you should know about.&lt;/p&gt;
&lt;p&gt;Future articles will focus on individual aspects of Rails to develop a deep and broad understanding of how everything works and how it can be moulded to your advantage.&lt;/p&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;h3&gt;Web applications&lt;/h3&gt;
&lt;p&gt;So why would you want to write an application? Well as just mentioned: most websites are run from web apps of some description. Many believe &amp;#8220;web 2.0&amp;#8221; to be the new fad, however it really translates to user-generated content, which we&amp;#8217;ve had for years, what do you think the first bulletin boards contained?&lt;/p&gt;
&lt;p&gt;&lt;acronym title="Software as a Service"&gt;SaaS&lt;/acronym&gt; is becoming a popular means of businesses starting up with minimal costs, rather than needing expensive email &amp;amp; workgroup servers, they can use &lt;a href="http://www.google.com/a"&gt;Google Apps&lt;/a&gt;, instead of expensive Sage licences, we are beginning to see &lt;a href="http://lessaccounting.com/"&gt;LessAccounting&lt;/a&gt; accounts, the list goes on. If you can develop something that solves a problem for yourself, others are likely to have the same problem, and you should rightfully be able to monetize upon that.&lt;/p&gt;
&lt;h3&gt;Ruby on Rails&lt;/h3&gt;
&lt;p&gt;Rails was originally produced as a tool to fulfill the needs of &lt;a href="http://37signals.com/"&gt;37Signals&lt;/a&gt; in their development of &lt;a href="http://basecamphq.com/"&gt;BaseCamp&lt;/a&gt;, however after Rails became public it has quickly become one of the best tools for web development.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/basecamp.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;A main point to grasp is that &lt;strong&gt;Rails is not a programming language&lt;/strong&gt;, but a framework for quick and easy development of web applications, built on top of Ruby (which is a language), hence the name &lt;em&gt;Ruby On Rails&lt;/em&gt;. You shouldn&amp;#8217;t worry if you don&amp;#8217;t know Ruby, or don&amp;#8217;t know how to program Ruby I&amp;#8217;ve written up an article on &lt;a href="/the-very-basics-of-ruby"&gt;The Very Basics of Ruby&lt;/a&gt; I suggest you read before continuing.&lt;/p&gt;
&lt;p&gt;What sets Rails apart from other frameworks is it&amp;#8217;s agile mindset, opinions and paradigms &amp;#8211; rather than trying to suit everyone it has focus. Rails employs the idea of &lt;em&gt;convention over configuration&lt;/em&gt; whereby it uses defaults for most of the development, usually these defaults will be exactly what you want, but you will still be able to override them if you need something else.&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;h3&gt;Ruby&lt;/h3&gt;
&lt;p&gt;I won&amp;#8217;t cover installing Ruby, as I&amp;#8217;ve briefly described them in my guide to &lt;a href="/the-very-basics-of-ruby"&gt;the basics of Ruby&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Rails&lt;/h3&gt;
&lt;p&gt;To run Rails you must first have Ruby installed and RubyGems, then it is as simple as: &lt;code&gt;gem install rails&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Once you have Ruby and Rails installed, you can start your journey to making millions in the next world-changing web application.&lt;/p&gt;
&lt;h3&gt;Suggested applications&lt;/h3&gt;
&lt;p&gt;For Mac users you are lucky as you can use &lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt;, quite possibly the best text editor ever invented, however all you need to code Ruby is a text editor (even notepad would do) and a command line interface (terminal, console or command prompt).&lt;/p&gt;
&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/textmate.jpg" alt="" /&gt;&lt;/p&gt;
&lt;h2&gt;Ideas &amp;amp; concepts in Rails&lt;/h2&gt;
&lt;h3&gt;Generators&lt;/h3&gt;
&lt;p&gt;Rather than creating loads of files manually, Rails builds in generators which create sets of files based on options that you provide. This can mean that you can create a basic application with no code whatsoever!&lt;/p&gt;
&lt;h3&gt;Model View Controller&lt;/h3&gt;
&lt;p&gt;Rails is a fully-fledged &lt;acronym title="Model View Controller"&gt;&lt;span class="caps"&gt;MVC&lt;/span&gt;&lt;/acronym&gt; framework, so your &lt;span class="caps"&gt;HTML&lt;/span&gt; (views) is separate from the data objects (models) and the code which makes changes to such objects (controllers), this keeps everything neat and tidy so you don&amp;#8217;t have to dig around to find what you&amp;#8217;re looking for.&lt;/p&gt;
&lt;p&gt;Currently, the general consensus is that you should have so-called &lt;em&gt;skinny controllers&lt;/em&gt; having most of the logic in the models, because the skeleton for controllers is produced in the generators, so keeping them as standard as possible leads to much easier maintenance.&lt;/p&gt;
&lt;h3&gt;RESTful &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;By default, Rails is setup to use the &lt;acronym title="Representational State Transfer"&gt;&lt;span class="caps"&gt;REST&lt;/span&gt;&lt;/acronym&gt; protocol as an &lt;acronym title="Application Programming Interface"&gt;&lt;span class="caps"&gt;API&lt;/span&gt;&lt;/acronym&gt; to allow other applications to integrate with your own.&lt;/p&gt;
&lt;h3&gt;Simple routing&lt;/h3&gt;
&lt;p&gt;Following on from the RESTful &lt;span class="caps"&gt;API&lt;/span&gt; which relies upon URLs and &lt;span class="caps"&gt;HTTP&lt;/span&gt; request methods, it would be a pain to setup these routes manually using .htaccess files and the like, so Rails takes away all this pain by allowing you to specify routes in a Ruby file, but they&amp;#8217;ll be covered in a dedicated future article.&lt;/p&gt;
&lt;h3&gt;Object-Relational Mapping&lt;/h3&gt;
&lt;p&gt;&lt;span class="caps"&gt;ORM&lt;/span&gt; is a programming technique that links your classes to tables in a database, so you have to write little or no &lt;span class="caps"&gt;SQL&lt;/span&gt;. Rails defaults to &lt;a href="http://www.sqlite.org/"&gt;SQLite&lt;/a&gt; for quick development, but also has adapters for databases such as &lt;a href="http://mysql.org"&gt;MySQL&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Where to go for help&lt;/h2&gt;
&lt;p&gt;The Rails community is going strong and there are hundreds of places you can find help, checkout the &lt;a href="http://rubyonrails.org/community"&gt;official RubyOnRails community page&lt;/a&gt;, &lt;a href="http://railsforum.com/"&gt;RailsForum&lt;/a&gt;, or you can even &lt;a href="#new_comment"&gt;leave a comment below&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Read the next in the series: &lt;a href="/posts/4-rails-101-file-structure"&gt;File Structure »&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 28 Dec 2008 15:19:56 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/3-rails-101-introduction</link>
      <guid>http://thinkrefresh.com/posts/3-rails-101-introduction</guid>
    </item>
    <item>
      <title>I'm 404'ed</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/gone.jpg" title="Where have the ThinkRefresh articles and screencasts gone?" alt="Where have the ThinkRefresh articles and screencasts gone?" /&gt;&lt;/p&gt;
&lt;p&gt;You may have noticed ThinkRefresh has gone through a few changes. Most apparent of all, the layout has changed and my backlog of articles and screencasts has disappeared from the list (&lt;em&gt;you can find them at the bottom of this article though&lt;/em&gt;), I have also updated my blog system which I coded in Rails.&lt;/p&gt;
&lt;h2&gt;Why the change?&lt;/h2&gt;
&lt;p&gt;Recently I am becoming more involved with a variety of web application projects (some with my good friend &lt;a href="/about-us"&gt;Neil&lt;/a&gt;), and so I need a suitable system for frequent posting of updates and tips based on my discoveries.&lt;/p&gt;
&lt;p&gt;While the blog didn&amp;#8217;t &lt;em&gt;need&lt;/em&gt; a new layout &amp;#8211; I enjoy working on new layouts, and I feel this one is much more professional and generally easier on the eyes.&lt;/p&gt;
&lt;h2&gt;Will the screencasts and articles return?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; most already have, you can find the whole Rails 101 series in the &lt;a href="/"&gt;index&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Where can I download the screencasts now?&lt;/h2&gt;
&lt;p&gt;Below is a list of all the files, right click to save them:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://videos.thinkrefresh.com/media/001-Automated-Client-Side-Authentication.mov"&gt;Automated Client-Side Validation&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://videos.thinkrefresh.com/media/002-Block-Helper-Methods.mov"&gt;Block Helper Methods&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://videos.thinkrefresh.com/media/003-Verified-Degradable-Deletion.mov"&gt;Verified Degradable Deletion&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://videos.thinkrefresh.com/media/004-Proactive-Logging.mov"&gt;Proactive Logging&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://videos.thinkrefresh.com/media/005-Spam-Filtering.mov"&gt;Spam Filtering&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://videos.thinkrefresh.com/media/006-Polymorphic-Permissons.mov"&gt;Polymorphic Permissions&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://videos.thinkrefresh.com/media/007-YAML-Configuration-Files.mov"&gt;&lt;span class="caps"&gt;YAML&lt;/span&gt; Configuration Files&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;Rails 101 Series
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="http://videos.thinkrefresh.com/media/Rails-101-001-Introduction.mov"&gt;Introduction To Rails&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://videos.thinkrefresh.com/media/Rails-101-002-File-Structure.mov"&gt;File Structure&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://videos.thinkrefresh.com/media/Rails-101-003-Generators.mov"&gt;Generators&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://videos.thinkrefresh.com/media/Rails-101-004-Routing.mov"&gt;Routing&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Sat, 27 Dec 2008 12:24:53 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/2-i-m-404-ed</link>
      <guid>http://thinkrefresh.com/posts/2-i-m-404-ed</guid>
    </item>
    <item>
      <title>Avoiding Presentation Problems</title>
      <description>&lt;p&gt;&lt;img src="http://assets.thinkrefresh.com/images/content/present.jpg" title="Steve Jobs - The King of Keynotes" alt="Steve Jobs - The King of Keynotes" /&gt;&lt;/p&gt;
&lt;p&gt;Recently I have been giving many presentations at university, and also watched others, some dire, some brilliant. You could immediately see who had put the effort in, for whom presentations were second nature, and who were simply let down by their slides.&lt;/p&gt;
&lt;p&gt;I am no guru of presentations, but I do like to make notes on others presentations to improve my own work. Because presentations are becoming increasingly common in the workplace and events like &lt;a href="http://barcamp.org/"&gt;BarCamp&lt;/a&gt; are cropping up more and more I thought it would be a good idea to pass these notes on.&lt;/p&gt;
&lt;h2&gt;Keep it simple, but not too simple.&lt;/h2&gt;
&lt;p&gt;Everyone knows reading from slides will never earn you any brownie points, looking at the top of someone&amp;#8217;s head as they peer down at their laptop isn&amp;#8217;t appealing, nor is the monotonous mumbling that usually follows, so please don&amp;#8217;t reach for copy-and-paste in your essays or blog posts when you are producing slides &amp;#8211; if you can&amp;#8217;t be bothered to summarise, your audience can&amp;#8217;t be bothered to read your slides.&lt;/p&gt;
&lt;p&gt;Another recent trend is to make &amp;#8216;designer&amp;#8217; slides, whereby you focus on your slide being an image, vaguely based on the topic, and limit yourself to just a few words, no bullet points, no diagrams. This technique works very well when you are a confident speaker as the slides can often have a much greater impact on the audience. You should only this technique when your audience are very clued up on what you are talking about though, because bullet points serve as summaries that can help your audience understand your speech, and without them you are relying on your accent, the microphone and what you say being completely clear and understandable.&lt;/p&gt;
&lt;p&gt;So in summary, unless you are a well spoken, influential speaker presenting to an audience of gurus on your topic, please stick to concise bullet points. If you need a figure to work to, here is what I work to: a maximum of 5 bullet points per slide, no more than 2 lines per bullet (try to keep sub-5 words though) and no fonts below 18pt (preferably 20+).&lt;/p&gt;
&lt;h2&gt;Be honest.&lt;/h2&gt;
&lt;p&gt;My last presentation was about my final year project, a Rails-based e-commerce platform (soon to be publicly released), and you may know I am quite the evangelist of Rails, the ideas, concepts and services which surround it, this rubbed off on the enthusiasm of my talk because I thoroughly believed in my topic. It is amazing how much of a difference a smile, or indeed any facial expression, will influence the mood of your audience.&lt;/p&gt;
&lt;h2&gt;Involve your audience.&lt;/h2&gt;
&lt;p&gt;Presentations do not have to merely be one way conversations, you can ask questions too, it&amp;#8217;s a great technique to grasp people&amp;#8217;s attention. Questions to the audience don&amp;#8217;t have to be your typical &lt;em&gt;&amp;#8216;how many of you&amp;#8230;?&amp;#8217;&lt;/em&gt; or &lt;em&gt;&amp;#8216;who knows X, Y or Z?&amp;#8217;&lt;/em&gt;, they can be rhetorical:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How long do you spend every day trying to debug your web apps, when you could be using X?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While you get no feedback other than the expressions and nodding of the odd person, it makes everyone think about their answer nonetheless.&lt;/p&gt;
&lt;h2&gt;Practice, but not too much.&lt;/h2&gt;
&lt;p&gt;Believe it or not, but Steve Jobs probably doesn&amp;#8217;t spend weeks preparing his speeches in-front of the mirror, over practicing will lead to a less exciting presentation as you loose the enthusiasm, and besides Steve often has super secret news in his speeches so he can&amp;#8217;t risk accidently leaking it.&lt;/p&gt;
&lt;p&gt;On the other end of the scale, it&amp;#8217;s not the best idea to avoid practicing altogether. Personally I like to run through it from start to finish (timing myself if there is a constraint) on my own, it feels bizarre to begin with, like producing screencasts, because you are talking to yourself, but you get used to it quickly. Once you can present to yourself well, try presenting to a small group of friends, even just one person will do, but try to get people as alike to your target audience as possible, because giving a presentation on Web Ontologies to your Grandma probably won&amp;#8217;t get you any useful feedback. There is definitely no right or wrong way to practice, but this should give you a starting point to finding your preferential method.&lt;/p&gt;
&lt;p&gt;If you have access to the room where you&amp;#8217;ll be giving the final presentation, try to visit it and get a feeling for how loud you&amp;#8217;ll have to speak, how many people to expect and the computer setup (or power and networking if you are using your own laptop).&lt;/p&gt;
&lt;h2&gt;Never, ever, rely upon technology.&lt;/h2&gt;
&lt;p&gt;In the last presentation I gave all 3 of the presenters, including myself, hadn&amp;#8217;t scoped out the room beforehand, luckily I had my Macbook with me, and there was power available so I was fine, the other two ran into problems though. The first logged onto Linux and booted up her presentation in OpenOffice which was a different program / version to what she had used, so her slides did not display correctly, the second couldn&amp;#8217;t even log on and required PowerPoint so she couldn&amp;#8217;t use the others Linux account, in the end I provided her with my laptop, but it definitely had a negative effect on the audience.&lt;/p&gt;
&lt;p&gt;There would have been a simple solution to both of these issues, which is to always export a &lt;span class="caps"&gt;PDF&lt;/span&gt; copy of your presentation and keep it on a &lt;span class="caps"&gt;USB&lt;/span&gt; stick so you don&amp;#8217;t have to worry about getting an internet connection. You will loose the animations by using a &lt;span class="caps"&gt;PDF&lt;/span&gt;, but you should always keep transitions to a bare minimum anyway &amp;#8211; you are much more likely to impress the audience with a lack of animation, than with an abundance of superfluous effects.&lt;/p&gt;
&lt;p&gt;This advice doubles up for live demos, whether you are showing off your new web application or a physical product, keep an emergency &lt;span class="caps"&gt;PDF&lt;/span&gt; of screenshots or photos for backup, Steve Jobs keeps a whole separate Mac for if/when things go wrong during his keynotes, but that might be going a bit far in some cases.&lt;/p&gt;
&lt;h2&gt;Executive Summary&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Keep it simple, but not too simple.&lt;/strong&gt; Don&amp;#8217;t overload your slides, but provide enough information to summarise your topics.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Be honest.&lt;/strong&gt; It&amp;#8217;s obvious when speakers don&amp;#8217;t fully believe in something, or are unsure about an idea.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Involve your audience.&lt;/strong&gt; Rhetorical questions really get those listening thinking.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Practice, but not too much.&lt;/strong&gt; We don&amp;#8217;t want a monotonous voice, but we don&amp;#8217;t want ums and errs either.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Never, ever, rely upon technology.&lt;/strong&gt; Always have PDFs as a backup, and if needs be even print them out.&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Fri, 26 Dec 2008 21:58:33 +0000</pubDate>
      <link>http://thinkrefresh.com/posts/1-avoiding-presentation-problems</link>
      <guid>http://thinkrefresh.com/posts/1-avoiding-presentation-problems</guid>
    </item>
  </channel>
</rss>
