如何在Rails中显示SVG图像?

时间:2016-05-02 16:14:28

标签: ruby-on-rails ruby-on-rails-4 svg

我在/app/asssets/images/symbols.svg上有一个svg图像,并将其作为内容。

<svg xmlns="http://www.w3.org/2000/svg"><symbol id="icon-search" viewBox="0 0 18 18"><path fill="currentColor" d="M12.8 11.4c.9-1.2 1.4-2.7 1.4-4.3C14.2 3.2 11 0 7.1 0S0 3.2 0 7.1c0 3.9 3.2 7.1 7.1 7.1 1.6 0 3.1-.5 4.3-1.4l5.2 5.2 1.4-1.4-5.2-5.2zM2 7.1C2 4.3 4.3 2 7.1 2s5.1 2.3 5.1 5.1-2.3 5.1-5.1 5.1S2 9.9 2 7.1z"/></symbol><symbol id="icon-view-default" viewBox="0 0 18 18"><g fill="currentColor"><path d="M8 11H0V0h8v11zM18 5h-8V0h8v5zM8 18H0v-5h8v5zM18 18h-8V7h8v11z"/></g></symbol><symbol id="icon-view-alt" viewBox="0 0 18 18"><g fill="currentColor"><path d="M8 8H0V0h8v8zM18 8h-8V0h8v8zM8 18H0v-8h8v8zM18 18h-8v-8h8v8z"/></g></symbol><symbol id="icon-view-full" viewBox="0 0 18 18"><g fill="currentColor"><path d="M18 8H0V0h18v8zM18 18H0v-8h18v8z"/></g></symbol><symbol id="icon-facebook" viewBox="0 0 9 19"><path fill="currentColor" d="M6.7 3.6H9V0H6.3c-3.3.1-4 2.1-4 4.1V6H0v3.5h2.2V19h3.4V9.5h2.8L8.9 6H5.6V4.9c0-.7.4-1.3 1.1-1.3z"/></symbol><symbol id="icon-twitter" viewBox="0 0 17.9 15"><path fill="currentColor" d="M17.9 1.8c-.3.2-1.2.5-2 .6.5-.3 1.3-1.3 1.5-2.1-.5.3-1.7.8-2.3.8C14.4.5 13.5 0 12.4 0c-2 0-3.7 1.7-3.7 3.8 0 .3 0 .6.1.8-2.8-.1-6-1.5-7.8-4-1.1 2-.2 4.2 1.1 5-.4 0-1.2-.1-1.6-.4 0 1.3.6 3.1 2.9 3.7-.5.4-1.3.3-1.6.3.1 1.1 1.6 2.6 3.3 2.6-.6.7-2.6 2-5.1 1.6 1.7 1 3.7 1.6 5.8 1.6 6 0 10.6-5 10.3-11.1v-.1c.6-.4 1.3-1.1 1.8-2z"/></symbol><symbol id="icon-pinterest" viewBox="0 0 18 18"><path fill="currentColor" d="M2.3 0h13.4C17 0 18 .9 18 2.3v13.4c0 1.4-1 2.3-2.3 2.3H2.3C1 18 0 17.1 0 15.7V2.3C0 .9 1 0 2.3 0zm10.8 2c-.4 0-.8.4-.8.8v1.9c0 .4.4.8.8.8h2c.4 0 .8-.4.8-.8V2.8c.1-.4-.3-.8-.8-.8h-2zM16 7.6h-1.6c.2.5.2 1 .2 1.5 0 3-2.5 5.4-5.6 5.4-3.1 0-5.6-2.4-5.6-5.4 0-.5.1-1.1.2-1.5H2v7.6c0 .4.3.7.7.7h12.5c.4 0 .7-.3.7-.7l.1-7.6zM9 5.5C7 5.5 5.4 7 5.4 9c0 1.9 1.6 3.5 3.6 3.5s3.6-1.6 3.6-3.5c0-2-1.6-3.5-3.6-3.5z"/></symbol><symbol id="icon-tumblr" viewBox="0 0 11 19"><path fill="currentColor" d="M8.6 15.9c-1.6 0-2.3-1.3-2.3-2.2V7.8h4.1v-3h-4V.1S4.7 0 3.5 0C3.5 4.1 0 4.9 0 4.9v2.8h2.3v7C2.3 17.1 4.4 19 7 19s4-1.1 4-1.1v-3.1c0 .1-.8 1.1-2.4 1.1z"/></symbol><symbol id="icon-menu" viewBox="0 0 274.5 224.5"><g fill="currentColor"><path d="M274 53.8H.5V.5H274v53.3zM274 138.9H.5V85.6H274v53.3zM274 224H.5v-53.3H274V224z"/></g></symbol><symbol id="bar" viewBox="0 0 274.5 54.3"><path fill="currentColor" d="M274 53.8H.5V.5H274v53.3z"/></symbol><symbol id="arrow" viewBox="0 0 38 14"><path fill="currentColor" d="M31 0l-1.4 1.4L34.2 6H0v2h34.2l-4.6 4.6L31 14l7-7-7-7z"/></symbol><symbol id="refresh" viewBox="0 0 19 16"><path fill="currentColor" d="M9.4 6.2l5.9 4.4L19 4.4l-1.7-1L15.7 6c-.9-3.5-4-6-7.7-6-4.4 0-8 3.6-8 8s3.6 8 8 8c2.1 0 4.1-.8 5.6-2.3l-1.4-1.4C11.1 13.3 9.6 14 8 14c-3.3 0-6-2.7-6-6s2.7-6 6-6c3 0 5.4 2.2 5.9 5l-3.3-2.4-1.2 1.6z"/></symbol></svg>

