1

I have a requirement to add the workflow submit button to the Experience Editor same as it appears in Content Editor.

I am aware that Sitecore displays Submit as a link in the message notification for the items in Draft state but I need to add a button to ribbon that can perform the same action as link.

Is there a way to do that?

0

After a long analysis, I finally managed to implement this and make it to work. The solution works and is tested on Sitecore 9.0.2. The flow is as follows:

  1. Create a class responsible for checking if the current selected item is using the correct workflow and if the button should be enabled or disabled for the current selected item.
  2. Create another class that is responsible for the action executed after clicking the button.
  3. Create required items in Sitecore Core Db and Master Db.
  4. Create a config to register the Speak request.

Detailed description of the steps, is as follows: Create a class called "CanExecuteSubmitWorkflow".

using Sitecore.Data.Items;
using Sitecore.ExperienceEditor.Speak.Server.Contexts;
using Sitecore.ExperienceEditor.Speak.Server.Requests;
using Sitecore.ExperienceEditor.Speak.Server.Responses;

namespace Sitecore.Workflows.Custom.ExperienceEditor
{
    public class CanExecuteSubmitWorkflow : PipelineProcessorRequest<ItemContext>
    {
        private const string DRAFT_WORKFLOW_STATE_ID = "{480BE83A-32A9-4E96-959D-4A35303B22D6}";// ID of the custom draft state of my custom workflow.
        public CanExecuteSubmitWorkflow()
        {
        }
        public override PipelineProcessorResponseValue ProcessRequest()
        {
            Item currentItem = base.RequestContext.Item;

            if (currentItem != null)
            {
                 if (currentItem.State?.GetWorkflowState()?.StateID.ToLower() == DRAFT_WORKFLOW_STATE_ID.ToLower())
                {
                    return new PipelineProcessorResponseValue()
                    {
                        Value = true
                    };
                }
            }

            return new PipelineProcessorResponseValue()
            {
                Value = null
            };
        }
    }
}

Create another class called "SubmitWorkflowProcessor".

using System.Linq;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.ExperienceEditor.Speak.Server.Contexts;
using Sitecore.ExperienceEditor.Speak.Server.Requests;
using Sitecore.ExperienceEditor.Speak.Server.Responses;
using Sitecore.Workflows;

namespace Sitecore.Workflows.Custom.ExperienceEditor
{
    public class SubmitWorkflowProcessor
    : PipelineProcessorRequest<ItemContext>
    {
        private const string DRAFT_WORKFLOW_STATE_ID = "{480BE83A-32A9-4E96-959D-4A35303B22D6}";// ID of the custom draft state of my custom workflow.
        private const string WORKFLOW_COMMAND_NAME = "Submit for approval"; // name of command item created under the /sitecore/system/workflows.
        public SubmitWorkflowProcessor()
        {
        }

        public override PipelineProcessorResponseValue ProcessRequest()
        {
            Item contextItem = base.RequestContext.Item;
            WorkflowResult workflowResult = null;

            var pipelineProcessorResponseValue = new PipelineProcessorResponseValue()
            {
                Value = null
            };

            if (contextItem != null)
            {
                if (contextItem.State?.GetWorkflowState()?.StateID.ToLower() == DRAFT_WORKFLOW_STATE_ID.ToLower())
                {
                    workflowResult = UpdateWorkflowState(contextItem, WORKFLOW_COMMAND_NAME.ToLower(), string.Empty);
                }
            }

            if (workflowResult != null && workflowResult.Succeeded)
            {
                pipelineProcessorResponseValue = new PipelineProcessorResponseValue()
                {
                    Value = true
                };
            }

            return pipelineProcessorResponseValue;
        }

        public static WorkflowResult UpdateWorkflowState(Item item, string commandName, string comment)
        {
            IWorkflow workflow = item.Database.WorkflowProvider.GetWorkflow(item);

            if (workflow == null)
            {
                return new WorkflowResult(false, "No workflow assigned to item");
            }

            WorkflowCommand command = workflow.GetCommands(item[FieldIDs.WorkflowState])
            .FirstOrDefault(c => c.DisplayName.ToLower() == commandName);

            if (command == null)
            {
                return new WorkflowResult(false, "Workflow command not found");
            }

            return workflow.Execute(command.CommandID, item, comment, false, new object[0]);
        }
    }
}

Create a Javascript file to call these class methods. The name of the file is "Sitecore.Workflow.ExperienceEditor.SubmitWorkflow.js".

define(["sitecore", "/-/speak/v1/ExperienceEditor/ExperienceEditor.js"], function (Sitecore, ExperienceEditor) {

    Sitecore.Commands.SubmitWorkflow =
    {
        canExecute: function (context) {
            var key = "ExperienceEditor.CanExecuteSubmitWorkflow";
            if (Sitecore[key] === undefined) {
                Sitecore[key] = context.app.canExecute("ExperienceEditor.CanExecuteSubmitWorkflow", context.currentContext);
            }
            return Sitecore[key];           
        },
        execute: function (context) {
        ExperienceEditor.PipelinesUtil.generateRequestProcessor("ExperienceEditor.ExecuteSubmitWorkflow", function (response) { 
           window.top.location.reload();
        }).execute(context);

        }
    };
});

Save this file inside \scripts\.

Create a config patch file to register the speak requests "Workflow.ExperienceEditor.Patch.config".

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" 
           xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore role:require="Standalone or ContentManagement">
    <sitecore.experienceeditor.speak.requests>
      <request name="ExperienceEditor.CanExecuteSubmitWorkflow" type="GNH.Foundation.Workflows.ExperienceEditor.CanExecuteSubmitWorkflow, GNH.Foundation.Workflows" />
      <request name="ExperienceEditor.ExecuteSubmitWorkflow" type="GNH.Foundation.Workflows.ExperienceEditor.SubmitWorkflowProcessor, GNH.Foundation.Workflows" />
    </sitecore.experienceeditor.speak.requests>
  </sitecore>

  1. Login to Sitecore.
  2. Switch to Core database.
  3. Create a new Sitecore.
  4. Item in "/sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Page Editor/" and name it WorkFlowChunk. This item should be created from "/sitecore/templates/System/Ribbon/Chunk" template.
  5. Set the ID field value to "HiddenContentChunk". Inside this item, create another item called "Submit for Approval" that is created from "/sitecore/templates/System/Ribbon/Large Button" template.
  6. Set the ID Field value to "SubmitForApproval".
  7. Go to Presentation->Details of this item. Add "Large Button" rendering.
  8. Go to Control Properties of this rendering.
  9. Add "trigger:button:click" to the Click field.
  10. Add "SubmitWorkflow" in the Command field.
  11. Add "SubmitButton" in the Id field.
  12. Check the "PostponedCall" checkbox.
  13. Add the path to the above script file in "PageCodeScriptFileName" field.
  14. Switch to master database.
  15. Under the workflow, create the command "Submit for approval". The name should match the constant name in the code.

Please note that the above example is coded to work with one Workflow and one Workflow Id which is fixed in the code. This can be implemented to work with any workflow just by doing minor changes.

This should provide a button in the ribbon of experience editor. enter image description here

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.