【问题标题】:How do I display SVG image in Rails?如何在 Rails 中显示 SVG 图像?
【发布时间】:2016-05-02 16:14:28
【问题描述】:

我在 /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

但在这两个页面上,我的网页上都看不到任何图像。

谁能帮我弄清楚如何完成这项工作?

【问题讨论】:

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


    【解决方案1】:

    在 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。

    【讨论】:

    • 如果你有一个 svg 的图标精灵怎么办?在开发环境中?
    • @StevenAguilar 我建议您将此作为一个新问题发布。这些天我没有做太多的 RoR。
    • 这似乎不适用于使用活动存储上传的 SVG
    • 有人编辑了答案;如果他们打破了,请与他们核对:(。
    【解决方案2】:

    试试inline_svg gem,它添加了一个辅助方法,用于将文件中的 SVG 直接内联到您的模板中

    【讨论】:

      【解决方案3】:

      您可以像显示图像一样显示 SVG。

      例如在haml中:

      %img{:src => "/images/image1.svg"}
      

      希望对你有帮助!

      【讨论】:

      • 没错,这适用于 Chrome、Firefox 和 Edge(截至今天的最新版本)。但是 Safari 不会显示由 rails img 助手提供的 svg 图像。
      【解决方案4】:

      我一直在为此尝试不同的解决方案,最终决定将 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
      

      【讨论】:

        【解决方案5】:

        简单明了:

        首先,将 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>
        

        【讨论】:

        【解决方案6】:

        创建一个助手:(每种情况的内容不同,自定义你自己的)

        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' %>
        

        【讨论】:

          【解决方案7】:

          与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

          【讨论】:

            【解决方案8】:

            你可以在 Rails 中插入 svg inline 而不需要任何额外的 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】:

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

              如果您有一个带有has_one_attached :logoitem 对象:

              <%= show_svg(item.logo_blob) %>
              

              那么助手就是:

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

              【讨论】:

                【解决方案10】:

                我真的不知道如何解析 SVG 文件;但是同样的东西也可以用于 SVG 文件。然后您可以在 SVG 文件中使用asset_path 助手;但问题是默认情况下,rails 会解析 CSS、JS 和 ERB。这样,SVG 内部的链接就可以与资产管道一起使用。也许如果您尝试将名称从“symbols.svg”更改为“symbols.svg.erb”,它将解析文件以获取正确的 url。

                你的问题是资产管道没有按照rails使用。

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

                编译文件的默认匹配器包括application.js, application.css 和所有非 JS/CSS 文件(这将包括所有图像 assets 自动)来自 app/assets 文件夹,包括你的 gem:[ Proc.new { |文件名,路径|路径 =~ /app/assets/ && !%w(.js .css).include?(File.extname(filename)) }, /application.(css|js)$/ ]

                关于辅助方法的更多信息

                2.3.2 CSS 和 Sass

                使用资产管道时,必须重写资产路径并 sass-rails 提供 -url 和 -path 助手(在 Sass 中连字符, 在 Ruby 中下划线)用于以下资产类别:图像、字体、 视频、音频、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

                如果您向 JavaScript 资产添加 erb 扩展,则可以使其成为 例如 application.js.erb,然后您可以在 你的 JavaScript 代码: $('#logo').attr({ src: "" });

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

                同样,您可以在 CoffeeScript 文件中使用asset_path 助手 带有 erb 扩展名(例如 application.js.coffee.erb):$('#logo').attr src: ""

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

                【讨论】:

                • 谢谢,我试过你说的:> 但还是没有图标.在我看来,rails 无法处理#bar 部分
                • 没有区别。我之前说的。在我看来,#bar 无法处理
                猜你喜欢
                • 2020-08-09
                • 2020-06-02
                • 1970-01-01
                • 2014-09-23
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-10-27
                • 1970-01-01
                相关资源
                最近更新 更多