April 10, 2013 by Alistair Deneys
Sitecore allows classes to subscribe to particular events so arbitrary code may run when certain “things” happen. Possibly one of the most often subscribed events is the
item:saved event which fires when an item is, you guessed it, saved. Whether through the UI or the API the event will always fire.
This is very handy for changing or cleaning up an item once the author has signaled that they’re happy with it (by hitting the save button). Just a side note, don’t do your validation here, use item or field validators instead.
Something that is often done using the
item:saved event is to move the item to an appropriate structure. Some may say this is good for SEO, but we do it in Sitecore as a performance measure. Sitecore performance (particularly in the content editor) can degrade if too many items exist under a common parent item. There are various guidelines floating about for the maximum number of child items that should be allowed under a common parent but I generally say try to keep it to less than 100 and definitely less than 200 (less is better).
When we talk about “structuring” an item we generally mean placing it into an item hierarchy of several levels. Each level in the hierarchy is related to some aspect of the item. If the item represents a person then the hierarchy levels may represent letters in their name (the person “John Smith” goes in
/person/s/john smith). If the item is date based the levels may represent elements of the date (an event goes in a year folder, then a month folder such as
Let’s say we have a news item with a field called
News Date which contains the date the news is being reported on. I prefer a separate date for this kind of item rather than inferring the news date from the updated or created fields as news can be authored ahead of time (press release) or may need to have minor updates made that shouldn’t affect the “date” of the item (fix a spelling mistake). Now we want to structure the news in a hierarchy based on the
News Date field.
Though this is good for performance we now have a single piece of data replicated in two places; once in the field and once in the structure. We need to ensure these two instances of the same data are kept in sync. And believe me, don’t trust your authors to ensure they keep the news in the right location.
The easiest way to ensure the date field and structure are kept in sync is by using the News Mover module from the Sitecore Marketplace. This module will move the item to a folder structure based on the date selected in the configured field by hooking into the
Awesome! We’ve got a way to ensure no news item is created in a flat structure…but what if we didn’t anticipate the volume of items beforehand and now we have 700 news items directly under the news root item before the News Mover module was put in place? Adding event handlers after the fact doesn’t retrospectively execute the handlers for any items.
(OK, not quite 700 items in my example screenshot but you get the idea.)
We need a way to execute the
item:saved event for all those items without manually going through and hitting that save button 700 items. We can do that with Revolver!
To process a number of items at once I can use one of the
search commands. For this case I’ll use the
find command as it uses content tree traversal so I can be sure all my items will be processed.
Next I need a way to save the item. This can be done by updating a field value. But I don’t really want to change anything on the item, I just want to invoke the save event. For setting a field value in Revolver I can use the
sf command which also allows me to use the previous field value in the new field value through the token
Let’s put it all together.
First I need to navigate down to my news root item. Let’s assume this lives at
Now to execute the find command on all the children of that item.
find (sf -nv __updated ($prev$))
I’ve specified no parameters to
find so it will process all children. If I wanted all descendants I would need to add the
-r parameter. The parameter passed to
find (enclosed in brackets) is the command to execute against each matched item; the
sf command. This command will set the value of the
__updated field to the current (previous) value. Incidentally this actually has no affect as Sitecore will update the field value immediately after we update the field value to show when it was last updated. The
-nv parameter causes Revolver to not create a new version before updating the field value. By setting the field value the
item:saved event is raised and News Mover can restructure the news items.