How To Automatically Order Episerver Pages

When a company decides to power their website using EpiServer, they usually have a content team that updates the website's content on a frequent basis. Despite best intentions, content editors can become a bit lazy when adding new content and forget to structure their pages in a nice way. After a period of months/years people may start to complain that they can't find pages. In a lot of the companies I've worked for, News and Blog pages are usually the worst offenders for these people moaning. One quick and very simple way to make content editors' lives easier is to implement a scheduled task that runs once a week, out of hours and re-orders the pages in alphabetical order. As most news items and blogs aren't dependent on the order they appear in the content tree, it's no biggie to change the sort order. Implementing something to make content editors' lives easier, can be an easy quick win that can keep a marketing department happy for another week :) Luckily, implementing a scheduled task to do this is pretty simple:

 [ScheduledPlugIn(
    DisplayName = "Page Ordering Scheduled Task",
    SortIndex = 100)]
    public class PageOrderingScheduledTask : JobBase
    {
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        int contentProcessed;

        int contentNotProcessed;

        int index;

        public PageOrderingScheduledTask()
        {
            IsStoppable = true;
            contentProcessed = 0;
            contentNotProcessed = 0;
            index = 0;
        }

        private long Duration { get; set; }

        public override string Execute()
        {
            var tmr = Stopwatch.StartNew();

            var contentTypeRepository = ServiceLocator.Current.GetInstance<IContentTypeRepository>();
            var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
            var contentModelUsage = ServiceLocator.Current.GetInstance<IContentModelUsage>();

            try
            {
                var contentType = contentTypeRepository.Load<ProductPage>();
                var usages = contentModelUsage.ListContentOfContentType(contentType).OrderBy(x => x.Name);

                foreach (var content in usages)
                {
                    var page = contentRepository.Get<PageData>(content.ContentLink);

                    if (page == null)
                        break;

                    index++;

                    var clone = page.CreateWritableClone();
                    clone.Property["PagePeerOrder"].Value = index;
                    contentRepository.Save(clone, EPiServer.DataAccess.SaveAction.Publish);

                    contentProcessed++;
                }
            }
            catch (Exception ex)
            {
                contentNotProcessed = contentNotProcessed++;
                Logger.Error(ex);
            }

            tmr.Stop();
            Duration = tmr.ElapsedMilliseconds;

            return ToString();
        }

        public override string ToString()
        {
            var logMesssage = contentNotProcessed > 0 ? "Please check the logs for the failed pages." : string.Empty;

            return string.Format(
                "Processed {0} in {1}ms on {2}. {3}",
                contentProcessed,
                Duration,
                Environment.MachineName,
                logMesssage);
        }
I based my page type on the Alloy site, so I'm re-ordering the product pages only. You'll obviously need to change 'contentTypeRepository.Load();' to use a page type in your project. In the code above, we use the ContentTypeRepository to get a reference to the product page type. I then use the content model usage API to get all page instances that use the product page in alphabetical order. After we have this list, it's just a simple case of iterating through the pages, setting the sort order, and then re-publishing.

I Could Do This Better?

If you're reading this and you're thinking that there's a few improvements you could make.. then that makes two of us. I've added the code for simplicity, but, if in production, I would check if the existing page had been published, if it hasn't then I'd exclude it from the process. Second, if you wanted to be really anal about the sort order, you could create an array that keeps a sort order for each parent, rather than creating one big counter, however, I'll leave that to you. Enjoy!

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

Back to top