Creative Coding

Creating a Simple Contact Form for Simple Needs


Whether you're starting a simple blog, creating a corporate website or building a creative portfolio with WordPress, a "Contact (Us)" page is (almost) always necessary and it's (almost) always better to have a contact form instead of sharing your e-mail address publicly (spam robots love them, though). Of course, there are plenty of great contact form plugins for WordPress but why bloat up the website with heavy plugins with lots of database queries, when we can use just a lovely, simple custom shortcode plugin instead?

Benefits of Building Your Own Contact Form

Plugins are awesome, but too many of them with lots of functionality you don't need can bloat up your website by using database connections, running extra PHP code, adding CSS stylesheets and JS files to your header... so, at some point, you just want to stay away from existing plugins, regardless of how awesome the plugin is that you want to use.

If you don't know how to code, I must admit that your hands are (kind of) tied and you're bound to use plugins. But if you're familiar with WordPress development at any level (and I'm assuming that you are, since you're still with me) then you should consider the benefits of hacking your own theme or coding your own plugin. Here are the advantages in my mind:

  • Optimization - Using too much code, especially extra code you don't need, can even push your hosting plan's limits in some cases. But even if you have plenty of resources on your server, optimization is always good for your website's health.
  • Cleanliness - Apart from the health of the server, cleaner code can be a huge benefit for your website loading & parsing speed. By coding/hacking on your own, you just use what you need and don't have to load tons of stuff in order to utilize a simple functionality on your website. It's even good for SEO, you know.
  • The joy of taking control - You should never underestimate the power of calling the shots. Taking control on your website definitely makes you a more enthusiastic designer/developer than using a bunch of ready-made code. That's why, even though we provide the full code for those who don't want to, I personally think that you should not copy/paste the code here but write it yourself. Even if you type exactly the same code, you could see how the plugin works and you feel the delight of taking control. Seriously.

The Code

All right, enough with the chit-chat - let's start coding! We're not going to deal with huge amounts of code or any kind of hard work here, so even if you're a beginner at PHP and/or WordPress, you can understand the code by following my lead and researching any part of the code that you don't recognize.

It's possible to put this code directly to your theme's functions.php file, but a better way to go is using it as a plugin. This way when you switch themes, you don't lose functionality and end up with shortcodes being printed in your content. Let's start with the standard plugin information:

Plugin Name: Simple Contact Form Shortcode
Plugin URI:
Description: A simple contact form for simple needs. Usage: <code>[contact email="your@email.address"]</code>
Version: 1.0
Author: Barış Ünver
Author URI:

// This line of comment holds the place of the amazingly simple code we're going to write. So you don't really need to read this.


A Tiny Helper Function: get_the_ip()

As you can guess from the name of the function, we're getting the real IP address of the user, even if the user is connecting through a proxy server. It's not bulletproof, of course, but we're going to use this as an extra bit of information from the user anyways.

Basically, we're going to try to get the different $_SERVER variables: HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP and REMOTE_ADDR, respectively. Here's the code:

