如何将文件网址传递给中间人

时间:2016-01-21 15:25:27

标签: ruby middleman

我正在编写一个帮助方法,在需要时将图像转换为base64字符串。以下是代码

  # config.rb
  helpers do
    def base64_url(img_link, file_type: "jpg")
      require "base64"
      if file_type =="jpg"
        "data:image/jpg;base64,#{Base64.encode64(open(img_link).to_a.join)}"
      elsif file_type =="png"
        "data:image/jpg;base64,#{Base64.encode64(open(img_link).to_a.join)}"
      else
        link
      end
    end
  end

在page.html.erb

<%= image_tag base64_url('/images/balcozy-logo.jpg') %>

现在问题是当ruby读取'/images/balcozy-logo.jpg'时,它从系统根目录而不是从项目的根目录中读取文件。

错误信息如下

Errno::ENOENT at /
No such file or directory @ rb_sysopen - /images/balcozy-logo.jpg

如何解决此问题并从project_root/source/images

传递正确的图片网址

1 个答案:

答案 0 :(得分:1)

在Middleman中app.root返回应用程序的根目录。还有app.root_path,它做同样的但返回一个Pathname对象,这稍微方便一点:

full_path = app.root_path.join("source", img_link.gsub(/^\//, ''))

如果gsubimg_link开头,/是必需的,因为它会被解释为文件系统的根目录。

我冒昧地对你的方法做了一些修改:

require "base64"

helpers do
  def base64_url(path, file_type: "jpg")
    return path unless ["jpg", "png"].include?(file_type)

    full_path = app.root_path.join("source", path.gsub(/^\//, ''))

    data_encoded = File.open(full_path, 'r') do |file|
      Base64.urlsafe_encode64(file.read)
    end

    "data:image/#{file_type};base64,#{data_encoded}"
  end
end

我在这里做了一些事情:

  1. require "base64"移至文件顶部;它不属于某种方法。

  2. 在方法的最开始点检查file_type,如果它不在列出的类型中,则提前返回。

  3. 使用File.open代替open(filename).to_a.join(或更简洁的open(filename).read)。 OpenURI(提供您正在使用的open方法)对于从本地文件系统读取来说是过度的。

  4. 使用Base64.urlsafe_encode64代替encode64。可能没有必要,但它没有受到伤害。

  5. 删除不必要的if;由于我们知道file_typejpgpng,我们可以直接在数据URI中使用它。

  6. 使用Middleman的内置资产系统可能有一种更优雅的方式来获取file_path或确定文件的MIME类型,但是对文档进行非常简短的搜索并没有&#39什么都没有。