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

<channel>
	<title>Katipo Developers Blog</title>
	<atom:link href="http://blog.katipo.co.nz/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.katipo.co.nz</link>
	<description></description>
	<lastBuildDate>Wed, 03 Mar 2010 04:14:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Three ways to increase New Relic RPM&#8217;s usefulness</title>
		<link>http://blog.katipo.co.nz/2010/03/03/three-ways-to-increase-new-relic-rpms-usefulness/</link>
		<comments>http://blog.katipo.co.nz/2010/03/03/three-ways-to-increase-new-relic-rpms-usefulness/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 04:13:07 +0000</pubDate>
		<dc:creator>kieran</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[new relic]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rpm]]></category>

		<guid isPermaLink="false">http://blog.katipo.co.nz/?p=104</guid>
		<description><![CDATA[Three recent and little known features of New Relic RPM which help increase usefulness.]]></description>
			<content:encoded><![CDATA[<p>Here at Katipo, we&#8217;re using New Relic RPM to monitor our deployed <a href="http://kete.net.nz">Kete</a> applications, to help make things as fast as possible. In order to make New Relic as useful as possible, I&#8217;ve been trying out three New Relic RPM features, some available in only the latest versions of RPM, on one of those sites. These recent and little-known features aren&#8217;t enabled by default, so I&#8217;m going to run you through them and how to set them up in this post.</p>
<p>If you don&#8217;t yet use New Relic RPM, you can get a Lite account for free by going to <a href="http://newrelic.com">newrelic.com</a>, where you can also test drive New Relic RPM on a real application. <span id="more-104"></span></p>
<p><strong>Custom request parameters</strong></p>
<p>New Relic does it&#8217;s best to record as much information about the current request as possible. The URL, split down into controller, action, id etc, the request referrer, GET and POST data&#8230;. but there is data that it doesn&#8217;t know about. Things like the current locale, the user who is currently logged in, or custom session params. Thankfully, there is a solution.</p>
<p>New Relic RPM contains a method for adding custom data to each transaction or error that is sent to it&#8217;s servers. Utilize this method inside of a before_filter in your application controller, and you&#8217;ll be gathering that extra data in no time. Here is the code we use.</p>
<blockquote>
<pre># Collect additional debug details for New Relic RPM is available
# Do this after all other before filters so details are present
before_filter :set_new_relic_custom_parameters
def set_new_relic_custom_parameters
  return unless defined?(NewRelic)
  NewRelic::Agent.add_custom_parameters(
    :locale =&gt; (I18n.locale if I18n.locale),
    :account =&gt; (logged_in? ? current_user.login : 'guest'),
    :return_to =&gt; (session[:return_to] if session[:return_to])
  )
end
private :set_new_relic_custom_parameters</pre>
</blockquote>
<p>Now, whenever RPM sends information about slow web requests or error reports, you&#8217;ll have more data to help replicate the issue.</p>
<p><strong>Passenger Queue Wait</strong></p>
<p>Sometimes the slowness might not be your app, but your app server. How do you tell if it&#8217;s serving requests fast enough? New Relic RPM now has the ability to report how long your visits were waiting in the &#8216;queue&#8217;, that is, the time between requesting the site and Apache actually processing that request. Getting this working is fairly simple.</p>
<blockquote><p>RequestHeader set X-REQUEST_START &#8220;%t&#8221;</p></blockquote>
<p>Simply set that in either your main apache.conf file, the VirtualHost directive, or a Directory directive.</p>
<p>Also, ensure that the headers Apache module is enabled. On Debian, you can do this by running the following as root.</p>
<blockquote><p># a2enmod headers</p></blockquote>
<p>That&#8217;s all it takes. Now, when RPM sends along information, it&#8217;ll send how long each request stayed in the queue, and display it at New Relic RPM&#8217;s web interface, on all graphs as &#8216;Queue Wait&#8217;. This should give you an indication of whether your application server is performing well.</p>
<p><span style="text-decoration: underline;"><span style="color: #000000;">Important Note:</span></span> If you run your application across multiple machines, each machine needs this header, and the clock on each machine must be synced with NTP or similar, or you&#8217;ll end up with very incorrect queue times. Users who run the entire site off one box need not worry about this issue.</p>
<p><strong>Garbage Collection delays</strong></p>
<p>I&#8217;m not going to go into much detail about Ruby Garbage collection here. Google &#8216;Ruby Garbage Collection&#8217; if you want to know more. Put simply though, in Ruby, while Garbage Collection runs, it stops the processing of your app. This could lead to slow page requests if it garbage collector, or GC, runs multiple times in the same request.</p>
<p>There are ways to tweak this using settings, but how do you know if it&#8217;s a problem to begin with? If you use Ruby Enterprise Edition, or another version of Ruby with the Railsbench GC patches compiled in, then all you need is the following line in your application.</p>
<blockquote><p>GC.enable_stats if defined?(GC) &amp;&amp; GC.respond_to?(:enable_stats)</p></blockquote>
<p>For Ruby on Rails users, you can stick that at the bottom of your config/environment.rb file. Basically, if GC is defined, and responds to the correct method, then use it. RPM will send this information back to New Relic, where you can view how long GC took in each of your requests, and deal with it accordingly.</p>
<p><strong>Conclusion</strong></p>
<p>Well, that&#8217;s all for now. Please feel free to share any additional features which help make New Relic even more useful in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.katipo.co.nz/2010/03/03/three-ways-to-increase-new-relic-rpms-usefulness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Migrating from Github to Gemcutter</title>
		<link>http://blog.katipo.co.nz/2010/01/19/migrating-from-github-to-gemcutter/</link>
		<comments>http://blog.katipo.co.nz/2010/01/19/migrating-from-github-to-gemcutter/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 02:53:29 +0000</pubDate>
		<dc:creator>kieran</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[gemcutter]]></category>
		<category><![CDATA[gems]]></category>
		<category><![CDATA[github]]></category>

		<guid isPermaLink="false">http://blog.katipo.co.nz/?p=100</guid>
		<description><![CDATA[Quick quote to migrating your gem list from Github to Gemcutter, the newest (and soon, only) gem hoster on the scene.]]></description>
			<content:encoded><![CDATA[<p>For those of you who follow this sort of thing, <a href="http://github.com">Github</a> shut down their gem building. Thankfully, a newer and easier gem hoster, <a href="http://gemcutter.org">Gemcutter</a>, appeared on the scene not long before that happened. The idea behind it, for those who haven&#8217;t heard of it, is that you manage your own gem building. Gemcutter doesn&#8217;t wait for your Gem spec to change before it makes a new gem. You simply build it locally, and push it to Gemcutter, using a handy gem they provide that extends Rubygems &#8216;gem&#8217; console command.</p>
<p>But Github was building gems for some time, and due to it&#8217;s continuing popularity, many well known Ruby on Rails developers and companies switched permanently to Github for their gem building/hosting at the time, so it&#8217;s likely that quite a few gems you&#8217;ve got installed are from Github.</p>
<p>To help transition over from Github to Gemcutter, <a href="http://github.com/maxim">Maxim Chernyak</a> wrote a great utility called <a href="http://github.com/maxim/off_github">off_github</a>, which looks at your list of gems, and tells you which ones you&#8217;re installed from Github, and whether they can be reinstalled from Gemcutter. It saves a lot of time and effort  than having to do it manually. So here&#8217;s how to get started&#8230;.</p>
<p><span id="more-100"></span>Firstly, lets get the latest version of Rubygems. This may not be needed for the off_github gem to function, but it pays to keep this up to date to prevent any issues with newer gems. Usually, you&#8217;ll want Rubygems version 1.3.0 or higher. At the time of this post, the current version is 1.3.5.</p>
<blockquote><p>$ gem &#8211;version<br />
1.2.1<br />
$ [sudo] gem update &#8211;system<br />
&#8230;&#8230;<br />
$ gem &#8211;version<br />
1.3.5</p></blockquote>
<p>Once that&#8217;s done, install the off_github gem. To do that, add Gemcutter as a source and run the gem install command.</p>
<blockquote><p>$ gem sources -a http://gemcutter.org<br />
$ [sudo] gem install off_github</p></blockquote>
<p><strong>Note: </strong>Rubyforge gems now points to Gemcutter, so the gem source adding isn&#8217;t technically needed to install off_github. That said, the off_github gem still checks for the Gemcutter source (it&#8217;s a bit outdated) and won&#8217;t work without it, so to get around it, install it before running, and you can remove it afterwards.</p>
<p>Now go ahead and run the off_github command. If you don&#8217;t use sudo to install gems, then be sure to add &#8211;no-sudo the end.</p>
<blockquote><p>$ off_github [--no-sudo]</p></blockquote>
<p>This&#8217;ll go ahead and return a list of gems that were installed from Github, what there Gemcutter gem name is, and the action it&#8217;ll take on that gem (usually reinstall). It&#8217;ll then ask you if you want to install. Type &#8216;Y&#8217;, hit enter, and then choose y/n/a at each prompt.</p>
<p>If everything went smoothly, you&#8217;re all done. You can now go ahead and delete both the Github and Gemcutter sources.</p>
<blockquote><p>$ gem sources -r http://gems.github.com<br />
$ gem sources -r http://gemcutter.org</p></blockquote>
<p>So know, you should have Rubyforge as your only gem source.</p>
<blockquote><p>$ gem sources<br />
*** CURRENT SOURCES ***<br />
http://gems.rubyforge.org</p></blockquote>
<p><strong>Additional Material:</strong></p>
<ul>
<li><a href="# http://www.rubypulse.com/episode-0.16_off_github.html">http://www.rubypulse.com/episode-0.16_off_github.html</a></li>
<li><a href="# http://www.rubypulse.com/episode-0.16.1_off_github_revisited.html">http://www.rubypulse.com/episode-0.16.1_off_github_revisited.html</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.katipo.co.nz/2010/01/19/migrating-from-github-to-gemcutter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IE7 and IE8 cannot support URI&#8217;s with underscores</title>
		<link>http://blog.katipo.co.nz/2009/09/28/ie7-and-ie8-cannot-support-uris-with-underscores/</link>
		<comments>http://blog.katipo.co.nz/2009/09/28/ie7-and-ie8-cannot-support-uris-with-underscores/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 23:19:14 +0000</pubDate>
		<dc:creator>kieran</dc:creator>
				<category><![CDATA[random]]></category>

		<guid isPermaLink="false">http://blog.katipo.co.nz/?p=93</guid>
		<description><![CDATA[Stumbled upon this. If you&#8217;re going to make a URI (domain or sub domain) with an underscore, think twice. IE7 and IE8 do not support these URI&#8217;s when dealing with cookies.
For more details, see this blog post, detailing the symptoms.
http://blog.patrick-morgan.net/2008/09/problems-with-ie7-sessions-not-saved-in.html
]]></description>
			<content:encoded><![CDATA[<p>Stumbled upon this. If you&#8217;re going to make a URI (domain or sub domain) with an underscore, think twice. IE7 and IE8 do not support these URI&#8217;s when dealing with cookies.</p>
<p>For more details, see this blog post, detailing the symptoms.</p>
<p><a href="http://blog.patrick-morgan.net/2008/09/problems-with-ie7-sessions-not-saved-in.html">http://blog.patrick-morgan.net/2008/09/problems-with-ie7-sessions-not-saved-in.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.katipo.co.nz/2009/09/28/ie7-and-ie8-cannot-support-uris-with-underscores/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Joomla vetting new signups</title>
		<link>http://blog.katipo.co.nz/2009/09/21/joomla-vetting-new-signups/</link>
		<comments>http://blog.katipo.co.nz/2009/09/21/joomla-vetting-new-signups/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 04:24:36 +0000</pubDate>
		<dc:creator>bob</dc:creator>
				<category><![CDATA[joomla]]></category>

		<guid isPermaLink="false">http://blog.katipo.co.nz/?p=87</guid>
		<description><![CDATA[A few sites that we have been working on  wanted an extra step with the signup process on their website that requires an additional level of vetting by the site administrator when a new user submits the online form.  To achieve this we made some minor changes to the core code.

The following change [...]]]></description>
			<content:encoded><![CDATA[<p>A few sites that we have been working on  wanted an extra step with the signup process on their website that requires an additional level of vetting by the site administrator when a new user submits the online form.  To achieve this we made some minor changes to the core code.</p>
<p><span id="more-87"></span></p>
<p>The following change removes the activation link from the email issued to the user and sends them an email notification that their application has been received.<br />
From the root of your Joomla site, go to /components/com_user/controller.php (approx line 367) and add:</p>
<div class="codesnip-container" >// Email the user that they have been vetted<br />
$mailfrom = $mainframe-&gt;getCfg(&#8217;mailfrom&#8217;);<br />
$fromname = $mainframe-&gt;getCfg(&#8217;fromname&#8217;);<br />
$email = $euser-&gt;email;<br />
$siteURL = JURI::base();<br />
$subject = &#8220;Vetting Accepted for [sitename]&#8220;;<br />
$message2 = sprintf(JText::_(&#8217;REG_ACTIVATE_COMPLETE_USER&#8217;),$siteURL);<br />
JUtility::sendMail($mailfrom, $fromname, $email, $subject, $message2);<br />
// *** END Email the user that they have been vetted</div>
<p>We also need to change&#8230;</p>
<div class="codesnip-container" >if (JUserHelper::activateUser($activation))</div>
<p>to:</p>
<div class="codesnip-container" >if ($euser = JUserHelper::activateUser($activation))</div>
<p>The next bit of code emails the account activation link and details through to the site administrator, who gets to decide if the application is successful.<br />
From the root of your Joomla site, go to /components/com_user/controller.php (approx line 524) and change to:</p>
<div class="codesnip-container" >// *** Added Site Admin activation link<br />
if ( $useractivation == 1 ){<br />
// $message = sprintf ( JText::_( &#8216;SEND_MSG_ACTIVATE&#8217; ), $name, $sitename, $siteURL.&#8221;index.php?option=com_user&amp;task=activate&amp;activation=&#8221;.$user-&gt;get(&#8217;activation&#8217;), $siteURL, $username, $password);<br />
$message = sprintf ( JText::_( &#8216;SEND_MSG_ACTIVATE&#8217; ), $name, $sitename, $siteURL.&#8221;index.php?option=com_user&amp;task=activate&amp;activation=&#8221;.$user-&gt;get(&#8217;activation&#8217;));<br />
$message2 = sprintf ( JText::_( &#8216;SEND_MSG_USER&#8217; ), $name, $sitename, $siteURL, $username, $password);<br />
} else {<br />
$message = sprintf ( JText::_( &#8216;SEND_MSG&#8217; ), $name, $sitename, $siteURL);<br />
$message2 = &#8221;;<br />
}<br />
// *** END Added Site Admin activation link</div>
<p>We then need to pass both user and admin notifications through to the script that generates and sends emails.<br />
From the root of your Joomla site, go to /components/com_user/controller.php (approx line 548) Added:</p>
<div class="codesnip-container" >// *** Added send User AND Admin notification<br />
JUtility::sendMail($mailfrom, $fromname, $mailfrom, $subject, $message);<br />
JUtility::sendMail($mailfrom, $fromname, $email, $subject, $message2);<br />
// JUtility::sendMail($mailfrom, $fromname, $email, $subject, $message); // old line<br />
// *** END Added send User AND Admin notification</div>
<p>Joomla now issues 2 emails when the signup form is submitted, rather than the usual one.</p>
<p>Some final changes are needed to the language files on the site, so that the email notifications make sense.  Make the following changes. From the root of your Joomla site, go to</p>
<p>/language/en-GB/en-GB.com_user.ini (approx line 84) and change:</p>
<div class="codesnip-container" >REG_ACTIVATE_COMPLETE=The Account has been successfully activated. The user has been sent an email and they now can log in.</div>
<p>/language/en-GB/en-GB.com_user.ini (approx line 85) and change:</p>
<div class="codesnip-container" >REG_ACTIVATE_COMPLETE_USER=Congratulations, your application to join the [sitename] website has been approved.\n\nYou can now use the login details you entered when registered to log in at %s</div>
<p>/language/en-GB/en-GB.com_user.ini (approx line 92) and change:</p>
<div class="codesnip-container" >REG_COMPLETE_ACTIVATE=Your account has been created and now is awaiting the vetting process &#8211; you should get an email containing your username and password. Once you are vetted you will use these to login.</div>
<p>/language/en-GB/en-GB.com_user.ini (approx line 120) and change:</p>
<div class="codesnip-container" >SEND_MSG_ACTIVATE=The following person %s has registered at %s. Their account activation link is that needs to be copied into your browser:\n%s\n\nAfter activation they will be able to login.</div>
<div class="codesnip-container" >SEND_MSG_USER=Hello %s,\n\nThank you for registering at %s. Your account is currently waiting to be vetted.\nYou will be notified by email once it is approved by an administrator.\nYou may then login to %s using the following username and password:\n\nUsername: %s\nPassword: %s</div>
<p>Finally, the User() helper function needs to be updated so that the activation confirmation email is sent to the user in question rather than the user currently logged into joomla (eg site administrator):  To do that, go to:</p>
<div class="codesnip-container" >/libraries/joomla/user/helper.php (line 72) Added:<br />
// *** Added send confirmation to user not admin<br />
// return true;<br />
return $user;<br />
// *** END Added send confirmation to user not admin</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.katipo.co.nz/2009/09/21/joomla-vetting-new-signups/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Adding Access Keys to a Joomla 1.5 Website.</title>
		<link>http://blog.katipo.co.nz/2009/09/21/adding-access-keys-to-a-joomla-1-5-website/</link>
		<comments>http://blog.katipo.co.nz/2009/09/21/adding-access-keys-to-a-joomla-1-5-website/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 03:22:56 +0000</pubDate>
		<dc:creator>bob</dc:creator>
				<category><![CDATA[joomla]]></category>

		<guid isPermaLink="false">http://blog.katipo.co.nz/?p=82</guid>
		<description><![CDATA[Developing in Joomla sometimes throws up minor issues with solutions so  simple that you wonder why they&#8217;re not in the core code.  While putting  together the Rangitikei District Council&#8217;s website we discovered that  there&#8217;s no easy way to set up Navigation Access Keys in Joomla 1.5, as  per the New Zealand [...]]]></description>
			<content:encoded><![CDATA[<p>Developing in Joomla sometimes throws up minor issues with solutions so  simple that you wonder why they&#8217;re not in the core code.  While putting  together the Rangitikei District Council&#8217;s website we discovered that  there&#8217;s no easy way to set up Navigation Access Keys in Joomla 1.5, as  per the New Zealand Government Web Standards  (<a href="http://webstandards.govt.nz/8-4-navigation-access-keys/">http://webstandards.govt.nz/8-4-navigation-access-keys/</a>).  The keys are  a great navigation aid to non-mouse users and are recommended by w3c  (<a href="http://www.w3.org/WAI/WCAG20/quickref/#keyboard-operation">http://www.w3.org/WAI/WCAG20/quickref/#keyboard-operation</a>).<br />
To add Access Keys to a Joomla site you need to hack at the core code of  your Joomla install.  There are some basic instructions on the Joomla  documentation site at <a href="http://docs.joomla.org/Adding_Access_Keys">http://docs.joomla.org/Adding_Access_Keys</a>.  This  sets up a new &#8220;Accessibility Access Key&#8221; field in the System Parameters  dropdown that&#8217;s available when you edit an menu item, allowing you to  simply enter the keystroke you want to associate with that menu link on  your site.</p>
<p>The hack makes it easy to add as many access keys as you need, and you  can offer more than just the basic keystroke options set on most  government websites.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.katipo.co.nz/2009/09/21/adding-access-keys-to-a-joomla-1-5-website/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Have fun testing your application with Cucumber</title>
		<link>http://blog.katipo.co.nz/2009/09/04/having-fun-testing-your-application-with-cucumber/</link>
		<comments>http://blog.katipo.co.nz/2009/09/04/having-fun-testing-your-application-with-cucumber/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 04:13:40 +0000</pubDate>
		<dc:creator>kieran</dc:creator>
				<category><![CDATA[random]]></category>

		<guid isPermaLink="false">http://blog.katipo.co.nz/?p=73</guid>
		<description><![CDATA[My experience with Cucumber. It's simple and has such a flexible style of feature testing, that writing tests hasn't been easier!]]></description>
			<content:encoded><![CDATA[<p>When I started on a new Ruby on Rails project at Katipo Communications, I evaluated a range of testing libraries, and decided on <a href="http://cukes.info/">Cucumber</a>. It&#8217;s simple and has a flexible style of feature testing. For more info about it, see the <a href="http://wiki.github.com/aslakhellesoy/cucumber">Cucumber Wiki Documentation</a>. In this post, I&#8217;ll detail some of my experiences with it for other developers who are considering using it.</p>
<p><span id="more-73"></span></p>
<p><strong>Experience with Cucumber</strong></p>
<p>Cucumber has been working out really well, and was very easy to get started with.</p>
<pre>
<div class="codesnip-container" >sudo gem install cucumber
cd ~/Work/app
script/generate cucumber</div>
</pre>
<p>That&#8217;ll install a new environment with the config.gem lines needed. It&#8217;ll also setup a features directory. Open that up, and start writing specs for your app. Simple!</p>
<p>Once I had all the basic step definitions for logging in, logging out, and various paths setup for login page, homepage, etc, writing new features was fairly easy, and executing them is just as easy (rake cucumber). Take for example, the following feature relating to session management.</p>
<pre>
<div class="codesnip-container" >Scenario: Login with correct details
  When I go to login
  And I fill in "Username" with "jane"
  And I fill in "Password" with "test"
  And I press "Login"
  Then I should see "Successfully logged in."</div>
</pre>
<p>Very straightforward and easy to read. And as such, the natural language of it means clients and other developers are able to see exactly what has been implemented, and that it is working as expected.</p>
<p>It&#8217;s running the entire test suite is fairly fast too (granted, it&#8217;s still quite small). I&#8217;m testing the core functionality of the new application so far, and it only takes ~40s to run all the features when using &#8216;progress&#8217; output (the  F..F..E  style output that test/unit does). The more verbose &#8216;pretty&#8217; output is nice, but quickly fills the terminal, so very easy to miss errors as they happen until the end, and also adds processing time (10s cut off when I switched to progress mode).</p>
<p>At one point in development, I had to test outgoing emails. Thankfully, Cucumber has a really great addition, called <a href="http://github.com/bmabey/email-spec">email-spec</a> by Ben Mabey. Writing a Cucumber feature for these emails was painless. Here is a snippet from one of the password reset features.</p>
<pre>
<div class="codesnip-container" >Scenario: Request Reset with correct email
  When I request a password reset for "example@example.com"
  Then I should receive an email
  When I open the email
  And I follow "Continue to reset your password" in the email
  Then I should see "Change My Password"</div>
</pre>
<p>I&#8217;ve made a few contributions to the email-spec project, which have been included in the latest release, enabled email testing for people other than yourself  ( When they open the email&#8230; Then they should see &#8230;  etc). Makes writing tests even easier.</p>
<p><strong>Other Thoughts</strong></p>
<p>I did find that you duplicate a lot when it comes to adding paths because Cucumber is framework independent. For example, if you have a &#8216;<em><strong>map.resources :events</strong></em>&#8216; Cucumber won&#8217;t provide you with paths like &#8216;the events index&#8217; or &#8216;add a new event&#8217; automatically. Would make a handy Cucumber addition though. In addition, because Cucumber uses Webrat, which has no idea how to interact with Javascript, you still need to fall back to the slow Selenium testing if you&#8217;re application relies on Javascript.</p>
<p><strong>Conclusion</strong></p>
<p>Cucumber has been really great and I&#8217;m happy to keep using it. If you&#8217;ve used Cucumber before, or are going to try it, or perhaps your didn&#8217;t like it and went with something else, let me know in the comments. I&#8217;m always happy to hear other peoples experiences.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.katipo.co.nz/2009/09/04/having-fun-testing-your-application-with-cucumber/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting the Most out of Your Website</title>
		<link>http://blog.katipo.co.nz/2009/08/21/getting-the-most-out-of-your-website/</link>
		<comments>http://blog.katipo.co.nz/2009/08/21/getting-the-most-out-of-your-website/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 00:02:55 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[random]]></category>

		<guid isPermaLink="false">http://blog.katipo.co.nz/?p=57</guid>
		<description><![CDATA[These are some preparation notes for a panel discussion with the NZ Industry Training Federation &#8211; ITOs Marketing and Communications Network. We were asked to respond to three questions:

My website is a dog&#8217;s breakfast, my boss wants it fixed, what do I need to do/think about mys elf before I contact a company?
What are the [...]]]></description>
			<content:encoded><![CDATA[<p>These are some preparation notes for a panel discussion with the NZ Industry Training Federation &#8211; ITOs Marketing and Communications Network. We were asked to respond to three questions:</p>
<ol>
<li>My website is a dog&#8217;s breakfast, my boss wants it fixed, what do I need to do/think about mys elf before I contact a company?</li>
<li>What are the most common mistakes you see being made on organisation&#8217;s website?</li>
<li>How do you measure value for money on your website?</li>
</ol>
<p><span id="more-57"></span></p>
<h3>1. My website is a dog&#8217;s breakfast, my boss wants it fixed, what do I need to do/think about myself before I contract a company?</h3>
<p>It&#8217;s important to realise that a web development company won&#8217;t know as much about your organisation and website as you do.</p>
<ul>
<li>You need to be the expert on your website.</li>
<li>To get the result you want, you will need to fill them in with all the information they will need.
<ul>
<li>This is the brief for the project.</li>
</ul>
</li>
<li>A good brief will stop wasted effort and money from people going down the wrong track and ensure you get the result you need.</li>
</ul>
<p>High level questions you should be able to answer are about how you define your website. These include:</p>
<ul>
<li>What is the purpose of the website?
<ul>
<li>Why have we got a website in the first place?</li>
</ul>
</li>
<li>What do we hope to develop with our internet presence? For example,
<ul>
<li>Customer or client education</li>
<li>Internal communication</li>
<li>Information gathering</li>
<li>Information dissemination</li>
<li>Sales</li>
</ul>
</li>
<li>Who is our target audience?
<ul>
<li>What do we want them to get from the website?</li>
<li>What do we want to get from them?</li>
</ul>
</li>
<li>What image do we want to portray on the Internet?
<ul>
<li>Do we have corporate branding standards which need to be complied with?</li>
</ul>
</li>
<li>Who owns the website?
<ul>
<li>Which person in the organisation is responsible for ensuring the website is up to date and loved.</li>
</ul>
</li>
</ul>
<p>Then on to fixing the dog&#8217;s breakfast.</p>
<ul>
<li>What is the scope of the project?
<ul>
<li>What exactly does your boss mean by fixing the dog&#8217;s breakfast?</li>
<li>Does the boss want a total website redevelopment along with a new design or some changes made to the existing site?</li>
</ul>
</li>
<li>What are the goals of this project?
<ul>
<li>e.g., to fix the dog&#8217; s breakfast so we get less complaints about the site and more registrations for courses.</li>
</ul>
</li>
<li>What kind of budget have you got?</li>
<li>What outcome will make this project successful?
<ul>
<li>This should be the goal for the project</li>
</ul>
</li>
<li>How will we measure success?
<ul>
<li>More sales</li>
<li>more email inquiries</li>
<li>more site visits</li>
<li>less complaints</li>
</ul>
</li>
</ul>
<p>You should be able to determine the measures of success against the website&#8217;s broad purpose and the goals for this project.</p>
<p>Armed with this information you will be able to give a brief to the contractor which lead to an excellent outcome.</p>
<h3>2. What are the most common mistakes you see being made on organisation&#8217;s website?</h3>
<p>Out of date content.</p>
<ul>
<li>This is often a	symptom of no company ownership of the site.</li>
<li>Because no-one 	owns it, no-one has the responsibility of keeping it up to date.</li>
</ul>
<p>Broken links</p>
<p>It&#8217;s hard to find information on the site</p>
<ul>
<li>Poor navigation
<ul>
<li>Links aren&#8217;t obvious</li>
<li>I include flash menus and some dropdown navigation systems in this.</li>
</ul>
</li>
<li>Poor search engine results
<ul>
<li>page titles, meta information</li>
</ul>
</li>
<li>Hard to read content
<ul>
<li>Overly wordy and long pages.
<ul>
<li>People don&#8217;t read, they scan.</li>
<li>So 7 plus or minus 2 words for sentences, get to the point quickly.
<ul>
<li>Use bullets</li>
<li>Use white space</li>
</ul>
</li>
</ul>
</li>
<li>Headings should summarise the page</li>
</ul>
</li>
</ul>
<p>Slow loading pages.</p>
<ul>
<li>pointless animations</li>
<li>flash</li>
</ul>
<h3>3. How do you measure value for money on your website?</h3>
<p>How do I measure if my website project gave me value for money?</p>
<p>This is the ROI or &#8220;Return on investment&#8221;. It should be directly related to how you have defined the site&#8217;s purpose and objectives.</p>
<p>With the purpose and objectives for the site in mind, you can set up measures of how your website meets it&#8217;s goals. For example, if a goal for a website change was to have increased number of applicants for a course, you could measure the number of applications made on-line. Of course, the number of new applicants may be greater than that because some people will be attracted to the course by the information on the website and apply for the course in person, over the phone or by snail mail</p>
<p>Easily measurable items to assess ROI:</p>
<ul>
<li>Sales &#8211; $
<ul>
<li>If you&#8217;re doing online sales</li>
</ul>
</li>
<li>Leads – for sales or services
<ul>
<li>emails,	contacts</li>
</ul>
</li>
<li>Conversions &#8211; how many people visit your site and do something
<ul>
<li>you	want people to join, participate in a survey, recommend your site or simply subscribe to your email newsletter?</li>
</ul>
</li>
</ul>
<p>From your website logs you can get indirect measures such as:</p>
<ul>
<li>Usability
<ul>
<li>How usable is your site to your visitors
<ul>
<li>From your website logs you can get information on
<ul>
<li>returning visitors</li>
<li>page views per visit</li>
<li>time on page</li>
<li>time on site</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>SEO
<ul>
<li>How much does Google love your site?
<ul>
<li>is it visiting regularly?</li>
<li>how many pages is it spidering</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>And finally:</p>
<ul>
<li>Social Media
<ul>
<li>What your users like and what they actually say about you.</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.katipo.co.nz/2009/08/21/getting-the-most-out-of-your-website/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OPACs for HLT &#8211; netbooting WebConverger on ASUS EEEBox b202</title>
		<link>http://blog.katipo.co.nz/2009/07/17/opacs-for-hlt-netbooting-webconverger-on-asus-eeebox-b202/</link>
		<comments>http://blog.katipo.co.nz/2009/07/17/opacs-for-hlt-netbooting-webconverger-on-asus-eeebox-b202/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 09:44:22 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[koha]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://blog.katipo.co.nz/?p=56</guid>
		<description><![CDATA[The OPACs at HLT have been failing one by one, so some replacements are in order.  The previous OPACs ran Mozilla in kiosk mode on a hand modified Debian install sufficiently rickety that after ~4 years I didn&#8217;t really want to touch it.
Somewhat surprisingly, the task (taking some hardware and netbooting it into a teenage-vandal-proof [...]]]></description>
			<content:encoded><![CDATA[<p>The OPACs at <a href="http://www.library.org.nz/">HLT</a> have been failing one by one, so some replacements are in order.  The previous OPACs ran Mozilla in kiosk mode on a hand modified Debian install sufficiently rickety that after ~4 years I didn&#8217;t really want to touch it.</p>
<p>Somewhat surprisingly, the task (taking some hardware and netbooting it into a teenage-vandal-proof web kiosk) didn&#8217;t appear to be a solved problem &#8211; there are still a lot of people rolling their own, I&#8217;ve done that once, I didn&#8217;t really want to do it again.</p>
<p>Webconverger almost fits the bill, with a couple of caveats:<span id="more-56"></span></p>
<ol>
<li>it doesn&#8217;t have direct support for netbooting</li>
<li><a title="it doesn't work with the EEEBox b202" href="http://groups.google.com/group/webc-users/browse_thread/thread/82d8bd5a7ac09c1e#%20)">it doesn&#8217;t work with the EEEBox b202</a></li>
</ol>
<p>As Webc is based on Debian Live (which does support PXE booting), and the b202 works fine with Ubuntu, both these issues seemed like they should be soluble, and after much mucking about, that proved true.</p>
<p>First up, there&#8217;s no way that I can see to get Webc to netboot without rebuilding it, so you need to be comfortable with that <a title="process." href="http://webconverger.org/develop/">process.</a>  Be warned that you will consume a fair amount of bandwidth downloading packages (multiple times if you don&#8217;t have a local cache), and that the build process is slooooow.</p>
<p>Solving the non functioning X display was relatively straightforward. First, you need to amend your X configuration.  Add a symlink and a file to the includes tree:
<div class="codesnip-container" >ls -l config/chroot_local-includes/etc/X11<br />
lrwxrwxrwx 1 root simon   13 2009-07-09 18:10 X -> /usr/bin/Xorg<br />
-rw-r&#8211;r&#8211; 1 root simon 1194 2009-07-09 18:10 xorg.conf</div>
<p>inside the xorg.conf you need something like:
<div class="codesnip-container" >Section &#8220;Device&#8221;<br />
Identifier	&#8220;Configured Video Device&#8221;<br />
Option &#8220;monitor-LVDS&#8221; &#8220;LVDS&#8221;<br />
EndSection<br />
Section &#8220;Monitor&#8221;<br />
Identifier	&#8220;LVDS&#8221;<br />
Option &#8220;Ignore&#8221; &#8220;true&#8221;<br />
EndSection<br />
Section &#8220;Monitor&#8221;<br />
Identifier	&#8220;Configured Monitor&#8221;<br />
EndSection<br />
Section &#8220;Screen&#8221;   Identifier	&#8220;Default Screen&#8221;<br />
Monitor	&#8220;Configured Monitor&#8221;<br />
EndSection</div>
<p>then, edit scripts/config and add &#8220;noxautoconfig&#8221; to the &#8211;bootappend-live line, and rebuild.</p>
<p>noxautoconfig disables autogeneration of the X config every time the machine boots &#8211; it isn&#8217;t ideal, in that it makes your build less portable, but it does give you a working display.  Hopefully, the Intel Xorg driver will be updated soon to make this unnecessary (it appears to be assuming that the b202 has a mobile graphics chipset, therefore it must have an LMDS display).</p>
<p>Netbooting Webc is also comparatively simple &#8211; the only major gotcha is that the stock Webc iptables ruleset blocks NFS, which means that your box will hang just before X starts up.   HLT don&#8217;t need iptables in their environment,  so I took the path of least resistance and removed the iptables package completely &#8211; alternatively, you could amend config/chroot_local-includes/etc/iptables.conf to allow NFS.</p>
<p>So to enable netbooting, you make changes as per the Debian live manual &#8211; add something like:</p>
<div class="codesnip-container" >-b net \<br />
&#8211;net-root-path &#8220;/srv/debian-live&#8221; \<br />
&#8211;net-root-server &#8220;192.168.1.1&#8243; \</div>
<p>to scripts/config, then edit config/chroot_local-packageslists/webconverger and remove the &#8220;iptables&#8221; entry.  Finally, if DNS resolution doesn&#8217;t work, you may need to remove &#8220;nonetworking&#8221; from the &#8211;bootappend-live line in scripts/config.  Rebuild webc, and be happy.</p>
<p><strong>Other local changes:</strong></p>
<p>Removed iptables, splashy, cups, iceweasel-webconverger and all the wireless drivers from the package list, and added cron, msttcorefonts and iceweasel-webcyourlibrary.  I needed cron because I wanted to be able to power down the kiosks after the library is closed.</p>
<p>I made some further changes to scripts/config file:</p>
<div class="codesnip-container" >&#8211;bootappend-live &#8220;quiet silent nosudo noxautoconfig homepage=http://www.library.org.nz/ video=vesa:ywrap,mtrr vga=792 nopersistent quickreboot timezone=Pacific/Auckland noblank kioskresetstation=2 swapon&#8221; \<br />
-k 686 \</div>
<p> the timezone is necessary for the cron jobs to work correctly, noblank turns off the screen blanking, swapon enables any swap partitions on the hard drive, and kioskresetstation restarts Iceweasel after two minutes of idleness.  The -k 686 causes the system to boot the 686 optimised kernel &#8211; it&#8217;s not critical, the default 486 kernel also works.  All good.</p>
<p>After making changes to the tree, I run</p>
<div class="codesnip-container" >$ sudo lh_clean &#8211;purge; lh_config ; sudo lh_build</div>
<p>to redo the build.  It&#8217;s a slow process, particularly if you use &#8211;purge.  Once built, to install I run:</p>
<div class="codesnip-container" >$ sudo rm -r /srv/webconverger /srv/debian-live ; sudo tar -C /srv -xzf binary-net.tar.gz ; sudo mv /srv/webconverger/debian-live /srv ; sudo rm -r /tftpboot/pxe/debian-live ; sudo mv /srv/webconverger/tftpboot/debian-live /tftpboot/pxe ; sudo cp prompt.cfg /tftpboot/pxe/debian-live/i386/boot-screens</div>
<p>I copy the prompt.cfg because I couldn&#8217;t work out how to turn off the pxelinux prompt from within debian-live &#8211; this just overwrites the installed file with a simple file that says:</p>
<div class="codesnip-container" >default live<br />
prompt 0<br />
noescape 1</div>
<p><strong>Hardware setup</strong></p>
<p>(mostly these are notes to myself so that when I have to repeat the process in the future I won&#8217;t forget steps):</p>
<p>Updated the BIOS (press Alr-F2 as the machine boots to run the updater), then made some changes in the BIOS &#8211; enabled LAN BootROM, disabled WLAN, Enabled ACPI 2.0 support, enabled Power on by LAN, Full screen logo disabled, Express gate disabled.</p>
<p>I used <a href="http://sourceforge.net/projects/billix/">Billix</a> to boot Ubuntu, shrink the second NTFS partition to 17.2GB, make an ext3 fs (15GB) and the remainder (1.7GB) into  swap, and installed Ubuntu server.  None of this is crucial, but I wanted grub installed, and wanted some swap space, and ubuntu is as good a way of achieving this as any.  Changes to /boot/grub/menu.lst: timeout 15, hiddenmenu, password (), alternative=false, lockold=true, howmany=1, memtest86=false, then run sudo update-grub.  Then add &#8220;title Reboot/nreboot&#8221; as the first option, and &#8220;lock&#8221; to all the remaining options.</p>
<p>I wanted grub because sometimes on warm boot the ethernet interface doesn&#8217;t bring up link, and PXE falls through to the hard drive.  I don&#8217;t know why this is &#8211; it might be a BIOS issue, it might be an incompatibility between my test switch and the b202 &#8211; either way, with grub I can force the machine to reboot and try again, rather than falling through to an unconfigured Windows install.</p>
<p>Verify grub is giving the correct behavior (password within 15 seconds to boot Windows or Ubuntu, otherwise reboot), go back to the BIOS, change the Boot device priority, first: Network boot, second HDD, USB/CDROM disabed, and set a Supervisor password on the BIOS so that it can&#8217;t be modified.  Reboot</p>
<p>When the PXE config text comes up, press Shift F10 to configure, disable the Config message, and set the Show message time to 1 Sec.  Add the MAC of the machine to DHCP/WOL configs, and test.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.katipo.co.nz/2009/07/17/opacs-for-hlt-netbooting-webconverger-on-asus-eeebox-b202/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Make Rails logger available in code normally outside of logger scope</title>
		<link>http://blog.katipo.co.nz/2009/01/24/make-rails-logger-available-in-code-normally-outside-of-logger-scope/</link>
		<comments>http://blog.katipo.co.nz/2009/01/24/make-rails-logger-available-in-code-normally-outside-of-logger-scope/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 23:19:40 +0000</pubDate>
		<dc:creator>walter</dc:creator>
				<category><![CDATA[open source]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://blog.katipo.co.nz/?p=55</guid>
		<description><![CDATA[Here&#8217;s a quick one.  Say you are debugging a bit of code in a plugin that doesn&#8217;t fall under the Rails app you are working on&#8217;s ActiveSupport context and thus &#8220;logger.debug&#8221; is not available to you.
You could write up your own logging mechanism, with or without using the Logger gem.  However, if what [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a quick one.  Say you are debugging a bit of code in a plugin that doesn&#8217;t fall under the Rails app you are working on&#8217;s ActiveSupport context and thus &#8220;logger.debug&#8221; is not available to you.</p>
<p>You could write up your own logging mechanism, with or without using the Logger gem.  However, if what you are working on is run by the Rails app and thus has the apps global constants available, you could simply tie it into the existing logger object in the Rails app like so in your file:</p>
<div class="codesnip-container" >logger = RAILS_DEFAULT_LOGGER</div>
<p>Then you can use logger.debug, logger.info, etc. to your heart&#8217;s content.  One caveat, if you are working on a gem or a something more general that won&#8217;t necessarily always be run in the context of Rails, then you will want to pull your use of logger out before distributing your code.  Otherwise you add a dependency on Rails that you may not intend.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.katipo.co.nz/2009/01/24/make-rails-logger-available-in-code-normally-outside-of-logger-scope/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding Gist commands to emacs</title>
		<link>http://blog.katipo.co.nz/2009/01/15/adding-gist-commands-to-emacs/</link>
		<comments>http://blog.katipo.co.nz/2009/01/15/adding-gist-commands-to-emacs/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 20:26:22 +0000</pubDate>
		<dc:creator>walter</dc:creator>
				<category><![CDATA[open source]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://blog.katipo.co.nz/?p=54</guid>
		<description><![CDATA[You have to give Logical Awesome credit for how much work they do to integrate GitHub&#8217;s services with tools that developers use.
The Gist service is a good example.  First they added command line support for it, then they simultaneously added in-editor support in Textmate, vim, and my own personal favorite emacs.  The blog [...]]]></description>
			<content:encoded><![CDATA[<p>You have to give <a href="http://logicalawesome.com/">Logical Awesome</a> credit for how much work they do to integrate <a href="http://github.com/">GitHub&#8217;s</a> services with tools that developers use.</p>
<p>The <a href="http://gist.github.com/">Gist</a> service is a good example.  First they added command line support for it, then they simultaneously added in-editor support in <a href="http://github.com/blog/233-gist-support-for-textmate">Textmate</a>, <a href="http://github.com/mattn/gist-vim">vim</a>, and my own personal favorite <a href="http://github.com/defunkt/gist.el/tree/master">emacs</a>.  The blog post announcing gist support in emacs and vim is <a href="http://github.com/blog/234-gist-vim-and-gist-el">here</a>.</p>
<p>So how do you add the gist support to emacs?  </p>
<p>First, you&#8217;ll need an account on github.com and have set up your ~/.gitconfig as outlined in <a href="http://github.com/blog/180-local-github-config">here</a>.</p>
<p>Then download or clone the gist.el file from <a href="http://github.com/defunkt/gist.el">http://github.com/defunkt/gist.el</a>, copy only the gist.el file from that repository to someplace in your <a href="http://www.emacswiki.org/emacs/LoadPath">emacs load path</a> (in my case /Users/walter/Library/Preferences/Aquamacs Emacs/ because I use <a href="http://aquamacs.org/">Aquamacs</a> on a Mac), and add a line to your ~/.emacs file or in my case /Users/walter/Library/Preferences/Aquamacs Emacs/Preferences.el that looks like this:</p>
<div class="codesnip-container" >(require &#8216;gist)</div>
<p>Then you have to either restart your emacs program or do M-x load-library and answer prompt with gist for the new gist commands to be available.</p>
<p>Now you have M-x commands like these:</p>
<dl>
<dt>gist-view-gist</dt>
<dd>view gists after they&#8217;re posted</dd>
<dt>gist-region</dt>
<dd>Post the current region as a new paste at gist.github.com<br />
Copies the URL into the kill ring.</dd>
<dt>gist-region-private</dt>
<dd>Post the current region as a new private paste at gist.github.com<br />
Copies the URL into the kill ring.</dd>
<dt>gist-buffer</dt>
<dd>Post the current buffer as a new paste at gist.github.com.<br />
Copies the URL into the kill ring.</dd>
<dt>gist-buffer-private</dt>
<dd>Post the current buffer as a new private paste at gist.github.com.<br />
Copies the URL into the kill ring.</dd>
<dt>gist-region-or-buffer</dt>
<dd>Post either the current region, or if mark is not set, the current buffer as a new paste at gist.github.com<br />
Copies the URL into the kill ring.</dd>
<dt>gist-region-or-buffer-private</dt>
<dd>you can probably guess&#8230;</dd>
<dt>gist-fetch</dt>
<dd>Given an gist id, fetches a Gist and inserts it into a new buffer<br />
If the Gist already exists in a buffer, switches to it.</dd>
</dl>
<p>Very useful stuff for collaboration, but without leaving your editor.</p>
<p>Enjoy,<br />
Walter</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.katipo.co.nz/2009/01/15/adding-gist-commands-to-emacs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
