Page Editor Ribbon Button
In the old days of Sitecore 6.x and 7.x you might have extended the Content Editor and Page Editor ribbons to give your content editors and marketers an easy access to a great customization of yours. Maybe you built a dialog to expose page metadata. Maybe you built a copy language utility. Maybe you built a workflow wizard of sort. Maybe you built all of the above and more. Whatever the case might be you probably have:
- An item in the
core
database. It will be under/sitecore/content/Applications/WebEdit/Ribbons/WebEdit
for Page Editor - A command name (e.g.
mycommands:doasisay
registered with a configuration patch to translate to aCommand
implementation - An XML control (a dialog form or a wizard form) that the command will fire up upon a click on the button
- Code-behind to power the control and interact with the user via Sheer UI
Experience Editor Ribbon Button
Sitecore 8 SPEAK-ified the ribbon. Ribbon buttons for the Experience Editor still live in the core
database but they now have … a layout (WAT).
The buttons you’ve built before are there but they don’t show up on the Sitecore 8 ribbon. They are not good enough. They need to step up and transfigure to become a kind of a button that can render itself. They need to be SPEAK-ified.
Transfiguration
[su_note note_color=”#fafafa”]We will be SPEAK-ifying a Large Button
for this article[/su_note]
Spell One
First, a button needs a new dress. Find your core
database item in Sitecore Rocks and add a LargeButton
rendering in the layout designer (Ctrl+U)
[su_note note_color=”#fafafa”]The Experience Editor ribbon is basically a SPEAK page at /sitecore/client/Applications/ExperienceEditor/Ribbon
. I suggest you just follow the code from there if you want to see how it’s built and how it works.[/su_note]
This step alone will render your button on the ribbon:
Spell Two
Now let’s redress the command. A Sheer UI command has basically three parts to it – a method that determines whether the command should be enabled, a method that triggers the dialog, and a method that acts upon the dialog completion.
Relevant pieces of the old command:
if (args.IsPostBack) { // act upon the dialog completion if (args.Result == "yes") { Context.ClientPage.SendMessage(this, "item:load(...)"); } } else { // trigger the dialog UrlString url = new UrlString(UIUtil.GetUri("control:CopyLanguage")); url.Add("id", item.ID.ToString()); url.Add("lang", item.Language.ToString()); url.Add("ver", item.Version.ToString()); SheerResponse.ShowModalDialog(url.ToString(), true); args.WaitForPostBack(); }The redressed command (formatted for the blog post):
define(["sitecore"], function (Sitecore) { Sitecore.Commands.ScoreLanguageTools = { canExecute: function (context) { return true; // we will get back to this one }, execute: function (context) { var id = context.currentContext.itemId; var lang = context.currentContext.language; var ver = context.currentContext.version; var path = "/sitecore/shell/default.aspx?xmlcontrol=CopyLanguage" + "&id=" + id + "&lang=" + lang + "&ver=" + ver; var features = "dialogHeight: 600px;dialogWidth: 500px;"; Sitecore.ExperienceEditor.Dialogs.showModalDialog( path, '', features, null, function (result) { if (result) { window.top.location.reload(); } } ); } }; });Very similar, isn’t it? Granted, I haven’t SPEAK-ified the dialog itself. Maybe next time.
Spell Three
To make the command accessible at runtime we need to instruct our SPEAK-ified button to load it as its page level script:
That’s it. The ribbon button is now fully functional.
Extra
One thing I didn’t cover yet is how to translate the
QueryState
. My original command was doing something like this:public override CommandState QueryState(CommandContext context) { Item item = context.Items[0]; return item.Appearance.ReadOnly ? CommandState.Disabled : CommandState.Enabled; }We have two options. We can either do it in JavaScript in
canExecute()
if we have enough information in thecontext
(we do, it hasisReadOnly
):// ... canExecute: function (context) { return !context.currentContext.isReadOnly; } // ...or we can call a processor on the server for help:
// ... canExecute: function (context) { var isEnabled = false; Sitecore.ExperienceEditor.PipelinesUtil.generateRequestProcessor( "Score.LanguageTools.IsEnabled", function (response) { isEnabled = response.responseValue.value; } ).execute(context); return isEnabled; } // ...where
Score.LanguageTools.IsEnabled
is declared as:<sitecore.experienceeditor.speak.requests> // ... <request name="Score.LanguageTools.IsEnabled" type="Score.Custom.LanguageTools.CanExecute, Score.Custom"/> // ... </sitecore.experienceeditor.speak.requests>and implemented as:
public class CanExecute : PipelineProcessorRequest<ItemContext> { public override PipelineProcessorResponseValue ProcessRequest() { RequestContext.ValidateContextItem(); return new PipelineProcessorResponseValue() { Value = !this.RequestContext.Item.Appearance.ReadOnly }; } }Resources
- Customize the Experience Editor Ribbon
- Sitecore Community Docs on SPEAK
- A new look to buttons in Experience Editor
[su_divider][/su_divider]
p.s. Is “SPEAK-ified” a word? Maybe it’s “spooky-fied”? Let me know what you think!