Skip to main content

You Just Got Vectored! SVG Image Formats

 If you're reading this, then you've come across a need that nearly all Opti developers encounter in their careers; You need to display a vector image format (SVGs and the like) properly, the <IMG> tag just isn't going to cut it anymore. Post like this are a right-of-passage for Opti bloggers.

"So," you think "if there are so many other blogs out there on the topic, why should I read yours?" Firstly, you enjoy my familiar and conversational tone of writing.

Cary Elwes does the English accent, I do the nerd stuff.

Second, you've already come this far, you might as well finish as this point, it's not long, I promise. To that point, and most importantly, I've seen some complex solutions out there, this one is a quick and simple implementation. 100% Guarantee!

The VectorFile class:
[MediaDescriptor(ExtensionString = "svg")]
    public class VectorFile : ImageData
    {
        public override Blob Thumbnail { get => BinaryData; }

        public virtual string XML
        {
            get
            {
                try
                {
                    var blob = BinaryData;
                    var xmlDoc = new XmlDocument();
                    xmlDoc.Load(blob.OpenRead());

                    return xmlDoc.InnerXml;
                }
                catch
                {
                    return "";
                }
            }
        }
    }

This delightful little class will extract the thumbnail for previews and place the image in an XML document that can be inserted into a view as an <SVG> tag. You can see from the MediaDescriptor attribute that we're only allowing .SVG files here. This list can be expanded as needed. This is where you can also supply further properties regarding your SVG in the class, it's just content after all! 

The VectorFileController class:


    public class VectorFileController : AsyncPartialContentComponent<VectorFile>
    {
        protected override async Task<IViewComponentResult> InvokeComponentAsync(VectorFile currentBlock)
        {
            return await Task.FromResult(View("~/Features/Media/_vectorFile.cshtml", currentBlock));
        }
    }

The should look familiar to CMS12 block development, just your run-of-the-mill controller. No tricks, no fills. 

The VectorFile view:

@model VectorFile

@if (Model != null)
{
    @((MarkupString)Model.XML)
}

A lot of devs would have you use @Html.Raw to put the SVG code on the screen, but with the MarkupString struct. We on less shaky ground here because MarkupString is parsed in an HTML or SVG format, rather than trusting that the silly SVG you grabbed off Pinterest for that company party doesn't have some nasty embedded code. 

Now, on the next upload to your Media folder, any SVG file should appear as a VectorFile instead of an ImageFile! (You did take the .svg extension out the MediaDescriptor of your raster image class, right?)

Told you it would be short and simple! Happy coding Opti-mists!

Comments