301 Redirect for Expression Engine 2
A great plugin was written for Expression Engine 1.x by Nick Cernis called Redirect301, but it was lacking support for Expression Engine 2.x- so I coded the plugin starting from Nick’s base to support it, and made a couple small changes along the way.
The most noticeable change is that you no longer include the external term inside the plugin. If your URL does not start with “http://” or “https://” the EE site’s URL is prepended to the given URL so redirects are not relative. This was how I wanted it in my particular site, because the URL is coming from a user input, which may be relative, or to an external site. The other change is that you can leave the URL empty, and the plugin will not do anything; this was for the case that it was an optional field in one of your channels.
<?php
$plugin_info = array(
'pi_name' => 'Redirect 301',
'pi_version' =>'1.2',
'pi_author' =>'Nick Cernis, Matt Gaidica',
'pi_author_url' => 'http://nickcernis.com/',
'pi_description' => 'EE2 - Redirects to another page or site using the 301 header.',
'pi_usage' => Redirect301::usage()
);
class Redirect301
{
function Redirect301()
{
$this->EE =& get_instance();
$url = $this->EE->TMPL->fetch_param('url');
$url = trim(html_entity_decode($url));
if(!empty($url))
{
$permanent = $this->EE->TMPL->fetch_param('permanent');
$external = FALSE;
if(strpos($url, 'http://') === 0 || strpos($url, 'https://') === 0)
$external = TRUE;
// Get the site's base URL
if (!$external)
{
$site_url = '';
$site = ( ! $this->EE->TMPL->fetch_param('site')) ? '1' : $this->EE->TMPL->fetch_param('site');
if (is_numeric($site))
$this->EE->db->select('site_system_preferences')->from('exp_sites')->where('site_id', $site);
else
$this->EE->db->select('site_system_preferences')->from('exp_sites')->where('site_name', $site);
$query = $this->EE->db->get();
if ($query->num_rows() > 0)
{
$row = $query->row_array();
$prefs = unserialize(base64_decode($row['site_system_preferences']));
$site_url = $prefs['site_url'].$prefs['site_index'];
}
}
switch ($permanent)
{
case "no":
if ($external)
Header( "Location:".$url );
else
Header( "Location:".$site_url.$url );
exit();
default:
Header( "HTTP/1.1 301 Moved Permanently" );
if ($external)
Header( "Location:".$url );
else
Header( "Location:".$site_url.$url );
exit();
}
}
}
// usage instructions
function usage()
{
ob_start();
?>
-------------------
HOW TO USE
-------------------
Redirect to the specified channel and template using the SEO-friendly 301 header:
{exp:redirect301 url="channel/template"}
If your URL does not start with "http://" or "https://" the site's URL is prepended so redirects are not relative.
Redirect without the 301 header:
{exp:redirect301 url="channel/template" permanent="no"}
If you're using the Multiple Site Manager, simply specify the name or ID of your site, like this:
{exp:redirect301 url="channel/template" site="site_short_name_or_id"}
-----------------------------------------
SAMPLE REDIRECT TEMPLATE
-----------------------------------------
The redirect301 plugin can be used to create a short link to long post names. Here's how:
1) Create a template group called "go"
2) Edit the index file to include the following code:
{exp:channel:entries limit="1" entry_id="{segment_2}" disable="member_data|trackbacks|pagination"}
{exp:redirect301 url="{channel}/{url_title}"}
{/exp:channel:entries}
This will take a URL such as http://yoursite.com/go/33/ and issue a 301 redirect to the full URL,
such as http://yoursite.com/articles/you-look-nice-today/
------------------------------
OPTIONAL ADDITIONS
------------------------------
To create a link within your posts that readers can share, simply append the post ID to the
short URL address, like this:
{exp:channel:entries}
<a href="{site_url}go/{entry_id}/">Short link to this page</a>
{/exp:channel:entries}
Optionally, you can add the following code between your <head> tags to help spiders determine that
the content is the same. This is good practice but isn't required for the redirect to work.
{exp:channel:entries}
<link rev="canonical" rel="alternate shorter" href="{site_url}go/{entry_id}" />
{exp:channel:entries}
<?php
$buffer = ob_get_contents();
ob_end_clean();
return $buffer;
}
}
?>
I left the documentation essentially the same. I use this plugin as an option in conjunction with the Structure add-on in Expression Engine 2. I setup a channel called “Redirect”, and assigned it as a “Page” inside of Structure; I also assigned it to a template I will share below.

There is a custom field called “redirect_url” for this channel, and here is the template it uses to actually make the redirect.
{exp:channel:entries channel="redirect" status="not closed" limit="1" disable="member_data|trackbacks|pagination"}
{if no_results}
{redirect="site/index"}
{/if}
{exp:redirect301 url="{redirect_url}"}
{/exp:channel:entries}
I invested time into this because I wanted to remain using the Structure add-on as it is, but have the ability to do simple redirecting. This need is pretty common in my experience, and the .htaccess file is not one I want to client accessing. Also, if I can avoid turning on PHP in the template and junking it up with intermixed EE tags, I prefer it that way. Good luck with it.
Comments