Imagine a content editor working in Sitecore, overwhelmed by a sea of workflow commands. Some commands are relevant to the current task, while others just clutter the interface. What if you could streamline their experience, automatically hiding unnecessary options based on the item's data? Customizing the workflow command visibility using the Appearance Evaluator Type makes this a reality. By leveraging field values, you can tailor the user experience, ensuring editors see only the commands they need, when they need them. Keep reading to discover how to unlock the power of custom workflow command visibility in Sitecore!
Appearance Evaluator Type Field
When you see a workflow command pop up in the gutter or the review section in the content editor tabs that's an appearance evaluator doing its thing. It can tweak how the command looks, including:
- The command's name
- Its logo
- Whether it's visible or not
- If it should keep the comments dialog quiet
To make your own workflow command appearance evaluator, you'll need to use the IWorkflowCommandAppearanceEvalutaor
interface from the Sitecore.Workflows
namespace in the Sitecore.Kernel
assembly. The Sitecore.Workflows.BasicWorkflowCommandAppearanceEvaluator, Sitecore.Kernel
class is a great starting point - it already has defaults for all the characteristics above. So if you're creating your own evaluator, you can extend this class instead of implementing the interface from scratch.
Implementation
In this blog post, we will be delving into the details of how to control the visibility of a workflow command based on the value in a specific field, in this case, 'Scheduled At'. This feature is particularly useful in situations where different workflow commands need to be displayed under different circumstances. We will focus on the 'Approve and Schedule' workflow command and discuss how its visibility can be managed depending on whether a value is present in the 'Scheduled At' field. The unique requirement we'll be addressing here is that the command should only be displayed when the 'Scheduled At' field value indicates a future date. This dynamic and condition-based visibility of workflow commands can greatly enhance the user experience and make the system more intuitive and user-friendly.
Code Sample
using Sitecore;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
using Sitecore.Workflows;
using System;
namespace YourNameSpace.Foundation.Workflows
{
public class CommandAppearanceEvaluator : BasicWorkflowCommandAppearanceEvaluator
{
public override WorkflowCommandState EvaluateState(Item item, Item workflowCommand)
{
DateField publishValidFromDate = item.Fields["__Scheduled At"];
<span class="hljs-comment">// Check if the field is not set or if the scheduled date is past or present</span>
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">string</span>.IsNullOrEmpty(publishValidFromDate.Value)||DateUtil.ToServerTime(publishValidFromDate.DateTime) <span class="hljs-tag"><span class="hljs-tag"><</span><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name"><span class="hljs-tag"><span class="hljs-name">=</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">DateUtil.ToServerTime</span></span></span></span></span><span class="hljs-tag">(</span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">DateTime.UtcNow</span></span></span></span></span><span class="hljs-tag">))
{
</span></span><span class="hljs-keyword"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">return</span></span></span></span></span></span></span><span class="hljs-tag"><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">WorkflowCommandState.Hidden</span></span></span></span></span><span class="hljs-tag">;
}
</span></span><span class="hljs-comment"><span class="hljs-tag"><span class="hljs-tag">// </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">If</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">the</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">scheduled</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">date</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">is</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">in</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">the</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">future</span></span></span></span></span><span class="hljs-tag">, </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">evaluate</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">the</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">state</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">based</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">on</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">the</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">workflow</span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">command</span></span></span></span></span></span></span><span class="hljs-tag">
</span><span class="hljs-keyword"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">return</span></span></span></span></span></span></span><span class="hljs-tag"> </span><span class="hljs-keyword"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">base</span></span></span></span></span></span></span><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">.EvaluateState</span></span></span></span></span><span class="hljs-tag">(</span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">item</span></span></span></span></span><span class="hljs-tag">, </span><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr"><span class="hljs-tag"><span class="hljs-attr">workflowCommand</span></span></span></span></span><span class="hljs-tag">);
}
}
}
The CommandAppearanceEvaluator
class inherits from BasicWorkflowCommandAppearanceEvaluator
, which is a Sitecore class used for evaluating the appearance (visibility) of workflow commands based on certain conditions. It overrides the EvaluateState
method from the base class. This method is responsible for determining the state (e.g., enabled, disabled, hidden) of a workflow command for a given item.
Specifically, the code snippet here focuses on items that have a value in the Scheduled At field. If the Scheduled At date is either not set or has already passed, it hides the associated workflow commands. However, if the scheduled date is in the future, it defers to the default behavior to determine the visibility of the commands. In essence, this code ensures that particular workflow command related to items with past or missing scheduled publishing dates are hidden from view. Thereby prohibiting Approve & Schedule Publish from being visible whenever the Scheduled AT field is empty or have a past date.
Now we will have to link the code with the command. For that purpose we go the workflow command and provide the class and assembly associated.
The Result
In the above screenshot the Scheduled At field is empty and thereby the Approve & Schedule Publish command is hidden for the reviewer as well as the editor.
Once providing a future date the Approve & Schedule Publish shows up in the workflow commands as in the above screenshot
Harnessing Dynamic Workflow Control in Sitecore
Wrapping up, this nifty feature gives you dynamic control over what workflow commands are seen, depending on specific field values. It gets rid of the clutter by hiding what you don't need and makes life easier for content editors.
With the code example and guide we've given you in this blog, you've got a hands-on way to get a grip on controlling workflow command visibility.
Thanks for reading!!!