<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <title>smallroomsoftware.com - Everything</title>
  <id>tag:www.smallroomsoftware.com,2009:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.8.0">Mephisto Drax</generator>
  
  <link href="http://www.smallroomsoftware.com/" rel="alternate" type="text/html" />
  <updated>2009-02-14T23:42:36Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/smallroomsoftware" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2009-02-14:2839</id>
    <published>2009-02-14T23:20:00Z</published>
    <updated>2009-02-14T23:42:36Z</updated>
    <category term="Projects" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/s22pwLr2h-c/getting-into-github-activerecord-previous_changes-gem" rel="alternate" type="text/html" />
    <title>Getting into github. ActiveRecord#previous_changes gem</title>
<content type="html">
            &lt;p&gt;Not using it as my main VCS but I'm appreciating the power of &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt; more and more. Subversion definitely still has it's place but Git is pretty damn compelling for any open source project and any closed source project of any real scale. And it is _so_ nice to have my old unmaintained projects on &lt;a href="http://www.github.com"&gt;github&lt;/a&gt; where I can leave people to fork with no help from me.&lt;/p&gt;

&lt;p&gt;As github makes it super-easy to &lt;a href="http://gems.github.com/"&gt;distribute ruby gems&lt;/a&gt; I thought I would write one for one for once. &lt;a href="http://github.com/tomriley/previous_changes/tree/master"&gt;previous_changes&lt;/a&gt; adds an instance method, &lt;code&gt;previous_changes&lt;/code&gt;, to ActiveRecord objects to retrieve what the &lt;code&gt;changes&lt;/code&gt; would have returned before a call to &lt;code&gt;save&lt;/code&gt;.&lt;/p&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2009/2/14/getting-into-github-activerecord-previous_changes-gem</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2008-10-10:2824</id>
    <published>2008-10-10T21:51:00Z</published>
    <updated>2009-02-15T18:20:43Z</updated>
    <category term="Projects" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/89NS_azxuHk/shopping-carts-on-rails" rel="alternate" type="text/html" />
    <title>Shopping carts on Rails</title>
<content type="html">
            &lt;p&gt;For a while now I've been looking at options for changing the software on my Dad's online store. We've been using &lt;a href="http://www.litecommerce.com/"&gt;LiteCommerce&lt;/a&gt; for a few years and although it's generally worked well, (and I would still recommend it) it's been hacked on quite a bit to add features and modify the way it behaves. Fiddling with partially encrypted PHP code isn't my idea of fun and upgrading is also a real pain. Also, for a PHP application, it isn't particularly fast. It's coded in a clever object oriented way but I would say the per request overhead is quite high. I looked at some other PHP shopping carts but nothing looked much more compelling that LiteCommerce. It might be nice to have someone else worry about the whole problem but I couldn't find a good hosted solution (and what's the fun in that!) I looked at &lt;a href="http://www.shopify.com"&gt;Shopify&lt;/a&gt; for a while and then realised it was pretty underpowered and kind of expensive.&lt;/p&gt;

&lt;p&gt;Ideally I'd like a Rails based shopping cart and I've been following the progress of &lt;a href="http://www.spreehq.org"&gt;Spree&lt;/a&gt; for a while now. Spree seems to gaining momentum but it's still missing a lot of features that I need. Also, I suspect that a lot of effort is going to go into building user interface for store configuration. Things like, configuring of shipping, tax, payment gateways etc. I actually think this is the wrong approach for Spree. Spree is almost exclusively going to be used by Rails programmers and Rails programmers are a lot happier configuring these kind of thing in code. I mean, that's just normal practice in Rubyland. Actually, I would count being able to configure my shipping rules with a bit of Ruby code a feature! Same goes for tax calculations. So I guess I would actually like Spree not to be a finished product in itself. Well maybe a finished product when you add some basic extensions. The extension system does seem really good and I hope that they use extensions for more core components (permutations, inventory control). For anything that might not quite fit a potential user's needs (like me!), so they can swap the default out and code their own.&lt;/p&gt;

