Making the reCAPTCHA Wordpress Plugin Validate
If you are like us, you want to harness the awesome power of reCAPTCHA for your Wordpress blog and you also want valid XHTML. Before now, this was impossible. DLB is pleased to offer you a fix, and continue doing our bit to make the web a more standardized place.
Background
reCAPTCHA is a free CAPTCHA service that helps to digitize books.
A CAPTCHA is a program that can tell whether its user is a human or a computer, by asking the user to copy some distorted text. You’ve probably seen them, either here, or elsewhere on the web. If not, just click here for an example.
reCAPTCHA gets these words from books that the Internet Archive is digitizing. Digitizing books is done by photographically scanning the book’s pages, and then transforming these scans into text using “Optical Character Recognition” (OCR).
All this together means that when you leave a comment, in addition to contributing to the discussion, you are both proving you are a person, not a spambot, and helping humanity’s effort to archive it’s knowledge digitally.
The Problem
Which is all milk and honey, but there’s a problem. As good citizens of the web, and as Wordpress users, BlogLESS utilizes reCAPTCHA’s handy Wordpress Plugin. But, as good citizens, BlogLESS is further committed to web standards. This means that all our HTML and CSS needs to be valid. Unfortunately, the Wordpress reCAPTCHA plugin doesn’t validate XHTML out of the box. (As it turns out, this is not its fault. It actually can’t validate out of the box, which we’ll see.)
The good news is, the fix is easy, once you understand the problem. You don’t need to be a pro to make your Wordpress comments template valid again.
The Fix
First, you’ll need to find the php files that write the reCAPTCHA to your comments template. They are two, although the file names changed between versions. I’ve checked against the lastest (v2.91), and the oldest version I could find (v2.5). If your version is somewhere in the middle of the two, you’ll have to extrapolate a little, but it shouldn’t be hard.
Anyhow, both versions have a file called recaptchalib.php. Version 2.5 has a second file called recaptcha.php, which changed to wp-recaptcha.php by 2.91. In any case, they should both be found in a directory that looks something like this:
Error the first
By 2.6, reCAPTCHA fixed this first error, so if you’re up-to-date, you can skip this step and move on to Error the second below. However, if you’re using 2.5, the fix is very easy. Open recaptchalib.php, and locate lines 126 to 130. These lines contain a complete <noscript> block. Find it and replace it with the following:
<noscript> <iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br /> <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea> <input type="hidden" name="recaptcha_response_field" value="manual_challenge" /> </noscript>';
Error the second
That one was just sloppy, and again, was fixed early in the plugin’s development. Unfortunately, the second validation failure is quite a bit more insidious. It takes place in the main plugin file ([wp-]recaptcha.php). In 2.5, find line 57. In 2.91 it’s line 431. In any case it looks like this:
<style type='text/css'>#submit {display:none;}</style>The w3c tells us that this error is because "The element named above was found in a context where it is not allowed. This could mean that you have incorrectly nested elements — such as a ’style’ element in the ‘body’ section instead of inside ‘head’…" Jackpot.
As it turns out, this puts us in a bit of a jam. Why? First, we’re in a noscript block, so we can’t apply this definition with Javascript (the most obvious choice). Second, the purpose of this definition is to hide a submit button that occurs in our Wordpress comments template and replace it with the one that we create on the following line (59,432) of our plugin file. This means we can’t use an plugin-scope PHP conditional.
So, the somewhat counter-intuitive way to handle this — but the only valid way you’re going to get — is to make two alterations. First, comment out the line that’s causing the trouble:
<!--<style type='text/css'>#submit {display:none;}</style>-->Now, open your comments template, usually:
and find the submit button (any input with id="submit"). Now what we’re going to do is actually only write the submit button for browsers that support javascript. Instead of your defacto submit button, use something like this:
<script type="text/javascript">
//<![CDATA[
/* Cf. http://www.designlessbetter.com/blogless/posts/making-recaptcha-validate */
document.write('<input name="submit" type="submit" id="submit" tabindex="5" value="Post this Comment" />');
//]]>
</script>Awesome!



Comments on this post
1.
Paul,
Thanks for your comment on my blog post about this same issue.
I’m interested in knowing more about how your Javascript addition to comments.php solves the problem. It seems to me that since most browsers have Javascript enabled, this solution outputs multiple ’submit’ buttons in most cases.
I’m glad others are trying to tackle this issue also.
2.
Tom,
You’ll notice that I’m not suggesting that you add a submit button to your comments.php. I’m suggesting that you replace the normal one with one that is output by Javascript. If you think about it, this means that the submit button will now display only for those users with Javascript enabled.
The net effect of this is that users with Javascript enabled get one submit button, and users without get zero. This is identical to the effect created by writing a submit button for all browsers and then setting the ‘display’ style to ‘none’ for browsers with Javascript disabled.
You can see for yourself by disabling Javascript in your browser.
Hope this clears things up,
Paul
3.
Post updated. I still have some tweaking to do to prevent a rogue input field from showing up w/ scripts disabled, but that’s a lower priority. Thanks again!
4.
Awesome, thanks for the information man, I really appreciate it. I will link to this page from the plugin description page. Hopefully the reCAPTCHA developers eventually fix this problem. Thanks for the solution in the meantime though.
5.
@Blaenk - Glad to be of service, and thanks for your hard work maintaining this useful plugin. Thanks for the link also.
@Tom - Thanks for the link and good luck with your rogue field.
6.
Hi - Many thanks for addressing the very issue that I came across (style tag in wrong place). Awesome blog design btw.
7.
Thanks, Narada. Glad to be of service.
8.
Great article. I was searching for some information on the recaptcha plugin for wordpress and found this. There is also another simple article that describes how to include five most used plugins at
http://www.madanrevoor.com/web-designing/wordpress-plugins-five-most-useful-wordpress-plugins-for-your-website
9.
Except you’re cheating with XHTML transitional! ;) In strict mode (the default for the latest Wordpress I believe?) the
iframeelement is not allowed. I replaced theiframewith anobjectinstead. Theiframeis retained for IE, using a conditional comment. Apparently IE won’t load a URI from another domain into anobjectby default.This approach would present problems for some edge case browsers that can support neither JavaScript nor the
objectelement.<!--[if IE]-->
As for the submit buttons, I can’t see the need for hiding the one button and then adding another one. Both are
inputs of type “submit” and both have the same name/value combination. Can’t that wholenoscriptblock be taken out? Or am I missing something obvious? Testing didn’t seem to reveal any problems.10.
Hmmm, the value of a comment preview is displayed above.
11.
Hi Michael.
Glad to hear you’ve found a fix that validates XHTML strict. The Recaptcha plugin comes by default using an
iframe, which works for those of us who validate against the Transitional DTD, so — frankly — the need to replace it it hadn’t occurred to me.On the Javascript tip: To understand what’s going on, you have to view your reCAPTCHA on a browser with Javascript disabled. The way the plugin works when js is disabled is that it hides the default Wordpress comment submit button, replacing it with its own. If it didn’t do this, you’d be able to just submit your comment without entering a CAPTCHA, thus defeating the purpose of the whole thing. As it stands, you have to enter the CAPTCHA, and then it gives you a confirmation code, which you have to paste into a form. The submit button for the form has to authenticate that code before it submits the comment, which the default Wordpress button doesn’t do. (This all gets handled gracefully by the Recaptcha [Javascript] API when js is available.)
The way it does this by default is to hide the Wordpress submit button with CSS. This isn’t valid because the style definition takes place in the body. So what I do instead is remove the CSS
scriptblock from thenoscriptblock in the body (note: with this block in place, the net effect is that the submit button is hidden in non-js browsers, making it visible only in js-enabled browsers), and replace it with a little javascript in the comments template that writes the submit button (note: same net effect).PS. Fixed the
codedefinition in comments. Comment previews would be nice, someday, time permitting. :)Trackbacks