EthicsComputerCourses
Join training +91 90532 10052

Contact & Enquiry Forms

WordPress · Lesson 14 of 30 Intermediate 7 min read Updated

By the end of this lesson you will add a working enquiry form to your site, protect it from spam bots and make sure the emails actually reach your inbox. You will also see how a developer builds a small secure form in code, which you will reuse in the final project.

A form is the reception desk of your website. A visitor walks in, fills in a slip, and someone in the office must receive it. If the slip gets lost or the desk is flooded with junk, you lose real customers.

Your options

WordPress core does not include a full form builder, so most sites use a plugin. Popular choices in the WordPress.org directory include Contact Form 7, WPForms (free "Lite" version plus paid plans), Fluent Forms and the forms module in Jetpack. All of them let you add a form as a block.

ApproachGood forThings to check
Form pluginMost sites; no codeSpam protection, whether entries are saved, export
Custom codeDevelopers who want a small, exact formYou must handle security and email yourself
Embedded third-party formGoogle Forms and similarLooks less integrated; data stored elsewhere

Use the two-minute safety check from Choosing Plugins Safely for any form plugin.

Adding a form with a plugin, step by step

The steps are similar in every form plugin. Here is the general flow.

Step 1: Install and activate your chosen form plugin.

Step 2: Open its menu (for example Contact or Forms) and create a new form.

Step 3: Add fields: Name, Phone, Email, Class (a dropdown with 9, 10, 11, 12) and Message. Mark Name and Phone as required.

Step 4: In the form's notification or mail settings, set To as your office email and the Subject as "New enquiry from the website".

Step 5: Save the form. Open your Contact page, add the plugin's form block and choose your form.

Step 6: Publish and submit a test entry. You should see a thank-you message on screen and an email in your inbox within a minute or two.

If the email does not arrive, read the next section.

Making sure emails arrive

WordPress sends email with a function called wp_mail(). By default it uses the server's basic mail system. Many inbox providers distrust these messages, so they land in spam or vanish.

