Optimize and style Contact Form 7 for WordPress
One of my favorite WordPress plugins is Contact Form 7 which I use on several of my WordPress based sites. Even though it’s highly customizable and configurable I have a few gripes with some hard coded functions in it. You can always edit the plugin file, which I did at first, but then you have to reapply your edits every time the plugin gets updated, which can be cumbersome as this plugin gets updated quite often. So instead of keep editing the plugin file on every update I created some overrides instead.
The Issues
- The url to the AJAX loader symbol is hardcoded into the plugin, so if you don’t use a white background in your theme the loading symbol looks quite ugly. If you replace the default icon with your own it gets overwritten on each plugin update.
- The javascripts for the plugin gets loaded on every single page of the site no matter if the plugin is used or not on that page, which adds unnecessary loading time where it’s not needed.
- The path to the stylesheet for the validation and submit messages is also hardcoded into the plugin, and if you edit the stylesheet to fit your theme, the edits gets lost on each update, and you have to reupload your custom stylesheet for the plugin.
The Solutions
So to not have to edit the plugin file, I added a few overrides in my theme’s functions.php file instead to change the behaviour of the plugin where needed.
Let’s start by taking care of the AJAX loading symbol. To change the path to the gif file I use a regular expression to update the url.
1 2 3 4 5 6 7 8 9 10 11 | // Change the URL to the ajax-loader image function change_wpcf7_ajax_loader($content) { if ( is_page('contact') ) { $string = $content; $pattern = '/(<img class="ajax-loader" style="visibility: hidden;" alt="ajax loader" src=")(.*)(" \/>)/i'; $replacement = "$1".get_template_directory_uri()."/images/ajax-loader.gif$3"; $content = preg_replace($pattern, $replacement, $string); } return $content; } add_filter( 'the_content', 'change_wpcf7_ajax_loader', 100 ); |
This function filters the content, tracks down the AJAX loader tag and replaces the URL with a path to the current {theme folder}/images/ajax-loader.gif. So you can have your own custom AJAX loader stored in your theme folder instead, untouched on each plugin update. I added the if( is_page(contact) ) {} to the function to make sure the filter only runs on pages where needed, to not waste CPU cycles on pages where the plugin is not used. Contact is the name of the page where I use the form, change it to the name, or names of pages where you use the plugin.
Okay, now let’s see take care of the script loading on each page of the site.
1 2 3 4 5 6 7 8 | // Add the Contact Form 7 scripts on selected pages function add_wpcf7_scripts() { if ( is_page('contact') ) wpcf7_enqueue_scripts(); } if ( ! is_admin() && WPCF7_LOAD_JS ) remove_action( 'init', 'wpcf7_enqueue_scripts' ); add_action( 'wp', 'add_wpcf7_scripts' ); |
This function removes the call to add the Contact Form 7 scripts on every page, and then adds back the call where needed, in my case I add them back at the page called contact, but change that to whatever works for you.
And finally, let’s deal with the stylesheet.
1 2 3 4 | function remove_wpcf7_stylesheet() { remove_action( 'wp_head', 'wpcf7_wp_head' ); } add_action( 'init' , 'remove_wpcf7_stylesheet' ); |
Here I actually remove the call to the stylesheet completely. As I have made my own style that fits my theme, I don’t use the default stylings. If you use the default stylings but just want it to load where needed, you could use an is_page condition like on the loading of the scripts. I could have put the Contact Form 7 Stylesheet in the theme folder using the same technique as on the AJAX loader to leave it untouched on a plugin update, but as I like to keep the calls to external files to a minimum to have the site load as fast as possible, I just put the WPCF7 CSS styles directly in my default style.css of my theme instead and got rid of the plugin stylesheet loading.
The Final Code
And here is what the final code looks like, ready to get pasted into the functions.php file in the theme you are using.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /** * Functions: Optimize and style Contact Form 7 - WPCF7 * */ // Remove the default Contact Form 7 Stylesheet function remove_wpcf7_stylesheet() { remove_action( 'wp_head', 'wpcf7_wp_head' ); } // Add the Contact Form 7 scripts on selected pages function add_wpcf7_scripts() { if ( is_page('contact') ) wpcf7_enqueue_scripts(); } // Change the URL to the ajax-loader image function change_wpcf7_ajax_loader($content) { if ( is_page('contact') ) { $string = $content; $pattern = '/(<img class="ajax-loader" style="visibility: hidden;" alt="ajax loader" src=")(.*)(" \/>)/i'; $replacement = "$1".get_template_directory_uri()."/images/ajax-loader.gif$3"; $content = preg_replace($pattern, $replacement, $string); } return $content; } // If the Contact Form 7 Exists, do the tweaks if ( function_exists('wpcf7_contact_form') ) { if ( ! is_admin() && WPCF7_LOAD_JS ) remove_action( 'init', 'wpcf7_enqueue_scripts' ); add_action( 'wp', 'add_wpcf7_scripts' ); add_action( 'init' , 'remove_wpcf7_stylesheet' ); add_filter( 'the_content', 'change_wpcf7_ajax_loader', 100 ); } |
This tweak was published when Contact Form 7 was at version 1.10, and should continue to work just fine as long as no major changes is made to the inner workings of the plugin.






KennethJune 9, 2009
thanks for the tips. this is exactly what I was looking for. I posted a message on the WP forums just yesterday and someone directed me here… thanks again! :)
( )JohanJune 9, 2009
You’re welcome. I am happy you find it useful. :)
( )KennethJune 9, 2009
Hello again. I got it working perfect but I do have one minor problem with the way the SPAN tags are hard coded into forms.
Could you whip up a function to remove the
??
I did some searching and found it in the /includes/classes.php file.
I could just remove it from the plugin, but as you said already, with each upgrade I would have to reapply the edits.
( )KennethJune 9, 2009
oops. I guess HTML tags are stripped from comments.
( )my question again…
Could you whip up a function to remove the
span=class wpcf7-form-control-wrap from the forms?
JohanJune 12, 2009
Hi again Kenneth,
If you simply want to strip away the span tags surrounding the form elements, you can do it like this:
which would get rid of the spans, leaving just the form elements. One drawback with removing the spans is that if you use the ajax validation for required fields, it doesn’t know on which field to display the validation required box over, as the plugin uses the spans to identify the fields.
( )JolidogJune 17, 2009
hello, I’m trying to implement your code, but I’m getting this error message:
Warning: preg_replace() [function.preg-replace]: Unknown modifier in function change_wpcf7_ajax_loader.
What can I be doing wrong?
I’m using wpcf7 version 1.10, wordpress 2.7 and an Hybrid subtheme.
the other functions are working correctly! Thank you!
( )JohanJune 18, 2009
Hi,
You’re not doing anything wrong. :) For some reason WordPress had stripped away a \ from my code in the post when I saved the post, so that’s why it didn’t work.
Thanks for bringing it to my attention. I’ve added back the missing \ in the code above, and now the preg_replace code snippet should work as expected.
( )Gary JonesJuly 7, 2009
My question is pretty basic. I’ve posted it on the developers site twice but got no response.
When I installed the plug-in I noticed a number of CSS files and screenshots of different custom forms in a directory called /styling. All I want to do is use one of these styles for my client, but I cannot find any instructions on how to do this. Appreciate any help.
( )JohanJuly 8, 2009
Hi Gary,
I think you are referring to the plugin cforms II which I have limited experience with, so I don’t really have any insight in how to use different styles for that one, sorry.
The plugin I wrote about in the post above is another one, Contact Form 7.
- Johan
( )Gary JonesJuly 8, 2009
Thanks, Johan. No, is is Contact Form 7 I am referring to. When I downloaded the plug-in it shows a number of different styles, but I can’t figure out how to use them. Appreciate any help. Their website is useless.
( )JohanJuly 10, 2009
Hm, I’ve only seen a couple of different stylings included in the cforms package. The current version of CF7 does only have some stylings for the ajax handling. Where in CF7 have you found these options, or are you maybe running an older version?
Johan
( )Gary JonesJuly 10, 2009
When you download the latest version it creates a subdirectory called /styling. In this directory there are various JPG files showing different styles, for example fancy_dark, and the CSS files to match, but there are no instructions on how to use a different style. I’ve searched everywhere. Not only do I need to use one of these styles for a client site, but I need to modify the contents to meet their needs.
( )JohanJuly 10, 2009
Well, fancy_dark (fancy_blue, fancy_brown, monospace_dark and so on) are styles included with the cforms plugin, so there seems to be some sort of mixup with the files there if you have intended to run Contact Form 7 instead.
If it really is Contact Form 7 you intend to use, make sure to uninstall the current plugin and get rid of all files you have installed in the plugin folder and grab the latest version of Contact Form 7 from here and you should get a completely different styling included (which is simply called stylesheet.css, located in the contact-form-7 folder and can be edited to your need).
( )FelixJuly 13, 2009
Huge thanks! Great job!
( )VenesaJuly 21, 2009
Not sure if you can assist but I have a little problem with CF7 version 1.10.1.
The contact form will only work from a firefox system. You cannot email from the contact form if you use Vista or XP.
The previous version worked perfectly. Any ideas. WP 2.7.1 is using Ubuntu.
( )DanJuly 21, 2009
Hi,
I would look to forward my Contact Form to a new page upon completion. Would you know how to do this? I was thinking I could add some code to the additional settings field, however I have had no luck. Any suggestions?
Thanks,
Dan
( )SebastianNovember 2, 2009
Dude, this shows the solution (simple).
http://www.grapethinking.com/wordpress-contact-form-7-plugin-landing-pag
( )pravinJuly 30, 2009
Hello, I had “page not found”(Error 404) error on form submission.
I rectified it by adding
wp_footer();
line in footer.php of my theme.
Now it is working fine.
( )TKAugust 9, 2009
Exactly what I was in need of. Thank you very much!
( )Dale JacobsAugust 20, 2009
Hey there,
This was just what I was looking for, to reduce the wp_head code, thanks!
I am having one issue though. I have 4 contact forms on my site, so I was trying to use an array with is_page… IE:
if ( is_page(‘168′, ‘1025′) )
or
if ( is_page(‘contact-and-submissions’,’story-submissions’) )
Sadly it only adds the contact form 7 scripts for the first page in the array, not the second.
Anything you can think of?
Regardless, happy to have at least removed the style sheet from loading on the page!
Dale Jacobs
( )JohanAugust 20, 2009
Hi Dale,
Yes, you need to provide the array operator for is_page to work with several pages. ie. is_page(array(20,40,50))
Here is a few examples, first with page names:
Or with page id’s:
Or a combination of names and id’s:
So any combination works. And in your case it would be like this:
Hope this helps. :)
( )Cheers!
Dale JacobsAugust 20, 2009
wow you rock, thanks for the quick reply!!
Dale
( )רופאי שינייםSeptember 28, 2009
very useful. thanks!
( )PatOctober 1, 2009
This is a great article, and I wish I could implement this code in my function.php file, but for some reason, it just does not work at all.
I am trying to build a child theme based on Thematic framework. It might have someting to do with hooks, or path, I do not know.
Any suggestions?
Thanks
( )JohanOctober 2, 2009
Hi Pat,
I wrote this entry when Contact Form 7 was at version 1.10, and has worked on all v1.x versions since.
Recently Contact Form 7 version 2.x was released and some function names were changed so the code above doesn’t work properly for v2.x.
I guess you have tried to get it to work with the latest 2.x version.
The code to change the AJAX loader image still works though, but the stylesheet and javascript tweaks needs a little modifcation.
To remove the stylesheet was done like this in 1.x
remove_action( ‘wp_head’, ‘wpcf7_wp_head’ );
But in 2.x it should be
And to remove the javascript was done like this in 1.x
remove_action( ‘init’, ‘wpcf7_enqueue_scripts’ );
in 2.x it should be
So if you modify these two lines I believe it should work properly for you. I’ll update the article with this information when I get some more time. :)
Cheers!
( )Johan
PatOctober 2, 2009
Thank you Johan for your reply.
Regarding the Ajax loader image, in my case, it does’t work. The path refers to the Thematic image folder instead of my child theme:
:-(
Now, for the stylesheet and the javascripts, I followed Justin Tadlock’s suggestions, and came up with this code:
`
/*
* Functions: Optimize Contact Form 7
*
*/
function deregister_cf7_js() {
if ( !is_page(‘contact’) ) {
wp_deregister_script( ‘contact-form-7′ );
}
}
add_action( ‘wp_print_scripts’, ‘deregister_cf7_js’, 100 );
function deregister_ct7_styles() {
wp_deregister_style( ‘contact-form-7′ );
}
add_action( ‘wp_print_styles’, ‘deregister_ct7_styles’, 100 );
`
ref.: http://justintadlock.com/archives/2009/08/06/how-to-disable-scripts-and-styles
Thanks for your help.
Now I need to figure out how to point to my child theme.
Pat
( )PatOctober 2, 2009
Ah! I found the solution:
Quote: In the event a child theme is being used, the parent theme directory URI will be returned, not the child theme directory URI (use get_stylesheet_directory_uri() instead)
ref.: http://codex.wordpress.org/Function_Reference/get_template_directory_uri
So, if you use a child theme, like I do, the code is this:
( )// Change the URL to the ajax-loader image
function change_wpcf7_ajax_loader($content) {
if ( is_page('contact') ) {
$string = $content;
$pattern = '/()/i';
$replacement = "$1". get_stylesheet_directory_uri()."/images/ajax-loader.gif$3";
$content = preg_replace($pattern, $replacement, $string);
}
return $content;
}
add_filter( 'the_content', 'change_wpcf7_ajax_loader', 100 );
JohanOctober 2, 2009
Awesome!
I was just about to check out the thematic theme, but I’m happy to see you got it sorted out anyway! Excellent! :)
Johan
( )ChristopheFebruary 26, 2010
Wonderful… Couldn’t solve this problem for 2 days!
( )Thanks a lot ;)
DanMarch 5, 2010
Thank you so much for this.
( )