<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Peter's Blog - Nodes for petersblogger</title>
    <link>http://www.petersblog.org/</link>
    <description>Nodes containing the tag petersblogger</description>
    <item>
      <title>Illustrated Blog</title>
      <link>http://www.petersblog.org/node/view/1620</link>
      <description>&lt;p&gt;
Up till now to put pictures in this blog I have had to: 
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
go into an image editor to resize the file to suit the blog (about 450-500 pixels wide). 
&lt;/li&gt;
&lt;li&gt;
fire up an sftp program to upload the file to /var/www/PetersBlogger/public/images 
&lt;/li&gt;
&lt;li&gt;
add a tag such as 
&lt;div class="verbatim-block"&gt;&lt;pre&gt;[/images/TheNewPicture.jpg]
&lt;/pre&gt;&lt;/div&gt;
to the &lt;a href="/tag/wilki"&gt;wilki&lt;/a&gt;. 
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;
It was a bit laborious, especially the SFTP bit which is why I didn't do it very often. 
&lt;/p&gt;
&lt;p&gt;
I've now added better support for pictures to &lt;a href="/tag/petersblogger"&gt;PetersBlogger&lt;/a&gt;. Here is an example: 
&lt;/p&gt;
&lt;div class="picture"&gt;&lt;div class="pictureframe"&gt;&lt;a href="/pictures/0000/0004/DSC00015.jpg" rel="lightbox" title="Girls Aloud"&gt;&lt;img alt="Girls Aloud" src="/pictures/0000/0004/DSC00015_normal.jpg"&gt;&lt;/a&gt;&lt;br/&gt;&lt;p&gt;Girls Aloud&lt;/p&gt;&lt;/div&gt;&lt;/div&gt; 
&lt;p&gt;
if you click on this you should be treated to a larger version of the image, thanks to &lt;a href="http://www.huddletogether.com/projects/lightbox2/"&gt;lightbox&lt;/a&gt; a javascript library. 
&lt;/p&gt;
&lt;p&gt;
PetersBlogger now supports a database of pictures so I can add a new picture, give it a name and upload it through the administration pages. The code uses the name as a caption under the photo and as alt text. I can use the name directly in my wilki text to choose which pictures to display. 
&lt;/p&gt;
&lt;p&gt;
The database of pictures is handled by the &lt;a href="http://agilewebdevelopment.com/plugins/attachment_fu"&gt;attachmentfu&lt;/a&gt; &lt;a href="/tag/rails"&gt;rails&lt;/a&gt; plugin. &lt;a href="http://clarkware.com/cgi/blosxom/2007/02/24#FileUploadFu"&gt;This article&lt;/a&gt; gives the steps required to get attachmentfu up and running. 
&lt;/p&gt;
&lt;p&gt;
The setup automatically handles resizing images to three sizes: thumbnail for listing in my picture admin page, a version that is no more than 500 pixels in either dimension for showing in the blog and a version that is no more than 800x600 for showing zoomed when you click on a picture. Attachmentfu has the sense to keep the aspect ratio correct automatically so I don't have to worry about portrait/landscape. I had to hack the imagescience library that does the resizing as it was hard-wired to save jpegs using JPEG_QUALITYSUPERB mode so the blog-sized images were taking up 150k. I changed this to JPEG_QUALITYAVERAGE and the size dropped to 15k or so, but it was a bit noisy so I've settled on JPEG_QUALITYGOOD and 38k images. You are on broadband? 
&lt;/p&gt;
&lt;p&gt;
I was slightly worried about how to change pictures, i.e. to upload a different version of a picture to replace an existing one, since the attachmentfu article I mentioned does not cover this. The answer is to use the exact same view code in the 'edit' page as in the 'new' page. Combined with rails scaffold code it Just Works! It even handles deleting the three old pictures and creating the new files. 
&lt;/p&gt;
&lt;p&gt;
My main motivation for doing this was so I can do it on the websites I host for other people and make it easier for them to upload pictures. PetersCMS is still in the planning stages but one problem has been cracked. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/petersblogger"&gt;petersblogger&lt;/a&gt; &lt;a href="/tag/rails"&gt;rails&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/1620</guid>
      <category domain="http://www.technorati.com/tag">petersblogger</category>
      <category domain="http://www.technorati.com/tag">rails</category>
    </item>
    <item>
      <title>Smile</title>
      <link>http://www.petersblog.org/node/view/1600</link>
      <description>&lt;p&gt;
In a mammoth programming session I implemented proper smileys &lt;img alt="wink" src="/images/smileys/wink.png" /&gt; 
&lt;/p&gt;
&lt;pre class="lazy"&gt;[[&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;:-)&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;smile&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;],
  [&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;:-(&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;sad&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;],
  [&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;8-)&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;cool&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;],
  [&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;;-)&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;wink&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;]].&lt;span class="Entity"&gt;each&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;strCode&lt;/span&gt;, &lt;span class="Variable"&gt;strFile&lt;/span&gt;|
  strText.&lt;span class="Entity"&gt;gsub!&lt;/span&gt;( strCode, &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&amp;lt;img alt=&lt;span class="Constant"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;#{&lt;/span&gt;strFile&lt;span class="String"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="Constant"&gt;\&amp;quot;&lt;/span&gt; src=&lt;span class="Constant"&gt;\&amp;quot;&lt;/span&gt;/images/smileys/&lt;span class="String"&gt;&lt;span class="String"&gt;#{&lt;/span&gt;strFile&lt;span class="String"&gt;}&lt;/span&gt;&lt;/span&gt;.png&lt;span class="Constant"&gt;\&amp;quot;&lt;/span&gt; /&amp;gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
&lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
My fingers were bleeding from all the typing &lt;img alt="sad" src="/images/smileys/sad.png" /&gt; Worked first time though &lt;img alt="smile" src="/images/smileys/smile.png" /&gt; 
&lt;/p&gt;
&lt;p&gt;
There is even alt text for blind people &lt;img alt="cool" src="/images/smileys/cool.png" /&gt; 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/petersblogger"&gt;petersblogger&lt;/a&gt; &lt;a href="/tag/rails"&gt;rails&lt;/a&gt; &lt;a href="/tag/ruby"&gt;ruby&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/1600</guid>
      <category domain="http://www.technorati.com/tag">petersblogger</category>
      <category domain="http://www.technorati.com/tag">rails</category>
      <category domain="http://www.technorati.com/tag">ruby</category>
    </item>
    <item>
      <title>Scraping WoW Armory in Ruby</title>
      <link>http://www.petersblog.org/node/view/1594</link>
      <description>&lt;p&gt;
I figured out how to scrape the Wow Armory for up-to-date information about my characters using ruby. This means I can do this directly in &lt;a href="/tag/petersblogger"&gt;PetersBlogger&lt;/a&gt; without using third party signature generators that disappear overnight or get absorbed into wow gold sites. 
&lt;/p&gt;
&lt;pre class="lazy"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt;   &lt;span class="Keyword"&gt;require&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;net/http&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; &lt;span class="Comment"&gt;  &lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt; &lt;span class="Comment"&gt;  &lt;span class="Comment"&gt;#&lt;/span&gt; Scrape wow character info.&lt;/span&gt;
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt; &lt;span class="Comment"&gt;  &lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt;   &lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;WoWInfo&lt;/span&gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;     &lt;span class="Keyword"&gt;begin&lt;/span&gt;
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;       strRealm &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Eonar&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt;       oInfo &lt;span class="Keyword"&gt;=&lt;/span&gt; []
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  12 &lt;/span&gt;       [&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Pookypoo&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Maevyn&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Maezyn&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Maexyn&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;].&lt;span class="Entity"&gt;each&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;strCharacter&lt;/span&gt;|
&lt;span class="line-numbers"&gt;  13 &lt;/span&gt;         oCharInfo &lt;span class="Keyword"&gt;=&lt;/span&gt; []
&lt;span class="line-numbers"&gt;  14 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  15 &lt;/span&gt; &lt;span class="Comment"&gt;        &lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  16 &lt;/span&gt; &lt;span class="Comment"&gt;        &lt;span class="Comment"&gt;#&lt;/span&gt; Open url.&lt;/span&gt;
&lt;span class="line-numbers"&gt;  17 &lt;/span&gt; &lt;span class="Comment"&gt;        &lt;span class="Comment"&gt;#&lt;/span&gt; Need to specify firefox as user agent as this makes the server return an XML&lt;/span&gt;
&lt;span class="line-numbers"&gt;  18 &lt;/span&gt; &lt;span class="Comment"&gt;        &lt;span class="Comment"&gt;#&lt;/span&gt; file.&lt;/span&gt;
&lt;span class="line-numbers"&gt;  19 &lt;/span&gt; &lt;span class="Comment"&gt;        &lt;span class="Comment"&gt;#&lt;/span&gt; Look the data up in the european armory. Change this for US.&lt;/span&gt;
&lt;span class="line-numbers"&gt;  20 &lt;/span&gt; &lt;span class="Comment"&gt;        &lt;span class="Comment"&gt;#&lt;/span&gt; If this is not done we get html.&lt;/span&gt;
&lt;span class="line-numbers"&gt;  21 &lt;/span&gt;         oResp &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;Net&lt;/span&gt;::&lt;span class="Entity"&gt;HTTP&lt;/span&gt;.&lt;span class="Entity"&gt;start&lt;/span&gt;( &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;armory.wow-europe.com&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;80&lt;/span&gt;) &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;http&lt;/span&gt;|
&lt;span class="line-numbers"&gt;  22 &lt;/span&gt;               http.&lt;span class="Entity"&gt;get&lt;/span&gt;( &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;/character-sheet.xml?r=&lt;span class="String"&gt;&lt;span class="String"&gt;#{&lt;/span&gt;strRealm&lt;span class="String"&gt;&lt;span class="String"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;(&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt; &lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;,&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;+&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;)&lt;/span&gt;&lt;span class="String"&gt;}&lt;/span&gt;&lt;/span&gt;&amp;amp;n=&lt;span class="String"&gt;&lt;span class="String"&gt;#{&lt;/span&gt;strCharacter&lt;span class="String"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  23 &lt;/span&gt;                           { &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;user-agent&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Mozilla/5.0 (Windows; U; Windows NT 5.0; en-GB; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;})
&lt;span class="line-numbers"&gt;  24 &lt;/span&gt;         &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  25 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  26 &lt;/span&gt;         oDoc &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;REXML&lt;/span&gt;::&lt;span class="Entity"&gt;Document&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt; oResp.&lt;span class="Entity"&gt;body&lt;/span&gt;
&lt;span class="line-numbers"&gt;  27 &lt;/span&gt;         oDoc.&lt;span class="Entity"&gt;elements&lt;/span&gt;[&lt;span class="Constant"&gt;1&lt;/span&gt;].&lt;span class="Entity"&gt;elements&lt;/span&gt;.&lt;span class="Entity"&gt;each&lt;/span&gt;( &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;characterInfo/character&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;oElement&lt;/span&gt;|
&lt;span class="line-numbers"&gt;  28 &lt;/span&gt;           oCharInfo &lt;span class="Keyword"&gt;&amp;lt;&amp;lt;&lt;/span&gt; {&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;race&lt;/span&gt; =&amp;gt; oElement.&lt;span class="Entity"&gt;attributes&lt;/span&gt;[&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;race&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;]}
&lt;span class="line-numbers"&gt;  29 &lt;/span&gt;           oCharInfo &lt;span class="Keyword"&gt;&amp;lt;&amp;lt;&lt;/span&gt; {&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;class&lt;/span&gt; =&amp;gt; oElement.&lt;span class="Entity"&gt;attributes&lt;/span&gt;[&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;class&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;]}
&lt;span class="line-numbers"&gt;  30 &lt;/span&gt;           oCharInfo &lt;span class="Keyword"&gt;&amp;lt;&amp;lt;&lt;/span&gt; {&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;level&lt;/span&gt; =&amp;gt; oElement.&lt;span class="Entity"&gt;attributes&lt;/span&gt;[&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;level&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;]}
&lt;span class="line-numbers"&gt;  31 &lt;/span&gt;         &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  32 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  33 &lt;/span&gt;         oDoc.&lt;span class="Entity"&gt;elements&lt;/span&gt;[&lt;span class="Constant"&gt;1&lt;/span&gt;].&lt;span class="Entity"&gt;elements&lt;/span&gt;.&lt;span class="Entity"&gt;each&lt;/span&gt;( &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;characterInfo/characterTab/talentSpec&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;oElement&lt;/span&gt;|
&lt;span class="line-numbers"&gt;  34 &lt;/span&gt;           oCharInfo &lt;span class="Keyword"&gt;&amp;lt;&amp;lt;&lt;/span&gt; {&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;spec&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;#{&lt;/span&gt;oElement&lt;span class="String"&gt;&lt;span class="String"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;attributes&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;[&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;treeOne&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;]&lt;/span&gt;&lt;span class="String"&gt;}&lt;/span&gt;&lt;/span&gt;/&lt;span class="String"&gt;&lt;span class="String"&gt;#{&lt;/span&gt;oElement&lt;span class="String"&gt;&lt;span class="String"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;attributes&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;[&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;treeTwo&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;]&lt;/span&gt;&lt;span class="String"&gt;}&lt;/span&gt;&lt;/span&gt;/&lt;span class="String"&gt;&lt;span class="String"&gt;#{&lt;/span&gt;oElement&lt;span class="String"&gt;&lt;span class="String"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;attributes&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;[&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;treeThree&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;]&lt;/span&gt;&lt;span class="String"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}
&lt;span class="line-numbers"&gt;  35 &lt;/span&gt;         &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  36 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  37 &lt;/span&gt;         oDoc.&lt;span class="Entity"&gt;elements&lt;/span&gt;[&lt;span class="Constant"&gt;1&lt;/span&gt;].&lt;span class="Entity"&gt;elements&lt;/span&gt;.&lt;span class="Entity"&gt;each&lt;/span&gt;( &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;characterInfo/characterTab/professions/skill&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;oElement&lt;/span&gt;|
&lt;span class="line-numbers"&gt;  38 &lt;/span&gt;           oCharInfo &lt;span class="Keyword"&gt;&amp;lt;&amp;lt;&lt;/span&gt; {oElement.&lt;span class="Entity"&gt;attributes&lt;/span&gt;[&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;key&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;].&lt;span class="Entity"&gt;to_sym&lt;/span&gt; =&amp;gt; oElement.&lt;span class="Entity"&gt;attributes&lt;/span&gt;[&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;value&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;]}
&lt;span class="line-numbers"&gt;  39 &lt;/span&gt;         &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  40 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  41 &lt;/span&gt;         oInfo &lt;span class="Keyword"&gt;&amp;lt;&amp;lt;&lt;/span&gt; {strCharacter =&amp;gt; oCharInfo}
&lt;span class="line-numbers"&gt;  42 &lt;/span&gt;       &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  43 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  44 &lt;/span&gt;       &lt;span class="Keyword"&gt;return&lt;/span&gt; oInfo
&lt;span class="line-numbers"&gt;  45 &lt;/span&gt;     &lt;span class="Keyword"&gt;rescue&lt;/span&gt;
&lt;span class="line-numbers"&gt;  46 &lt;/span&gt;       &lt;span class="Keyword"&gt;return&lt;/span&gt; []
&lt;span class="line-numbers"&gt;  47 &lt;/span&gt;     &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  48 &lt;/span&gt;   &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
This lot generates the info in &lt;a href="/post/wow"&gt;this page&lt;/a&gt; which is linked to under 'My Characters' over to the right. It should be fairly up-to-date as the cache will flush once a day causing the armory to be requeried. Currently the output is presented in a rails view thus: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &amp;lt;% &lt;span class="Entity"&gt;cache&lt;/span&gt;( &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;part&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;wow&lt;/span&gt;) &lt;span class="Keyword"&gt;do &lt;/span&gt;%&amp;gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;   &lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;table&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;   &amp;lt;% &lt;span class="Variable"&gt;WoWInfo&lt;/span&gt;().&lt;span class="Entity"&gt;each&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;oCharInfo&lt;/span&gt;| %&amp;gt;
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt;     &amp;lt;% oCharInfo.&lt;span class="Entity"&gt;each_pair&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;strChar&lt;/span&gt;, &lt;span class="Variable"&gt;oInfo&lt;/span&gt;| %&amp;gt;
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;       &lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;tr&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;td&lt;/span&gt; &lt;span class="MetaTag"&gt;colspan&lt;/span&gt;=&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;2&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;b&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;%= strChar %&amp;gt;&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="MetaTag"&gt;b&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="MetaTag"&gt;td&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="MetaTag"&gt;tr&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt;       &amp;lt;% oInfo.&lt;span class="Entity"&gt;each&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;oItem&lt;/span&gt;| %&amp;gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;         &amp;lt;% oItem.&lt;span class="Entity"&gt;each_pair&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;strItem&lt;/span&gt;, &lt;span class="Variable"&gt;strValue&lt;/span&gt;| %&amp;gt;
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;           &lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;tr&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt;             &lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;td&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;%= strItem %&amp;gt;:&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="MetaTag"&gt;td&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;td&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;%= strValue %&amp;gt;&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="MetaTag"&gt;td&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt;           &lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="MetaTag"&gt;tr&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt;         &amp;lt;% &lt;span class="Keyword"&gt;end&lt;/span&gt; %&amp;gt;
&lt;span class="line-numbers"&gt;  12 &lt;/span&gt;       &amp;lt;% &lt;span class="Keyword"&gt;end&lt;/span&gt; %&amp;gt;
&lt;span class="line-numbers"&gt;  13 &lt;/span&gt;     &amp;lt;% &lt;span class="Keyword"&gt;end&lt;/span&gt; %&amp;gt;
&lt;span class="line-numbers"&gt;  14 &lt;/span&gt;   &amp;lt;% &lt;span class="Keyword"&gt;end&lt;/span&gt; %&amp;gt;
&lt;span class="line-numbers"&gt;  15 &lt;/span&gt;   &lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="MetaTag"&gt;table&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  16 &lt;/span&gt; &amp;lt;% &lt;span class="Keyword"&gt;end&lt;/span&gt; %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
All the work is done by the WoWInfo method which I put in the application helper. I didn't use a controller method for this. 
&lt;/p&gt;
&lt;p&gt;
I'm going to think about a nicer presentation with some pictures of the actual guys rather than generic pictures of bald redhead dwarves. 
&lt;/p&gt;
&lt;p&gt;
UPDATE: I've added my old Aerie Peak toons to the output but the code above still stands. &lt;a class="autolink" href="http://eu.wowarmory.com/character-sheet.xml?r=Aerie+Peak&amp;n=Lugulas" title="Lowbie Rogue"&gt;Lugulas&lt;/a&gt; was my old auction alt who I've never named here before, hence level 10 with level 75 (dis)enchanting. I find myself missing them... 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/games"&gt;games&lt;/a&gt; &lt;a href="/tag/petersblogger"&gt;petersblogger&lt;/a&gt; &lt;a href="/tag/rails"&gt;rails&lt;/a&gt; &lt;a href="/tag/ruby"&gt;ruby&lt;/a&gt; &lt;a href="/tag/warcraft"&gt;warcraft&lt;/a&gt; &lt;a href="/tag/wow"&gt;wow&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/1594</guid>
      <category domain="http://www.technorati.com/tag">games</category>
      <category domain="http://www.technorati.com/tag">petersblogger</category>
      <category domain="http://www.technorati.com/tag">rails</category>
      <category domain="http://www.technorati.com/tag">ruby</category>
      <category domain="http://www.technorati.com/tag">warcraft</category>
      <category domain="http://www.technorati.com/tag">wow</category>
    </item>
    <item>
      <title>Raking in Drupal posts</title>
      <link>http://www.petersblog.org/node/view/1574</link>
      <description>&lt;p&gt;
Rake is the ruby equivalent of make except it is much better in that you are scripting in ruby and not the nasty primeval make language. Rails uses rake a lot as a simple place to gather together a load of administration tasks such as running tests, running database migrations etc. 
&lt;/p&gt;
&lt;p&gt;
When I moved all my drupal blog posts from drupal over to &lt;a href="/tag/petersblogger"&gt;PetersBlogger&lt;/a&gt; I decided to use a nice organised rake script rather than do my usual practise of having a directory full of utility scripts. 
&lt;/p&gt;
&lt;p&gt;
In my rails installation I created a file called lib/tasks/jobs.rake and in it I put my import code: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; task (&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;import_drupal&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;environment&lt;/span&gt;) &lt;span class="Keyword"&gt;do&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;   print &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Importing Drupal&lt;span class="Constant"&gt;\n&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;   oTagTable &lt;span class="Keyword"&gt;=&lt;/span&gt; {}
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt; &lt;span class="Comment"&gt;  &lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt; &lt;span class="Comment"&gt;  &lt;span class="Comment"&gt;#&lt;/span&gt; Import all the articles.&lt;/span&gt;
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt; &lt;span class="Comment"&gt;  &lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;   &lt;span class="Support"&gt;Drupal&lt;/span&gt;::&lt;span class="Entity"&gt;Article&lt;/span&gt;.&lt;span class="Entity"&gt;find&lt;/span&gt;(&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;all&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;conditions&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;type &amp;lt;&amp;gt; 'image'&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).&lt;span class="Entity"&gt;each&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;oArticle&lt;/span&gt;|
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;     print &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;#{&lt;/span&gt;oArticle&lt;span class="String"&gt;&lt;span class="String"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;title&lt;/span&gt;&lt;/span&gt;&lt;span class="String"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="Constant"&gt;\n&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt;     oTime &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;Time&lt;/span&gt;.&lt;span class="Entity"&gt;at&lt;/span&gt;( oArticle.&lt;span class="Entity"&gt;created&lt;/span&gt;)
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt;     oPost &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;Post&lt;/span&gt;.&lt;span class="Entity"&gt;create&lt;/span&gt;( &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;nid&lt;/span&gt; =&amp;gt; oArticle.&lt;span class="Entity"&gt;nid&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt;                         &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;title&lt;/span&gt; =&amp;gt; oArticle.&lt;span class="Entity"&gt;title&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  12 &lt;/span&gt;       &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;body&lt;/span&gt; =&amp;gt; oArticle.&lt;span class="Entity"&gt;body&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  13 &lt;/span&gt;       &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;created&lt;/span&gt; =&amp;gt; oTime)
&lt;span class="line-numbers"&gt;  14 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  15 &lt;/span&gt; &lt;span class="Comment"&gt;    &lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  16 &lt;/span&gt; &lt;span class="Comment"&gt;    &lt;span class="Comment"&gt;#&lt;/span&gt; import the tags related to the article.&lt;/span&gt;
&lt;span class="line-numbers"&gt;  17 &lt;/span&gt; &lt;span class="Comment"&gt;    &lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  18 &lt;/span&gt;     oArticle.&lt;span class="Entity"&gt;tags&lt;/span&gt;.&lt;span class="Entity"&gt;each&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;oTag&lt;/span&gt;|
&lt;span class="line-numbers"&gt;  19 &lt;/span&gt;       &lt;span class="Keyword"&gt;if&lt;/span&gt; oTagTable[oTag.&lt;span class="Entity"&gt;tag&lt;/span&gt;]
&lt;span class="line-numbers"&gt;  20 &lt;/span&gt;         oNewTag &lt;span class="Keyword"&gt;=&lt;/span&gt; oTagTable[oTag.&lt;span class="Entity"&gt;tag&lt;/span&gt;]
&lt;span class="line-numbers"&gt;  21 &lt;/span&gt;       &lt;span class="Keyword"&gt;else&lt;/span&gt;
&lt;span class="line-numbers"&gt;  22 &lt;/span&gt;         oNewTag &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;Tag&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt;( &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;tag&lt;/span&gt;=&amp;gt;oTag.&lt;span class="Entity"&gt;tag&lt;/span&gt;)
&lt;span class="line-numbers"&gt;  23 &lt;/span&gt;         oTagTable[oTag.&lt;span class="Entity"&gt;tag&lt;/span&gt;] &lt;span class="Keyword"&gt;=&lt;/span&gt; oNewTag
&lt;span class="line-numbers"&gt;  24 &lt;/span&gt;       &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  25 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  26 &lt;/span&gt;       oPost.&lt;span class="Entity"&gt;tags&lt;/span&gt; &lt;span class="Keyword"&gt;&amp;lt;&amp;lt;&lt;/span&gt; oNewTag
&lt;span class="line-numbers"&gt;  27 &lt;/span&gt;     &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  28 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  29 &lt;/span&gt; &lt;span class="Comment"&gt;    &lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  30 &lt;/span&gt; &lt;span class="Comment"&gt;    &lt;span class="Comment"&gt;#&lt;/span&gt; Import the comments for the article.&lt;/span&gt;
&lt;span class="line-numbers"&gt;  31 &lt;/span&gt; &lt;span class="Comment"&gt;    &lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  32 &lt;/span&gt;     oArticle.&lt;span class="Entity"&gt;comments&lt;/span&gt;.&lt;span class="Entity"&gt;each&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;oComment&lt;/span&gt;|
&lt;span class="line-numbers"&gt;  33 &lt;/span&gt;       strWho &lt;span class="Keyword"&gt;=&lt;/span&gt; oComment.&lt;span class="Entity"&gt;name&lt;/span&gt;
&lt;span class="line-numbers"&gt;  34 &lt;/span&gt;       strComment &lt;span class="Keyword"&gt;=&lt;/span&gt; oComment.&lt;span class="Entity"&gt;comment&lt;/span&gt;
&lt;span class="line-numbers"&gt;  35 &lt;/span&gt;       &lt;span class="Keyword"&gt;if&lt;/span&gt; strWho &lt;span class="Keyword"&gt;==&lt;/span&gt; &lt;span class="Constant"&gt;nil&lt;/span&gt; &lt;span class="Keyword"&gt;or&lt;/span&gt; strWho &lt;span class="Keyword"&gt;==&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  36 &lt;/span&gt;         strWho &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Peter&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  37 &lt;/span&gt;       &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  38 &lt;/span&gt;       &lt;span class="Keyword"&gt;if&lt;/span&gt; strComment &lt;span class="Keyword"&gt;==&lt;/span&gt; &lt;span class="Constant"&gt;nil&lt;/span&gt; &lt;span class="Keyword"&gt;or&lt;/span&gt; strComment.&lt;span class="Entity"&gt;strip&lt;/span&gt; &lt;span class="Keyword"&gt;==&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  39 &lt;/span&gt;         strComment &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;{nothing to say}&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  40 &lt;/span&gt;       &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  41 &lt;/span&gt;       oPost.&lt;span class="Entity"&gt;comments&lt;/span&gt; &lt;span class="Keyword"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="Support"&gt;Comment&lt;/span&gt;.&lt;span class="Entity"&gt;create&lt;/span&gt;( &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;who&lt;/span&gt; =&amp;gt; strWho,
&lt;span class="line-numbers"&gt;  42 &lt;/span&gt;           &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;body&lt;/span&gt; =&amp;gt; strComment,
&lt;span class="line-numbers"&gt;  43 &lt;/span&gt;           &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;created&lt;/span&gt; =&amp;gt; &lt;span class="Support"&gt;Time&lt;/span&gt;.&lt;span class="Entity"&gt;at&lt;/span&gt;( oComment.&lt;span class="Entity"&gt;timestamp&lt;/span&gt;), &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;published&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;1&lt;/span&gt;)
&lt;span class="line-numbers"&gt;  44 &lt;/span&gt;       &lt;span class="Keyword"&gt;if&lt;/span&gt; &lt;span class="Keyword"&gt;not&lt;/span&gt; oPost.&lt;span class="Entity"&gt;comments&lt;/span&gt;[&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;1&lt;/span&gt;].&lt;span class="Entity"&gt;valid?&lt;/span&gt;
&lt;span class="line-numbers"&gt;  45 &lt;/span&gt;         p oPost.&lt;span class="Entity"&gt;comments&lt;/span&gt;[&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;1&lt;/span&gt;]
&lt;span class="line-numbers"&gt;  46 &lt;/span&gt;         p oPost.&lt;span class="Entity"&gt;comments&lt;/span&gt;[&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;1&lt;/span&gt;].&lt;span class="Entity"&gt;errors&lt;/span&gt;
&lt;span class="line-numbers"&gt;  47 &lt;/span&gt;       &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  48 &lt;/span&gt;     &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  49 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  50 &lt;/span&gt;     oPost.&lt;span class="Entity"&gt;save!&lt;/span&gt;
&lt;span class="line-numbers"&gt;  51 &lt;/span&gt;   &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  52 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
This creates a rake task called 'import_drupal' which I can invoke simply by running 
&lt;/p&gt;
&lt;pre class="lazy"&gt;rake import_drupal
&lt;/pre&gt;
&lt;p&gt;
The task runs with the appropriate rails environment so all my models are in place. I had to create a model to access the records in the drupal database thus: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; &lt;span class="Keyword"&gt;module&lt;/span&gt; &lt;span class="Entity"&gt;Drupal&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt;   &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="Entity"&gt;Comment&lt;span class="Superclass"&gt; &lt;span class="Superclass"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt;     establish_connection configurations[&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;drupal&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;]
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt;     set_table_name &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;comments&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt;   &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt;   &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="Entity"&gt;Tag&lt;span class="Superclass"&gt; &lt;span class="Superclass"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt;     establish_connection configurations[&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;drupal&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;]
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt;     set_primary_key &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tid&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt;     has_and_belongs_to_many &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;articles&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt;       &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;class_name&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Drupal::Article&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt;       &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;join_table&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;awtags_node&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  12 &lt;/span&gt;       &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;foreign_key&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tid&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  13 &lt;/span&gt;       &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;association_foreign_key&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;nid&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  14 &lt;/span&gt;     set_table_name &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;awtags&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  15 &lt;/span&gt;   &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  16 &lt;/span&gt;   &lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="Entity"&gt;Article&lt;span class="Superclass"&gt; &lt;span class="Superclass"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  17 &lt;/span&gt;     establish_connection configurations[&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;drupal&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;]
&lt;span class="line-numbers"&gt;  18 &lt;/span&gt;     set_primary_key &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;nid&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  19 &lt;/span&gt;     &lt;span class="Variable"&gt;self&lt;/span&gt;.&lt;span class="Entity"&gt;inheritance_column&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;poopy&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  20 &lt;/span&gt;     has_many &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;comments&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;table_name&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;comments&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;foreign_key&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;nid&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;class_name&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Drupal::Comment&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  21 &lt;/span&gt;     has_and_belongs_to_many &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;tags&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  22 &lt;/span&gt;       &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;class_name&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;Drupal::Tag&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  23 &lt;/span&gt;       &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;join_table&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;awtags_node&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  24 &lt;/span&gt;       &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;foreign_key&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;nid&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;,
&lt;span class="line-numbers"&gt;  25 &lt;/span&gt;       &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;association_foreign_key&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tid&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  26 &lt;/span&gt;     set_table_name &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;node&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  27 &lt;/span&gt;   &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="line-numbers"&gt;  28 &lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
This model handles all the relationships between the records, including the has_and_belongs_to_many relationship between posts and tags (provided by &lt;a href="/tag/awtags"&gt;awtags&lt;/a&gt;). 
&lt;/p&gt;
&lt;p&gt;
I needed an entry in config/database.yml to define the connection to the drupal database: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;drupal:
  adapter: mysql
  database: petersblog
  username: secret
  password: doyouthinkidpostithere
&lt;/pre&gt;
&lt;p&gt;
and it all works nicely. If I invoke it thusly: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;rake import_drupal RAILS_ENV=production
&lt;/pre&gt;
&lt;p&gt;
then it will import the posts into the rails production database. 
&lt;/p&gt;
&lt;p&gt;
I'm giving away a few of my schema secrets here which pedantic rails developers might leap on, specifically I have used my own fields called 'nid' and 'created' to perform roles that rails already provides 'id' and 'created_on' for. The reason for the duplication was that during development I was having problems setting these fields to the values from the drupal database, rails was insisting on giving them it's own values. By having my own fields I had total control. There are no doubt ways around this but I didn't have time to find them (although I did find other people moaning about the same problem). 
&lt;/p&gt;
&lt;p&gt;
And that's how I managed to save 1500 posts from the hell that is php. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/petersblogger"&gt;petersblogger&lt;/a&gt; &lt;a href="/tag/rails"&gt;rails&lt;/a&gt; &lt;a href="/tag/rake"&gt;rake&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/1574</guid>
      <category domain="http://www.technorati.com/tag">petersblogger</category>
      <category domain="http://www.technorati.com/tag">rails</category>
      <category domain="http://www.technorati.com/tag">rake</category>
    </item>
    <item>
      <title>Archives</title>
      <link>http://www.petersblog.org/node/view/1573</link>
      <description>&lt;p&gt;
If you are &lt;i&gt;really&lt;/i&gt; bored, you might like to check out my new &lt;a href="/post/archive"&gt;Archive Page&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
I thought about putting it in the sidebar but I didn't for a few reasons: 
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
it's ugly 
&lt;/li&gt;
&lt;li&gt;
it takes time to generate the page and I didn't want the rendering of every url that wasn't already cached to require this hit. 
&lt;/li&gt;
&lt;li&gt;
who cares anyway? It's mainly there to open up the older posts to search bots without them having to go through page/next 100 times. 
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;
On a more technical level, it uses the following route to give 'nice urls' for the year/month combinations: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post/on/:year/:month&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;listbyyearmonth&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post/on/:year&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;listbyyearmonth&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
so March 2005 would be '/post/on/2005/3' which is cool. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/blogging"&gt;blogging&lt;/a&gt; &lt;a href="/tag/petersblogger"&gt;petersblogger&lt;/a&gt; &lt;a href="/tag/rails"&gt;rails&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/1573</guid>
      <category domain="http://www.technorati.com/tag">blogging</category>
      <category domain="http://www.technorati.com/tag">petersblogger</category>
      <category domain="http://www.technorati.com/tag">rails</category>
    </item>
    <item>
      <title>Keeping your attention</title>
      <link>http://www.petersblog.org/node/view/1571</link>
      <description>&lt;p&gt;
Since I added the page count thing yesterday (that only I can see since I don't want everyone to know how often I tweek the site and reboot) I got this: 
&lt;/p&gt;
&lt;div style="text-align:center"&gt;&lt;img src="/images/ADayMakes.gif" alt="images/ADayMakes.gif"/&gt;&lt;/div&gt; 
&lt;p&gt;
I think I've managed to map all the urls from my old drupal blog to this new blog: according to &lt;a href="/tag/statcounter"&gt;statcounter&lt;/a&gt; (which is a bit slow loading today) I had 1,103 page loads yesterday compared to 1,167 last week on the old blog. Any missed urls would lead to the 404 page which doesn't have the hit counter or statcounter on it (hum, could catch the 404's and redirect them to main page with a flash notice..). 
&lt;/p&gt;
&lt;p&gt;
Statcounter works under javascript and so does not count bots and paranoid people with javascript disabled. It is interesting therefore that the latter outnumber the javascript users by 2.5:1. And none of this includes rss/atom feeds. 
&lt;/p&gt;
&lt;p&gt;
For the record, here are the routes I used to map my drupal urls to &lt;a href="/tag/petersblogger"&gt;PetersBlogger&lt;/a&gt; urls. This is from config/routes.rb: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;&lt;span class="line-numbers"&gt;   1 &lt;/span&gt; map.&lt;span class="Entity"&gt;root&lt;/span&gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;list&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   2 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;   3 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   4 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; map the various rss feeds&lt;/span&gt;
&lt;span class="line-numbers"&gt;   5 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   6 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tag/:tagname/feed&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tag&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rss&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   7 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tags/:tagname/feed&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tag&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rss&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   8 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tag/feed/:tagname&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tag&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rss&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;   9 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;blog/feed/1&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rss&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  10 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;blog/feed&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rss&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  11 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;blog/1/feed&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rss&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  12 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rss.xml&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rss&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  13 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  14 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  15 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; map the atom feeds&lt;/span&gt;
&lt;span class="line-numbers"&gt;  16 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  17 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tags/:tagname/atom.xml&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tag&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;atom&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  18 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;node/:id/atom.xml&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;atom&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  19 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;atom/feed&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;atom&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  20 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  21 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  22 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; Map pages&lt;/span&gt;
&lt;span class="line-numbers"&gt;  23 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  24 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;node/view/:id&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;show&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  25 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;node/:id&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;show&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  26 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; not sure what below was for&lt;/span&gt;
&lt;span class="line-numbers"&gt;  27 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;node/:id/tag/function.require&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;show&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  28 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;node/:id/function.require&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;show&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  29 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tag/:tagname&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;listbytag&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  30 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tags/:tagname&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;listbytag&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  31 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tags/:tagnamex/tags/:tagname&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;listbytag&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  32 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;blog/tags/:tagname&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;post&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;listbytag&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  33 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tag&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;controller&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;tag&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;list&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  34 &lt;/span&gt; 
&lt;span class="line-numbers"&gt;  35 &lt;/span&gt; &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; Install the default routes as the lowest priority.&lt;/span&gt;
&lt;span class="line-numbers"&gt;  36 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;:controller/:action/:id&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class="line-numbers"&gt;  37 &lt;/span&gt; map.&lt;span class="Entity"&gt;connect&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;:controller/:action/:id.:format&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
I fixed most of the above by searching the access logs for 404's (page not found) and looking for patterns. I'm not sure why drupal felt the need to support so many variants on urls for the same page/feed or how people managed to find them. Note the silly 'tags/:tagnamex/tags/:tagname': I had old urls of the form '/tag/213/tag/34' because of sloppy relative linking. 
&lt;/p&gt;
&lt;p&gt;
Rails routing is sublimely simple and flexible. It would have taken me days to get all the above working with mod_rewrite rules. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/petersblogger"&gt;petersblogger&lt;/a&gt; &lt;a href="/tag/rails"&gt;rails&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/1571</guid>
      <category domain="http://www.technorati.com/tag">petersblogger</category>
      <category domain="http://www.technorati.com/tag">rails</category>
    </item>
    <item>
      <title>PetersBlogger gets Live Preview</title>
      <link>http://www.petersblog.org/node/view/1567</link>
      <description>&lt;p&gt;
I wanted &lt;a href="/tag/petersblogger"&gt;PetersBlogger&lt;/a&gt; to have a preview facility when composing posts that would automatically run the text I was editing through my &lt;a href="/tag/wilki"&gt;wilki&lt;/a&gt; filter as I typed and give me a live preview of how the post would turn out when it was formatted and displayed. No pressing a preview button for me, I wanted it to &lt;i&gt;just happen&lt;/i&gt;. Sounds like a job for AJAX. But how to do this in &lt;a href="/tag/rails"&gt;rails&lt;/a&gt;? Well it turns out to be very easy. 
&lt;/p&gt;
&lt;p&gt;
I put this in my form where I edit a post: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;p&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;lt;%= f.&lt;span class="Entity"&gt;text_area&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;body&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;size&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;100x40&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;html&lt;/span&gt; =&amp;gt; { &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;id&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;body&lt;/span&gt;} %&amp;gt;&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="MetaTag"&gt;p&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&amp;lt;%= observe_field &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;post_body&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;url&lt;/span&gt; =&amp;gt; { &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;action&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;wilkify&lt;/span&gt; },
    &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;frequency&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;3.00&lt;/span&gt;,
    &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;update&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;preview&lt;/span&gt;,
    &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;with&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;'text='+escape( $('post_body').value)&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
%&amp;gt;
&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;div&lt;/span&gt; &lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;id&lt;/span&gt;&lt;span class="MetaTag"&gt;=&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;span class="String"&gt;preview&lt;/span&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;/&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
This puts some javascript in the page that monitors the text_area where I am editing and, if it changes it will invoke the 'wilkify' action in my controller, passing it what I have typed thus far. 
&lt;/p&gt;
&lt;p&gt;
The 'wilkify' action is very simple, it just gets the text, wilkifies it and makes sure it is rendered as a simple piece of html, without the main site layout: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;&lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;wilkify&lt;/span&gt;
  strBody &lt;span class="Keyword"&gt;=&lt;/span&gt; params[&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;text&lt;/span&gt;]
  strBody &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;CGI&lt;/span&gt;::&lt;span class="Entity"&gt;unescape&lt;/span&gt;( strBody)
  &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;text&lt;/span&gt; &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Variable"&gt;Wilki&lt;/span&gt;( strBody)
  render &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;layout&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;false&lt;/span&gt;
&lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
I have a small view defined to wrap the preview text in a couple of div's, just as if they were appearing on the site: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;div&lt;/span&gt; &lt;span class="MetaTag"&gt;class&lt;/span&gt;=&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;node&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;div&lt;/span&gt; &lt;span class="MetaTag"&gt;class&lt;/span&gt;=&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;bodynode&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;&lt;/span&gt;&lt;span class="MetaTag"&gt;div&lt;/span&gt; &lt;span class="MetaTag"&gt;class&lt;/span&gt;=&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;entry&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
      &amp;lt;%= &lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;text&lt;/span&gt; %&amp;gt;
    &lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="MetaTag"&gt;div&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="MetaTag"&gt;div&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="MetaTag"&gt;&lt;span class="MetaTag"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="MetaTag"&gt;div&lt;/span&gt;&lt;span class="MetaTag"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
The wikified text is then inserted into the edit form in the div with the id 'preview'. 
&lt;/p&gt;
&lt;p&gt;
I have to add the prototype javascript library to the head section of the main application layout: 
&lt;/p&gt;
&lt;pre class="lazy"&gt;&amp;lt;%= javascript_include_tag &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;prototype&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt; %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
It is not entirely perfect and I would never let strangers use it because they could type malformed html and totally mess things up but it is good enough for me. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/petersblogger"&gt;petersblogger&lt;/a&gt; &lt;a href="/tag/rails"&gt;rails&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/1567</guid>
      <category domain="http://www.technorati.com/tag">petersblogger</category>
      <category domain="http://www.technorati.com/tag">rails</category>
    </item>
    <item>
      <title>Blogging Reborn</title>
      <link>http://www.petersblog.org/node/view/1566</link>
      <description>&lt;p&gt;
I've missed blogging while I've been working on &lt;a href="/tag/petersblogger"&gt;PetersBlogger&lt;/a&gt;. My old &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt; blog was limping along: while administering the site it kept logging me out. I can admit now that I was running an old version of drupal (4.7?) which I couldn't upgrade due to module dependencies (mainly &lt;a href="/tag/awtags"&gt;awtags&lt;/a&gt;). The old code wasn't running that smoothly under php5 &lt;a href="/node/1559"&gt;despite initial appearancies&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
I'm happy with my new blog platform, it's running really nicely on my &lt;a href="/tag/slicehost"&gt;slicehost&lt;/a&gt; slice and I've learnt an awful lot about rails while developing it. I will try to do a braindump of rails experiencies in forthcoming posts (cross fingers). 
&lt;/p&gt;
&lt;p&gt;
Drupal is a fine CMS and I'm using Drupal 5 on my company intranet. My thoughts on a drupal vs ruby on rails debate would be: 
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
drupal/php/apache is easier to deploy than a rails/ruby/mongrel/nginx deploy: I moved my drupal site between about four different hosts and did it each time in less than an hour. A rails setup is more convoluted (especially mongrel_cluster). However, this site is running much faster under rails than it was under drupal. The difference is probably down to php and apache being more mainstream and slightly more refined and hence easy to set up. I'm not saying rails is a total pain, just that if I only had ten minutes in which to deploy a site I would be reaching for drupal. If I only wanted to install the source and a few modules and never touch any coding then I would be happy with drupal. 
&lt;/li&gt;
&lt;li&gt;
I love ruby and rails development. There is no comparison, php seems to me as much a bastard language as visual basic 6. Ruby was cleanly developed as an object orientated language, php is having object orientation grafted on as an afterthough. 
&lt;/li&gt;
&lt;li&gt;
If I look through my drupal source I see no unit testing. Ruby/Rails has unit testing built in and I'm completely sold on it. I don't think I will ever trust any code (especially code I write) if it hasn't been unit tested. Some interesting aspects of unit testing: 
&lt;ul&gt;&lt;li&gt;
I understand now the 'test driven' approach to development where you design a module's api by first roughing out how the tests will work: the unit test is your first experience of using the new api. It's during testing that you learn how nice an api will be. 
&lt;/li&gt;
&lt;li&gt;
If the documentation of a new ruby/rails tool is dubious, look in the unit tests to see how the author intended it to be used. If there are no tests then run. 
&lt;/li&gt;
&lt;li&gt;
If I run into a tricky bug, it's better to first reproduce it in unit tests, fix it there and then be happy that the bug will never recur. It's easier to debug code in a unit test (essentially a command line application) than on a live website. 
&lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;
&lt;li&gt;
all ruby on rails applications follow basically the same architecture. It is fairly easy to figure out how a new application works. Every php application is different. I know I'm comparing a web framework to a programming language but none of the php applications (drupal, phpmyadmin) or am familiar with (wordpress) share a common architecture. New php application to maintain? New learning curve. 
&lt;/li&gt;
&lt;li&gt;
my new site is being hammered with attempts to post to /comments/reply, even though it doesn't use that url for comment submission. The comment spammers know drupal and know where to test the locks. If any of them ever bother to try to find my comment submission url they will only find the same captcha that protected my drupal site (which was much easier to implement in rails, simply as a validation on the model). 
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Related Posts: &lt;a href="/tag/blogging"&gt;blogging&lt;/a&gt; &lt;a href="/tag/drupal"&gt;drupal&lt;/a&gt; &lt;a href="/tag/petersblogger"&gt;petersblogger&lt;/a&gt; &lt;a href="/tag/rails"&gt;rails&lt;/a&gt; &lt;a href="/tag/ruby"&gt;ruby&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/1566</guid>
      <category domain="http://www.technorati.com/tag">blogging</category>
      <category domain="http://www.technorati.com/tag">drupal</category>
      <category domain="http://www.technorati.com/tag">petersblogger</category>
      <category domain="http://www.technorati.com/tag">rails</category>
      <category domain="http://www.technorati.com/tag">ruby</category>
    </item>
    <item>
      <title>New Blog Platform</title>
      <link>http://www.petersblog.org/node/view/1565</link>
      <description>&lt;p&gt;
This blog is now running on my new &lt;a href="/tag/rails"&gt;rails&lt;/a&gt; based blogging platform which I have called &lt;a href="/tag/petersblogger"&gt;PetersBlogger&lt;/a&gt; (I'm not good at names). 
&lt;/p&gt;
&lt;p&gt;
It's mostly complete. Features: 
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
post articles (or you wouldn't be reading this) 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="/tag/wilki"&gt;wilki&lt;/a&gt; formatting including syntax highlighting with &lt;a href="http://ultraviolet.rubyforge.org/"&gt;ultraviolet&lt;/a&gt; e.g. 
&lt;pre class="lazy"&gt;strThis &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;that&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
comments, including 
&lt;ul&gt;&lt;li&gt;
moderation list 
&lt;/li&gt;
&lt;li&gt;
Peter's simplistic captcha system 
&lt;/li&gt;&lt;/ul&gt;

&lt;/li&gt;
&lt;li&gt;
tagging 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://pingomatic.com/"&gt;pingomatic&lt;/a&gt; submission 
&lt;/li&gt;
&lt;li&gt;
Technorati tags 
&lt;/li&gt;
&lt;li&gt;
rss feeds (no atom yet) 
&lt;/li&gt;
&lt;li&gt;
uses &lt;a href="http://api.rubyonrails.org/classes/ActionController/Caching/Fragments.html"&gt;fragment caching&lt;/a&gt; for performance 
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;
Todo list: 
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
AJAX formatting preview 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="/tag/atom"&gt;atom&lt;/a&gt; feeds (do I care?) 
&lt;/li&gt;
&lt;li&gt;
search (or rely on google) 
&lt;/li&gt;
&lt;li&gt;
tag cloud 
&lt;/li&gt;
&lt;li&gt;
archives by month/year: you DO care what I wrote in Feb 2005 right? 
&lt;/li&gt;
&lt;li&gt;
gimmicks 
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;
Please let me know if you spot any sillies (that's if comment submission is working at all). 
&lt;/p&gt;
&lt;p&gt;
It's nice to use because the administration interface isn't split out into a seperate set of web pages, when I 'log in' I simply get extra buttons to press in the pages that you are seeing. 
&lt;/p&gt;&lt;p&gt;Related Posts: &lt;a href="/tag/blogging"&gt;blogging&lt;/a&gt; &lt;a href="/tag/petersblogger"&gt;petersblogger&lt;/a&gt; &lt;a href="/tag/rails"&gt;rails&lt;/a&gt;&lt;/p&gt;</description>
      <guid>http://www.petersblog.org/node/view/1565</guid>
      <category domain="http://www.technorati.com/tag">blogging</category>
      <category domain="http://www.technorati.com/tag">petersblogger</category>
      <category domain="http://www.technorati.com/tag">rails</category>
    </item>
  </channel>
</rss>
