Exposing Page Metadata in Experience Editor

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.

Advertisements
Exposing Page Metadata in Experience Editor

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s