Experience Editor is, ultimately, the way that editors should interact with content in pages. I mean, as a developer, I quite like Content Editor for seeing my Sitecore content…
… but editors would typically prefer something a bit more visual, something a bit more WYSIWYG. That’s a large part of the value that Sitecore give – inline editing. It’s the point of a lot of content management systems.
That’s fine, and I’ve always found the Experience Editor fairly impressive in this regard – but what do you do about content that’s not visible in the page?
A good example is page metadata – so, canonical URLs, metadata tags, browser titles (for the browser tab), etc.. You might also have a ‘summary’ or ‘thumbnail’ to use in some form of content aggregation.
Well, in the SharePoint systems I used to work with, we’d use Edit Panels in the page – that is, areas of the page that would only be shown to editors, and that would let them set these bits of text. It worked pretty well, but it was a little… awkward.
How about if we presented a dialog instead?
I came across this post by Rey Rahadian about doing just that. I’m not a huge fan of Sitecore Rocks – though it’s been a while since I used it. Anyway, I wondered, can I do this by hand, and can I do it better? Rather than presenting a specific set of fields, I’d rather present an entire Field Section – something like ‘Page Metadata’ – and let this vary per page. For example, some pages might have a ‘Summary’ field in the ‘Page Metadata’ section, and others might not. By displaying the section, we’ll handle that.
First problem, adding a new button to the ribbon:
I added a Metadata strip to the ribbon:
And then a Large Button. The settings you can’t see is that I set an ID value too, of “EditMetaDataButton”
This has Presentation Details – and edit the large button. Set a tooltip:
Set up the events. Note the command. We’ll come back to that.
In the Behaviour section, set the AccessKey field to be your field section you want to display. Yeah, I know, that doesn’t seem right. AccessKey shouldn’t be for that – but it seems to be the way that works….
Lastly, set the script file to a new script (which we’re about to look at). I set it’s path to be under /sitecore/shell/client/Sitecore/ExperienceEditor/Commands/ – this seemed to make sense, structurally.
Okay, so what about that script? Basically, all it does is define a command (with the same command name we set on the button). This command has 2 functions – can it execute, and what it should do when executing.
define(["sitecore", "/-/speak/v1/ExperienceEditor/ExperienceEditor.js"], function (Sitecore, ExperienceEditor) {
Sitecore.Commands.LaunchFieldEditor =
{
canExecute: function (context) {
return true;
},
execute: function (context) {
context.currentContext.argument = context.button.viewModel.$el[0].accessKey;
ExperienceEditor.PipelinesUtil.generateRequestProcessor("ExperienceEditor.GenerateFieldEditorUrl", function (response) {
var DialogUrl = response.responseValue.value;
var dialogFeatures = "dialogHeight: 680px; dialogWidth: 520px; ";
ExperienceEditor.Dialogs.showModalDialog(DialogUrl, '', dialogFeatures, null);
}).execute(context);
}
};
});
When executing it calls a processor to generate a url for the new FieldEditor dialog we want to open. This processor is:
public class GenerateFieldEditorUrl : PipelineProcessorRequest<ItemContext>
{
public string GenerateUrl()
{
List<string> fieldsInSection = GetFieldsInSection(RequestContext.Item, RequestContext.Argument);
var fieldList = CreateFieldDescriptors(fieldsInSection);
var fieldeditorOption = new FieldEditorOptions(fieldList);
//Save item when ok button is pressed
fieldeditorOption.SaveItem = true;
fieldeditorOption.Title = "Edit Metadata";
return fieldeditorOption.ToUrlString().ToString();
}
public List<string> GetFieldsInSection(Item item, string sectionName)
{
Template template = TemplateManager.GetTemplate(item.Template.ID, item.Database);
return template.GetFields().Where(x => x.Section.Name.Equals(sectionName, StringComparison.OrdinalIgnoreCase)).OrderBy(x=>x.Sortorder).Select(x=>x.Name).ToList();
}
private List<FieldDescriptor> CreateFieldDescriptors(List<string> fields)
{
var fieldList = new List<FieldDescriptor>();
foreach (string field in new ListString(fields))
{
fieldList.Add(new FieldDescriptor(RequestContext.Item, field));
}
return fieldList;
}
public override PipelineProcessorResponseValue ProcessRequest()
{
return new PipelineProcessorResponseValue
{
Value = GenerateUrl()
};
}
}
That will get the fields in a section by name, and feed them to the FieldEditor dialog.
Lastly, patch in the processor:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<sitecore.experienceeditor.speak.requests>
<request name="ExperienceEditor.GenerateFieldEditorUrl" type="Unified.Feature.Chrome.ExperienceEditor.GenerateFieldEditorUrl, Unified.Feature.Chrome" />
</sitecore.experienceeditor.speak.requests>
</sitecore>
</configuration>
And that should be it. You should have a button that opens a field editor for a given section name.
Hi Andy, I did not understand the screen after the sentence – This has Presentation Details – and edit the large button. Set a tooltip:
Is this the presentation detail of large button.?
Yes, IIRC the button node in Sitecore has presentation detail. I think you can get to it by selecting the button, and then in the ribbon find and click the “presentation details” button.
Thanks for the quick reply Andy,
In my case, I am seeing the blank window(modal dialog) on clicking of Presentation Details.Is there any way I can send out the screenshot to you?
Hi Andy, it is in addition to my last reply, it is not blank window but I can see “Layout Detail” window on clicking of presentation detail of this button(Edit Metadata). Please help me, if I am doing anything wrong.
[…] I found a few useful posts: Trigger SPEAK alerts programmatically, Open SPEAK dialog in EE and Andy Burns’ post. They got me 75% of the way there but they didn’t address how to raise multiple dialogs. I […]