28 Nov 2012
Below is a simple solution to stupid, yet annoying spam problem. I never actually realised how bad it can get until I started this blog. Not that I get a lot of visitors and genuine commentators, but for some reason I used to get approximately 10 spammy comments per day - that's across all blog posts.
TL;DR
The idea for this spam block is very simple: apparently spam bots rely on the presence of certain fields in your HTML comment form. If you change names of those fields on the server, that will confuse hell out of those poor spambots that try to help some shady SEO dudes to make their living. It doesn't have to be a big change - just adding an extra "1" or "a" in front of every value for "name" attribute on ‹input › tags.
We do need to make sure that genuine posters are still able to use the comments form though. So we need to make those changes transparent to them. One thing that distinguishes genuine users from spambots is the presence of, well, browser. So we can use a simple piece of Javascript to revert the changes made on server.
Drawbacks/Disclaimer
This method requires editing of your comments.php file. Since this file is a part of the Wordpress installation, it can be overwritten whenever you happen to upgrade your Wordpress or theme next time, thus removing your superior, tailor-made spam protection. So please consider this drawback and whether that's a showstopper for you at all.
Step by Step Guide
comment_form(array(
'fields' => array(
'author' => sprintf('<input name="author" type="text" placeholder="%s" value="' . esc_attr( $commenter['comment_author'] ) . '" />', __(Name', 'origami')),
'email' => sprintf('<input name="email" type="text" placeholder="%s" value="' . esc_attr( $commenter['comment_author_email'] ) . '" />', __('Email', 'origami')),
'url' => sprintf('<input name="url" type="text" placeholder="%s" value="' . esc_attr( $commenter['comment_author_url'] ) . '" />', __('Website', 'origami')),
comment_form(array(
'fields' => array(
'author' => sprintf('<input name="zauthor" type="text" placeholder="%s" value="' . esc_attr( $commenter['comment_author'] ) . '" />', __(Name', 'origami')),
'email' => sprintf('<input name="zemail" type="text" placeholder="%s" value="' . esc_attr( $commenter['comment_author_email'] ) . '" />', __('Email', 'origami')),
'url' => sprintf('<input name="zurl" type="text" placeholder="%s" value="' . esc_attr( $commenter['comment_author_url'] ) . '" />', __('Website', 'origami')),
),
(function($) {
$(document).ready(function() {
$('#commentform').children('[name^="z"]').each(
function(i, e) {
$(e).attr('name', $(e).attr('name').substring(1))
})
})
})(jQuery)
Notice how we specifically select only elements with name that starts with the arbitrary character (in this case "z") in our $('#commentform').children('[name^="z"]') statement? So if you were to use some other character instead, make sure you modify the script accordingly
Hope you find this helpful. Let me know of any comments, concerns or questions.