Thursday, December 11, 2014

Sitecore bug solution: Media Library item Title meta info field not working

The problem

We have found that a number of Sitecore versions (at minimum up to 7.2) have a problem with defining the Title field (used for onhover's) of Media items such as images.
Even though Sitecore has a Title field on media library items (metadata), it is not rendered correctly. We tested this on multiple sitecore environments with these scenarios:

  • using the sc:image fieldrenderer
  • rich text field using an inclosed image from the media library

I opened up a ticket with Sitecore and they acknowledged the problem as a bug and will take this up with their patching and version releases.

In the meanwhile you can

As a workaround, you can do the following:

To resolve this issue in the <sc:image> XSL Extension Control

You can override the <processor type="Sitecore.Pipelines.RenderField.GetImageFieldValue, Sitecore.Kernel" /> processor in the <renderField> pipeline.

You should create your own class.
For example:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class GetImageFieldValue
    {
        protected virtual ImageRenderer CreateRenderer()
        {
            return new ImageRenderer();
        }

        public void Process(RenderFieldArgs args)
        {
            if (args.FieldTypeKey == "image")
            {
                ImageRenderer renderer = this.CreateRenderer();
                renderer.Item = args.Item;
                renderer.FieldName = args.FieldName;
                renderer.FieldValue = args.FieldValue;
                renderer.Parameters = args.Parameters;
                //
                if (!args.Parameters.Keys.Contains("title"))
                {
                    Field innerField = args.Item.Fields[args.FieldName];
                    ImageField imageField = new ImageField(innerField, args.FieldValue);
                    if (imageField.MediaItem != null)
                        renderer.Parameters.Add("title", imageField.MediaItem.Fields["title"].Value);
                }
                //
                args.WebEditParameters.AddRange(args.Parameters);
                RenderFieldResult result = renderer.Render();
                args.Result.FirstPart = result.FirstPart;
                args.Result.LastPart = result.LastPart;
                args.DisableWebEditContentEditing = true;
                args.DisableWebEditFieldWrapping = true;
                args.WebEditClick = "return Sitecore.WebEdit.editControl($JavascriptParameters, 'webedit:chooseimage')";
            }
        }
    }


Build the solution and move the .dll file to the /Website/bin folder. 
Change the <processor type="Sitecore.Pipelines.RenderField.GetImageFieldValue, Sitecore.Kernel" /> processor.
 Example:
   <processor type="Namespace.YourProcessorClass, AssemblylName" />

To resolve this issue in the Rich Text field

You can override  <CodeBeside Type="Sitecore.Shell.Controls.RichTextEditor.InsertImage.InsertImageForm,Sitecore.Client"/>  in the InsertImage.xml file (Website\sitecore\shell\Controls\Rich Text Editor\InsertImage).
You should create your own class and inherit it from the Sitecore.Shell.Controls.RichTextEditor.InsertImage.InsertImageForm class.
Override the OnOk method.
Example:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
protected override void OnOK(object sender, EventArgs args)
        {
            Assert.ArgumentNotNull(sender, "sender");
            Assert.ArgumentNotNull(args, "args");
            string str = this.Filename.Value;
            if (str.Length == 0)
            {
                SheerResponse.Alert("Select a media item.", new string[0]);
            }
            else
            {
                Item root = this.DataContext.GetRoot();
                if (root != null)
                {
                    Item rootItem = root.Database.GetRootItem();
                    if ((rootItem != null) && (root.ID != rootItem.ID))
                    {
                        str = FileUtil.MakePath(root.Paths.Path, str, '/');
                    }
                }
                MediaItem item = this.DataContext.GetItem(str);
                if (item == null)
                {
                    SheerResponse.Alert("The media item could not be found.", new string[0]);
                }
                else if (!(MediaManager.GetMedia(MediaUri.Parse((Item)item)) is ImageMedia))
                {
                    SheerResponse.Alert("The selected item is not an image. Select an image to continue.", new string[0]);
                }
                else
                {
                    MediaUrlOptions shellOptions = MediaUrlOptions.GetShellOptions();
                    string text = !string.IsNullOrEmpty(HttpContext.Current.Request.Form["AlternateText"]) ? HttpContext.Current.Request.Form["AlternateText"] : item.Alt;
                    Tag image = new Tag("img");
                    this.SetDimensions(item, shellOptions, image);
                    image.Add("Src", MediaManager.GetMediaUrl(item, shellOptions));
                    image.Add("Alt", StringUtil.EscapeQuote(text));
                    //
                    if (!string.IsNullOrEmpty(item.Title))
                        image.Add("Title", StringUtil.EscapeQuote(item.Title));
                    //
                    if (this.Mode == "webedit")
                    {
                        SheerResponse.SetDialogValue(StringUtil.EscapeJavascriptString(image.ToString()));
                        base.OnOK(sender, args);
                    }
                    else
                    {
                        SheerResponse.Eval("scClose(" + StringUtil.EscapeJavascriptString(image.ToString()) + ")");
                    }
                }
            }
        }

Also you should copy the SetDimensions method from the InsertImageForm class.
Example:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private void SetDimensions(MediaItem item, MediaUrlOptions options, Tag image)
        {
            Assert.ArgumentNotNull(item, "item");
            Assert.ArgumentNotNull(options, "options");
            Assert.ArgumentNotNull(image, "image");
            NameValueCollection form = HttpContext.Current.Request.Form;
            if ((!string.IsNullOrEmpty(form["Width"]) && (form["Width"] != item.InnerItem["Width"])) && (form["Height"] != item.InnerItem["Height"]))
            {
                int num;
                int num2;
                if (int.TryParse(form["Width"], out num))
                {
                    options.Width = num;
                    image.Add("width", num.ToString());
                }
                if (int.TryParse(form["Height"], out num2))
                {
                    options.Height = num2;
                    image.Add("height", num2.ToString());
                }
            }
            else
            {
                image.Add("width", item.InnerItem["Width"]);
                image.Add("height", item.InnerItem["Height"]);
            }
        }

Build the solution and move the .dll file to the /Website/bin folder. Change <CodeBeside Type="Sitecore.Shell.Controls.RichTextEditor.InsertImage.InsertImageForm,Sitecore.Client"/> in the InsertImage.xml file.
 Example:
   <CodeBeside="Namespace.YourProcessorClass, AssemblylName" />

Hope this helps any of you who might currently be facing this problem !
And a big thanks to Support for acknowledging this problem !

No comments:

Post a Comment