Appropriate place for wp_redirect?

So I’m developing a site that contains a multi-step registration process, with limited information stored in $_SESSION.

Each step is a page-specific template.

The basic logic is (I thought) simple:

if ($_POST) {
  // do logic
  if (!errors) {
    wp_redirect('the next step');
    exit;
  }
} // end $_POST actions

if (errors)
  display errors

display page content

However, I’m getting the dreaded headers already sent by (output started at theme/templates/head.php:2) in wp-includes/pluggable.php:896

It works for the most part when I develop locally. The only time I’ve run into this issue is when I tried to add respond.js to head.

What’s the best way to resolve this for now? Something like ob_start() in head and ob_end_flush() at the end of footer?

Is there a better way to do potentially-redirecting logic than what I’m doing now?

1 Like

For reference, the ob_start/ob_end_flush solution works. I’m still open to better suggestions though!

I am working on a new theme with a similar issue. I have about 8 custom pages with forms that redirect on success.

For validation I submit the form pages to themselves, but then redirecting causes an error since page-XXX.php files are called after head.php.

I think the solution is to make a new base-page-XXX.php file for each of the custom pages and then just put wp_redirect before the head, but I’d like to know if there’s a better way. It almost defeats the purpose of having base.php when I have to copy it so many times.

Not really a Roots question, but you’ll most likely want to use the template_redirect hook:

function check_post_data() {
  if ($_POST) {
    // do logic
    if (!errors) {
      wp_redirect('the next step');
      exit;
    }
  } // end $_POST actions
}
add_action('template_redirect', 'check_post_data');

You may need to run some specific checks on $_POST data or even is_page() depending on your structure.

1 Like

You’re right that it’s not a Roots-specific question, but the issue is caused by Roots’ use of base.php. Normally get_header() would be called inside a page template, so adding a redirect or other code before it is simple. I was hoping there was a Roots process for doing what I’m describing, but since there isn’t then I’ll figure something out.

I tried using your suggestion, but since I need to pass a (potential) multitude of error/success/warning messages to the page after validation I think it’s easier to just use a custom base.php for those pages.

Thank you for your help, cfx.

1 Like