<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>http://www.jandaweb.com/</id>
  <title>Jandaweb Blog posts</title>
  <updated>2008-06-29T17:24:00+01:00</updated>
  <link href="http://www.jandaweb.com/blog_posts.atom" rel="self"/>
  <entry>
    <id>tag:www.jandaweb.com,2008:/blog_posts/8</id>
    <updated>2008-06-29T17:32:15+01:00</updated>
    <title>assert_valid_xhtml - now with RSpec matcher!</title>
    <link type="text/html" href="http://www.jandaweb.com/blog_posts/8" hreflang="en" rel="alternate"/>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<h2>RSpec matcher for assert_valid_xhtml</h2><pre>
<code>
script/plugin install git://www.jandaweb.com/assert_valid_xhtml
</code>
</pre>
<p>Then add <code>config.include ValidateXhtml</code> to your spec/spec_helper.rb</p><p>Now you're ready to do</p><pre>
<code>
it "should be valid" do
  render "/some/template"
  response.should be_valid_xhtml
end
</code>
</pre><br/><h2>Fudge warning</h2><p>The matcher will not validate your view with its full layout, as I haven't worked out how to get views to render with a layout from a view test. Instead, it wraps a valid XHTML header / footer around the rendered template.</p><p>Let me know if you can do this better!</p>      </div>
    </content>
    <author>
      <name>Andrew Bruce</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.jandaweb.com,2008:/blog_posts/7</id>
    <updated>2008-06-27T17:04:07+01:00</updated>
    <title>Testing XHTML validity with Ruby and libxml</title>
    <link type="text/html" href="http://www.jandaweb.com/blog_posts/7" hreflang="en" rel="alternate"/>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<h2>Update: now a plugin</h2><p>Rails 2.1 and git only. You still need to install the libxml-ruby gem, and you need git installed to install the plugin. Install plugin with:</p><pre><code>script/plugin install git://www.jandaweb.com/assert_valid_xhtml</code></pre>
<br/><h2>Slow validation</h2><p>The <a href="http://blog.codahale.com/2006/03/05/responsiblemarkup-v01-unit-test-your-way-to-responsible-markup/">responsible_markup</a> plugin from codahale is fine and dandy if you want all the features and you're always connected to the net. If, however, like me, you're moving around a bit and sometimes get a dodgy connection, or simply want to speed up your functional tests' XHTML validation, give this a spin.</p><p>It's an assertion that can be stuck into your test_helper.rb or made into a plugin as you see fit. <br/><del>I didn't think it was worth making a special plugin just yet, as it's very limited in scope.</del>
<br/>It assumes you're doing XHTML 1.0 validation.</p><h2>Installation</h2><p>Install the libxml gem:</p><p><code>sudo gem install libxml-ruby</code></p><p>Download the XHTML 1.0 DTDs to a special directory:</p><pre><code>cd YOUR_RAILS_PROJECT
mkdir doc/dtd
cd doc/dtd
wget http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd
wget http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
wget http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent
wget http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent</code></pre>
<p>Now you're ready to paste some code. Open up your test/test_helper.rb and stick the following require lines somewhere at the top, after "require 'test_help'":</p><pre><code>require 'xml/libxml'
require 'md5'</code></pre>
<p>We'll be doing some md5 hashing to (almost) guarantee unique versions of markup.</p><p>Here's the assertion!</p><pre><code>
def assert_valid_xhtml
  checksum = MD5.new(@response.body)
  path = "/tmp/assert_valid_xhtml_#{checksum}"

  return true if File.exists?("#{path}-valid")

  dtd = XML::Dtd.new("-//W3C//DTD XHTML 1.0 Strict//EN", 
                     RAILS_ROOT + '/doc/dtd/xhtml1-strict.dtd')

  unless File.exists?(path)
    File.open(path, 'w') { |f| f.puts @response.body }
  end

  doc = XML::Document.file(path)
  if doc.validate(dtd)
    FileUtils.mv(path, "#{path}-valid")
  else
    assert false
  end
