In this article I will show another useful and great functionality from Sitecore: serialization of items having specific templates, on Save action.
The idea behind this post is that you might have some sensitive configuration or settings items, for which you would like to keep track of changes made or for version control.
The first step would be to create a new settings item, where to select the templates for items you want to keep serialized.
You can put something in the source of the Treelist like:
datasource=/sitecore/templates&includetemplatesforselection=Template
This will show items to select just under /Templates, and will allow users to select only *Templates *items, and nothing else.
Next, we need to define our own handler for the Save event, in Web.config:
<event name="item:saved">
...
<handler type="Custom.Serialization.SaveSerializationByTemplate, Custom.Serialization" method="OnItemSaved"/>
</event>
The type of the handler needs to be the class, followed by the assembly name, and the method attribute is the enter point for the event.
Here is the code for the method:
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Events;
using System;
using Sitecore.Data.Serialization;
using Sitecore.Diagnostics;
using Sitecore;
namespace Custom.Serialization
{
public class SaveSerializationByTemplate
{
private const string TEMPLATES_TO_SERIALIZE_FIELD_NAME = "Templates To Serialize";
private const string SERIALIZATION_SETTINGS_PATH = "/sitecore/content/Settings/serialization-settings";
public void OnItemSaved(object sender, EventArgs args)
{
Item currentItem = SitecoreEventArgs.GetItem(args, 0);
if (currentItem == null || currentItem.TemplateID.IsNull)
{
return;
}
Item serializationSettings = Context.ContentDatabase.GetItem(SERIALIZATION_SETTINGS_PATH);
if (serializationSettings != null && !string.IsNullOrEmpty(serializationSettings[TEMPLATES_TO_SERIALIZE_FIELD_NAME])
&& serializationSettings[TEMPLATES_TO_SERIALIZE_FIELD_NAME].Contains(currentItem.TemplateID.ToString()))
{
Log.Info("Serialization started for: " + currentItem.Paths.FullPath, this);
ShadowWriter.PutItem(Operation.Updated, currentItem, currentItem.Parent);
}
}
}
}
In the EventArgs, Sitecore sends us the current item for which the Save is made. Then, I am getting the Serialization settings item from the content database (master), and check if the template of the current item is found within the selected ones from the settings item.
If found, I am logging the operation and writing the item path, then* call the Serialization method*.
The result is that under the serialization folder, Sitecore will create a .item file, where the serialized version of the Item will be found.
The root folder for Serialization is defined in Web.config:
<!-- SERIALIZATION FOLDER
Points to the root of serialized databases tree (when using serialization functionality). Default value: $(dataFolder)/serialization
-->
<setting name="SerializationFolder" value="$(dataFolder)/serialization" />
and can be changed to point to a custom folder.
There are some further benefits we can achieve from this functionality. We could have an external monitoring tool on that folder, and when a change happens, automatically put the new changes to our Version Control System. This way, we will have a track of all the changes made, and easily be able to revert to one of them.
The “Revert” command can be called from the “Developer” option in the Ribbon:
When this is called, Sitecore checks in the Serialization location, in the above example being:
serializationmastersitecorecontentHomeall-fields.item
and if the file is found, it will apply these rules: It will adjust the item to have the versions & values from the file, and changes from the database that aren’t found in the file, will be removed. (extra versions, different field values).
It is important to keep in mind that by using this option, we can have some data-loss.
Another option would be to hit the “Update” button, instead of Revert.
With Update, the behavior changes, as Sitecore will try to fetch any versions from the file that aren’t in the database, and add them if that’s the case. If a version exists both in the file and in the database, Sitecore will overwrite it only if the date in the “Updated” field in the file is newer than the one from the database.
Another difference between Revert and Update is that when using the last one, Sitecore won’t overwrite the “Item name”, “Template ID”, “Origin ID” and “Parent ID” fields of the item.
Having the big picture in mind, there are also some improvements that can be done to the code: since the event is firing on every Save of an item to check against its template, we can store the Serialization Settings item in a Custom Sitecore Cache, and improve the performance for the behavior, as I will show in a future post.
Nonetheless, there’s no need for limiting just to the “Save” event for this. Maybe we want to add the serialization for a “item:versionRemoved” or even an “item:deleting” event, just keep your mind open about it
This is all, hope you find the functionality useful.