LibrarySites.Banner

Dynamic Workflow Command Appearance

Sitecore 8 allows developers to dynamically control the name, logo, visibility and suppress comments on any workflow command. This allows developers to change how commands appear in the UI based on any custom code which can increase usability of implementations.

With the content testing features we've added in Sitecore 8, we found we needed to change the appearance of workflow commands depending on the state of the item. This requirement surfaced when we added the "Approve with Test" command to the sample workflow. It would be frustrating for users if they executed this command only to have the test creation dialog report there are no test candidates available.

Content testing workflow approval commands

In previous versions of Sitecore we already had the capability to hide a command based on any custom logic we like. Have a look at the sample workflow that comes out-of-the-box. That "__OnSave" command on the "Draft" state is never shown in the UI. There is a class used to filter that command out. But in Sitecore 8, we don't just want to hide a command, we also needed to change the text of the command.

We have 3 commands on the "Awaiting Approval" state: "Approve with Test", "Approve without Test" and "Reject". Sure, we could filter out "Approve with Test" and hide it from display, but then the only approval command would be "Approve without Test" which might be accepted by some users but seems a little odd.

To overcome this we've introduced "Workflow Command Appearance Evaluators" in Sitecore 8. An appearance evaluator is invoked when a command will be displayed in the UI and the evaluator can change any of the appearance characteristics on the command including:

  • Command name
  • Command logo
  • Command visibility
  • Whether the comments dialog should be suppressed

Workflow command appearance evaluators must implement the IWorkflowCommandAppearanceEvalutaor interface available in the Sitecore.Workflows namespace of the Sitecore.Kernel assembly. The Sitecore.Workflows.BasicWorkflowCommandAppearanceEvaluator, Sitecore.Kernel class is a workflow command appearance evaluator that provides defaults for each of the characteristics above. So in practice, if you're implementing your own appearance evaluator you can extend this class rather than just implementing the interface and having the provide implementations for all the methods.

Out-of-the-box we've included a workflow command appearance evaluator that always hides a command: Sitecore.Workflows.HiddenCommandStateEvaluator, Sitecore.Kernel. You can see this in use on the "__OnSave" command of the updated sample workflow in Sitecore 8.

To assign an appearance evaluator to a command simply specify the .net type of the class in the Appearance Evaluator Type field of the command definition item itself.

Hidden command state evaluator

So let's take a look at a custom workflow command appearance evaluator that will convert the name of the command to be reversed and hide the command on Mondays. I didn't say this appearance evaluator would be useful except as a demonstration aid. :)

Start with creating a new class which inherits from BasicWorkflowCommandAppearanceEvaluator.

using Sitecore.Workflows;

namespace Sandbox.Workflows
{
  public class SillyAppearanceEvaluator : BasicWorkflowCommandAppearanceEvaluator
  {

  }
}

Now we'll override the GetCommandName() method to reverse the command name.

public override string GetCommandName(Item item, Item workflowCommand)
{
  var name = base.GetCommandName(item, workflowCommand);
  return string.Join("", name.ToCharArray().Reverse());
}

And now we'll override the WorkflowCommandState() method to change the visibility based on the day of the week.

public override WorkflowCommandState EvaluateState(Item item, Item workflowCommand)
{
  if (DateTime.Now.DayOfWeek == DayOfWeek.Monday)
    return WorkflowCommandState.Hidden;
  else
    return base.EvaluateState(item, workflowCommand);
}

With that all compiled and deployed to my solution I can now make use of this obscure appearance evaluator by adding the type name of it to the Appearance Evaluator Type field of a workflow command.

Custom workflow command appearance evaluator assigned to command

And here's how the command now displays, at least when it's not a Monday.

Custom workflow command appearance evaluator in action

Alistair Deneys

Content Testing Project Team

  • Interesting. A similar concept is implemented slightly different for the Experience Editor ribbon buttons. The "Other" button that converts to Preview or Debug or Explore based on the selection you make. That button has SPEAK presentation details that define IconAndLabelRequest "command". The command is PipelineProcessorRequest<ValueItemContext> that responds with a JSON structure that has an icon and a label. I wonder if you plan on adapting the same technique when the workflow buttons get SPEAK-ified as well.   There's also an analogue to the good old Sheer's QueryState() on commands that determines whether a button is enabled or disabled (the canExecute() method on the SPEAK JavaScript command).   I guess I wonder if it's truly warranted to have a special IWorkflowCommandAppearanceEvalutaor? Will other parts have their own I<SubjectArea>AppearanceEvaluator as well or rather adopt a more generic technique that allows to show/hide UI elements as well as change their appearance based on current context?

  • Good points Pavel. However with the workflow stuff above we needed a way to tie the evaluator to the command itself. It's not part of the button. If we had static buttons we could have used QueryState(), but the buttons themselves are dynamically created based on the workflow options. This is why it wasn't appropriate to use something like that.   To make use of SPEAK techniques we'd need to have the workflow commands contain SPEAK layout details. Interesting idea for the future...