This may be a little broad so I'd appreciate any pointers.
Is there a way to replace the typical 404 response with 410 for pages that have been deleted? Obviously I'd like to keep 404 responses for genuine 404's.
Thanks.
Sitecore Stack Exchange is a question and answer site for developers and end users of the Sitecore CMS and multichannel marketing software. It only takes a minute to sign up.
Sign up to join this communityThis may be a little broad so I'd appreciate any pointers.
Is there a way to replace the typical 404 response with 410 for pages that have been deleted? Obviously I'd like to keep 404 responses for genuine 404's.
Thanks.
You certainly could, but it requires a couple moving parts:
To know whether a requested URL used to exist or not, you'll need to track pages as they're deleted so you can check that list later.
You'll need an item:deleted
event handler:
public class PageDeletionLogger
{
public void ItemDeleted(object sender, EventArgs args)
{
var deletedItem = Event.ExtractParameter(args, 0) as Item;
var formerParentId = Event.ExtractParameter(args, 1) as ID;
if (deletedItem == null || formerParentId == (ID)null || formerParentId == ID.Null)
return;
// If this item is being manipulated in a different database (e.g. "web" because it's being published), ignore it
if (!"master".Equals(deletedItem.Database?.Name, StringComparison.OrdinalIgnoreCase))
return;
// If this item is a template or a branch, ignore it
if (deletedItem.Paths.Path.StartsWith("/sitecore/templates/"))
return;
// Ignore items that aren't pages
if (!TemplateManager.GetTemplate(deletedItem).IsDerived(new ID("id-of-base-page-template")))
return;
// TODO:Log the page details/URL here
}
}
(And you'll need this handy template checking method [beware: it's recursive]):
public static class TemplateExtensions
{
public static bool IsDerived([NotNull]this Template template, [NotNull]ID templateId)
{
return template.ID == templateId || template.GetBaseTemplates().Any(baseTemplate => IsDerived(baseTemplate, templateId));
}
}
And you'll need to patch it into config:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<events>
<event name="item:deleted">
<handler type="Custom.Events.PageDeletionLogger,Custom" method="ItemDeleted" />
</event>
</events>
</sitecore>
</configuration>
HttpRequestBegin
pipelineThen, when incoming requests are processed, you'll need to look them up in your list of deleted pages and see whether they should get a 410 or 404.
public class DeletedPageResolver : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
// If we resolved a context item, get out
if (Sitecore.Context.Item != null)
return;
var listOfDeletedPageUrls = // TODO: Get the list of deleted page URLs
if (listOfDeletedPageUrls.Contains(args.Context.Request.RawUrl))
{
// TODO: Set your 410 HTTP status code
}
}
}
And, of course, you'll need to patch that into config, too:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<httpRequestBegin>
<processor type="Custom.Processors.HttpRequestBegin.DeletedPageResolver, Custom" patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']"/>
</httpRequestBegin>
</pipelines>
</sitecore>
</configuration>
I've not worked with the 410 status code before, so it's possible you'll need to do more to avoid having the page redirect to an error page (e.g. resolve the Sitecore.Context.Item
to a page that has the 410 error content you want to display).