Images with view data parameters in Episerver CMS

Images with view data parameters in Episerver CMS

In my previous blog post I explained how you can reduce the size of your images using webp transformation of the fly provided by CDN cloudfare in Episerver DXP, which can be checked in this link.

In this blog post, we will work upon the code of my previous post in order to make the image view rendered handle view data parameters sent by the caller. Just as a reminder, this code is based on the episerver foundation cms site implementation which for now uses a controller, an specific cast to handle images and does not support view data parameters.

The change to allow this functionality to work is set in the _ImageRenderer.cshtml partial view using the following code:

@using EPiServer.Web.Mvc.Html
@using Foundation.Features.Media

@model ImageMediaDataViewModel

@{
    var imgLink = Url.ContentUrl(Model.ImageLink);
    var noClassInPicture = ViewData["noClassInPicture"] != null && bool.Parse(ViewData["noClassInPicture"].ToString());
}
<picture @(!noClassInPicture ? RenderProperty("class", ViewData["class"]) : RenderProperty("class", null))>
    <source srcset="@imgLink?format=webp" type="image/webp" alt="@Model.AltText" longdesc="@Model.Description" title="@(Model.Title ?? Model.Name)"
            @(noClassInPicture ? RenderProperty("class", ViewData["class"]) : RenderProperty("class", null))
            @RenderProperty("style", ViewData["style"])
            @RenderProperty("role", ViewData["role"])
            @RenderProperty("aria-hidden", ViewData["ariaHidden"])>
    <img src="@imgLink" alt="@Model.AltText" longdesc="@Model.Description" title="@(Model.Title ?? Model.Name)" loading="lazy"
         @(noClassInPicture ? RenderProperty("class", ViewData["class"]) : RenderProperty("class", null))
         @RenderProperty("style", ViewData["style"])
         @RenderProperty("role", ViewData["role"])
         @RenderProperty("aria-hidden", ViewData["ariaHidden"]) />
</picture>

@helper RenderProperty(string property, object data)
{
    if (!string.IsNullOrEmpty(property) && data != null)
    {
        @:@property="@data"
    }
}

We handle several view data parameters like the one called no class in picture which if true will put the class you send as parameter inside each source and image tag instead of setting it on the picture tag which is the default behavior.

ViewData["noClassInPicture"]

Other view data parameters that we handle are class, style, role, aria-hidden which can be used to further modify the behavior and styling of the images displayed.

ViewData["class"]

Finally, we use the helper method RenderProperty to be able to render the different view data parameters properly in the picture, image and source tags.

@helper RenderProperty(string property, object data)
{
    if (!string.IsNullOrEmpty(property) && data != null)
    {
        @:@property="@data"
    }
}

Now, if you want to use the new renderer in an image content reference property with allowed type ImageMediaData      

        [UIHint(UIHint.Image)]
        public ContentReference ThumbnailImage { get; set; }

you can use the following code:

  @Html.PropertyFor(x => x.ThumbnailImage, new { @class = "article-card__image", role = "logo" })

Where the class view data parameter will be rendered as part of the picture tag and the role view data parameter will be applied to the image and source tags. The final result will be an html picture tag similar to this.

You can add as many other view data parameters to the picture, source and image tags as you want by adding a line similar to this one in the respective tag.

@RenderProperty("aria-hidden", ViewData["ariaHidden"])

And that is all. I hope this blog post helps someone and as always keep learning !!!

Written by:

Jorge Cardenas

Developer with several years of experience who is passionate about technology and how to solve problems through it.

View All Posts

Leave a Reply