&lt;p&gt;(&lt;b&gt;Update:&lt;/b&gt; Sean points out below that Spree's tax and shipping calculation to plug in as Ruby code. I think it's great that Spree is taking this developer-centric approach and not aiming to be a turnkey solution. Just to be clear, I think Spree is &lt;em&gt;by far&lt;/em&gt; the most promising shopping cart system I've seen for a programmer to pick up and adapt for their client.)&lt;/p&gt;

&lt;p&gt;So in the end, I realised that in the long-run, building a custom cart is going to be less of a hassle and more of a benefit than migrating to some other software that has it's own quirks and distinctive way of viewing the world. Actually, it has turned out not be as much work as I had expected. As I mentioned above, lots of the complexity of reusable cart software comes from having to provide enough flexibility and configuration UI. I get to ignore all this and essentially hard-code things like shipping rules and tax calculations. So I can quickly code up a shipping exceptions for certain products. I also don't need a sand-boxed template editor - I just use normal erb templates.&lt;/p&gt;

&lt;p&gt;So I've probably put about 6 weeks of work into this and I already have the &lt;a href="http://www.thestringzone.co.uk"&gt;new site running&lt;/a&gt;. I think that's a pretty good advertisement for how fast you can build a fairly non-trivial application with &lt;a href="http://www.rubyonrails.org"&gt;Rails&lt;/a&gt;. I haven't implemented all of the features I have planned but it effectively does everything for my dad's business that Litecommerce did and a bit more. Building and deploying a Rails app from scratch is certainly a smoother process than it was a couple of years ago (more on that later).&lt;/p&gt;

&lt;p&gt;Here are some screenshots:&lt;/p&gt;

&lt;table&gt;
  &lt;tr&gt;
    &lt;td&gt;
      &lt;a href="/assets/2008/10/12/cart.png"&gt;&lt;img class="bordered" src="/assets/2008/10/12/cart.png" width="180" /&gt;&lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="/assets/2008/10/12/checkout.png"&gt;&lt;img class="bordered" src="/assets/2008/10/12/checkout.png" width="180" /&gt;&lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="/assets/2008/10/12/payment.png"&gt;&lt;img class="bordered" src="/assets/2008/10/12/payment.png" width="180" /&gt;&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;
      &lt;a href="/assets/2008/10/12/order.png"&gt;&lt;img class="bordered" src="/assets/2008/10/12/order.png" width="180" /&gt;&lt;/a&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;a href="/assets/2008/10/12/permutations.png"&gt;&lt;img class="bordered" src="/assets/2008/10/12/permutations.png" width="180" /&gt;&lt;/a&gt;
    &lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2008/10/10/shopping-carts-on-rails</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2008-08-18:2822</id>
    <published>2008-08-18T19:28:00Z</published>
    <updated>2008-08-18T19:33:42Z</updated>
    <category term="Projects" />
    <category term="rails" />
    <category term="ssl" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/L25y0f_VILM/testing-your-ssl-requirements-with-webrick-in-development-mode" rel="alternate" type="text/html" />
    <title>Testing your SSL requirements with Webrick in development mode</title>
<content type="html">
            &lt;p&gt;Testing SSL pages (login pages etc) in development mode doesn't seem to be supported out of the box with Rails. Turns out that webrick includes an SSL server and it isn't too hard to set. You need &lt;a href="http://pastie.org/25896"&gt;this script&lt;/a&gt; (mentioned &lt;a href="http://lists.netisland.net/archives/phillyonrails/phillyonrails-2006/msg00392.html"&gt;here&lt;/a&gt;). I changed the :ip setting and then saved it in my project as script/ssl_server. The trick is to run both the script/server and the script/ssl_server scripts at the same time. The &lt;em&gt;problem&lt;/em&gt; is that you'll be using non-standard ports so the &lt;a href="http://github.com/rails/ssl_requirement/tree/master"&gt;ssl_requirement&lt;/a&gt; plugin will fail to provide the correct redirects (it assumes ports 80 and 443). There's a &lt;a href="http://dev.rubyonrails.org/ticket/7947"&gt;ticket and patch about this&lt;/a&gt; but it doesn't look like it's going to be applied anytime soon. Let's just patch the code ourselves, replacing ssl_requirement's ensure_proper_protocol method.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def ensure_proper_protocol
  return true if ssl_allowed?

  if ssl_required? &amp;amp;&amp;amp; !request.ssl?
    redirect_to "https://" + request.host + (RAILS_ENV == 'development' ? ':3001' : '') + request.request_uri
    return false
  elsif request.ssl? &amp;amp;&amp;amp; !ssl_required?
    redirect_to "http://" + request.host + (RAILS_ENV == 'development' ? ':3000' : '') + request.request_uri
    return false
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So I ran into another problem with my SSL pages, this time in production. If you use the &lt;a href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html"&gt;assets host&lt;/a&gt; feature, you'll find your SSL protected pages reference assets with normal unsecured http URLs. This will cause a lot of security warning dialogs for IE users so you have to deal with it. You need all referenced media to be server over SSL. Luckily, you can supply a Proc to generate asset URLs and this Proc receives the current 'request' object which we can interrogate. Turns out that this is such a common situation, the example in the &lt;a href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html"&gt;rails docs&lt;/a&gt; gives the solution. Let's get our four hostname pipelining back too:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ActionController::Base.asset_host = Proc.new { |source, request|
  if request.ssl?
    "#{request.protocol}#{request.host_with_port}"
  else
    "#{request.protocol}asset#{(source.hash % 4)}.rentability.com"
  end
}
&lt;/code&gt;&lt;/pre&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2008/8/18/testing-your-ssl-requirements-with-webrick-in-development-mode</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2008-07-28:2821</id>
    <published>2008-07-28T18:32:00Z</published>
    <updated>2008-07-28T18:49:38Z</updated>
    <category term="Projects" />
    <category term="mostblueskies" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/LXzg-cFhN1U/non-stop-blue-skies" rel="alternate" type="text/html" />
    <title>Non-stop most blue skies</title>
