contact

or cancel

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