Workflow implementation is important for content governance. When content author updates a page in Sitecore experience editor, Sitecore notifies content author to submit the page to push it to next workflow state.
But what about the rendering data sources present on the page. Do they get pushed to next workflow state or not?
Sitecore does push the rendering data source items present on page to next workflow state if you have the below setting set to true in your configs (which is true by default Sitecore 8.2 onwards) -
<setting name="WebEdit.AffectWorkflowForDatasourceItems" value="true" patch:source="Sitecore.ExperienceEditor.config"/>
However, that's not all. Some of the rendering data sources may be dependent on other items (we will call them linked items), especially for container renderings (which act as container for other data items). There is no setting in Sitecore OOB that can push the linked items to next workflow state. Content authors have to manually push such data items to next workflow state which becomes problematic if they have to do it every now and then. So, if your content authors want to get these linked items pushed to next workflow state when they move page item to next workflow state, you may have to build customization. An easy way of doing this is by adding a custom action in workflow.
A custom action can be added to a command in workflow as in snapshot below -
The Type string points to class name where the logic for the custom action will be implemented. The logic implemented in the class -
- gets the page item on which submit action is being called
- gets the rendering data sources from the page item
- gets the linked items from the rendering data source items and stores them in a list.
- checks if the current users has permissions to push the items to next workflow state
- executes command to push the linked items to next workflow state.
Here goes the code implementing the logic -
public class DataSourceRelatedItemsWorkflowProcessing{public virtual void Process(WorkflowPipelineArgs args){var dataItem = ItemConverter.Convert(args.DataItem);var linkedItemList = GetItemsLinkedToDataSources(args.DataItem);foreach (var item in linkedItemList){if (item.Access.CanWrite() && (!item.Locking.IsLocked() || item.Locking.HasLock()))WorkflowUtility.ExecuteWorkflowCommandIfAvailable(item, args.CommandItem, args.CommentFields);}}private List<Item> GetItemsLinkedToDataSources(Item dataItem){var linkedItemList = new List<Item>();var linkFieldTypes = DataTypes.LinkedDataTypes;//Find all datasources of the page itemvar datasourceItems = ItemUtility.GetItemsFromLayoutDefinedDatasources(dataItem, Context.Device, dataItem.Language); ;foreach (var datasourceItem in datasourceItems){foreach (Field field in datasourceItem.Fields){if (linkFieldTypes.Any(linkFieldType =>linkFieldType.Equals(field.Type, StringComparison.OrdinalIgnoreCase))){var linkedItemIds = field.Value.Split('|');var linkedItems = from linkedItemId in linkedItemIdslet linkedItem = datasourceItem.Database.GetItem(linkedItemId, datasourceItem.Language)where linkedItem != nullselect linkedItem;linkedItemList.AddRange(linkedItems);}}}return linkedItemList;}}
public static class DataTypes{public static string[] LinkedDataTypes = new[]{"Droplink","Checklist","Multilist","Treelist","QueryTreeList","TreelistEx","Inline Item List","Multilist with Search","Relative TreeList"};}
Hope this helps to understand how we can customize Sitecore's workflow to make it more content author friendly :)
Comments
Post a Comment