<content type="html">
            &lt;p&gt;Finally, I have Most Blue Skies running reasonably well on one of our servers. Here's the "live" world view:&lt;/p&gt;

&lt;p&gt;
&lt;img src="http://84.45.17.145/~server/mapComposite500.png" /&gt;
&lt;/p&gt;

&lt;p&gt;... with some including &lt;a href="http://84.45.17.145/~server/most-blue.shtml"&gt;current "bluest" sky here...&lt;/a&gt;. At the moment, the server struggles to run enough sky calculations to keep the simulation up-to-date. I think it runs about 10 per second. That's on a dual 2Ghz G5 Xserve. We currently have 500,000 places in the database to test which will take about 14 hours to run through. Lets say half of those are in the dark and half or the remainder are under cloud. That's still several hours worth of calculations. So I need to either learn Fortran and improve the &lt;a href="http://www.nrel.gov/rredc/smarts/"&gt;SMARTS software&lt;/a&gt; for batch processing (not that likely), buy more servers or code some kind of Most Blue Skies @ Home system where the public or sponsors can donate some processing power to the project. Maybe I can find a Fortran to Java translator. That might be a way forward...&lt;/p&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2008/7/28/non-stop-blue-skies</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2008-07-22:2820</id>
    <published>2008-07-22T23:07:00Z</published>
    <updated>2008-08-11T13:22:57Z</updated>
    <category term="book" />
    <category term="concurrency" />
    <category term="java" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/s35ff6ytlH4/java-concurrency-in-practise-essential-reading" rel="alternate" type="text/html" />
    <title>Java Concurrency in Practise - essential reading!</title>
<content type="html">
            &lt;p&gt;&lt;img src="http://www.javaconcurrencyinpractice.com/images/jcip-cover.jpg" width="200" /&gt;
Just finished reading &lt;a href="http://www.javaconcurrencyinpractice.com"&gt;Java Concurrency in Practise&lt;/a&gt; and I'd highly, highly recommend it. This book quickly scares you into thread-safety seriously! It contains a lot of information relating to Java's memory model that you're unlikely to pick up from the javadoc (without a lot of effort anyway) and is written really, really nicely. Definitely increased my appreciation for Java and for how well optimised the JVMs are nowadays.&lt;/p&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2008/7/22/java-concurrency-in-practise-essential-reading</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2008-04-25:2797</id>
    <published>2008-04-25T13:12:00Z</published>
    <updated>2008-04-25T14:00:06Z</updated>
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/YArDsX63pMs/mod_rails-makes-life-easier" rel="alternate" type="text/html" />
    <title>mod_rails makes life easier</title>
<content type="html">
            &lt;p&gt;Every six months there seems to be a new, preferred way to deploy a Rails application. Mongrel+mod&lt;em&gt;proxy has worked OK for me for a while, but it's a bit fiddly to set up and quite tricky to make robust across reboots or crashes. Even normal restarts of my mongrel clusters sometimes fails. Now there is &lt;a href="http://www.modrails.com/"&gt;mod&lt;/em&gt;rails&lt;/a&gt; which seems to provide most of the advantages of a mongrel cluster with the simplicity of an apache module that spawns rails processes on demand. This is definitely becoming my preferred deployment method. I might even move &lt;a href="http://www.rentability.com"&gt;rentability&lt;/a&gt; to mod_rails when I get the chance as it'll simplify our server configuration a lot.&lt;/p&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2008/4/25/mod_rails-makes-life-easier</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2008-02-18:2786</id>
    <published>2008-02-18T22:48:00Z</published>
    <updated>2008-02-19T00:54:51Z</updated>
    <category term="Projects" />
    <category term="rentability" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/vWPx4kpCXCo/flowy-automagic-page-layout" rel="alternate" type="text/html" />
    <title>Flowy page layouts</title>
<content type="html">
            &lt;p&gt;For a long time we've wanted to get better looking property adverts onto Rentability. We thought about offering several layout templates that the owner could choose from. Then we thought about totally "floating" layouts where the user creates several "blocks" of content (text or photos) that are designed to flow down the page and be happy with different page widths and font sizes. The user doesn't have precise control over the placement of blocks. Instead, they have a bunch of blocks, of different dimensions that slot together down the page (from right to left and top to bottom) filling all available space. With fixed element widths (say a third or two thirds of the page) you can get a nice magazine/newspaper style look. Of course, a simple CSS float:left won't work all that well - you get a lot of holes where elements sort of clear:right as they wrap around down the page. So I tried to create this 'flowy' layout with javascript. The javascript measures each block, figures out how it slots into the layout, then positions it absolutely.&lt;/p&gt;

