Slideshows and Page Editor

I want my content editors to be able to do anything in the Page Editor that they can do in the Content Editor, giving them the choice to use what they prefer. However, when the editor wants to change a slideshow on a page they must do this through the Content Editor, because when they try to make a change in the Page Editor they get the following error message (or a message similar to it):

Uncaught DOM element is expected to have a non-empty chromes collection.
    Sitecore.PageModes.Chrome.Base.extend._clickHandler
    c
    d.event.handle
    k.handle.m

I was talking about this with another Sitecore developer during a Sitecore Usergroup, and what he suggested was instead of showing it as a slideshow in Page Editor mode, have the images and text be underneath each other. While that’s certainly a valid option, I don’t really like it because it takes away one of the strengths of the Page Editor: See what the result will be while you are changing it.

What I decided to do was create an additional button in the Page Editor and create my own class that inherits from Sitecore’s FieldEditorCommand class.

Create the command

I’ve created a class which inherits the Sitecore.Shell.Applications.WebEdit.Commands.FieldEditorCommand.

For display purposes I’ve overridden the CommandState as well, to disable the button if the page doesn’t have a slideshow. I simply check this by getting the value of a field called Source:

public override CommandState QueryState(CommandContext context)
{
  if (string.IsNullOrEmpty(Sitecore.Context.Item["Source"]))
  {
    return CommandState.Disabled;
  }

  return base.QueryState(context);
}

The Execute method will call the field editor, so we’ll need to implement that:

public override void Execute(CommandContext context)
{
  Assert.ArgumentNotNull(context, "context");
  if (context.Items.Length >= 1)
  {
    var args = new ClientPipelineArgs(context.Parameters);
    args.Parameters.Add("uri", context.Items[0].Uri.ToString());
    Sitecore.Context.ClientPage.Start(this, "StartFieldEditor", args);
  }
}

Now all that’s left is overriding the GetOptions method. The Slideshow field is a dropdown pointing to an item with a multilistfield called Images. We’ll want to edit the Title, Keywords and Description fields of the respective images:

protected override PageEditFieldEditorOptions GetOptions(ClientPipelineArgs args, NameValueCollection form)
{
  Assert.IsNotNull(args, "args");
  Assert.IsNotNull(form, "form");
  Assert.IsNotNullOrEmpty(args.Parameters["uri"], "uri");

  Sitecore.Data.ItemUri uri = Sitecore.Data.ItemUri.Parse(args.Parameters["uri"]);
  Assert.IsNotNull(uri, "uri");

  var item = Sitecore.Data.Database.GetItem(uri);
  Assert.IsNotNull(item, "item");

  var slideShowItem = Sitecore.Context.ContentDatabase.GetItem(item["Source"]);
  Assert.IsNotNull(slideShowItem, "slideShowItem");

  var fields = new List<Sitecore.Data.FieldDescriptor>();
  fields.Add(new Sitecore.Data.FieldDescriptor(slideShowItem, "Images"));
  var images = (MultilistField)slideShowItem.Fields["Images"];
  foreach (var image in images.GetItems())
  {
    foreach (string fieldName in GetFieldNames())
    {
      fields.Add(new Sitecore.Data.FieldDescriptor(image, image.Fields[fieldName].Name));
    }
  }

  var options = new PageEditFieldEditorOptions(form, fields);
  options.PreserveSections = false;
  options.DialogTitle = "Edit the slideshow");
  options.Icon = item.Appearance.Icon;
  return options;
}

private IEnumberable<string> GetFieldNames()
{
  yield return "Title";
  yield return "Keywords";
  yield return "Description";
}

Note that I’m not only adding the image fields (Title, keywords and description), but also the multilistfield in which the images are selected (as highlighted in line 17).

The one drawback of course is that we need to save the changes we make before the page reflects them, and if we change the Images multilistfield we’ll need to re-open the editor to see that reflected on our popup.

Include the command:

I’ll use an include file to patch my config.

  <?xml version="1.0"?>
  <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
      <commands>
        <command name="pageeditor:slideshow" type="TestApplication.PageEditorSlideshows.PageEditorSlideshows, TestApplication" />
      </commands>
    </sitecore>
  </configuration>

Add the button:

To add a button to the Page Editor we’ll need to open the Core database and navigate to /sitecore/content/Applications/WebEdit/Ribbons/WebEdit. I’ll create my button under the existing ‘Page Editor/Edit’ node:

tree

I’ve added the following field values:

Header:   Edit slideshow
Icon:         Applications/32×32/photo_scenery.png
Click:         pageeditor:slideshow
Tooltip:    Edit the slideshow

Now it’s time to test it!

This is how it looks on a page without a slideshow attached:

ribbon_disabled

We could’ve hidden the button instead (by returning CommandState.Hidden instead of CommandState.Disabled), but I tend to just disable them to keep the ribbon consistent across the board.

This is how it looks on a page which does have a slideshow:

ribbon_enabled

If we then click our new button:

popup

Perfect.

Advertisements

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