The fix is to send through a proper mail service using SMTP (Simple Mail Transfer Protocol), the standard way mail servers talk. An SMTP plugin, such as WP Mail SMTP or FluentSMTP, connects WordPress to your email provider (your host's mailbox, Google Workspace, Zoho Mail or a transactional email service).

  1. Step 1: Create a mailbox such as website@brightfuture.in with your provider.
  2. Step 2: Install an SMTP plugin and enter the provider's SMTP details or connect with the provider's sign-in option.
  3. Step 3: Use the plugin's Send test email button.
  4. Step 4: Ask your domain provider to add the SPF and DKIM DNS records that your mail provider gives you. These prove that your server is allowed to send mail for your domain.

Store SMTP passwords only in the plugin settings or wp-config.php, never inside a page or a shared document.

Stopping spam

Bots fill forms with junk links. Use more than one layer:

  • Honeypot: a hidden field that humans never see. Bots fill it, so any entry with it filled is rejected.
  • CAPTCHA services such as Cloudflare Turnstile or Google reCAPTCHA, which most form plugins support.
  • Akismet or a similar spam filter service.
  • Validation: a phone field that accepts only digits stops many junk entries.

Collecting personal data responsibly

An enquiry form collects personal data: names, phone numbers, emails. India's Digital Personal Data Protection Act, 2023 and its rules set duties for anyone who collects such data. Without giving legal advice, good practice is:

  • collect only what you need (a coaching enquiry rarely needs a home address)
  • say clearly why you collect it, near the form, and link to your Privacy Policy
  • do not add people to marketing lists unless they agree
  • delete old enquiries you no longer need

Check the current rules or ask a lawyer for anything beyond a simple enquiry form.

A custom form in code

Developers sometimes want a small form with no extra plugin. Here is a secure enquiry form added with a shortcode (a tag like [bf_enquiry_form] that you place in a Shortcode block). You will learn shortcodes properly in Shortcodes vs Blocks.

First, the form. It posts to admin-post.php, WordPress's built-in address for handling form submissions:

PHP
<?php
add_shortcode( 'bf_enquiry_form', function () {
    if ( isset( $_GET['enquiry'] ) && 'sent' === $_GET['enquiry'] ) {
        return '<p>Thank you! Our office will call you within one working day.</p>';
    }
    ob_start();
    ?>
    <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
        <input type="hidden" name="action" value="bf_enquiry">
        <?php wp_nonce_field( 'bf_enquiry', 'bf_nonce' ); ?>
        <p><label>Name <input type="text" name="bf_name" required></label></p>
        <p><label>Phone <input type="tel" name="bf_phone" pattern="[0-9]{10}" required></label></p>
        <p class="bf-hp" hidden><label>Leave empty <input type="text" name="bf_website"></label></p>
        <p><button type="submit">Send enquiry</button></p>
    </form>
    <?php
    return ob_get_clean();
} );

Three security ideas appear here:

  • wp_nonce_field() adds a nonce, a one-time token that proves the form came from your site.
  • esc_url() makes the address safe to print inside HTML.
  • bf_website is the hidden honeypot field.

Next, the handler. WordPress calls admin_post_nopriv_bf_enquiry for logged-out visitors and admin_post_bf_enquiry for logged-in users:

PHP
<?php
function bf_handle_enquiry() {
    $nonce = isset( $_POST['bf_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['bf_nonce'] ) ) : '';
    if ( ! wp_verify_nonce( $nonce, 'bf_enquiry' ) ) {
        wp_die( 'Security check failed. Please go back and try again.' );
    }
    if ( ! empty( $_POST['bf_website'] ) ) {
        wp_die( 'Spam detected.' ); // the honeypot was filled
    }

    $name  = sanitize_text_field( wp_unslash( $_POST['bf_name'] ?? '' ) );
    $phone = preg_replace( '/\D/', '', wp_unslash( $_POST['bf_phone'] ?? '' ) );

    if ( '' === $name || 10 !== strlen( $phone ) ) {
        wp_die( 'Please enter your name and a 10-digit phone number.' );
    }

    wp_mail(
        get_option( 'admin_email' ),
        'New enquiry from ' . $name,
        "Name: $name\nPhone: $phone"
    );

    $back = wp_get_referer() ?: home_url( '/' );
    wp_safe_redirect( add_query_arg( 'enquiry', 'sent', $back ) );
    exit;
}
add_action( 'admin_post_nopriv_bf_enquiry', 'bf_handle_enquiry' );
add_action( 'admin_post_bf_enquiry', 'bf_handle_enquiry' );

When Rohan submits "Rohan Verma" and "98765 43210", the office receives an email like this:

Output
Subject: New enquiry from Rohan Verma
Name: Rohan Verma
Phone: 9876543210

Rohan is redirected back to the same page and sees the thank-you message. Notice that the spaces in the phone number were removed by preg_replace(), so "98765 43210" still passes the 10-digit check.

Common mistakes

  • Never testing the form after launch. Submit a test entry every month; settings and mail servers change.
  • Relying on server mail. Use SMTP and set up SPF and DKIM.
  • Sending enquiries to a personal Gmail only. If that person leaves, enquiries go with them. Use an office address.
  • Asking for too much data. Every extra field lowers the number of people who finish the form.
  • Skipping the nonce and sanitising in custom code.

Key points

  • WordPress has no full form builder in core; use a trusted form plugin or careful custom code.
  • wp_mail() sends mail; use an SMTP plugin plus SPF and DKIM records so emails arrive.
  • Fight spam with a honeypot, a CAPTCHA service and validation.
  • Collect only the personal data you need and explain why, linking to your Privacy Policy.
  • Custom forms need a nonce, sanitised input, escaped output and a redirect after success.

Exercise

Extend the custom form with an optional Class dropdown (9, 10, 11, 12). In the handler, accept only those four values; anything else should be saved as "Not given". Add the class to the email body.

Show solution

Add the field to the form:

HTML
<p><label>Class
  <select name="bf_class">
    <option value="">Choose</option>
    <option>9</option><option>10</option><option>11</option><option>12</option>
  </select>
</label></p>

In the handler, check against an allow-list before using it:

PHP
<?php
$class = sanitize_text_field( wp_unslash( $_POST['bf_class'] ?? '' ) );
if ( ! in_array( $class, [ '9', '10', '11', '12' ], true ) ) {
    $class = 'Not given';
}
$body = "Name: $name\nPhone: $phone\nClass: $class";

An allow-list is safer than trying to block bad values, because anything not on the list is rejected.

Quick Quiz

1. Why do WordPress emails often land in spam?

2. What is a honeypot field?

3. Which hook handles a form posted to admin-post.php by a logged-out visitor with action set to bf_enquiry?

4. What does wp_nonce_field() add to a form?

Learn WordPress with a mentor

Free lessons get you started. Our WordPress & Website Building training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call