&lt;p&gt;In the editing UI I've used &lt;a href="http://script.aculo.us/"&gt;scriptaculous&lt;/a&gt; to animate the reflowing of reordered blocks. This isn't always entirely intuitive - try the demo below - but then the whole approach is a compromise of sorts.&lt;/p&gt;

&lt;p&gt;It's not beyond the realms of possibility that a layout will flow slightly differently on two different browsers. Actually, Sim's &lt;a href="http://www.rentability.com/en/houses/3"&gt;advert for the Pigeonnier&lt;/a&gt; lays out differently on IE than it does on Safari. Both looks great though! It's interesting how robust this technique can be.&lt;/p&gt;

&lt;p&gt;Unless I've shown you a preview, you're probably wondering what the hell I'm going on about. &lt;a href="http://www.rentability.com/en/demo_blocks"&gt;Here's a demo page that you can play with&lt;/a&gt; (the changes you make are only visible by you).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.rentability.com/en/demo_blocks"&gt;&lt;img src="http://www.smallroomsoftware.com/assets/2008/2/12/demo_blocks.png" /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2008/2/18/flowy-automagic-page-layout</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2008-02-15:2788</id>
    <published>2008-02-15T22:12:00Z</published>
    <updated>2008-02-19T00:38:36Z</updated>
    <category term="Projects" />
    <category term="svn" />
    <category term="trac" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/soqb2F7mixs/fix-for-missing-authors-problem-with-svnsync-and-trac" rel="alternate" type="text/html" />
    <title>Fix for missing authors problem with svnsync and trac</title>
<content type="html">
            &lt;p&gt;&amp;lt;strike&gt;
Anyone pointing &lt;a href="http://trac.edgewall.org/"&gt;trac&lt;/a&gt; at a subversion repository built with &lt;a href="http://svn.collab.net/repos/svn/trunk/notes/svnsync.txt"&gt;svnsync&lt;/a&gt; might run into the same problem as me - trac shows commits but they show with author set to the username passed to the svnsync command and not the real author from the source repository. My best guess is that this happens because trac detects the checkin before synsync has copied over the revision properties (that includes changing the author). So to fix it, just add a post-revprop-change hook script (to the target repository) that tells trac to resync the revision concerned:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh
REV="$2"
TRAC_ENV="/path/to/trac/environment"

/usr/bin/trac-admin "$TRAC_ENV" resync "$REV"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I also add the call to the contributed &lt;a href="http://trac.edgewall.org/browser/trunk/contrib/trac-post-commit-hook"&gt;trac-post-commit-hook&lt;/a&gt; in there too (rather than putting it in post-commit):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/usr/bin/python /path/to/trac-post-commit-hook -p "$TRAC_ENV" -r "$REV"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;lt;/strike&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update: 19/02/08:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After receiving a lot of duplicate emails from trac I realised that the above approach isn't quite good enough. svnsync updates revision properties more than once per commit (once for each property I guess) so you end up resyncing redundantly and, in my case, calling trac-post-commit-hook several times (resulting in duplicate ticket updates). So I decided not to use the subversion hook scripts and to do what I needed to do to trac directly after running svnsync. Here's the script I run with cron:&lt;/p&gt;

&lt;pre class="textmate-source twilight"&gt;&lt;span class="source source_ruby"&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt;!/usr/bin/env ruby
&lt;/span&gt;
&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; This is script is run every 5 minutes. It syncs the svn repository onto the
&lt;/span&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; trac server. It also manually tells trac to resync each revision and calls
&lt;/span&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; the trac-post-commit-hook for each revision.
&lt;/span&gt;
&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;SVN_USER&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;rails&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;FROM&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;svn://www.example.org/project&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TO&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;file:///path/to/repos-mirror/&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TRAC_ENV&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;/path/to/trac/environment&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;POST_COMMIT_HOOK_SCRIPT&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;/path/to/trac-post-commit-hook&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;

sync_output &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="string string_interpolated string_interpolated_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;`&lt;/span&gt;svnsync sync --non-interactive --username "&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;SVN_USER&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;" "&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TO&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;" "&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;FROM&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;"&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;`&lt;/span&gt;&lt;/span&gt;

