WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I created a custom registration form which works fine when used as a custom page template. I needed it as a shortcode so I created a shortcode using the function below

/* Custom shortcode */
function team_reg_form(){
require_once(ABSPATH . WPINC . '/registration.php');
global $wpdb, $user_ID;

echo '<div id="team-reg-form">';

//if the form is posted we need to validate
   $user_login = $_POST['user_email'];
   $user_email = $_POST['user_email'];

   $billing_phone  = $_POST['billing_phone'];   

   //initialize a WP_Errror object
   $errors = new WP_Error();

   //email is required
   if (  isset($user_email) && $user_email == '' )
      $errors->add('email_required', __('The email field is required.'));
   //email needs to be a valid email
   if (  isset($user_email) && !is_email($user_email) )
      $errors->add('email_invalid', __('The email is not valid.'));

       $errors = $user_id = wp_insert_user(array('user_login' => $user_login, 'user_email' => $user_email));
          update_usermeta($user_id, 'billing_phone', $billing_phone);
          //update_usermeta($user_id, 'first_name', $first_name);
          update_usermeta( $user_id, 'first_name', $_POST['first_name'] );
   //if we still do not have any errors it was a success
   if (!is_wp_error($errors)) {
        wp_redirect( 'https://example.com/'); exit;
   }else{//output the errors
      foreach($errors->errors as $code => $error)
         echo '<p>'.$error[0].'</p>';
echo '<form name="registerform" id="registerform" action="'. the_permalink().'" method="post">
<label for="first_name">'. _e('Name').'<br />
<input type="text" name="first_name" id="first_name" class="input" value="'. esc_attr(stripslashes($first_name)).'" tabindex="2" /></label>
<label for="user_email">'. _e('E-mail').'<br />
<input type="text" name="user_email" id="user_email" class="input" value="'. esc_attr(stripslashes($user_email)) .'" tabindex="2" /></label>
<label for="billing_phone">'. _e('Phone').'<br />
<input type="text" name="billing_phone" id="billing_phone" class="input" value="" tabindex="4" /></label>

'. do_action('register_form').'

<p class="submit">
<input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="'. esc_attr_e('Register').'" tabindex="100" />

add_shortcode('teamform', 'team_reg_form');
share|improve this question
And what happens? Is the problem when the page with the shortcode displays or when you submit the form? – s_ha_dum Jan 29 '13 at 19:45
When your shortcode renders, headers have already been sent, so wp_redirect will give you a headers already sent error. It won't work, but shouldn't result in a 500. Also, shortcodes need to return their content, not echo. – Milo Jan 29 '13 at 19:46
@s_ha_dum it breaks the site no pages load I get http 500 errors on all pages. – Anagio Jan 29 '13 at 20:02
@Milo I commented out my redirect, and changed the echo's to returns and still getting the error – Anagio Jan 29 '13 at 20:02
I copied your code into a throwaway install and I get no 500 errors-- PHP notices, yes, but no 500 errors even when I submit the form. I think something else is involved. – s_ha_dum Jan 29 '13 at 21:18

Try using output buffering:

function team_reg_form(){

    //your code

    return ob_get_clean();
} // END function team_reg_form

In this code, ob_start() stops any output (like echo) from reaching the screen, instead storing it internally for later usage, i.e., it buffers any output. Then, ob_get_clean() is called, which returns (in string form) what normally would have been output to the screen. ob_get_clean() also turns buffering off, then erases the buffer.

share|improve this answer
Thanks after removing code refreshing a few times I found it was my return '<div id="team-reg-form">'; causing the problem so I moved that into the the bottom return. I did keep the ob_start() function. – Anagio Jan 30 '13 at 11:01
returnexits the function at that point, skipping the rest of the function. So you need to either store everything in a $variable for later return'ing, or use output buffering and echo. – akTed Jan 30 '13 at 11:42

Since this is part of a shortcode, it's going to occur in a content area and you are echoing content. That part is fine.

But you have a major problem with using wp_redirect() in that function. That cannot occur in the content area. It needs to happen before headers are sent.

What you should do is have two separate functions. The first would be your shortcode to display the registration form and any errors, as you have. The second should be hooked to an action that occurs before headers are sent where it is safe to do the redirect. That would init or template_redirect.

That function should handle the form field validation and your redirect. Put your errors into a global variable and you can pick them up in the shortcode function for display if errors exist.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.