Wednesday 28 September 2016

It's always the simple things (a quick reminder about Sitecore access permissions)

Recently I inherited a project that has been ongoing for quite some time (so I'm not yet familiar with how it's been set up), and today I wasted a bunch of time debugging a general link field which wasn't generating the correct URL (in fact, it wasn't generating a URL at all!).  I figured it would be something simple, and sure enough it did turn out to be, but I got bogged down in the hunt long enough that I figured it was worth a post, on the off chance someone tries to search the same keywords I did (with no clues in the search results).

The general link field was on a datasource item, and was linking to another page on the site (ie using "Insert link" rather than "Insert external link" to create an internal link). This current project is using Glass Mapper (which I think distracted me a bit) and the Link.Url proprty was empty.  I thought maybe the field was being mapped incorrectly, but it all looked ok.  I tried grabbing the link field on the datasource Item directly (LinkField)RenderingContext.Current.Rendering.Item.Fields["MyLinkField"] and found that the InternalPath field was empty, and the TargetItem was null, even though the TargetID field was populated with the correct ID of the linked page.

Long story short, after digging through the code used to generate the URL I realised the Sitecore.Context.Database.GetItem("linkedItemId") was returning null, even though I could see the item in the Sitecore content editor.  Shortly thereafter it hit me: when would the context database return null for an item that obviously exists? When the current user doesn't have access to it! Yep that's right, the linked page had anonymous read access disabled, so that even though a link can be created by an author, the end user can see a link but cannot see the item and therefore the URL cannot be generated.

Moral of the story: if you can't get/see the link to an item, check the security and access permissions on that item!

Monday 26 September 2016

Adding a button to Experience Editor to open the image editor app

I ran across a question in Stack Overflow today about how to show "edit image" in Sitecore experience editor? and thought that would be an easy one to tackle.  Originally I figured I could copy the command from the existing link ("Edit Image") in the content editor and it would be a very simple answer, however it turns out that it's not quite so easy.

If you have access to a decompiler, take a look at the existing command Sitecore.Shell.Framework.Commands.Shell.EditImage as well as the existing command for selecting an image in Experience Editor Sitecore.Shell.Applications.WebEdit.Commands.ChooseImage. You'll see that they're similar, but unfortunately they use two different methods of opening a dialog (Windows.RunApplication and SheerResponse.ShowModalDialog), as well as reading the image from the context vs from the URL, so we can't reuse the existing class as-is. Fortunately the two classes are similar enough that you can easily re-use code from both, and make a class which opens the image editor in a modal dialog (as required by the experience editor).  I've posted a gist to the full class below.

Step 1:
Duplicate one of the buttons under /sitecore/system/Field types/Simple Types/Image/WebEdit Buttons
Change the icon and text to something meaningful to your authors.
Make the contents of the Click field: chrome:field:editcontrol({command:"webedit:changeimage"})
(annoyingly there's already a webedit:editimage which opens the image properties, so we can't name it that).

Step 2:
Create your custom command class (eg. EditImage.cs), make it serializable and inherit from WebEditImageCommand like the other EE buttons. I have posted the full class as a gist to make it easier to read and copy.

Step 3:
Open App_Config\Include\Sitecore.ExperienceEditor.config and duplicate the entry for webedit:chooseimage. Change the command name to webedit:changeimage as per step 1, and change the type to the custom command class you created in step 2.

When you select an image in the Experience Editor, you should now have an extra button in the list which opens the image editor in a modal window when clicked!

Extra 'edit image' button second from the left
After clicking the button, the image is opened in the image editor modal

Note: You'll have to refresh the window to see the updated image.  I leave it as an exercise for the reader to determine a way to get the image to refresh after closing the modal :) or maybe I'll write that up in a later post...