&lt;span class="keyword keyword_control keyword_control_ruby"&gt;unless&lt;/span&gt; sync_output&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;empty?
  revisions &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; sync_output&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;scan&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby"&gt;/&lt;/span&gt;Committed revision &lt;span class="string string_regexp string_regexp_group string_regexp_group_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_group punctuation_definition_group_ruby"&gt;(&lt;/span&gt;&lt;span class="constant constant_character constant_character_escape constant_character_escape_ruby"&gt;\d&lt;/span&gt;+&lt;span class="punctuation punctuation_definition punctuation_definition_group punctuation_definition_group_ruby"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;flatten
  puts sync_output

  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;for&lt;/span&gt; rev &lt;span class="keyword keyword_control keyword_control_ruby"&gt;in&lt;/span&gt; revisions
    puts &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Telling trac about revision &lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;rev&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;...&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt;
    puts &lt;span class="string string_interpolated string_interpolated_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;`&lt;/span&gt;/usr/bin/trac-admin "&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TRAC_ENV&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;" resync "&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;rev&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;"&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;`&lt;/span&gt;&lt;/span&gt;
    puts &lt;span class="string string_interpolated string_interpolated_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;`&lt;/span&gt;/usr/bin/python "&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;POST_COMMIT_HOOK_SCRIPT&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;" -p "&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TRAC_ENV&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;" -r "&lt;span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"&gt;&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;#{&lt;/span&gt;rev&lt;span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby"&gt;}&lt;/span&gt;&lt;/span&gt;"&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;`&lt;/span&gt;&lt;/span&gt;
  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;
&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2008/2/15/fix-for-missing-authors-problem-with-svnsync-and-trac</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2008-02-14:2787</id>
    <published>2008-02-14T14:56:00Z</published>
    <updated>2008-05-24T00:20:37Z</updated>
    <category term="Projects" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/38UdURPMD-0/trac-0-11-installation-on-centos-fedora" rel="alternate" type="text/html" />
    <title>Trac 0.11 installation on Centos/Fedora</title>
