Skip to content

Instantly share code, notes, and snippets.

@CGaskell
Created July 30, 2014 09:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CGaskell/e36aff1bbdd0048664de to your computer and use it in GitHub Desktop.
Save CGaskell/e36aff1bbdd0048664de to your computer and use it in GitHub Desktop.
AliasRedirector for Sitecore. `This replaces the built in AliasResolver
using System.Web;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Links;
using Sitecore.Pipelines.HttpRequest;
using Sitecore.Resources.Media;
namespace DetangledDigital.SC.Pipelines
{
/*
* @CGaskell
*
* Sitecore aliases out of the box are used as short urls to a content item.
* Out of the box when using aliasing, the pages are not redirected to the original item
* but just assign the context item to the original item leaving the Url to be of the alias.
* This creates a big problem for SEO of content duplication.
*
* Contains extended functionality to persist the querystring
*
* This module replaces the original AliasResolver with one that redirects.
* The replacement is configured in Redrow.config
*/
public class AliasRedirector : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull(args, "args");
if (!Settings.AliasesActive)
{
Tracer.Warning("Aliases are not active.");
return;
}
var database = Context.Database;
if (database == null)
{
Tracer.Warning("There is no context database in AliasResover.");
return;
}
Profiler.StartOperation("Resolve alias.");
if (database.Aliases.Exists(args.LocalPath) && !ProcessItem(args))
ProcessExternalUrl(args);
Profiler.EndOperation();
}
private static void ProcessExternalUrl(HttpRequestArgs args)
{
var targetUrl = Context.Database.Aliases.GetTargetUrl(args.LocalPath);
if (targetUrl.Length <= 0)
return;
ProcessExternalUrl(targetUrl);
}
private static void ProcessExternalUrl(string path)
{
if (Context.Page.FilePath.Length > 0)
return;
Context.Page.FilePath = path;
}
private static bool ProcessItem(HttpRequestArgs args)
{
var targetId = Context.Database.Aliases.GetTargetID(args.LocalPath);
if (!targetId.IsNull)
{
var target = args.GetItem(targetId);
if (target != null)
ProcessItem(args, target);
return true;
}
Tracer.Error("An alias for \"" + args.LocalPath + "\" exists, but points to a non-existing item.");
return false;
}
private static void ProcessItem(HttpRequestArgs args, Item target)
{
// Check sitecore hasnt found an item for the url
if (Context.Item != null)
return;
Tracer.Info("Using alias for \"" + args.LocalPath + "\" which points to \"" + target.ID + "\"");
var query = HttpContext.Current.Request.Url.Query;
SendResponse(target, query, args);
}
// Once a match is found and we have a Sitecore Item, we can send the 301 response.
private static void SendResponse(Item redirectToItem, string queryString, HttpRequestArgs args)
{
var redirectToUrl = GetRedirectToUrl(redirectToItem);
args.Context.Response.Status = "301 Moved Permanently";
args.Context.Response.StatusCode = 301;
args.Context.Response.AddHeader("Location", redirectToUrl + queryString);
args.Context.Response.End();
}
// Consider media items when generating item URL
private static string GetRedirectToUrl(Item redirectToItem)
{
if (!redirectToItem.Paths.Path.StartsWith(RedirectsConstants.Paths.MediaLibrary))
return LinkManager.GetItemUrl(redirectToItem);
var mediaItem = (MediaItem)redirectToItem;
var mediaUrl = MediaManager.GetMediaUrl(mediaItem);
var redirectToUrl = StringUtil.EnsurePrefix('/', mediaUrl);
return redirectToUrl;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment