2

I need to render a image in SVG format on my site. I want to create another rendering variant of the SXA Image Rendering Variant, so that the image is rendered as SVG. With the current Image Rendering Variant renders image as

<a title="LW Logo Image Link" href="/"><img src="/-/media/Project/LW/LW/logo-lmage.svg?iar=0&amp;hash=F9D590BA05C61D36E9D5808F830D3D29" alt="" data-variantitemid="{F10CA728-FEDA-4706-B8D6-1651842E4BBA}" data-variantfieldname="Image"></a>

I want the new variant to render the image as

<svg role="img" focusable="false" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"width="500"height="40" viewBox="0 0 500 40" overflow="visible"><path d="M489 26.8v-5.5h2.2c3........."></path></g></svg>

Can this be done with creating a new Rendering variant or do I need to create a custom SXA component?

2 Answers 2

4

If you want control over the markup using C# then you can try something like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <renderField>
        <processor
          patch:instead="processor[@type='Sitecore.Pipelines.RenderField.GetImageFieldValue, Sitecore.Kernel']"
          type="Company.Foundation.Media.Pipelines.RenderField.GetImageFieldValue, Scms.Foundation.Media" />
      </renderField>
    </pipelines>
   </sitecore>
 </configuration>
using Sitecore.Diagnostics;
using Sitecore.Pipelines.RenderField;

namespace Company.Foundation.Media.Pipelines.RenderField
{
    public class GetImageFieldValue : Sitecore.Pipelines.RenderField.GetImageFieldValue
    {
        public override void Process(RenderFieldArgs args)
        {
            Assert.ArgumentNotNull((object)args, nameof(args));
            if (!this.IsImage(args))
            {
                return;
            }

            var renderer = new ImageRendererEx();
            this.ConfigureRenderer(args, renderer);
            this.SetRenderFieldResult(renderer.Render(), args);
        }
    }
}
using System.IO;
using System.Text;
using System.Xml.Linq;
using Sitecore;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Xml.Xsl;

namespace Company.Foundation.Media.Pipelines.RenderField
{
    public class ImageRendererEx : ImageRenderer
    {
        public override RenderFieldResult Render()
        {
            var obj = Item;
            if (obj == null)
            {
                return RenderFieldResult.Empty;
            }

            var attributes = Parameters;

            if (attributes == null)
            {
                return RenderFieldResult.Empty;
            }

            var width = MainUtil.GetInt(Extract(attributes, "width", "w"), 0);
            var height = MainUtil.GetInt(Extract(attributes, "height", "h"), 0);
            var scale = MainUtil.GetFloat(Extract(attributes, "scale", "sc"), 0.0f);
            var maxWidth = MainUtil.GetInt(Extract(attributes, "maxWidth", "mw"), 0);
            var maxHeight = MainUtil.GetInt(Extract(attributes, "maxHeight", "mh"), 0);

            var innerField = obj.Fields[FieldName];

            if (innerField == null) return base.Render();

            var imageField = new ImageField(innerField, FieldValue);

            ParseField(imageField);
            AdjustImageSize(imageField, scale, maxWidth, maxHeight, ref width, ref height);

            if (imageField.MediaItem == null) return base.Render();

            var imageMediaItem = new MediaItem(imageField.MediaItem);

            if (imageMediaItem.MimeType == "image/svg+xml")
            {
                return new RenderFieldResult(RenderSvgImage(imageMediaItem, width, height));
            }

            return base.Render();
        }

        private string RenderSvgImage(MediaItem mediaItem, int width, int height)
        {
            Assert.ArgumentNotNull(mediaItem, nameof(mediaItem));

            string result;

            using (var reader = new StreamReader(mediaItem.GetMediaStream(), Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }

            var svg = XDocument.Parse(result);

            if (svg.Document?.Root == null) return result;

            if (width > 0)
            {
                svg.Document.Root.SetAttributeValue("width", width);
            }

            if (height > 0)
            {
                svg.Document.Root.SetAttributeValue("height", height);
            }

            result = svg.ToString();

            return result;
        }
    }
}

Comments: If you really want to be fancy you can use similar code but turn it into a Scriban function.

1
  • When we add same .svg file (animated ) then animation does not work for second one through this code.
    – Ashish
    Commented Mar 1, 2023 at 7:53
1

You should create a new rendering variant and add a Scriban template under it. enter image description here

This worked for me just fine

enter image description here

Make sure to select your new rendering variant on the rendering itself: enter image description here

enter image description here

Edit: If you store the inline SVGs in, say a multi line text field on the item the scriban template can call them with {{i_page.SvgField}}

More on SVG syntax can be found here and in the 3 child articles: Scriban templates

If you want to properly integrate SVGs into Sitecore you have to follow one of the blog posts: Inserting SVG files/markup

Adding an SVG image to the Media Library

Once you have the C# code to get a Media Library item's SVG value you can integrate with scriban, to do something like {{my_custom_function i_item "ImageFieldWithSvg"}}

Creating Custom Embedded Function in Scriban

1
  • 1
    How exactly does this render the actual image selected in the field? This is just hard coding an SVG into the template
    – Richard Seal
    Commented Apr 13, 2021 at 2:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.