Validating ambethia recaptcha in xHTML strict

Contact forms are an integral part of any website, whether it’s a blog, an e-shop or a simple brochure site. They give your audience a voice and a way to get back to you, they can provide valuable feedback and open up interesting discussions. It’s nice to open the door to people and listen to what they have to say about you, your service or product.

By giving a voice to your audience at the same time you open up your “ears” to the heaps of spam bots in the internets. Unless you are really, really challenged in “those” departments, cialis, viagra and peeeeeenis extensions are probably not what you want to have to sort through to find valid responses and enquiries. The solution to that for some time has been the addition of a captcha to our forms.

image

There have been many discussions about captchas in the last few years. One thing is clear, they have to work in a variety of conditions, with and without javascript, with or without images, for people with no or limited vision or hearing etc. They truly have to be accessible if they are not to stop communication between you and your audience.

My favorite captcha solution has for some time been recaptcha. It’s accessible, customizable and works with all the systems I work, including rails. Jason L Perry of ambethia has created a nifty little plugin for integrating recaptcha into your rails applications.

The problem

Assuming that you use this plugin and you, like me, code mostly in xHTML strict then the default plugin, although it’s really easy to integrate and works fantastically, will make the W3C validator throw a tantrum. The no script version of the plugin uses iframes to pull in the captcha which is not allowed in xHTML strict.

I had a look on the internets to see if there is a ready made patch for getting the plugin to play nicely but I couldn’t find any, so here’s my solution. (If you do know of another solution please let me know)

The solution

In the original plugin (/vendor/plugins/recaptcha/lib/recaptcha.rb) at line 32 you will find the replacements for when the user has javaScript turned off. You will see how it creates an iframe to pull in the captcha.


xhtml.noscript do
  xhtml.iframe(:src => "#{uri}/noscript?k=#{key}",
               :height => options[:iframe_height] ||= 300,
               :width  => options[:iframe_width]  ||= 500,
               :frameborder => 0) {}; xhtml.br
  xhtml.textarea(:name => "recaptcha_challenge_field", :rows => 3, :cols => 40) {}
  xhtml.input :name => "recaptcha_response_field",
              :type => "hidden", :value => "manual_challenge"
end

To make your plugin validate you have to make the following ammends.

  1. change your iframe to an object
    xhtml.iframe
    to
    xhtml.object
  2. change your src to data
    :src
    to
    :data
  3. add your object type
    :type  => "text/html"
  4. remove your frameborder
    :frameborder => 0
    and the trailing linebreak
    xhtml.br
  5. wrap the whole thing into a div with a unique id. This will stop the validator from complaining that the object element “is not allowed here” as well as giving you something to hook your styles on.

Your finished block of code should look like this in your plugin:


unless options[:noscript] == false
  xhtml.noscript do
    xhtml.div(:id => 'non_js_recaptcha') {
    xhtml.object(:data    => "#{uri}/noscript?k=#{key}",
                 :type  => "text/html",
                 :height => options[:object_height] ||= 300,
                 :width  => options[:object_width]  ||= 500
                 ) {};
        xhtml.textarea nil, :name => "recaptcha_challenge_field",
                 :rows => options[:textarea_rows] ||= 3,
                 :cols => options[:textarea_cols] ||= 40
        xhtml.input :name => "recaptcha_response_field",
                 :type => "hidden", :value => "manual_challenge" 
    };
  end

The result

The result is valid xHTML strict and a beautiful captcha that works without javaScript too. Success!

In the generated html it will look like this:


<noscript>
  <div id="non_js_recaptcha">
    <object type="text/html" width="500" height="300" data="http://api.recaptcha.net/noscript?k=YOURKEYHERE">
      <textarea name="recaptcha_challenge_field" cols="40" rows="3"></textarea>
      <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
    </object>
  </div>
</noscript>

You can download the patched file here .

Comments

Name:

Email:

Location:

URL:

Remember my personal information

Notify me of follow-up comments?

in twitterland...

twitter is having some oauth changes, twits will appear again here shortly

Follow me on twitter

Archives

The old site is still accessibile here.

©acidsmile (unless otherwise stated)

the views expressed throughout this site are my own
and do not necessarily reflect those of my employer