Sitecore find unused templates

Long lived Sitecore projects tend to build up dead templates and renderings as design, features and functions evolve. Finding those unused templates is not always just a matter of checking the Sitecore link database for templates with no references because:

  • Template inheritance can leave a web of references that is hard to decipher.
  • The link database could be broken.
  • __Standard values leave false references.

But most important of all: Editors tend to leave dead web pages in an unpublished folder, in fear of loosing some data, and then forgetting all about it years later.

So lets solve this the fun way: Lets code!

STEP 1: CREATE A REPOSITORY OF ALL TEMPLATES

This repository gets all templates from a specific folder. If you are following the helix principles by the book you probably have 3 folders (feature, foundation, project), but I assume that you are the type that puts these folders into one folder to hold them neatly together. If not, you need to call this repository for each of your folders and merge the results.

using System.Collections.Generic;
using Sitecore.Data;
using Sitecore.Data.Items;

namespace MyProject
{
  public class TemplateRepository
  {
    private readonly Database _database;
    private readonly List<TemplateItem> _templates = new List<TemplateItem>();

    public TemplateRepository(Database database)
    {
      _database = database;
    }

    public IEnumerable<TemplateItem> Get(string rootPath)
    {
      _templates.Clear();
      Item rootItem = _database.GetItem(rootPath);
      if (rootItem == null)
        return _templates;
      Iterate(rootItem);
      return _templates;
    }

    private void Iterate(Item item)
    {
      if (item.TemplateID == Sitecore.TemplateIDs.Template)
        _templates.Add(item);
      if (!item.HasChildren)
        return;
      foreach (Item child in item.Children)
      {
        Iterate(child);
      }
    }
  }
}

STEP 2: ITERATE ALL ITEMS OF YOUR SOLUTION

Next step is to iterate over all items in your solution, and for each item, get the templates, and the templates inherited by these templates, and the templates inherited by these templates etc. until you have found all the templates that are used.

The templates not used is found simply by returning all templates, excluding those that are used.

using System;
using System.Collections.Generic;
using System.Linq;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;

namespace Myproject
{
  public class FindUnusedTemplatesService
  {
    private IEnumerable<TemplateItem> _allTemplates;
    private List<TemplateItem> _usedTemplates = new List<TemplateItem>();

    public IEnumerable<TemplateItem> FindUnusedTemplates(string rootPath)
    {
      _allTemplates = new TemplateRepository(WebDatabase).Get("/sitecore/templates/");
      _usedTemplates.Clear();

      Item root = WebDatabase.GetItem(rootPath);
      if (root != null)
        Iterate(root, 1);

      var unusedTemplates = _allTemplates.Where(t => !_usedTemplates.Any(t2 => t2.ID == t.ID));
      return unusedTemplates;
    }

    private void Iterate(Item root)
    {
      IterateTemplates(root.Template);
      Response.Write("<hr/>");

      if (!root.HasChildren)
        return;

      foreach (Item child in root.Children)
      {
        Iterate(child);
      }
    }

    private void IterateTemplates(TemplateItem root)
    {
      if (root.ID == Sitecore.TemplateIDs.StandardTemplate)
        return;

      if (_usedTemplates.All(t => t.ID != root.ID))
        _usedTemplates.Add(root);

      if (!root.BaseTemplates.Any())
        return;
      foreach (var baseTemplate in root.BaseTemplates)
      {
        IterateTemplates(baseTemplate);
      }
    }

    private Database WebDatabase
    {
      get
      {
        return Factory.GetDatabase("web");
      }
    }
  }
}

USAGE:

FindUnusedTemplatesService service = new FindUnusedTemplatesService();
var unusedTemplates = service.FindUnusedTemplates("sitecore/content");

foreach (var unusedTemplate in unusedTemplates)
{ 
  ID id = unusedTemplate.ID;
  string path = unusedTemplate.InnerItem.Paths.FullPath;
  int baseTemplatesCount = unusedTemplate.BaseTemplates.Count();
  // ... etc ...
}

MORE TO READ:

 

Advertisements

About briancaos

Developer at Pentia A/S since 2003. Have developed Web Applications using Sitecore Since Sitecore 4.1.
This entry was posted in Sitecore 5, Sitecore 6, Sitecore 7, Sitecore 8, Sitecore 9 and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.