function wptuts_get_the_ip() {
	if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
	elseif (isset($_SERVER["HTTP_CLIENT_IP"])) {
		return $_SERVER["HTTP_CLIENT_IP"];
	else {
		return $_SERVER["REMOTE_ADDR"];

The Shortcode

If you follow my posts here on Wptuts+, you know that I absolutely love WordPress' Shortcode API.

I'm going to divide the shortcode into 3 sections to be able to explain it better, but let's not forget to open and close the shortcode function first:

function wptuts_contact_form_sc( $atts ) {

	// This line of comment, too, holds the place of the brilliant yet simple shortcode that creates our contact form. And yet you're still wasting your time to read this comment. Bravo.

add_shortcode( 'contact', 'wptuts_contact_form_sc' );

Attributes of Our Shortcode

We need to set a few attributes in order to stay flexible while still being lightweight. Here's ten:

extract( shortcode_atts( array(
	// if you don't provide an e-mail address, the shortcode will pick the e-mail address of the admin:
	"email" => get_bloginfo( 'admin_email' ),
	"subject" => "",
	"label_name" => "Your Name",
	"label_email" => "Your E-mail Address",
	"label_subject" => "Subject",
	"label_message" => "Your Message",
	"label_submit" => "Submit",
	// the error message when at least one of the required fields are empty:
	"error_empty" => "Please fill in all the required fields.",
	// the error message when the e-mail address is not valid:
	"error_noemail" => "Please enter a valid e-mail address.",
	// and the success message when the e-mail is sent:
	"success" => "Thanks for your e-mail! We'll get back to you as soon as we can."
), $atts ) );

Remember that we're going to reference them in our code as a variable with the attribute's name (e.g. $label_submit).

E-Mailing the E-Mail

This is the most important part of the function, so I'll go ahead and explain the code inside the code, with comment lines:

// if the <form> element is POSTed, run the following code
	$error = false;
	// set the "required fields" to check
	$required_fields = array( "your_name", "email", "message", "subject" );

	// this part fetches everything that has been POSTed, sanitizes them and lets us use them as $form_data['subject']
	foreach ( $_POST as $field => $value ) {
		if ( get_magic_quotes_gpc() ) {
			$value = stripslashes( $value );
		$form_data[$field] = strip_tags( $value );

	// if the required fields are empty, switch $error to TRUE and set the result text to the shortcode attribute named 'error_empty'
	foreach ( $required_fields as $required_field ) {
		$value = trim( $form_data[$required_field] );
		if ( empty( $value ) ) {
			$error = true;
			$result = $error_empty;

	// and if the e-mail is not valid, switch $error to TRUE and set the result text to the shortcode attribute named 'error_noemail'
	if ( ! is_email( $form_data['email'] ) ) {
		$error = true;
		$result = $error_noemail;

	if ( $error == false ) {
		$email_subject = "[" . get_bloginfo( 'name' ) . "] " . $form_data['subject'];
		$email_message = $form_data['message'] . "\n\nIP: " . wptuts_get_the_ip();
		$headers  = "From: " . $form_data['name'] . " <" . $form_data['email'] . ">\n";
		$headers .= "Content-Type: text/plain; charset=UTF-8\n";
		$headers .= "Content-Transfer-Encoding: 8bit\n";
		wp_mail( $email, $email_subject, $email_message, $headers );
		$result = $success;
		$sent = true;
	// but if $error is still FALSE, put together the POSTed variables and send the e-mail!
	if ( $error == false ) {
		// get the website's name and puts it in front of the subject
		$email_subject = "[" . get_bloginfo( 'name' ) . "] " . $form_data['subject'];
		// get the message from the form and add the IP address of the user below it
		$email_message = $form_data['message'] . "\n\nIP: " . wptuts_get_the_ip();
		// set the e-mail headers with the user's name, e-mail address and character encoding
		$headers  = "From: " . $form_data['your_name'] . " <" . $form_data['email'] . ">\n";
		$headers .= "Content-Type: text/plain; charset=UTF-8\n";
		$headers .= "Content-Transfer-Encoding: 8bit\n";
		// send the e-mail with the shortcode attribute named 'email' and the POSTed data
		wp_mail( $email, $email_subject, $email_message, $headers );
		// and set the result text to the shortcode attribute named 'success'
		$result = $success;
		// ...and switch the $sent variable to TRUE
		$sent = true;

The Contact Form

This part is, of course, as important as the previous part. After all, how can the previous code send an e-mail if there's no contact form? :)

// if there's no $result text (meaning there's no error or success, meaning the user just opened the page and did nothing) there's no need to show the $info variable
if ( $result != "" ) {
	$info = '<div class="info">' . $result . '</div>';
// anyways, let's build the form! (remember that we're using shortcode attributes as variables with their names)
$email_form = '<form class="contact-form" method="post" action="' . get_permalink() . '">
		<label for="cf_name">' . $label_name . ':</label>
		<input type="text" name="your_name" id="cf_name" size="50" maxlength="50" value="' . $form_data['your_name'] . '" />
		<label for="cf_email">' . $label_email . ':</label>
		<input type="text" name="email" id="cf_email" size="50" maxlength="50" value="' . $form_data['email'] . '" />
		<label for="cf_subject">' . $label_subject . ':</label>
		<input type="text" name="subject" id="cf_subject" size="50" maxlength="50" value="' . $subject . $form_data['subject'] . '" />
		<label for="cf_message">' . $label_message . ':</label>
		<textarea name="message" id="cf_message" cols="50" rows="15">' . $form_data['message'] . '</textarea>
		<input type="submit" value="' . $label_submit . '" name="send" id="cf_send" />

Tip: If you looked carefully at the HTML code of the contact form, you probably saw the extra $subject variable. Remember the shortcode attribute 'subject' with no default value? This means that you can use the shortcode like this, if you want to set a default subject: [contact subject="Job application"]

The return of the Shortcode

This last bit is pretty simple: Show the success message if the e-mail is sent, or the e-mail form and the error message (if there is one). Here's the code:

if ( $sent == true ) {
	return $info;
} else {
	return $info . $email_form;

We're not showing the form again if the e-mail is sent, but if you want to show it anyways, you could use this simple line instead:

return $info . $email_form;


Of course, the code by itself wouldn't look great. With some make-up, CSS, we can make our form prettier. Add these lines of CSS code into your style.css file of your theme:

.contact-form label, .contact-form input, .contact-form textarea { display: block; margin: 10px 0; }
.contact-form label { font-size: larger; }
.contact-form input { padding: 5px; }
#cf_message { width: 90%; padding: 10px; }
#cf_send { padding: 5px 10px; }

If you did everything right, you will see something similar to the image below:

Screenshot of our contact form

Congratulations, you just built your own contact form shortcode!


This simple contact form is adequate for most websites but if you want to add more fields to it, you just need to edit the form and add the $form_data['name_of_the_new_field'] variables into the $email_message variable (and maybe add the field's name to the $required_fields array.

If you have any ideas on how to improve this code or show your website pages where you used it, please share your comment with us below!

Related Posts
  • Web Design
    Walk Users Through Your Website With Bootstrap TourTour retina
    When you have a web application which requires some getting used to from your users, a walkthrough of the interface is in order. Creating a walkthrough directly on top of the interface makes things very clear, so that's what we're going to build, using Bootstrap Tour.Read More…
  • Web Design
    Implementing the Float Label Form PatternForm float input retina
    Using Matt Smith’s mobile form interaction design as a guide, we will create a stunning form interaction for the web that’s both beautiful and accessible using HTML, CSS and JavaScript.Read More…
  • Code
    HTML & CSS
    Mobile First With Bootstrap 3Bootstrap 3 preview
    Ok so a couple of weeks now, on it's very own two year anniversary Mark Otto and the rest of the guys responsible for the develop and maintenance of Bootstrap announced the official release of the framework's third version, and it came on steroids, let's see what we're getting.Read More…
  • Web Design
    Foundation for Beginners: Custom Forms and SwitchesFoundation form retina
    Following on from our look at buttons in Zurb's Foundation, let's now take a look at custom forms and switches. During this tutorial we're going to work on an exercise; a contact form which you can add to your projects or just play around with. Once we've built that, we'll move onto other form elements.Read More…
  • Code
    Intro to Flask: Adding a Contact PageFlask
    In the previous article in this mini-series, we leveraged Flask to build a simple website that contains "Home" and "About" pages using a generalized workflow that we can apply to other Flask-based web apps. In this lesson, I'll demonstrate how to add a "Contact" page that allow users to send you messages.Read More…
  • Code
    Creative Coding
    Creating Nifty Petitions Inside Your PostsCreating nifty petitions inside your posts 200
    WordPress is a great multi-purpose platform. You can create many websites with many different purposes: a corporate website, a photography showcase, a news portal, a restaurant website with interactive menus... Oh, and blogs, of course. You can blog with WordPress. Forgot about that. Strangely, non-profit organizations tend to overlook this flexibility and take advantage of it. In this tutorial, we're going to show how to create a simple petition script to demonstrate how an organization can benefit from WordPress.Read More…