end</code></pre><br/><h2>Usage</h2><p>Now you can stick "assert_valid_xhtml" after any request to make sure it's valid. Okay, so the results don't come back too pretty and they go to STDERR instead of the failure notice, but this was knocked together quickly.</p><p>If you want to see what the code is doing try a "watch ls /tmp" while rake is running. You'll see the files being marked off as valid as it works.</p>      </div>
    </content>
    <author>
      <name>Andrew Bruce</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.jandaweb.com,2008:/blog_posts/6</id>
    <updated>2008-06-24T22:20:39+01:00</updated>
    <title>Git crash course</title>
    <link type="text/html" href="http://www.jandaweb.com/blog_posts/6" hreflang="en" rel="alternate"/>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<p>Since the <a href="http://weblog.rubyonrails.org/2008/4/2/rails-is-moving-from-svn-to-git">Rails core team switched to git</a> a lot of rails developers have followed suit. Not wishing to be left out, I have been moving some projects to git recently, although somewhat unusually I have been migrating from darcs. git seems pretty good now that I understand the basics, but the documentation for getting started did leave me a little confused. To compensate, here is my 10 minute crash course in getting started with git.</p><p>This guide assumes that you are working in a small team, have a central server with git installed and are familiar with ssh.</p><h2>Creating a central repository</h2><p>In the git world, every developer has their own full copy of the repository. This is where their changes get committed to. However, with each developer having their own repository and these repositories being in different states it is difficult to say what the authoritative state of a project is. This is easily solved by setting up another central copy of the repository which all developers have access to and to which changes are pushed when they are ready to be shared with the world.</p><p>I set this up in the quickest/easiest way I could be creating a new user called 'git' on our development server and adding each developer to the authorized_keys file. I then created a directory called <code>repos</code> under the git user's home directory to store all of the git repositories.</p><h2>First steps: getting content into a new repository</h2><p>I decided to move an existing internal (for now) project called <code>panda</code> from darcs into git. You can use <a href="http://wiki.darcs.net/DarcsWiki/Tailor">tailor</a> to convert between the two different SCMs, but I was lazy and just ditched the darcs history and started the git repository from the current working version.</p><p>On my laptop (where I write most of my code), I got a fresh copy of the latest panda code and removed the _darcs directory. (This is similar to doing an <code>svn export</code>.) Next, I turned it into a git repository with <code>git init</code>. This creates the git repository but does not add any of the existing files to it. You can see this by running <code>git status</code>. You'll see a whole load of files that haven't been added to the repository yet.</p><p>Before we add all the files, it's worth taking the time to tell git to rails' temporary or generated files. (This is the git equivalent of <code>_darcs/prefs/boring</code> or <code>svn propset svn:ignore</code>.) Edit the file <code>.git/info/exclude</code> and add the patterns of the files you want to ignore. I added:</p><pre><code>
