Adding Options to Sitecore Applications
Recently I was asked what I like the most about Sitecore. There are many reason’s I like Sitecore, but one stand out reason is it’s extensibility. I like how I can extend Sitecore’s UI and processes to add my own functionality or change how Sitecore works to meet my client’s requirements.
So, extending the Sitecore UI. On a recent project we had a requirement to provide a utility that was context sensitive. The utility in question was to perform operations on users, so I looked into extending the Sitecore User Manager application. I chose this application cause it already provides the functionality to list and search for users. I can select a user and perform various actions on that user.
Much of Sitecore’s UI is defined in the core
database. This is where most of those menus and ribbons that you use every day are defined. When you see an application in Sitecore that contains a ribbon, such as the Content Editor, User Manager, Workbox, etc, those ribbons are defined in the core
DB. This is where we can easily extend the applications with our own custom context sensitive commands.
In this article I’d like to add a command to the User Manager to allow me to reset some custom properties for a user. This basic approach can be used to create your own context sensitive application for any of the Sitecore applications mentioned above.
Firstly, we need to create the new ribbon entry to have it appear on the UI. Using the database switcher on the desktop tray, switch to the core
database, open the content editor and navigate down to /sitecore/content/Applications/Security/User Manager/Ribbon/Home/Tools
. This item is the definition for the tool chunk on the User Manager’s ribbon. Insert a new item based on the template System/Ribbon/Small button
and name it “Reset Custom Properties”. Fill in the fields as follows:
Field
Value
Header
Reset Custom Properties
Icon
Applications/32x32/notebook_preferences.png
Click
usermanagercust:resetcustomprops
The Header
and Icon
fields are shown on the ribbon. The Click
field refers to a Sitecore command which we’ll define in one moment. Your item should look like this:
The Click
field contains the name of a Sitecore command to execute. Sitecore will match this command to a command in the /configuration/sitecore/commands
configuration element by name. By default, Sitecore defines all it’s commands in the App_Config\Commands.config
file. But we’ll define our command in a config patch file so we don’t update any Sitecore provided files. Create a new file at App_Config\Include\CustomCommands.config
and enter the following:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<commands>
<command name="usermanager:resetcustomprops"
type="Demo.Commands.ResetCustomProperties,Demo"/>
</commands>
</sitecore>
</configuration>
The type
in the command definition refers to the Command type to instantiate and execute. Now onto creating our custom command type. Compile the following code in Visual Studio and drop the resulting assembly into the bin
folder. The following code is just the shell of the command, wired up to show everything working.
using Sitecore.Shell.Framework.Commands;
using Sitecore.Web.UI.Sheer;
namespace Demo.Commands
{
public class ResetCustomProperties : Command
{
public override void Execute(CommandContext context)
{
SheerResponse.Alert("ResetCustomProperties");
}
}
}
In the code above we define a new class which implements the abstract class Sitecore.Shell.Framework.Commands.Command
. The Execute()
method is called when the user clicks the command in the Sitecore UI, so this is where we implement our logic. In the above code, I’m simply telling the client page to display a javascript alert to the user to prove the code was called through the user of the SheerResponse.Alert()
method.
Now when I open the user manager in Sitecore I see our new custom ribbon button displayed and if I click it I see the alert message from our command class.
The above shows the basics for extending the ribbon with new commands. We could implement the logic to fulfil the command inside the Execute()
method, but if we have an operation that will take some time to complete, this approach would provide no feedback to the user and would lock the UI as a postback is processing. To make it more usable and non-blocking we can leverage techniques from my article Long Running Process Options. The technique I’ll implement for this scenario is using the Progress Box.
using Sitecore.Security.Accounts;
using Sitecore.Shell.Applications.Dialogs.ProgressBoxes;
using Sitecore.Shell.Framework.Commands;
namespace Demo.Commands
{
public class ResetCustomProperties : Command
{
public override void Execute(CommandContext context)
{
ProgressBox.Execute("ResetCustomProperties",
"Reset Properties",
new ProgressBoxMethod(ExecuteOperation),
context.Parameters["username"]);
}
protected void ExecuteOperation(params object[] parameters)
{
if(parameters == null || parameters.Length == 0)
return;
string username = parameters[0].ToString();
if (!string.IsNullOrEmpty(username))
{
var user = User.FromName(username, false);
if (user != null)
{
if (Sitecore.Context.Job != null)
Sitecore.Context.Job.Status.Messages.Add(
"Resetting properties for user " + username);
user.Profile.RemoveCustomProperty("prop1");
user.Profile.RemoveCustomProperty("prop2");
user.Profile.RemoveCustomProperty("prop3");
}
}
}
}
}
In the above code, we’ve used the static Execute()
method of the ProgressBox
class to create a progress dialog box on the Sitecore client page. The last two parameters of the method are the delegate to run and any parameters to pass. The username
parameter in the Parameters
property of the command context is set by the User Manager application. The delegate is run inside a Sitecore job. The progress box reads the status of the job and outputs relevant information on the dialog.
So you can see how easy it is to add options to a Sitecore ribbon. For item based commands the Items
property of the command context can be used instead of a value from the Parameters
property.
How does all this mocking compare to your previous post from two years ago using a custom test runner?
/blog/2010/11/19/unit-testing-in-sitecore-is-not-scary/
Have your opinions changed?