<content type="html">
            &lt;p&gt;How come every time I install trac I do it a different way? Mostly, I'm installing on Centos or Fedora these days. The RPMs available rpmforge only go up to trac 0.10. It seems sensible to go with the 0.11 beta for a new installation - the trac admin web UI is included by default, there are fewer dependencies and the default ticket workflow has changed a bit. After some fiddling about with the manual download, realising that trac.cgi is missing (maybe it's deprecated) I realised that installation is fairly straightforward if you get setup&lt;em&gt;tools (some strange python "egg" installer) and use mod&lt;/em&gt;python rather than cgi/fcgi (it's more efficient and easier anyway).&lt;/p&gt;

&lt;p&gt;So here are my steps so I don't forget them:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# As root
wget http://peak.telecommunity.com/dist/ez_setup.py
python ez_setup.py

easy_install Pygments
easy_install Genshi
easy_install Trac

trac-admin /srv/trac/myproject initenv
chown -R apache:apache /srv/trac/myproject

nano /etc/httpd.d/trac.conf

# And add something like:

&amp;lt;Location "/trac"&amp;gt;
  SetHandler mod_python
  PythonInterpreter main_interpreter
  PythonHandler trac.web.modpython_frontend 
  PythonOption TracEnvParentDir /srv/trac
  PythonOption TracUriRoot /trac

  # The following gives basic HTTP authentication
  AuthType Basic
  AuthName "Trac"
  AuthUserFile /srv/users.htpasswd
  Require valid-user

  # ... which should be used with SSL:
  SSLRequireSSL
&amp;lt;/Location&amp;gt;

service httpd restart
&lt;/code&gt;&lt;/pre&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2008/2/14/trac-0-11-installation-on-centos-fedora</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2008-01-03:2731</id>
    <published>2008-01-03T17:52:00Z</published>
    <updated>2008-04-25T13:11:51Z</updated>
    <category term="blog" />
    <category term="spam" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/xOBuIzC2w8o/brilliant-anti-blog-spam-technique" rel="alternate" type="text/html" />
    <title>Brilliant anti-(blog)spam technique</title>
<summary type="html">&lt;p&gt;&lt;a href="http://www.artweb-design.de/projects/mephisto-plugin-inverse-captcha-for-comments-anti-spam"&gt;This works&lt;/a&gt; brilliantly!&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;&lt;a href="http://www.artweb-design.de/projects/mephisto-plugin-inverse-captcha-for-comments-anti-spam"&gt;This works&lt;/a&gt; brilliantly!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.artweb-design.de/projects/mephisto-plugin-inverse-captcha-for-comments-anti-spam"&gt;This works&lt;/a&gt; brilliantly!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Well it worked perfectly for a couple of months. Now some spambots seem to cope with it (they check for non-visible form elements I guess). I might try &lt;a href="http://code.google.com/p/form-spam-protection/"&gt;this rails plugin&lt;/a&gt;.&lt;/p&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2008/1/3/brilliant-anti-blog-spam-technique</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2008-01-03:2730</id>
    <published>2008-01-03T17:17:00Z</published>
    <updated>2008-01-03T17:46:57Z</updated>
    <category term="prototype" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/3Ig4amqO6rQ/transport-js-with-prototype-1-6" rel="alternate" type="text/html" />
    <title>transport.js with prototype 1.6</title>
<content type="html">
            &lt;p&gt;Recently I've been working on embedded enquiry forms that Rentability users can place on their own website to take enquiries via their Rentability account. We wanted the person enquiring to remain on the owners homepage after submitting their enquiry (rather than be redirected to our site) so an AJAX submission was called for. Of course, when you try to make an ajax request from one domain to another (even if the code that is making the request came from the target domain), you find it doesn't work - most browsers veto the request for security reasons. The workaround is to use SCRIPT tags to emulate AJAX requests. Luckily, Thierry Schellenbach has &lt;a href="http://www.mellowmorning.com/2007/10/25/introducing-a-cross-site-ajax-plugin-for-prototype/"&gt;written a plugin&lt;/a&gt; for &lt;a href="http://www.prototypejs.org"&gt;Prototype&lt;/a&gt; to make Prototype AJAX requests use this SCRIPT tag technique.&lt;/p&gt;

&lt;p&gt;Unfortunately, there are some major limitations here. For a start, you're obviously limited to using the GET method. In our case this is quite irritating as it's an "update" action that's being called (which is normally only accessible via a POST). Also, the request is going to be made with whatever request headers the browser decides to use. IE is typically &lt;a href="http://blog.peelmeagrape.net/2007/8/15/respond_to-order-is-important"&gt;braindead&lt;/a&gt; in this respect and will probably cause you pain if you have both JS and HTML responses for your action (as we do).&lt;/p&gt;

&lt;p&gt;Also, the transport.js only works with prototype 1.5 out of the box. I fiddled for a while trying to fix it for 1.6 but I didn't feel much like wasting hours getting my head around how people hack OO into javascript. That stuff just freaks me out. So I just ended up copying and pasting the AJAX.Request constructor from prototype. Here you go:&lt;/p&gt;

&lt;pre class="textmate-source twilight"&gt;&lt;span class="linenum"&gt;    1&lt;/span&gt; &lt;span class="source source_js"&gt;&lt;span class="meta meta_class meta_class_js"&gt;&lt;span class="support support_class support_class_js"&gt;Ajax.Request&lt;/span&gt;.&lt;span class="support support_constant support_constant_js"&gt;prototype&lt;/span&gt; = &lt;/span&gt;&lt;span class="support support_class support_class_js"&gt;Object&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;extend&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;Ajax&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;Request&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_js"&gt;prototype&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;, &lt;/span&gt;&lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt;
&lt;span class="linenum"&gt;    2&lt;/span&gt;     &lt;span class="meta meta_function meta_function_json meta_function_json_js"&gt;&lt;span class="entity entity_name entity_name_function entity_name_function_js"&gt;initialize&lt;/span&gt;: &lt;span class="storage storage_type storage_type_function storage_type_function_js"&gt;function&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js"&gt;(&lt;/span&gt;&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_js"&gt;url, options&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt;
&lt;span class="linenum"&gt;    3&lt;/span&gt;         &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt;
&lt;span class="linenum"&gt;    4&lt;/span&gt;           method:       &lt;span class="string string_quoted string_quoted_single string_quoted_single_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;'&lt;/span&gt;post&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt;    5&lt;/span&gt;           asynchronous: &lt;span class="constant constant_language constant_language_boolean constant_language_boolean_true constant_language_boolean_true_js"&gt;true&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt;    6&lt;/span&gt;           contentType:  &lt;span class="string string_quoted string_quoted_single string_quoted_single_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;'&lt;/span&gt;application/x-www-form-urlencoded&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt;    7&lt;/span&gt;           encoding:     &lt;span class="string string_quoted string_quoted_single string_quoted_single_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;'&lt;/span&gt;UTF-8&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt;    8&lt;/span&gt;           parameters:   &lt;span class="string string_quoted string_quoted_single string_quoted_single_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js"&gt;'&lt;/span&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt;    9&lt;/span&gt;           evalJSON:     &lt;span class="constant constant_language constant_language_boolean constant_language_boolean_true constant_language_boolean_true_js"&gt;true&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;,&lt;/span&gt;
&lt;span class="linenum"&gt;   10&lt;/span&gt;           evalJS:       &lt;span class="constant constant_language constant_language_boolean constant_language_boolean_true constant_language_boolean_true_js"&gt;true&lt;/span&gt;
&lt;span class="linenum"&gt;   11&lt;/span&gt;         &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
&lt;span class="linenum"&gt;   12&lt;/span&gt;         &lt;span class="support support_class support_class_js"&gt;Object&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;extend&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js"&gt;, &lt;/span&gt;options &lt;span class="keyword keyword_operator keyword_operator_js"&gt;||&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;{&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
&lt;span class="linenum"&gt;   13&lt;/span&gt; 
&lt;span class="linenum"&gt;   14&lt;/span&gt;         &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;method&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;method&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_function support_function_js"&gt;toLowerCase&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;()&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
&lt;span class="linenum"&gt;   15&lt;/span&gt; 
&lt;span class="linenum"&gt;   16&lt;/span&gt;         &lt;span class="keyword keyword_control keyword_control_js"&gt;if&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="support support_class support_class_js"&gt;Object&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;isString&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;parameters&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;))&lt;/span&gt;
&lt;span class="linenum"&gt;   17&lt;/span&gt;           &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;parameters &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;parameters&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;toQueryParams&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;()&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
&lt;span class="linenum"&gt;   18&lt;/span&gt;         &lt;span class="keyword keyword_control keyword_control_js"&gt;else&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_js"&gt;if&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="support support_class support_class_js"&gt;Object&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;isHash&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;parameters&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;))&lt;/span&gt;
&lt;span class="linenum"&gt;   19&lt;/span&gt;           &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;parameters &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;parameters&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;toObject&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;()&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
&lt;span class="linenum"&gt;   20&lt;/span&gt;         
&lt;span class="linenum"&gt;   21&lt;/span&gt;         &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;transport &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_js"&gt;!&lt;/span&gt;&lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;crossSite&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt; ? Ajax&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;getTransport&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;()&lt;/span&gt; : &lt;span class="meta meta_class meta_class_instance meta_class_instance_constructor"&gt;&lt;span class="keyword keyword_operator keyword_operator_new keyword_operator_new_js"&gt;new&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_instance entity_name_type_instance_js"&gt;scriptTransport&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
&lt;span class="linenum"&gt;   22&lt;/span&gt;         &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;asynchronous &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_js"&gt;!&lt;/span&gt;&lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;crossSite&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt; ? &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;&lt;span class="support support_constant support_constant_dom support_constant_dom_js"&gt;options&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;asynchronous : &lt;span class="constant constant_language constant_language_boolean constant_language_boolean_false constant_language_boolean_false_js"&gt;false&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
&lt;span class="linenum"&gt;   23&lt;/span&gt;         &lt;span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js"&gt;//&lt;/span&gt;turns of the timed onLoad executer
&lt;/span&gt;&lt;span class="linenum"&gt;   24&lt;/span&gt;         &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;transport&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;respondToReadyState &lt;span class="keyword keyword_operator keyword_operator_js"&gt;=&lt;/span&gt; &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;respondToReadyState&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;bind&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;&lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
&lt;span class="linenum"&gt;   25&lt;/span&gt;         &lt;span class="variable variable_language variable_language_js"&gt;this&lt;/span&gt;&lt;span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js"&gt;.&lt;/span&gt;request&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;(&lt;/span&gt;url&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;
&lt;span class="linenum"&gt;   26&lt;/span&gt;         &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt;
&lt;span class="linenum"&gt;   27&lt;/span&gt; &lt;span class="meta meta_brace meta_brace_curly meta_brace_curly_js"&gt;}&lt;/span&gt;&lt;span class="meta meta_brace meta_brace_round meta_brace_round_js"&gt;)&lt;/span&gt;&lt;span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2008/1/3/transport-js-with-prototype-1-6</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2007-11-18:2720</id>
    <published>2007-11-18T13:58:00Z</published>
    <updated>2007-11-18T14:04:41Z</updated>
    <category term="rails" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/UDG33HHYZeI/complex-html-emails-templates-in-rails" rel="alternate" type="text/html" />
    <title>Reuse existing partials in ActionMailer HTML emails</title>
