Making an extension to wrap inline svg helper gem

I’m fairly new to ruby and have been using Middleman to build out some static documentation. I’d like to be able to use a inline svg helper from another gem.

Reading over the middleman doc, it sounds like this may be possible by creating a middleman extension that wraps the inline svg helper from https://github.com/jamesmartin/inline_svg.

Having little knowledge of ruby/middleman, I’m curious if this is the right direction I should be going to do this/if this is possible with middleman?

Hello @bjankord

I use a helper to do that

def svg(name)
  root = Middleman::Application.root
  file_path = "#{root}/source/images/#{name}.svg"
  return File.read(file_path) if File.exists?(file_path)
  '(not found)'
end

in your partial simply use

<%= svg 'logo' %>

We also use a helper, but use the sitemap to find the SVG files. I’m curious if anyone has thoughts about this vs. David’s explicit file path approach.

def artifact_icon(artifact_name)
  path = "work/images/artifact_#{artifact_name}.svg"
  if resource = sitemap.find_resource_by_path(path)
    file = File.open(resource.source_file, 'r')
    return file.read
  else
    puts "#{ANSI_COLOR_RED}Unknown artifact icon #{artifact_name} in #{current_resource.path}#{ANSI_COLOR_RESET}"
    # empty roundrect
    return '[hardcoded SVG here]'
  end
end
1 Like

Thanks @flexbox and @gerwitz for the replies. I was hoping to specially use the helper provided by the inline_svg gem in middleman. I want to use its features of being able to pass in attributes to the SVG via the helper.

I could see building out a custom helper in middleman to do this as an option, but I was more curious if there is a way to use the inline_svg gem helper in middleman.

I’m thinking that making a custom extension that wraps the inline_svg might be the direction I want to explore, but not sure. I’m curious if this is the right direction I should be going to do this/if this is possible with middleman?

I found this somewhere and use it on my site. Does this help?

# Middleman - Inline SVG Helper
# ------------------------------------------------------------------------------
# 1. Save this file at `[project_root]/helpers/image_helpers.rb`
# 2. Restart your local Middleman server if it's running
# 3. Embed SVG files into your template files like so:
#
#      <%= inline_svg("name/of/file.svg") %>
#
#    The helper also allows for CSS classes to be added:
#
#      <%= inline_svg("name/of/file.svg", class: "my-addl-class") %>
#
module ImageHelpers

  # Embed SVG images inline within a Middleman template.
  # ---
  # Adapted from the work of James Martin and Steven Harley.
  # Reference: https://robots.thoughtbot.com/organized-workflow-for-svg
  def inline_svg(filename, options = {})
    asset = sprockets.find_asset(filename)

    # If the file wasn't found, embed error SVG
    if asset.nil?
      %(
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 30"
          width="400px" height="30px"
        >
          <text font-size="16" x="8" y="20" fill="#cc0000">
            Error: '#{filename}' could not be found.
          </text>
          <rect
            x="1" y="1" width="398" height="28" fill="none"
            stroke-width="1" stroke="#cc0000"
          />
        </svg>
      )

    # If the file was found, parse it, add optional classes, and then embed it
    else
      file = asset.source.force_encoding("UTF-8")
      doc = Nokogiri::HTML::DocumentFragment.parse file
      svg = doc.at_css "svg"

      if options[:class].present?
        svg["class"] = options[:class]
      end

      doc
    end
  end
end