Workflow
In Orchard Core, workflows, webhooks, and other custom actions can be triggered by events such as publishing or unpublishing a content item. These capabilities are part of Orchard Core's extensibility and event-driven architecture.
Think of a workflow like a recipe for tasks we want to happen automatically in our CMS. For example:
When a user fills out a form, send them an email.
When we create a new content item, notify someone.
Schedule a task to run at a specific time.
A workflow has two main parts:
Trigger: This is what starts the workflow, like "Content Item Created" or "Form Submitted".
Tasks: These are the steps that happen after the trigger, like "Send Email" or "Show Notification".
Create Workflow via Admin Dashboard
For the simplicity of our demo, let's say we want to write a log every time a content item is created.
Before we begin, we need to make sure the OrchardCore.Workflows
feature is enabled.
To create a new workflow, please visit the Configuration > Workflows in the admin menu.
After clicking on New Workflow, we can give our workflow a name, like "Log on Content Creation".
We then need to Save to proceed.

After creating the workflow, we need to add a new trigger. Here, we choose "Create Content" as the trigger. This means the workflow will start whenever a new content item is created.

Next, we click Add Task to add a task. Choose "Log" as the task.

Finally, we need to connect the Content Created Trigger to the Send Email activity. This tells Orchard Core, "When a content item of Product Information is created, log a Information message."

We also need to indicate the trigger as our Startup Event by clicking on it and select the "power icon" to mark it as startup event, as pointed out in the screenshot below.

As shown in the screenshot above, in order for a workflow to execute, at least one activity must be marked as the start of the workflow. Only triggers can be marked as the start of a workflow. A workflow can have more than one start event. This allows us to trigger a workflow in response to various types of events.
Test of Workflow Trigger
Now, when we create a new Product Information content item, a log will be printed out in the console, as shown below.

In fact, we can also head to the Instances page to view the history of workflow executions.

The Text field of the log event accepts Liquid. Let's use Liquid template to enhance it so that we know who created the content item. By default, the Liquid templates have access to a common set of objects. In addition, there are other properties available by default to any activity that supports Liquid expressions. So, we can do something as follows.
This is a log from the Workflow for Product Information Creation:
{{ Workflow.Input.ContentItem | json }} - User: {{ User.Identity.Name }}.

Start the Workflow Programatically
In Orchard Core, we can use StartWorkflowAsync
to run workflows. This method starts a new workflow instance based on a given workflow type.
Firstly, we retrieve a list of available workflow types which is available through IWorkflowTypeStore
.
var workflowTypes = await workflowTypeStore.ListAsync();
For our example above, since we only have one workflow, the method above should return the following JSON.
"workflowTypes": [
{
"id": 52,
"workflowTypeId": "4y8rkbh0xbbchrd9k26tdswpnd",
"name": "Log on Content Creation",
"isEnabled": true,
"isSingleton": false,
"lockTimeout": 0,
"lockExpiration": 0,
"deleteFinishedWorkflows": false,
"activities": [
{
"activityId": "4yshv2dkk07s96v69yg1d94rwe",
"name": "ContentCreatedEvent",
"x": 0,
"y": 60,
"isStart": true,
"properties": {
"ContentTypeFilter": [
"ProductInformation"
],
"ActivityMetadata": {
"Title": "Product Information Creation"
}
}
},
{
"activityId": "4fpj20x90qtmkss8jgdzh0sgna",
"name": "LogTask",
"x": 450,
"y": 50,
"isStart": false,
"properties": {
"ActivityMetadata": {
"Title": "Product Information Creation Log"
},
"LogLevel": "Information",
"Text": {
"Expression": "This is a log from the Workflow for Product Information Creation: {{ Workflow.Input.ContentItem | json }} - User: {{ User.Identity.Name }}."
}
}
}
],
"transitions": [
{
"id": 0,
"sourceActivityId": "4yshv2dkk07s96v69yg1d94rwe",
"sourceOutcomeName": "Done",
"destinationActivityId": "4fpj20x90qtmkss8jgdzh0sgna"
}
],
"properties": {}
}
]
Hence, for demo purpose, let's see how we can start this workflow which has the id 52.
// ...
using OrchardCore.Workflows.Services;
namespace OCBC.HeadlessCMS.Controllers;
[ApiController]
[Route("api/v1/product")]
public class ProductController(
// ...
IWorkflowTypeStore workflowTypeStore,
IWorkflowManager workflowManager) : Controller
{
// ...
[HttpGet("trigger-workflow/{contentItemId}")]
public async Task<IActionResult> TriggerWorkflowDemo(string contentItemId)
{
// Load the workflow definition.
var workflowType = await workflowTypeStore.GetAsync(52);
if (workflowType == null)
{
return BadRequest(new { Error = "Workflow not found." });
}
var productInformation = await orchard.GetContentItemByIdAsync(contentItemId);
var input = new Dictionary<string, object>()
{
{ "ContentItem", productInformation },
};
// Invoke the workflow.
var workflowContext = await workflowManager.StartWorkflowAsync(workflowType, input: input);
return Ok(new { workflowTypes, workflowContext });
}
}
When we visit this endpoint, we shall see a new instance being created in the execution history of this workflow.
HTTP Workflow
Orchard Core provides HTTP-related task which allows us to perform a HTTP request to a given URL through OrchardCore.Workflows.Http
.
Before we begin, we need to make sure the OrchardCore.Workflows.Http
feature is enabled.
Let's create a HTTP request task as shown below.

The URL used in this example is Beeceptor, a mock API service. Beeceptor is a free, lightweight service designed for testing, mocking, and intercepting HTTP APIs. It is an excellent tool for quickly setting up endpoints to simulate or test API requests without needing to build a backend service.
After that, we link this HTTP request task with the Log task we created above, as demonstrated in the following screenshot.

So when this workflow is started, we shall see not just a log printed in the console, but the Beeceptor will detect that the endpoint /orchard-core
is called.

Last updated