<content type="html">
            &lt;p&gt;This might be useful for anyone wanting to reuse action/controller templates/partials in HTML emails sent with ActionMailer. It causes templates/partials to be resolved relative to the 'views' directory rather than relative to the relevant mailer templates directory (which is the default).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module ActionMailer
  class Base
    # We have to go root relative here because of the change below
    def render_message(method_name, body)
      render :file =&amp;gt; "#{mailer_name}/#{method_name}", :body =&amp;gt; body
    end

    # This allows root relative partials to be located correctly
    def initialize_template_class(assigns)
      ActionView::Base.new(template_root, assigns, self)
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2007/11/18/complex-html-emails-templates-in-rails</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2007-09-30:2715</id>
    <published>2007-09-30T14:09:00Z</published>
    <updated>2007-09-30T14:31:49Z</updated>
    <category term="backup" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/t-eZ-q6pLlY/superduper-and-un-filevaulting" rel="alternate" type="text/html" />
    <title>SuperDuper and Un-FileVaulting</title>
<content type="html">
            &lt;p&gt;SuperDuper is missing a key feature - the ability to read and backup the files in the current user's home directory even if the user is using Apple's FileVault feature. It should give two options: Option one should be to mount the spare image on the backup drive and do a smart update to it. Option two should be to write directly to the backup volume and turning off FileVault on the backup volume (presuming you're using FileVault because you carry your machine about with you during the day but you don't carry your backup drive).&lt;/p&gt;

