Skip to content

Instantly share code, notes, and snippets.

@NickCraver
Created February 1, 2017 22:36
Show Gist options
  • Save NickCraver/2d8c49374059792830e278fe406b2d79 to your computer and use it in GitHub Desktop.
Save NickCraver/2d8c49374059792830e278fe406b2d79 to your computer and use it in GitHub Desktop.
A simple SVG helper for Stack Overflow that inlines SVGs into Razor views efficiently
using System;
using System.IO;
using System.Web;
using System.Web.Hosting;
namespace StackOverflow.Helpers
{
public static class Svg
{
// NOTE: To add a new SVG icon, copy paste the line below. Paste it after the other ones.
// The variable's name needs to match the exact .svg name in Content/Img/svg-icons.
//
// TEMPLATE:
// public static IHtmlString SvgName { get; } = GetImage(nameof(SvgName));
public static IHtmlString Achievements { get; } = GetImage(nameof(Achievements));
public static IHtmlString Help { get; } = GetImage(nameof(Help));
public static IHtmlString Inbox { get; } = GetImage(nameof(Inbox));
public static IHtmlString Moderator { get; } = GetImage(nameof(Moderator));
public static IHtmlString ReviewQueue { get; } = GetImage(nameof(ReviewQueue));
public static IHtmlString SalaryCalculatorJobsCTA { get; } = GetImage(nameof(SalaryCalculatorJobsCTA));
public static IHtmlString SalaryCalculatorWorkHereCTA { get; } = GetImage(nameof(SalaryCalculatorWorkHereCTA));
public static IHtmlString StackExchange { get; } = GetImage(nameof(StackExchange));
private const int MaxReasonableSize = 4096;
private static IHtmlString GetImage(string fileName)
{
// This needs to be accessed inline, on a request to work properly - so here we are. It's cheap for initial loads.
var basePath = HostingEnvironment.MapPath(@"~/Content/Img/svg-icons/");
try
{
var path = $"{basePath}/{fileName}.svg";
var imageString = File.ReadAllText(path);
// Okay so now we have the svg asset loaded into the string,
// if we're on DEBUG let's do some sanity checking on the .svg itself.
// This way we throw in dev.
#if DEBUG
if (imageString.Length > MaxReasonableSize)
{
throw new Exception($"{path} is larger than the maximum allowed SVG icon size: {MaxReasonableSize.Commify()} bytes.");
}
if (imageString.Contains("<!--"))
{
throw new Exception($"{path} contains <!-- --> style comments. Please ensure this file is minified properly.");
}
#endif
return MvcHtmlString.Create(imageString);
}
catch (Exception ex)
{
// If the file wasn't able to be loaded at all, we should just throw.
// This throw should never happen on prod since people should be checking after they add a new SVG
// and the entry for it in this file, but you know, just in case.
#if DEBUG
// A nice little error message for the person who's using this to see.
throw new Exception($"Unable to open {fileName}.svg. Check that the file is in the correct path the name matches what's listed in Svg.cs", ex);
#else
GlobalApplication.LogException(ex);
return MvcHtmlString.Empty;
#endif
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment