Hi Mark,
There is yet another problem with redirects: in some situations you not only cannot perform redirect, but you even cannot test if condition on which you would like to perform redirect was met or not.
For example it seems that it is not possible to perform redirect in cases when {exp:query} tag does not output anything. That is, the code
{exp:query sql="SELECT title FROM exp_weblog_titles WHERE weblog_id = '5' AND url_title ='My title'"}
{if total_results == 0}
{exp:redirect_to location="my_template_group/my_template" method="script"}
{/if}
{/exp:query}
will not work.
Neither will the code as this (see thread)
{exp:subsegment segment="3" separator="-" index="0" parse="inward"}
{exp:weblog:entries weblog="my_weblog" url_title="{subsegment}"}
{if no_results}
{redirect="my_template_group/my_template" method="script"}
{/if}
{/exp:weblog:entries}
{/exp:subsegment}
In both examples it is impossible to perform redirect in case the tag outputs nothing since it is impossible to test if the tag has outputted nothing.
I suppose that it may exist also such situation when the tag has some output, but it is not possible before redirecting to test if it has output or if it has expected output.
I gave some thought on this problem and here is a solution:
In order to test if some complicated condition on which redirect should be performed was met, we need to wrap the code expressing that condition with {exp:redirect_to} and {/exp:redirect_to} tag pair and to check if the tagdata of this tag pair is equal or not equal to some expected string or not.
Here is the code using which you would be able test if {exp:qeery} tag has no output and redirect if it has no output:
{exp:redirect_to location="my_template_group/my_template" method="script"}
{exp:query sql="SELECT title FROM exp_weblog_titles WHERE weblog_id = '5' AND url_title ='My title'"}
{title}
{/exp:query}
{/exp:redirect_to}
If parameter “tagdata” would be added then there would be possible to test not only if there is output and redirect if there is no output, but also to test if there is certain string outputted and redirect if string entered as “tagdata” parameter is equal to string outputted.
Here is the code using which you would be able test if {exp:qeery} tag has outputted a string “1” and redirect if it has outputted this string (checking if string “1” was outputted we are really checking if certain entry exists):
{exp:redirect_to location="my_template_group/my_template" tagdata="1" method="script"}
{exp:query sql="SELECT title FROM exp_weblog_titles WHERE weblog_id = '5' AND url_title ='My title'"}
{total_results}
{/exp:query}
{/exp:redirect_to}
To enable this functionality is quite easy. The function I have published in my previous post should be changed as follows:
function Redirect_to()
{
global $TMPL, $FNS;
// Fetch the tagdata
$tagdata = $TMPL->tagdata;
// Fetch our parameters from the plugin tag
$location = str_replace("/", "/" ,$TMPL->fetch_param('location'));
$method = $TMPL->fetch_param('method');
$condition = $TMPL->fetch_param('tagdata');
// Perform a check to see if a full url is not given in the location parameter
if (strpos($location, 'http') !== 0 AND !(strpos($location, 'http') > 0))
{
// If we only find segments then use the create_url function to
// create our URL needed for correct re-direction
$location = $FNS->create_url($location);
}
// Clean tagdata from new line, carriage return and tab symbols
$tagdata = trim($tagdata);
$tagdata = str_replace('\n','', $tagdata);
$tagdata = str_replace('\r','', $tagdata);
$tagdata = str_replace('\t','', $tagdata);
$tagdata = str_replace('\x0B','', $tagdata);
// Perform a check if tagdata conforms to condition, or, in case condition not supplied,
// if tagdata is equal to empty string or space symbol
if ($condition === $tagdata OR (($condition === FALSE) AND (($tagdata === '') OR ($tagdata === ' '))))
{
// Perform a check to see if method parameter supplied
if ($method === FALSE)
{
// If we do not find method parameter then perform PHP redirect
$FNS->redirect($location);
}
else
{
// If we find method parameter then create redirection javascript and output it
$output = '<script type="text/javascript">location.href="'.$location.'"</script>';
$this->return_data = $output;
}
}
}