现在,我在网上找到一个html模板,图像显示为:

  <svg>
      <use xlink:href="assets/img/symbols.svg#bar"></use>
    </svg>

如何在轨道上完成这项工作。

我试过了:

 <use xlink:href="images/symbols.svg#bar"></use>

和svg-inline gem

但两者都在我的网页上看不到任何图片。

任何人都可以帮我弄清楚如何使这项工作?

10 个答案:

答案 0 :(得分:15)

在Rails应用程序中显示SVG(可缩放矢量图形)

具体包括资产编译中的SVG文件类型

production.rb 

  config.assets.precompile += %w( '.svg' )  

  # Must include to get inline SVGs to work in deploy
  config.assets.css_compressor = :sass

创建帮助程序以显示SVG

myhelper.rb

def show_svg(path)
  File.open("app/assets/images/#{path}", "rb") do |file|
    raw file.read
  end
end

在您的视图中调用SVG处理助手

<%= show_svg('symbols.svg') %>

根据您的问题,我不是100%清楚您的实施,但这些步骤可以让您达到SVG图像可见的程度。一旦看到SVG,就可以应用CSS。

答案 1 :(得分:3)

您可以使用与图像相同的方式显示SVG。

例如haml:

%img{:src => "/images/image1.svg"}
希望它有所帮助!

答案 2 :(得分:2)

尝试使用inline_svg gem,它会添加一个辅助方法,用于将SVG从文件直接嵌入到模板中

答案 3 :(得分:1)

类似于 nvm 的方法,我有一个助手来帮助构建 use 标签的资产路径并确保父 svg 标签具有适当的属性

def external_svg(identifier, attributes = {})
  # identifier: <file name without extension>#<fragment id>
  file_name, fragment = identifier.split('#')
  file_name += '.svg'
  attributes.merge!(xmlns: 'http://www.w3.org/2000/svg')
  content_tag :svg, attributes do
    tag.use href: "#{image_path(file_name)}##{fragment}"
  end
end

在视图中,您的 SVG 资产将被这样调用:external_svg 'symbols#icon-search', class: 'icon',结果为 html:

<svg xmlns="http://www.w3.org/2000/svg" class="icon">
  <use href="<asset pipeline path>/symbols.svg#icon-search" />
</svg>

由于外部引用的 SVG 现在是 well supported,因此您不需要任何特定于 SVG 的 gem 即可使用。

在使用这种方法时,值得注意的是优点(缓存)和缺点(CSS 样式限制)。看到这个Twitter thread

答案 4 :(得分:0)

直截了当:

首先,将svg添加到assets.rb

