Sitecore and Code Reusability

As a software developer, I always relish in that moment when I realize that a client’s request for functionality can be fulfilled using some code that I’ve already written (we developers call this “reusability”). My first step with any new project is to determine whether the functionality goal fits in the same abstract mold as something I’ve done before, which can save the client valuable time and money.

With Sitecore, the ability for multiple inheritance of templates makes it easy to reuse most of my code. For instance, I can have a template that defines Navigation elements within that item – whatever it is (page, folder, “snippet”, etc), and can treat each item the same way no matter what it is. Read on for a specific example of code reuse within Sitecore.

Creating the Data Template in Sitecore

Our client wanted home page banners (and other content) to automatically expire without having to do anything extra in Sitecore. This would allow the client to queue up the next year’s home page banners and “set it and forget it.” If this rule was isolated to home page banner, I could have gone the route of including the fields for expiration on home page banner exclusively, but I wouldn’t do that 🙂

Here is an overview of the template I created, which could then be added to any template chain, along with some code to handle expirations (minimal), in order to get the desired effect.

Expirable Data (Sitecore Template)
StartDate (DateTime field)
EndDate (DateTime field)
OccurrenceWeekday (Item Picker field [Ideally have a dictionary item with weekday children items])

The OccurrenceWeekday picker was specific for this client and you may or may not need it. But certain things should only show up on certain days, e.g. , a TGIF banner should only show up on Friday.

For the sake of brevity, we can assume the home page banner template would then include just the “Image” of type Image. You could add a March banner of a lion from March 1 to 15, and a lamb banner from March 16 to 31. Your banner could be a TGIF banner on Friday, and a camel on Wednesday.

This begs the question: what happens when two banners fit the criteria? What shows on Wednesday March 26th? OccurrenceWeekday takes precedence, followed by Random Selection. This last one is helpful for when Start and End Dates overlap, or more than one item is scheduled for Wednesday.

For most uses of this code, the requirements were “I need a list of N banners to rotate, and expired ones should ‘fall off,’ and let the order be determined by Sitecore tree order.”

Expirable Data Code

A precursor to our code: Wrapper is the base class, we don’t use code generation, but Wrapper is inherited and fields are added in order to get the data from Sitecore. This may seem like a lot of work at first but it’s quick and easy, and the Delphic team’s preferred method. The property implementations are stripped for the sake of brevity, but they would each contain a call to the helper class to return the value in the field that they represent.

 				public class ExpirableDataWrapper : Wrapper { 				public ExpirableDataWrapper(){ }  // empty default constructor 				public ExpirableDataWrapper(Item item) : base(item) { }  // initialization list with Sitecore Item 				public DateTime StartDate { get; } 				public DateTime EndDate { get; } 				public List OccurrenceWeekday { get; } 				private List GetOccurrenceWeekday() { ...  } // instance method to populate weekdays off of field 				} 				

There is a static method added to this class:

 				public static T Create(Item item) where T : ExpirableDataWrapper, new() 				{ 				T t = new T(); 				t.item = item; 				t.weekdays = t.GetOccurrenceWeekday(); 				return t; 				} 				

Now we have all of the data from Sitecore that we need. The class for getting fresh content for “today” needs to account for this class being implemented on any type of item within Sitecore. The first line explains this neatly:

 				public class ExpirableDataList : List where T : ExpirableDataWrapper, new() 				{ 				private Item parentItem;  				public static ExpirableDataList Filter(ExpirableDataList input, DateTime startDate, DateTime endDate, int maxCount) where T : ExpirableDataWrapper, new() 				{ 				List allDays = GetDays(startDate, endDate); 				Func expireLogic = item => 				(item.StartDate == DateTime.MinValue || startDate >= item.StartDate) && 				(item.EndDate == DateTime.MinValue || endDate <= item.EndDate) && 				(!item.OccurrenceWeekday.Any() || (item.OccurrenceWeekday.Any() && 				allDays.Intersect(item.OccurrenceWeekday).Any()));  				ExpirableDataList list = new ExpirableDataList(input.Where(expireLogic).ToList().Take(maxCount)); 				return list; 				} 				} 				

Implementing Expirable Data

Implementation of this idea for new template types going forward is very simple (which is the point in front-loading the complexity).

1. Add the Expirable Data template as a base template to the item type that you want to make expirable.

Expirable Data Template

2. Populate the tree with nodes of this type. Then, to select the items that are “active” right “now,” add this line. (Create takes a parent item which contains expirable child items.

IList homeHeroes = 				ExpirableDataList.Create(this.Item, DateTime.Now); 				

The function can be tested with different dates as it wasn’t written to assume “active right now,” but active at this specific period in time. These little things can help with making sure the functionality is working correctly.

This is just one example of how an abstract design, concise templates, multiple template inheritance, and code reuse can help in quickly adding functionality. Keeping all of the logic uniform makes debugging easier, and this code, as it is abstract and written against a template which doesn’t have anything client specific, can be brought over to new projects and reused everywhere.

Taking the time to plan out the solution can pay off down the road, rather than just addressing the specific task with a “quick and dirty” solution. Sitecore makes this all possible by being very developer friendly as well!

« Prev Article
Next Article »