&lt;p&gt;SuperDuper can't do either of these things but you can sort of approximate option 2 by backing up in two phases to two different volumes. First backup the entire disk minus your home directory and your sparse image (stored somewhere like /Users/.tom/) then backup your home directory to another disk/partition. If you end up booting from the backup, obviously your home directory is going to be missing (or rather, it's backup up to another volume) so you'll want to create at least one non-FileVaulted account that you can log into and recreate your home directory. Actually, you could even alter the backup system so that it sees the home directory backup as your home directory. Then you don't have to do any copying/fixing to get up and running again (at least until you want to restore your internal drive). You could get SuperDuper to run a script after backup. Something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nicl -raw /Volumes/SystemBackup/var/db/netinfo/local.nidb \
    -create /users/tom home /Volumes/HomeBackup
nicl -raw /Volumes/SystemBackup/var/db/netinfo/local.nidb \
    -delete /users/tom home home_loc
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I tried this and it seems to work. The only odd thing that happened was that after rebooting my "HomeBackup" volume was set to "Ignore Permissions" which I had to then switch off in the Get Info window.&lt;/p&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2007/9/30/superduper-and-un-filevaulting</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2007-07-23:871</id>
    <published>2007-07-23T17:23:00Z</published>
    <updated>2007-07-23T17:55:37Z</updated>
    <category term="Projects" />
    <category term="localisation" />
    <category term="localization" />
    <category term="rails" />
    <category term="rentability" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/wi_grySFUh0/simple-java-properties-style-rails-localisation-with-gibberish" rel="alternate" type="text/html" />
    <title>Simple java properties style rails localisation with Gibberish</title>
<content type="html">
            &lt;p&gt;I had a session preparing the &lt;a href="http://www.rentability.com"&gt;Rentability&lt;/a&gt; front-end for localization the other day. Luckily I found the &lt;a href="http://errtheblog.com/post/4396"&gt;Gibberish&lt;/a&gt; rails plugin which makes localizing the static text fairly painless - you can store the translated strings in yml files, and the syntax is very simple. I made a slight patch to gibberish so it'll print the key next to each string on the live app so that the human translator can see where each key is used on the running site:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module Gibberish
  module Localize
    alias_method :old_translate, :translate
    def translate(string, key, *args)
      str = old_translate(string, key, *args)
      "#{str} &amp;lt;span class=\"translation-key\"&amp;gt;#{key}&amp;lt;/span&amp;gt;"
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can put that in environment.rb (maybe if RAILS__ENV == 'development'). Here's some CSS:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;span.translation-key {
  font-size: 11px;
  font-weight: normal;
  color: black;
  background-color: yellow;
  font-family: geneva;
  border: 1px solid #444;
  padding: 0 1px;
  text-transform: none;
  font-style: normal;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src="http://www.smallroomsoftware.com/assets/2007/7/23/gibberish_keys.png" width="300" /&gt;&lt;/p&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2007/7/23/simple-java-properties-style-rails-localisation-with-gibberish</feedburner:origLink></entry>
  <entry xml:base="http://www.smallroomsoftware.com/">
    <author>
      <name>admin</name>
    </author>
    <id>tag:www.smallroomsoftware.com,2007-06-26:625</id>
    <published>2007-06-26T18:15:00Z</published>
    <updated>2007-06-26T18:24:25Z</updated>
    <category term="Discovered" />
    <category term="monocle" />
    <link href="http://feedproxy.google.com/~r/smallroomsoftware/~3/RmYqZz9OSOQ/perfect-high-street" rel="alternate" type="text/html" />
    <title>Perfect High Street</title>
<content type="html">
            &lt;p&gt;&lt;img src="http://www.smallroomsoftware.com/assets/2007/6/26/street.png" /&gt;
&lt;a href="http://www.monocle.com/business/perfect_high_street.php"&gt;Here's a nice animation&lt;/a&gt; from the idealists (or maybe complete fantasists) at &lt;a href="http://www.monocle.com"&gt;Monocle&lt;/a&gt; magazine. I'd be happy if Woolworths came back to Cambridge...&lt;/p&gt;
          </content>  <feedburner:origLink>http://www.smallroomsoftware.com/articles/2007/6/26/perfect-high-street</feedburner:origLink></entry>
</feed>