中的资产预编译列表中
application.config.assets.precompile +=
    %w(<your other files> symbol-defs.svg)

然后在你的erb / haml文件中引用它,如下所示:

<svg class="icon gr-menu">
  <use xlink:href="<%= asset_path('symbol-defs') %>#gr-menu"></use>
</svg>

答案 5 :(得分:0)

创建帮助:(每种情况下的内容都不同,自定义一个)

def icon(icon, css_class: "")
  content_tag(:svg, class: "icon icon_#{icon} #{css_class}") do
      content_tag(:use, nil, 'xlink:href' => "#icon_#{icon}")
  end
end

像这样使用:

<%= icon 'arrow-menu' , css_class: 'arrow-breadcrumb' %>

答案 6 :(得分:0)

为此,我一直在尝试不同的解决方案,并最终将svg文档放入html.erb部分中。由于svg是有效的html,因此只需将其从资产移动到视图即可。

<%# app/views/home/index.html.erb %>

<%= render partial: "svgs/some_svg.html.erb"

给予

app
| views
| | home
| | | index.html.erb
| | svgs
| | | some_svg.html.erb

答案 7 :(得分:0)

对于基于 Elvn 响应的 ActiveStorage,我发现有更好的方法

如果您有一个带有 itemhas_one_attached :logo 对象:

<%= show_svg(item.logo_blob) %>

那么助手是:

    def show_svg(blob)
      blob.open do |file|
        raw file.read
      end
    end

答案 8 :(得分:0)

您可以在 Rails 中内联插入 svg,无需任何额外的 gem,使用如下所示:

<%= render inline: Rails.root.join('public/icon.svg').read %>

如果您需要单击 svg 来执行某些操作,例如发出 POST 请求,请将整个内容包含在带有 link_todo 中,如下所示:

<%= link_to some_path(@something), method: :post do %>
    <%= render inline: Rails.root.join('public/icon.svg').read %>
<% end %>

答案 9 :(得分:-1)

我真的不知道如何解析SVG文件;但同样的事情可以用于SVG文件。然后,您可以在SVG文件中使用asset_path帮助程序;但是默认情况下,catch会解析CSS,JS和ERB。通过这种方式,SVG内部的链接可以与资产管道一起使用。也许如果您尝试更改&#39; symbols.svg&#39; to&#39; symbols.svg.erb&#39;它将解析文件以获取正确的URL。

问题在于资产管道不能用于轨道。

这就是你可以解析(预处理)svg文件的方法:

  

编译文件的默认匹配器包括application.js,   application.css和所有非JS / CSS文件(这将包括所有图像   自动资产来自app / assets文件夹,包括你的宝石:[   Proc.new {| filename,path | path =〜/ app / assets /&amp;&amp; !%W(.js文件   .css).include?(File.extname(filename))},/ application。(css | js)$ /]

有关助手方法的更多信息

  

2.3.2 CSS和Sass

     

使用资产管道时,必须重写资产路径   sass-rails提供-url和-path助手(在Sass中连字符,   在Ruby中强调了以下资产类别:image,font,   视频,音频,JavaScript和样式表。

image-url("rails.png") becomes url(/assets/rails.png)
image-path("rails.png") becomes "/assets/rails.png".
     

也可以使用更通用的形式:

asset-url("rails.png") becomes url(/assets/rails.png)
asset-path("rails.png") becomes "/assets/rails.png"
     

2.3.3 JavaScript / CoffeeScript和ERB

     

如果您将一个erb扩展名添加到JavaScript资源中,那就可以了   例如application.js.erb,然后可以使用asset_path助手   您的JavaScript代码:$(&#39; #logo&#39;)。attr({src:&#34;&lt;%=   asset_path(&#39; logo.png&#39;)%&gt;&#34; });

     

这会写入被引用的特定资产的路径。

     

同样,您可以在CoffeeScript文件中使用asset_path帮助程序   使用erb扩展名(例如,application.js.coffee.erb):$(&#39; #logo&#39;)。attr   src:&#34;&lt;%= asset_path(&#39; logo.png&#39;)%&gt;&#34;

您可以查看: http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets