WordPress: Extending the Contact Form 7 Plugin

There are tonnes of good plugins for displaying contact forms on your WordPress blog, even a simple comment form without displaying the comments would do just fine, but let’s speak about one called Contact Form 7 written by Takayuki Miyoshi. I don’t think there’s a reason behind the number 7, perhaps it meant the year 2007, when Takayuki published the first version of his plugin.

First of all I’d like to note that he plugin is very well written, it’s very, and I mean VERY flexible, and only due to its flexibility we’re allowed to extend its functionaltiy. Of course Takayuki’s probably missed some filters and hooks that other plugin and theme developers would love to see, but the modules directory is good enough, despiting the fact that it’ll probably be erased and rewritten after an ongoing plugin update.

Now, suppose you have designed a placed a contact form in your sidebar as a widget, using the Contact Form 7 shortcode. It’s got all the necessary fields, AJAX powered form, Akismet spam check & so on. But we’re missing something. Contact Form 7 is located in your sidebar, which means that you’re displaying it on most (if not all) of your posts and pages. Now when somebody writes a message via your contact form, you’re left guessing which page the visitor was viewing while typing.

This may be crucial in e-commerce situations, say you’re selling books from your blog, and a visitor contacts you to ask “who’s the publisher of this book?” or “how many pages does this book have?”. So you received an e-mail and you have no idea which book is being mentioned. You’re lucky if you only work with one publisher, or all your books are 100 pages long ;)

Anyways, let’s create a new file in the modules folder of the plugin, and call it sourceurl.php:

wpcf7_add_shortcode('sourceurl', 'wpcf7_sourceurl_shortcode_handler', true);

function wpcf7_sourceurl_shortcode_handler($tag) {
	if (!is_array($tag)) return '';

	$name = $tag['name'];
	if (empty($name)) return '';

	$html = '<input type="hidden" name="' . $name . '" value="http://' . $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"] . '" />';
	return $html;
}

This is very easy to understand once you’ve read (and understood) what’s written in the other modules. Try to take a look at text.php for a while, it includes the code for both text and e-mail fields. I copied some of the code for the text fields, simplified it a little and removed the validation process (why validate our own URL?), and voila, 12 lines of code ;)

Save the file and go to your Contact Form 7 settings in your WordPress admin panel. Select the contact form you’d like to add source URL to and in the part where it says “Form” add the new short code (sourceurl) and give it a name (thesource):

[sourceurl thesource]

Now you can use “thesource” in your Mail part of the contact form settings, say:

Source URL: <a href="[thesource]">[thesource]</a><br />

Then look for the new Source URL in your e-mail ;) So if you’ve used more than one contact form on several different pages, just to distinguish them in your emails, you can merge them into one now. You can use a similar way to add other interesting data to your e-mails such as, say the user’s IP address for instance, browser capabilities, etc.

About the author

Konstantin Kovshenin

WordPress Core Contributor, ex-Automattician, public speaker and consultant, enjoying life in Moscow. I blog about tech, WordPress and DevOps.

29 comments

  • Hey – any idea how I can get the_excerpt as a hidden field into the form and emailed to me when the user submits the form?

    • Toby, sure, same way as described above, but you should use get_the_excerpt() in the return value. Then use the appropriate short code.

  • Contact Form 7's spam protection isn't getting the job done for me. I was hoping I can find some info on how to improve its spam protection. Please let me know if you have any solutions.

    • Zadling, I believe CF7's spam protection is based on Akismet, which does 99% of the job.. Anyway you can always add a captcha if you're getting loads of spam ;)

  • Great info, thanks for sharing on the interwebs. Question, how could one go about modifying this in a fashion to include IP address and browser?

    • Same way I guess, it shouldn't be too complicated, trust me ;) Make sure you post a code snippet when you figure it out :)

  • Hmm… tried this and instead of the shortcode working on the form, the page is just printing the shortcode as if it weren't shortcode but plain text.

    Here's what I did:
    a) Copied the text.php in the Modules folder, renamed it,
    b) removed the relevant code, pasted in the above extension verbatim,
    c) added the shortcode [sourceurl thesource] to the Form field
    d) Added [thesource] to the message body.

    Result:
    [sourceurl thesource] is printed as plain text on the test page showing the form.

    Any ideas? Do I have to set CF7 to recognize the module somehow?

  • Thanks a bunch !! This worked great. I had to add the tags that were left out because I assumed it may not need them. I was wrong. Maybe you can update the code snippet for others.

    Works great !!

  • Hey, How would I use something like this so I could make the email to field change depending on a value I set using a custom meta box.

    Example – I want each property site to have the same form, but I simply want to use a custom meta box to specify the agents email so that the email goes to the particular advertiser? any ideas?

    • David, not sure about this one, might need some extra contact form hi-jacking. But first thing that comes in to my mind is using the same technique I described above to define a shortcode, say [advertiser] and have it use global $post and get_post_custom to retrieve the post meta.

  • Does anybody have any knowledge of an extension using Contact Form7 to load inputted information from the form into a table in the MySQL data base?

  • Hi Kovshenin

    First thanks a lot for the code. It's just what I needed.

    Second. I also needed to know the persons Ip Address as Mark said and I did it. For those looking for this, here is the code (very similar to what Kovshenin did ):
    <code>
    wpcf7_add_shortcode('ipaddress', 'wpcf7_ipaddress_shortcode_handler', true);

    function wpcf7_ipaddress_shortcode_handler($tag) {
    if (!is_array($tag)) return '';

    $name = $tag['name'];
    if (empty($name)) return '';

    $html = '';
    return $html;
    }
    </code>

  • Sorry, WordPress filtered the input field:

    $html = '*input type="hidden" name="' . $name . '" value="' . $_SERVER['REMOTE_ADDR'] . '" /*';

    ATTENTION: Remove * and use the appropriate html (I only did this so that wordpress wouldn't filter it again)

    Cheers Kovshenin and thanks again ;)

  • This is what i was looking for Konstantin…

    I needed a solution were i could track if the user was coming from a GooglePPC Ad, or via a search engine. this covers the basics for what i needed..

    superb,

  • Thank you so much for this great post, I was looking for something like this and it helped me alot. Great post…

  • Hi, will this work with creating custom tags in the form (front facing) script?

    I have a custom form on the side of each page and when someone submits that it will go to the main, cf7 powered, form prefilled with the visitor details from my custome form.

    So I'll need to prefill text inputs with things like name, email address etc.

    Any ideas??

    Cheers