log/*.log
db/schema.rb
db/*.sqlite3
nbproject
</code></pre><br/><br/><p>(That last one is to ignore NetBeans' files.) You might want to add the various tmp directories too. Now you can add the rails project files to the git repository with <code>git add .</code></p><p>One problem remains. The extremely observant amongst you might have noticed that the log and lib (and a few more) directories don't show up in the output of <code>git status</code>. This is because git (stupidly) doesn't track empty directories. To force git to include them, create an empty file in these directories and run <code>git add .</code> again. (You might want to add <code>-v</code> to <code>git add .</code> to see what it's adding.) I did this with:</p><pre><code>
~/git/panda$ touch log/.gitinclude
~/git/panda$ git add . -v
add 'log/.gitinclude'
</code></pre><br/><br/><p>You can now commit your changes (<code>git commit</code>) and we're ready to push them centrally. To prepare the ground, create a repository on the central server to push the content into. On the central server, as the git user, I created <code>/home/git/repos/panda</code> then changed to this directory and ran <code>git init</code>. Back on my laptop, I named this remote repository to save me having to remember and type the full location each time. I did this with <code>git remote add origin git@name.of.server:repos/panda</code>. Now I'm all ready to push the changes, which I can do with <code>git push origin master</code>.</p><h2>A crash course in git branches</h2><p>Branches in git are pretty much the same as branches in any other SCM (except, of course, darcs which is too clever to need branches). However, if you come from an SVN background it is important to understand that the branch/edit/merge cycle is not only best practice, it is thankfully easy to do.</p><p>Having each developer always work in a branch is a great way of ensuring that</p><ol><li> the <code>master</code> stays clean and represents the latest <strong>stable</strong> version of the project</li><li> changes can easily be shared with other developers without breaking their repository</li><li> a single developer can jump from, say, the latest development to bug fixing the currently deployed version quickly and easily (and without either task contaminating the other)</li></ol><br/><p>Branches are good. Start using them from the outset and life becomes easy later.</p><p>The typical branch/edit/merge cycle in git is easy to do, although it does suffer from unfortunate naming. The <code>checkout</code> command is used to switch between branches, and is the most common way of creating a new branch. The flow for carrying out some work is:</p><pre><code>
$ git checkout -b &lt;name of branch&gt; (a)
&lt;make some changes&gt;
$ git status (b)
$ git add . (c)
$ git commit (d)
</code></pre><br/><br/><ol><li> This creates a new branch to work in. The command says "create a new branch called &lt;name of branch&gt; and change to it immediately"</li><li> This shows you what changes are ready to be committed</li><li> This adds all of the changes, ready to commit. If you want to selectively add changes use <code>git add &lt;path&gt;</code> rather than <code>git add .</code></li><li> This takes the modified or new files you have added (all of them in our example) and commits them to the repository.</li></ol><br/><p><em>Steps c and d can be combined into <code>git commit -a</code> if you are confident that you know what has changed.</em></p><h2>When to branch and when to commit</h2><p>Branches are not created for every change you make, but rather for groups of changes. I tend to create a new branch for every user story I work on, and commit after each acceptance criteria is met, or more frequently if an acceptance criteria requires many steps to satisfy.</p><h2>Sharing changes: merging and pushing</h2><p>Once you have finished (and committed) some work that you want to share with other developers then the git process is to merge the changes back into the master branch and push them to the central server so that other people can pick them up. The <code>master</code> branch was created automatically when you ran <code>git init</code> and this is the branch which should hold the latest stable version of the project.</p><p>Merging is easy under git. First, change to the master branch using <code>git checkout</code>, and then merge the changes in using ... <code>git merge</code>. The steps are:</p><pre><code>
$ git checkout master
$ git merge &lt;name of branch&gt;
</code></pre><br/><br/><p>Assuming there are no conflicts, you can then push this newly merged master back to the central server with:</p><pre><code>
$ git push origin master
</code></pre><br/><br/><p>...and everyone can pick up your changes.</p><h2>Final reflections</h2><p>I have only been dabbling with git for about one month now, and only using it in anger for the past week. Inevitably my current 'best practices' will change as I get to know it better. There may be better ways of doing some of the above steps, and there is a lot that I didn't talk about. However, hopefully this will be enough to get you start with your own shared git development.</p>      </div>
    </content>
    <author>
      <name>John Cinnamond</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.jandaweb.com,2008:/blog_posts/5</id>
    <updated>2008-05-22T11:04:55+01:00</updated>
    <title>Handling body element classes in Rails</title>
    <link type="text/html" href="http://www.jandaweb.com/blog_posts/5" hreflang="en" rel="alternate"/>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<p>Setting the class attribute in the &lt;body&gt; element of a page can be really handy for CSS and JavaScript hooks. For example, if I wanted all pages with the class "checkout" to be laid out in a particular way, I could simply add the class to all the pages that were in the checkout phase, then add some CSS rules for ".checkout".</p><p>Rails' content_for method is useful for including sections of markup that don't fit in the main content of a page. But when it comes to setting classes for the body tag, content_for doesn't really cut the mustard.</p><h2>First attempt</h2><p>Here was my attempt at using content_for to set a template's body class:</p><pre><code>&lt;% content_for :body_attributes, 'class="checkout"' %></code></pre>
<p>Then, in my layout:</p><p><code>&lt;body &lt;%= yield :body_attributes %&gt;&gt;</code></p><p>This worked well until I wanted to add a class that indicated the current controller. Since I'd already explicitly set "class=" in each template, I couldn't easily modify the attribute to add further classes.</p><h2>Helper to the rescue!</h2><p>So I wrote a helper to do this better. Here it is!</p><pre><code>def body_classes
  @body_classes ||= [controller.controller_name]
end</code></pre>
<p>As you can probably guess, the @body_classes instance variable defaults to an array with a single item: the name of the current controller. Handy for controller-wide CSS changes.</p><p>Here's how to call it from your layout.</p><pre><code>&lt;body class="&lt;%= body_classes.join(' ') %>"></code></pre>
<p>So now when you want to add an extra class to the default controller name, simply do the following from your template.</p><p><code>&lt;% body_classes &lt;&lt; 'checkout' %&gt;</code></p><p>Since class names are separated by spaces, array manipulation is a lot more suitable for this task than content_for.</p>      </div>
    </content>
    <author>
      <name>Andrew Bruce</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.jandaweb.com,2008:/blog_posts/1</id>
    <updated>2008-04-24T10:12:29+01:00</updated>
    <title>The Birth of Johndown</title>
    <link type="text/html" href="http://www.jandaweb.com/blog_posts/1" hreflang="en" rel="alternate"/>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
<p>If you've ever been maddened by <a href="http://daringfireball.net/projects/markdown/">Markdown</a> or troubled by <a href="http://www.textism.com/tools/textile/">Textile</a> then Johndown might be what you're after. We'll soon be releasing this new text to <a href="http://en.wikipedia.org/wiki/Xhtml">XHTML</a> language that we use on our own internal tools. As the name implies, it was originally written by <a href="http://www.jandaweb.com/team_members#john">John</a> and is based on Markdown. It's written entirely in Ruby and will have full open source code, with an accompanying Rails plugin.</p><p>The unintuitive bits of Markdown that Johndown addresses:</p><p> <ul><li> The need to escape certain characters, such as underscores, with backslashes</li><li>  The need to indent pasted code by repeatedly hitting the space bar in browser textareas</li><li>  The fact that one has to press space twice at the end of a line to get a line break</li></ul><br/>We're putting the finishing touches to the first release, including adding a safe mode for avoiding <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">XSS</a> attacks. We'll let you know when it's done!</p>      </div>
    </content>
    <author>
      <name>Andrew Bruce</name>
    </author>
  </entry>
</feed>
