Protecting Plone Registration Forms with ReCAPTCHA

February 24, 2009 at 10:56 AM | categories: Computers, Programming | View Comments

We recently launched the CIOC Community Site running on Plone. While we have not actually had any SPAM on the site yet, we continually get automated SPAM registrations that we then need to go and clear out. Last night Kate got fed up, so I decided to see if I could put a CAPTCHA on the form.

Looks like there is a proposal to include CAPTCHA support. The de facto standard CAPTCHA tool for Plone seems to be collective.captcha, but I wanted to be able to use the ReCAPTCHA service.

Luckily there is collective.recaptcha which is in beta and, while not listing any releases on the Plone site, is available from the Cheese Shop. But, alas, there is no documentation. It is supposed to be a drop in replacement for collective.captcha so with a little sleuthing and I got it to work. Here's how.


I am using the unified Unix installer so everything is done via buildout. Following the instructions on the collective.captcha page we need to add collective.recaptcha to your eggs list and collective.recaptcha to your zcml list. Then run ./bin/buildout and restart your Plone instance.


We need to enter our private and public ReCAPTCHA keys in the collective.recaptcha setup form which is located at

Registration Form Modifications

Using this site as a helpful reference I was able to figure out the additions I needed to make to the registration form and validator.

You need to go in through your Plone site setup into the Zope Management Interface. Navigate to portal_skins/plone_login. Click join_form and then the customize button. You should now be able to customize the form contents. Down near the bottom of the form there is a line:

<div class="formControls"></div>

Above that line you need to add:

<div class="field"
     tal:define="error errors/captcha|nothing;"
     tal:attributes="class python:test(error, 'field error', 'field')">
  <label for="captcha" i18n:translate="label_captcha">Captcha</label>

  <span class="fieldRequired" title="Required"

  <div class="formHelp" i18n:translate="help_captcha">
    Provide the text in the image. Just to avoid spambots
  <p tal:replace="structure here/@@captcha/image_tag" />


Note that the difference from the code provided by Mikel Larreategi is that ReCAPTACH provides the input element itself, so you need to omit the div that includes the <input type="text"> tag.

Once you have that saved, you need to go back to portal_skins/plone_login and click join_form_validate and once again click customize. At the bottom of the validation code, just before return state add:

captcha = context.REQUEST.get('recaptcha_response_field')
view = context.restrictedTraverse('@@captcha')

if not view.verify(captcha):
    state.setError('captcha', _(u'Are you a bot? Try again...'))

Note that the difference in the validation code from Mikel Larreategi's is that the ReCAPTCHA inserted input tag is called recaptcha_response_field and not captcha.

Hopefully that is helpful to someone other than me :)

Read and Post Comments

Winterlicious X2 / AGO / Dirty Dancing

February 06, 2009 at 09:15 AM | categories: General | View Comments

Yesterday Kate and I had a very indulgent day. The Winterlicious promotion is happening in Toronto right now and we decided to take full advantage of it. We booked a lunch and dinner reservation and then built a day in Toronto around it.

First we went to Barootes for lunch. I had the Chicken, Leek and Barley soup while Kate had the Baby Organic Greens with Apple Cider Vinaigrette. The we both had Penne with Spicy Italian sausage in Basil Tomato Sauce and finished it off with their "Special of the Week" which was Chocolate Layer Cake. Yummy.

Once we left there we walked to the AGO to check out the new building and have a look through the new collections. The walk was a chilly at -8C but we got there quick enough that we did completely loose the feeling in our extremities (about 10-15 minutes).

The new AGO building is a welcome change. It makes the building much more interesting and the extra exhibit space made for the opportunity to see many works that were locked away in the vaults before. Add the new works, and even if you were very familiar with what used to be on display, I am sure you will find something new to see. The new centrepiece staircase goes all the way up to the 5th floor and is outside the main structure of the building between the 4th and 5th floors similar to the staircase on the other side of the building. Disappointingly, they are having a major problem with condensation on the glass between the 4th and 5th floors of the staircase. They had to close that section of the staircase and the water is damaging the dry wall in places. After all the money and effort that went into the transformation I hope they will be able to find a quick solution to the problem and it is just a matter of working out the kinks.

After about 4 hours at the AGO, it was time for the cold walk back to King St for our dinner at Marcel's Bistro. Both Kate and I had the Salad to start, followed by Pork tenderloin in a tomato sauce with mashed potatoes & seasonal vegetables. We shared a 1/2L of the Italian Terrazze Della Luna Pinot Grigio 2007. For desert Kate had Vanilla ice cream with hot chocolate sauce in puff pastry while I had the chocolate mouse cake. Again yummy, but I think Barootes was better.

To complete the day, we had tickets to Dirty Dancing. We had excellent seats, 3rd row, first balcony center which we got for the ridiculously low price of $30 each. Thank you Red Flag Deals. The play was good, but not your traditional the story line is sung kind of musical. It was more like a play with a lot of music and dancing in it. If you liked the movie, you'll probably like the play.

In all it was a very long, fun, expensive but high value day.

Read and Post Comments