Dynamically set who receives contact form email

I’m working on a gym’s website that has profiles for all of their trainers, and includes an “Email Me” link. I didn’t want to expose their email publicly, so I’m using a contact form and passing their “Trainer ID” (the post ID of the trainer’s page) in the URL string. Ex: /contact-a-trainer?trainer=29

You could do the same thing with a dropdown menu of people to contact. Use their name as the ‘Label’ and the post ID as the ‘Value’.  Then when processing the email, use the post ID from the field they selected to get the email address.

Another common use case for this is an “Email the Author” feature, so readers can send an email directly to the author of a post without knowing their email address. I implemented this recently on Denison Forum (here’s the code).

This tutorial is specifically for WPForms, but the same concept could be used for other form plugins – you would just need to figure out the appropriate filters. You don’t need the premium version for this; the free WPForms Lite will work just fine.

I’ve placed the following code in my core functionality plugin. You could also put it in your theme’s functions.php file.

* Core Functionality Plugin
* @package CoreFunctionality
* @since 1.0.0
* @copyright Copyright (c) 2014, Bill Erickson & Jared Atchison
* @license GPL-2.0+
// Trainer Form
define( 'EA_TRAINER_FORM_ID', 160 );
// Hidden field we're using for trainer ID
// In WPForms, set default value to {query_var key="trainer"}
define( 'EA_TRAINER_FIELD_ID', 4 );
* Adds trainer photo and name at top of form
* @author Bill Erickson
* @link http://www.billerickson.net/contact-form-dynamic-notification/
* @param array $form_data, form data
function ea_trainer_on_form( $form_data ) {
// Only run on the 'Contact a Trainer' form, and if a trainer is specified in the URL
if( !( EA_TRAINER_FORM_ID == $form_data['id'] && isset( $_GET['trainer'] ) ) )
// Display trainer
$trainer = intval( $_GET['trainer'] );
$name = get_the_title( $trainer );
$photo = get_the_post_thumbnail( $trainer, 'thumbnail', array( 'class' => 'alignleft' ) );
echo '<h2 class="trainer">' . $photo . $name . '</h2>';
add_action( 'wpforms_frontend_output', 'ea_trainer_on_form', 9 );
* Use trainer email address
* @author Bill Erickson
* @link http://www.billerickson.net/contact-form-dynamic-notification/
* @param array $email, contains all the information used to build email notification (address, message...)
* @param array $fields, form fields
* @param array $entry, form entry
* @param array $form_data, form data
* @return array $email
function ea_trainer_email_address( $email, $fields, $entry, $form_data ) {
if( !( EA_TRAINER_FORM_ID == $form_data['id'] ) )
return $email;
$trainer = false;
foreach( $fields as $field) {
if( EA_TRAINER_FIELD_ID == $field['id'] ) {
$trainer = intval( $field['value'] );
if( ! $trainer )
return $email;
$trainer_email = is_email( get_post_meta( $trainer, 'ea_trainer_email', true ) );
if( !empty( $trainer_email ) )
$email['address'] = array( $trainer_email );
return $email;
add_filter( 'wpforms_entry_email_atts', 'ea_trainer_email_address', 10, 4 );

On Line 12 I’ve defined the Form ID. I then use this constant in the two following functions. This way, if I ever need to change the form ID I can do it once and it applies everywhere.

Lines 21-34 add a header to the top of the form. I check to see if a trainer has been specified ( $_GET['trainer'] ) and that we’re on the right form, then display the trainer’s name ( get_the_title() ) and photo ( get_the_post_thumbnail() ). I’ve hooked this to wpforms_frontend_output with a priority of 9. The actual form fields use that hook and a priority of 10 so this puts it right before the form fields.

Lines 47-59 change the form’s To email address to the trainers. I’m using the wpforms_entry_email_atts filter which lets you modify the email attributes right before it is sent. First I make sure we’re on the right form and that a trainer has been specified. We’re using a post meta field named ea_trainer_email for the email address, so I grab that with get_post_meta() and run it through is_email() to make sure it’s a properly formatted email address. If it is, I set that as the To email address.

Note that every time I call $_GET['trainer'] I wrap it in intval(). This sanitizes the data, ensuring only an integer is supplied.

Bill Erickson

Bill Erickson is the co-founder and lead developer at CultivateWP, a WordPress agency focusing on high performance sites for web publishers.

About Me
Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments are closed. Continue the conversation with me on Twitter: @billerickson


  1. Joshua says


    Nice! I like the simplicity of this cod. I’ll have to check out WPForms. I’ve been using Gravity Forms for some time and, while I like Gravity Forms in general, it feels like overkill for a site with just a contact form.

    I put together a similar walk-through a while back that is specific to Gravity Forms – dynamically populating a dropdown with site users and routing the contact form submission email to the specific user. I have since started using a custom post type for staff more frequently, like your post, but I haven’t had a chance to put together and updated walk-through.


  2. Kathi says

    Hi, This is exactly what I was looking for. You mention that this could be used using WPForms Lite. However, hidden fields are not available in the Lite version. Did I misunderstand? I will purchase the paid version if that’s what is needed.

    • Bill Erickson says

      Ah you’re right! I didn’t realize hidden fields were only available on the paid versions. The Basic version ($39) will have it though. Here’s a good link to use: WPForms 🙂

    • Bill Erickson says

      Good catch! This has been fixed.

      This is what happens when I generalize code for a blog post but don’t test the resulting code.

  3. Andy Ingham says

    Hi Bill,

    This post was useful to me when I was setting up a form in a very similar situation.

    The only problem is that when you’re reviewing the form submissions in the admin area, you can’t see what email address the notifications went to. Did you have the same problem?

  4. Sam McCarthy says

    Thank you Bill, for this and every other useful bit of code you post on your site. I’ve lost count of the number of times I’ve encountered a problem or challenge, Googled it, and found the most complete and reliable result to be on your site. You’re a huge help man.