Strategies for URL redirection in WordPress front-end pages

I know that is not a common situation but sometimes it’s necessary to redirect the current page to another URL. Inside WordPress back-end is relatively simple but from the WordPress front-end templates that shows the Posts, Pages… It’s a little more complicated.

Change direction

In this article we’ll see some strategies for redirecting the URLs, all of them based in using the WP function template_redirect (see the official documentation of the function template_redirect for further information) therefore, we assume that all next examples are always inside this former WP function in the functions.php file of your theme.

The general structure for all examples is this

<?php
function special_redirect () {

    begin_condition  // something like 'if ( is_404() ) {...'  
                     // or  'if ( $_SERVER['HTTP_USER_AGENT'] ) { ...'
                     // or  'if ( $post->ID == '88882' ) { ...'
        our_strategy
    end_condition
    die();
}
add_action( 'template_redirect', 'special_redirect' );
?>

In this first code we see the general shape of all these strategies, because in all of them firstly, we’ll check if certain condition is TRUE, and in this case, then we’ll apply the strategy for the redirection, and finally, we’ll always end with PHP die(). So, as I said, we’ll see only the code for strategies.

Examples of strategies for redirection

Using Location:

The most simple is to use the php function header() with the clause Location:. Its so simple but it just works when you are redirecting pages or query URLs but It dosen’t work with the main url.

header("Location: http://www.yoursite.com/\r\n");

of course we can add some other headers clause like Content-Type, etc.

header("Location: http://www.yoursite/\r\n");
header("User-Agent: " . $_SERVER['HTTP_USER_AGENT'] . "\r\n");  // we keep the same user agent
header("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" );
header("Accept-Language: en-us,en;q=0.5\r\n" );
header("Accept-Encoding: gzip,deflate\r\n" );
header("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" );
header("Keep-Alive: 300\r\n" );
header("Connection: keep-alive\r\n" );
header("Referer: " . $_SERVER['HTTP_REFERER'] . "\r\n" ); // we keep the referer url

Using GET protocol

In case that we want to send to the new address some data (a internal code, the referer address, a number or whatever) we can use the second strategy based on the same function but using the GET protocol call to the server. In that case, and assuming that we has previously converted our vars in a well-formatted url query –for example &time=12:00&date=05/31/2016&name=john–, our previous example is slightly modified.

header("GET /path_address/?query\r\n");
header("Host: http://www.yoursite/\r\n");  // we keep the same user agent
header("User-Agent: " . $_SERVER['HTTP_USER_AGENT'] . "\r\n");  // we keep the same user agent
header("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" );
header("Accept-Language: en-us,en;q=0.5\r\n" );
header("Accept-Encoding: gzip,deflate\r\n" );
header("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" );
header("Keep-Alive: 300\r\n" );
header("Connection: keep-alive\r\n" );
header("Referer: " . $_SERVER['HTTP_REFERER'] . "\r\n" ); // we keep the referer url

Using POST protocol

The third strategy is to try (yes, I said ‘to try’) to use the POST protocol for making a redirection and, in addition, to send data as in a form… Well, I will write the code but, hardly ever works properly because this strategy interferes directly with the internal WordPress rewritting rules and the own structure of the loading rutine of WordPress so WP doesn’t allow you to send form data to a normal Post or Page. It’s possible but it’s quite complicated, so here just a brief example as a documentation. (In next article, perhaps).

// $data = a well formatted url query string;

header("POST /path_address/ HTTP/1.1\r\n");
header("Host: localhost\r\n");  // or the complete host address
header("User-Agent: " . $_SERVER['HTTP_USER_AGENT'] . "\r\n");
header("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" );
header("Accept-Language: en-us,en;q=0.5\r\n" );
header("Accept-Encoding: gzip,deflate\r\n" );
header("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" );
header("Referer: " . $_SERVER['HTTP_REFERER'] . "\r\n" );
header("Content-type: application/x-www-form-urlencoded\r\n");
header("Content-length: " . strlen($data) . "\r\n");
header("Connection: close\r\n\r\n");
header( $data );

Using POST but with Streams

Normaly, a simple POST call is a big problem but, if you do want to force sending data like in a form, you must use a PHP stream like in this fourth example,

// the body 'headers' that we want to use for this redirection
$headers = array ( "User-Agent"		=> $_SERVER['HTTP_USER_AGENT'], 
		   "Accept"		=> 'text/html,application/xhtml+xml',
		   "Accept-Language"	=> 'en-us,en;q=0.5',
		   "Accept-Charset"	=> 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
		   "Referer"		=> $_SERVER['HTTP_REFERER'],
                   // other headers
);
// the colection of vars to send
$data = array ( '_data1'  => value1,
                '_data2'  => value2,
                '_data3'  => value3,
                //
                '_dataN'  => valueN,
);

// we change the codification for data characters if is necessary
foreach( $data as $key => $value ) 
    $data[$key] = urlencode ( $value );

// now we're going to open the stream
$params = array(
	'http' => array(
		'method' => 'POST',
		'content' => http_build_query($data) // we transform the array 
                                                     // into a query string
	)
);

if (!is_null($headers)) {
	$params['http']['header'] = '';
	foreach ($headers as $k => $v) {
		$params['http']['header'] .= "$k: $v\r\n";
	}
}

// we creates a stream resource
$url   = get_bloginfo ('url' ) . '/path_address/';
$stream = stream_context_create( $params );
// we are forcing a new window/tab in browser for this set of $params

// now, we open the stream as a file in read mode binary, ie, we receive the content result 
// of the previous opened browser window
$file = @fopen( $url, 'rb', false, $stream );
if ($file) {
   echo @stream_get_contents($fp);
} else {
   // Error
   echo '<pre>';
   throw new Exception("Error loading '$url'", 'your error code here' );
   echo '</pre>';
}

// Here, the redirection is completed

By the way, I’ve modified and simplified this last code example because my original code was quite more complicated notwithstanding at heart, this code is based in a famous internet example so it exists an original and complete PHP example that’s is fully documented in a lot of places on the web so, I do advise you to take a look on it.

Strategies of POST using javascript

In all of these former cases, we has been using PHP but, it’s also possible to do the same redirection but using strategies based on javascript. For example, we can write a little script that writes a form on the screen and then executes a submit form event. In that case, in the zone of the strategy, we’ll write something like

// Previous PHP code, where the 'condition' that has to be TRUE
$_host = get_bloginfo ('url' );
$_path = 'the path of the redirecting page'
?>

<script type="text/javascript">
function rpost(path, params, method) {
    method = method || "post"; // Set method to post by default if 
                               // it's not specified.

    var form = document.createElement("form");
    form.setAttribute("method", method );  // POST as a method for default
    form.setAttribute("action", path );    // the PATH where to recover the
                                           // data from.

    // we construct a hidden field for each one of our query vars
    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);
            form.appendChild(hiddenField);
         }
    }

    // we instroduce this form probably in a hidden zone of the page
    document.body.appendChild(form);
    form.submit(); // we send the form to the server
}
rpost('<?php echo $_host . $_path; ?>', {WhoCalling: '<?php echo $_SERVER['HTTP_REFERER']; ?>'});
</script>    
<?php
// Nothing else here because never will be executed...    
// This example, as the former, is also documented and augmented in several
// other websites. Please, study the original code.

Strategies based on HTML Anchors for when all of the rest doesn’t work

And finally a last strategy for when neither of the previous ones don’t works (and sometimes, it happens). It’s based in the use, not of a form but of an HTML anchor element so, instead of a submit event, in this case, we’ll trigger a click event. See the next example.

$_host = get_bloginfo('url');
$_path = "/our_path_to_go/";
echo '<!DOCTYPE html><html><head></head><body>';
echo '<a type="submit" href="' . $_host . $_path . '" id="is_the_click_anchor"></a>';
echo '<script type="text/javascript">var l = document.getElementById("is_the_click_anchor"); l.click();</script>';
echo '</body></html>';

// perhaps we'll want also to add the onclick() function... Perfect.

Finaly, remember that, even before WordPress begins to process the user request, there usually is a file called .htaccess in the web server that could be modifying all the set of rewrite rules in just a couple of its instructions so, before beginning to write a function for redirection, please take a deep look to the .htaccess file of your webserver (usually on webserver root installation directory) and find out if there are additional silent: rewrites, conditions, groups, exclusions, special, redirections… Yeah! Take a look ‘inside’ this file.

Well, probably there are more strategies but I tkink that with this former group of examples we will be able to solve the most of the situations.

Have a nice WordPressing!

Leave a Comment

   Mandatory field
You can use these HTML tags inside the commment.
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>