Try Now
More in this section
Blogs RSS feed

Sitefinity Workflow: Defining the Scope of the Workflow by Page Groups

by Peter Marinov

“Divide et impera” or Divide and Conquer

In a series of blog posts, we have examined how the workflow can be used to achieve various customizations. The posts reviewed how we can create advanced customizations to help meet any business case with ease by using code and guard activities.

This post will recount yet another way to leverage the Windows Workflow Foundation (WWF) implementation in Sitefinity CMS. Specifically, you will learn how to create custom guard activities with which you can implement complex logic within the elements of the workflow. So, let’s get to it.

The Question

Workflow in Sitefinity is scoped by content type—Pages, News items. Blogs, Events, etc. For example, if we take the Pages, you would define a workflow for all the pages on the web site and the approvers would be responsible for all them.

But what if we wanted to have different approvers for different page groups? The HR department wants to approve all pages under “About Us,” while the marketing team wants ownership of all product related pages. Sitefinity easily accommodates this type of scenario, and we’ll go through how below.

Group Pages with No Solution

The Solution

In a previous blog post (link here), I described how Guard Activities are used like filters to prevent users from passing beyond certain points on the workflow. By using them, we can control the business logic and the UI of Sitefinity. The built-in Guard Activities have properties to help us facilitate that process, but we will instead use something more advanced to tackle this.

We will implement a custom guard activity to help us incorporate a logic to check if a user is assigned to special approvers group responsible for any given group page and its associated child pages.

The Steps

For this solution, we have to consider different factors like maintenance and implementation. With that in mind, using Role naming convention is a good solution. For example, we can create some roles like “Workflow-About Us” and “Workflow-Products,” then assign the respective users to these roles.

Group Pages with Solution

In the custom GuardActivity, we will first identify the current page parent group. If there is a nested hierarchy, we will traverse the ancestors of the page node to find the group to get the parent group page.

Once you have the name of the group page, check the user roles for the users in question to see if the user has a role for this particular page group.

Below is a sample guard activity that can be used. You can also download the sample files with the instructions from this link.

using System;
using System.Activities;
using System.Linq;
using System.Web;
using Telerik.Sitefinity.Security;
using Telerik.Sitefinity.Workflow.Activities;
namespace SitefinityWebApp.Workflows
    public class PageGroupsGuardActivity : GuardActivity
        protected override void Execute(CodeActivityContext context)
            var property = context.DataContext.GetProperties()["workflowItem"];
            if (property != null)
                var securedItem = property.GetValue(context.DataContext);
                var pageNode = securedItem as Telerik.Sitefinity.Pages.Model.PageNode;
                string groupName = null;
                while (pageNode.Parent != null)
                    var parent = pageNode.Parent;
                    if (parent.NodeType == Telerik.Sitefinity.Pages.Model.NodeType.Group) // you can add a check if it is one of your top groups
                        groupName = parent.Title;
                    pageNode = pageNode.Parent;
                if (string.IsNullOrEmpty(groupName)) return;
                string neededRole = string.Concat("Workflow-", groupName);
                var roles = SecurityManager.GetCurrentUser().GetRoles();
                bool isInRole = false;
                foreach (var role in roles)
                    if (role.Equals(neededRole, StringComparison.InvariantCultureIgnoreCase))
                        isInRole = true;
                if (!isInRole)
                    throw new HttpException(String.Format("You are not allowed to work on that page. To do so, you should be in role {0}", neededRole));

What’s next

I hope you will find this review useful. Following a similar approach, you can create workflows scoped by culture or by blog, blog post–just name it. The options are endless.

As a final note, your feedback is much appreciated. Please let us know about any advanced scenarios you would like to see us address in future posts.  We will surely take them into consideration when improving the workflow for future releases.

Leave a comment