7

Consider the template:

Company

  • Logo (Image field)
  • Company Name (Text field)

The Company template has standard values set on both fields. If we get a Company item and save it using Glass without making any changes, the Logo field no longer uses the standard value. (The Company Name field is untouched.)

The issue, it seems, is that the Glass.Mapper.Sc.DataMappers.SitecoreFieldImageMapper serializes the value of that field differently than Sitecore does. When it tries to save, it thinks it's a change to the field and no longer uses the standard value.

Standard Value:

<image mediaid="{GUID}" />

Glass-generated Value:

<image height="64" width="64" mediaid="{GUID}" alt="Alt text" />

Is there a way to make Glass generate the same output as Sitecore?

Dan Sinclair
  • 907
  • 1
  • 9
  • 27

1 Answers1

0

I think that problem is in a way how SitecoreFieldImageMapper map ImageField to Image. For getting Height, Width and Alt are used public properties. If we look on them via reflector we will see that values of it get not directly from field:

public string Alt
{
    get
    {
        string text = base.GetAttribute("alt");
        if (text.Length == 0)
        {
            Item item = this.MediaItem;
            if (item != null)
            {
                MediaItem mediaItem = item;
                text = mediaItem.Alt;
                if (text.Length == 0)
                {
                    text = item["Alt"];
                }
            }
        }
        return text;
    }
    set
    {
        base.SetAttribute("alt", value);
    }
}

If field does not contain value(e.g. for "alt": if (text.Length == 0)) then value will be received from MediaItem that is linked. It cause adding Height, Width and Alt from media library item after saving of field.

To fix this problem you could try replace this code:

int height = 0;
int.TryParse(field.Height, out height);
int width = 0;
int.TryParse(field.Width, out width);

img.Alt = field.Alt;
img.Height = height;
img.Width = width;

with direct getting attributes rather than usage of properties:

int height = 0;
if(int.TryParse(field.GetAttribute("height"), out height))
{
    img.Height = height;
}


int width = 0;
if(int.TryParse(field.GetAttribute("width"), out width))
{
    img.Width = width;
}

img.Alt = field.GetAttribute("alt");

With Alt property everything should be ok. But there could be problems with Width and Height as they are not Nullable and I am not sure how GlassMapper will handle Image with Width and Height that you haven't set.

Anton
  • 9,682
  • 11
  • 38
  • 68
  • Are you suggesting creating a custom ImageMapper and updating those properties as in your answer, or where would I actually add that code? – Dan Sinclair Jun 16 '16 at 11:51
  • Yes, I do suggest to create a custom ImageMapper as problem is there. I am not sure if you will be able to configure to use your ImageMapper using configuration files.But GlassMapper is open source, you are able to fork sources on GitHub, make you changes and get new assembly with new ImageMapper. https://github.com/mikeedwards83/Glass.Mapper – Anton Jun 16 '16 at 12:03
  • Rather than cloning the repo and building, I suggest you inherit `SitecoreFieldImageMapper`, override the get method with your implementation and register in `CreateResolver`: https://jammykam.wordpress.com/2015/11/09/custom-glass-mapper-data-handlers-part-2/ You can then just use it on a as-required basis. Be sure to read part-1 of the article as well. – jammykam Jun 17 '16 at 09:10