Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable asset file #61

Merged
merged 6 commits into from
Apr 12, 2017
Merged

Configurable asset file #61

merged 6 commits into from
Apr 12, 2017

Conversation

jamesmartin
Copy link
Owner

This branch allows a configurable, user-supplied collaborator that must accept a filename and return a String representing the SVG document requested by the filename, adhering to the interface of the existing InlineSvg::AssetFile class (E.g. a #named method).

By default, InlineSvg falls back to the default implementation that reads data from a File.

This functionality supports users of the gem who want more control over where their SVG assets are located. For example, it would be possible to write a custom asset file implementation that loaded all required SVG files into process memory at boot time, rather than reading from disk on every render. Equally, it would be possible to (finally) allow SVGs to be loaded from remote URLs (E.g. on S3 etc.).

@jamesmartin jamesmartin merged commit 904d625 into master Apr 12, 2017
@jamesmartin jamesmartin deleted the configurable-asset-file branch April 12, 2017 04:18
@teeparham
Copy link

teeparham commented Apr 14, 2017

Thank you. This is a nice feature.

Using this new feature, one might do something like this:

class InMemorySVG
  SVGS = {
    marker: "<svg>something</svg>",
    other: "<svg>other</svg>"
  }

  def self.named(name)
    SVGS[name]    
  end
end

InlineSvg.configure do |config|
  config.asset_file(InMemorySVG)
end

# view
= inline_svg(:marker, class: "blue")

Is that the basic idea?


As an aside, here's an example of how to memoize inline SVGs to speedup rendering without using a custom loader. I wanted to render SVG map markers with different colors using CSS. Calling inline_svg repeatedly in a view was expensive, so I wrapped the method (in a presenter or helper):

def svg_marker
  @svg_marker ||= inline_svg("marker.svg", class: "blue")
end

The benefit of the above code is that it loads the SVG from the file only once per request, which was fast enough for my case.

@jamesmartin
Copy link
Owner Author

jamesmartin commented Apr 18, 2017

Is that the basic idea?

@teeparham yes, that's the basic idea. Taking your example one step further I've been experimenting with having the custom asset file take a list of static asset directories (and filter patterns) that it uses to glob for SVGs, which are then pre-loaded into memory on application startup. That way all assets are cached and avoid filesystem reads. I may make this an optional part of the gem if it turns out to be useful.

Calling inline_svg repeatedly in a view was expensive, so I wrapped the method (in a presenter or helper)

That's a nice example of memoizing the call to inline_svg. I've been profiling the code recently and plan to make some performance improvements soon such that even hundreds of thousands of calls per page should be super fast (not the case currently).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants