Umbraco Caching AtoZ Helper and Partial
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Umbraco.Core;
using Umbraco.Web.Mvc;
using Umbraco.Web;
using System.Web.Mvc;
using System.Web.Caching;
using System.Web.Configuration;
using Umbraco.Core.Logging;
using System.Diagnostics;
using umbraco.interfaces;
using Umbraco.Core.Services;
using Umbraco.Core.Events;
using Umbraco.Core.Publishing;
using Umbraco.Core.Models;
namespace Jumoo.UmbLocalGov
{
// helper class, clears the cache - when things are published.
public class LocalGovTools : ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
ContentService.Published += ContentServicePublishEvent;
ContentService.UnPublished += ContentServicePublishEvent;
}
private void ContentServicePublishEvent(IPublishingStrategy sender, PublishEventArgs<IContent> args)
{
// Clear all AtoZs
// could be cleverer - the cache has the root ID in it, so you could just clear caches where
// the ID is a parent of the current page - not sure it makes much diffrence, because the
// rebuild only happens once, and it doesn't take 'that' long
ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheByKeySearch("AtoZPages");
}
}
// AtoZ
public static class AtoZHelper
{
private static SortedDictionary<string, string> GetAtoZPages(UmbracoHelper umbHelper, string[] excludedTypes)
{
var root = umbHelper.TypedContentAtRoot().First();
return GetAtoZPages(umbHelper, excludedTypes, root);
}
private static SortedDictionary<string, string> GetAtoZPages(UmbracoHelper umbHelper, string[] excludedTypes, IPublishedContent root)
{
var cacheName = string.Format("AtoZPages_{0}", root.Id);
var cache = ApplicationContext.Current.ApplicationCache;
SortedDictionary<string, string> azPages = cache.GetCacheItem <SortedDictionary<string, string>>(cacheName);
if (azPages == null)
{
Stopwatch sw = new Stopwatch();
sw.Start();
// if its not in the cache build it.
azPages = new SortedDictionary<string, string>();
var sitePages = root.Descendants().Where(
x => x.IsVisible()
&& !excludedTypes.Contains(x.DocumentTypeAlias)
&& x.GetPropertyValue<bool>("includeInAtoZ"));
foreach (var page in sitePages)
{
var title = page.GetPropertyValue<string>("title", page.Name);
if (!azPages.ContainsKey(title))
{
azPages.Add(title.Trim(), page.Url);
}
if (page.HasProperty("aZNames"))
{
string[] others = page.GetPropertyValue<String>("aZNames")
.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var entry in others)
{
if (!azPages.ContainsKey(entry))
{
azPages.Add(entry.Trim(), page.Url + "#" + entry.Trim() );
}
}
}
}
cache.InsertCacheItem<SortedDictionary<string, string>>(cacheName, CacheItemPriority.Default, () => azPages);
sw.Stop();
LogHelper.Info<LocalGovTools>("AtoZ Cache [{1}] {2} entries for {3} pages, built {0}ms", () => sw.ElapsedMilliseconds, ()=> cacheName, ()=> azPages.Count(), ()=> sitePages.Count() );
}
return azPages;
}
public static SortedDictionary<string, string> GetAtoZEntries(this UmbracoHelper umbraco, string letter)
{
return GetAtoZEntries(umbraco, letter, new string[] { });
}
public static SortedDictionary<string,string> GetAtoZEntries(this UmbracoHelper umbraco, string letter, string[] exclude, IPublishedContent root)
{
SortedDictionary<string, string> AtoZ = GetAtoZPages(umbraco, exclude, root);
SortedDictionary<string, string> filteredPages = new SortedDictionary<string, string>();
foreach(var entry in AtoZ.Where(x => x.Key.ToLower().StartsWith(letter.ToLower())))
{
filteredPages.Add(entry.Key, entry.Value);
}
return filteredPages;
}
public static SortedDictionary<string, string>GetAtoZEntries(this UmbracoHelper umbraco, string letter, string[] exclude)
{
var root = umbraco.TypedContentAtRoot().First();
return GetAtoZEntries(umbraco, letter, exclude, root);
}
}
}
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@using Jumoo.UmbLocalGov;
@{
var letter = Request.QueryString["letter"];
if (!string.IsNullOrWhiteSpace(letter))
{
<h2>@letter.ToUpper()</h2>
// get everthing with the letter.
var entries = Umbraco.GetAtoZEntries(letter, new string[] { "DataTypeToIgnore" } );
if (entries.Any()) {
<ul class="atoz-entries">
@foreach(var entry in entries)
{
<li><a href="@entry.Value">@entry.Key</a></li>
}
</ul>
}
else
{
<div class="alert alert-error">No Entries found</div>
}
}
}