If you need to execute custom business logic when an item is published in Sitecore CMS, the best way to achieve this is by creating a custom workflow action. This allows you to hook into Sitecore’s publishing process and inject your own logic when content is published, whether it involves modifying CMS content, interacting with external services, or any other tasks you may need to automate.
This guide will walk you through the steps of creating a custom workflow action in Sitecore, and we'll provide you with an example code snippet that you can adapt for your own business logic. The instructions below are applicable to all versions of Sitecore CMS.
Step 1: Set Up a Workflow Action in Sitecore
First, you need to create a workflow within Sitecore that triggers when an item is published. For this, you'll assign the Auto Publish action to the Published state. This action will be responsible for executing the workflow when content is published.
To integrate your custom business logic, you'll need to specify the C# class name and its associated assembly in the workflow. This class will contain the logic that should run when the item transitions to the Published state.
Step 2: Write Your Custom Action C# Class
In this step, you will write the C# code that defines the custom action for your workflow. This action could perform a wide range of tasks—such as modifying fields in the published item, calling external APIs, or executing other system operations as part of the publishing process.
Below is an example of how you can write a custom workflow action class in Sitecore:
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Publishing;
using Sitecore.SecurityModel;
using Sitecore.Web;
using Sitecore.Workflows.Simple;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
namespace ABC.Foundation.Configuration.Pipelines
{
public class CustomPublishAction
{
// Method that will be invoked during the workflow
public void Process(WorkflowPipelineArgs args)
{
// Retrieve the item being processed
Item dataItem = args.DataItem;
Item innerItem = args.ProcessorItem.InnerItem;
NameValueCollection urlParameters = WebUtil.ParseUrlParameters(innerItem["parameters"]);
// Retrieve custom parameters for deep publishing, related items, etc.
bool deep = GetDeep(urlParameters, innerItem);
bool related = GetRelated(urlParameters, innerItem);
Database[] targetDatabases = GetTargets(urlParameters, innerItem, dataItem).ToArray();
Language[] languages = GetLanguages(urlParameters, innerItem, dataItem).ToArray();
bool compareRevisions = IsCompareRevision(urlParameters, innerItem);
// Ensure publishing settings are enabled and we have valid targets and languages
if (!Settings.Publishing.Enabled || !targetDatabases.Any() || !languages.Any())
return;
// Perform the publishing action
PublishManager.PublishItem(dataItem, targetDatabases, languages, deep, compareRevisions, related);
// Here you can add your custom logic, such as updating item fields or making API calls
// Example: Get the current item's fields like Title and Description
// You can further call external APIs or modify fields here
}
// Check if the publishing is deep (recursive)
private bool GetDeep(NameValueCollection parameters, Item actionItem) =>
GetStringValue("deep", parameters, actionItem) == "1";
// Check if revision comparison is enabled
private bool IsCompareRevision(NameValueCollection parameters, Item actionItem) =>
GetStringValue("smart", parameters, actionItem) == "1";
// Check if related items should be published
private bool GetRelated(NameValueCollection parameters, Item actionItem) =>
GetStringValue("related", parameters, actionItem) == "1";
// Get the target databases for publishing
private IEnumerable<Database> GetTargets(NameValueCollection parameters, Item actionItem, Item dataItem)
{
using (new SecurityDisabler())
{
var sources = GetEnumerableValue("targets", parameters, actionItem).ToList();
// Default to the system publishing targets if no specific target is defined
if (!sources.Any())
{
Item targetsItem = dataItem.Database.Items["/sitecore/system/publishing targets"];
if (targetsItem != null)
sources = targetsItem.Children.Select(child => child["Target database"]).Where(dbName => !string.IsNullOrEmpty(dbName)).ToList();
}
foreach (var dbName in sources)
{
Database database = Factory.GetDatabase(dbName, false);
if (database != null)
yield return database;
else
Log.Warn($"Unknown database in PublishAction: {dbName}", this);
}
}
}
// Get the languages to be used for publishing
private IEnumerable<Language> GetLanguages(NameValueCollection parameters, Item actionItem, Item dataItem)
{
using (new SecurityDisabler())
{
IEnumerable<string> languageNames = Enumerable.Empty<string>();
if (GetStringValue("alllanguages", parameters, dataItem) == "1")
{
// If all languages are selected, fetch them from the system languages
Item languagesItem = dataItem.Database.Items["/sitecore/system/languages"];
if (languagesItem != null)
languageNames = languagesItem.Children.Where(child => child.TemplateID == TemplateIDs.Language)
.Select(child => child.Name);
}
else
{
// Use the languages specified in the parameters
languageNames = GetEnumerableValue("languages", parameters, actionItem);
string itemLanguage = GetStringValue("itemlanguage", parameters, dataItem);
if ((itemLanguage == "1" || itemLanguage == null) && !languageNames.Contains(dataItem.Language.Name))
yield return dataItem.Language;
}
// Yield the language objects for publishing
foreach (var languageName in languageNames)
{
if (Language.TryParse(languageName, out var language))
yield return language;
else
Log.Warn($"Unknown language in PublishAction: {languageName}", this);
}
}
}
// Helper methods to fetch values from parameters or item fields
private string GetStringValue(string name, NameValueCollection parameters, Item actionItem)
{
string value = actionItem[name];
return !string.IsNullOrEmpty(value) ? value : parameters[name];
}
private IEnumerable<string> GetEnumerableValue(string name, NameValueCollection parameters, Item actionItem)
{
string value = actionItem[name];
if (!string.IsNullOrEmpty(value))
return value.Split('|', StringSplitOptions.RemoveEmptyEntries);
string parameter = parameters[name];
return string.IsNullOrEmpty(parameter) ? Enumerable.Empty<string>() : parameter.Split(',', StringSplitOptions.RemoveEmptyEntries);
}
}
}
Step 3: Test and Validate Your Custom Workflow Action
Once you've created the custom workflow action, it's time to test it. To do this, publish an item in Sitecore and verify if the business logic inside your C# class is executed properly. You can use debugging tools or log output to monitor the behavior of your custom action.
Ensure that any custom actions you’ve defined (e.g., updating fields, making API calls) are working as expected. You can refine and expand the logic as needed for more complex use cases.
By using a custom workflow action in Sitecore, you can automate complex tasks as part of the content publishing process. Whether you’re interacting with external systems, updating item fields, or performing other custom operations, this approach gives you the flexibility to integrate business logic directly into the publishing lifecycle.
Importance and Benefits of Custom Workflow Actions:
Creating custom workflow actions in Sitecore offers several significant advantages for your content management and publishing processes:
Automate Complex Tasks: By adding custom business logic to the publishing pipeline, you can automate tasks that would otherwise require manual intervention. This helps save time, increase efficiency, and ensure consistency across your content management operations.
Enhanced Flexibility: Sitecore’s custom workflow actions allow you to hook into the publishing process at any point and perform tasks tailored to your business needs. Whether you need to update item fields, notify external systems, or initiate downstream processes, you can customize the publishing workflow to fit your exact requirements.
Improved Workflow Management: By utilizing custom actions, you ensure that your publishing workflow is aligned with the broader business logic of your organization. This means that publishing operations are not just about moving content to the live environment—they can also trigger necessary business functions automatically.
Increased Control and Compliance: Custom workflow actions give you fine-grained control over the publishing process. For example, if certain content requires validation or approval from an external service before being made live, you can integrate this into the workflow. This ensures that your publishing process aligns with organizational requirements and complies with any internal or external regulations.
Integration with External Systems: Custom workflow actions can be used to integrate Sitecore with external systems, such as CRMs, marketing automation platforms, or analytics tools. This makes it easier to trigger actions in other systems as part of the publishing process, ensuring your entire technology stack works together seamlessly.
Streamlined User Experience: With automated processes, content managers and editors can focus on creating and curating high-quality content, rather than dealing with manual publishing steps. The workflow becomes more intuitive, and users can rely on automated actions to handle repetitive or complex tasks.
By creating a custom workflow action in Sitecore CMS, you unlock the potential to automate complex tasks during the content publishing process. Whether you’re modifying fields, integrating with external APIs, or managing other business operations, custom workflow actions provide the flexibility and control needed to streamline your publishing workflow.
This approach not only saves time and reduces errors but also enables you to scale your operations by automating repetitive tasks and ensuring that all your business logic is integrated directly into the Sitecore publishing lifecycle.
Start integrating custom business logic into your Sitecore publishing process today to enhance your content workflows, improve efficiency, and ensure seamless integration with external systems.
Happy learning and automating your Sitecore workflows!