【问题标题】:css.erb file in SinatraSinatra 中的 css.erb 文件
【发布时间】:2013-03-10 05:12:57
【问题描述】:

例如,是否可以在 Sinatra 中有一个 css.erb 文件来提供来自 AWS 的图像。我正在从 AWS 中提取我的静态资产,例如可以在我的视图中提取图像

<%= image_tag( aws_asset "/assets/img/banner2.jpg") %>

aws_asset 是设置 AWS url 的助手

helpers do
 def aws_asset( path )
 File.join settings.asset_host, path
 end
end

configure :development do 
 set :asset_host, "https://s3-eu-west-1.amazonaws.com/#{ENV['FOG_DIRECTORY']}" 
end

所以问题是我如何从我的 css 文件中获取背景图像以从 AWS 中提取该图像

编辑

当前设置

myapp.rb

get "/assets/css/style.css" do
erb :style 
end

layout.erb

<%= stylesheet_link_tag  "/assets/css/style.css"  %>

style.css

body {
background: url('<%= aws_asset "/assets/img/banner1.jpg" %>');

}

谢谢

【问题讨论】:

  • 忘记我的其他评论,我看到你已经问过这个问题了! :)
  • 检查实际输出(在浏览器的源代码视图或开发者控制台中)并检查生成的 URL 是否正确。您可以访问它们,您应该会看到图像。
  • 好吧,它们不像我通常期望的那样显示为链接,您无法单击它来查看文件,例如,背景:url('');
  • 要么将style.css重命名为style.erb(无需执行其他操作,只需重新启动),要么重命名为style.css.erb 也将erb :style替换为@987654330 @.
  • 好的,所以将 .erb 分机添加到 css 文件会停止所有 css 的呈现,因此只有 .erb 分机也是如此。第二个建议也没有区别?

标签: css ruby amazon-s3 sinatra assets


【解决方案1】:

因为您已经为此使用 ERB:

body
{
  background-image:url('banner2.jpg');
}

会变成:

body
{
  background-image:url('<%= aws_asset "/assets/img/banner2.jpg" %>');
}

这就是简单的答案。但是,由于您可能从 AWS 提供了很多文件,因此在您需要的所有不同地方使用帮助程序可能会变得很烦人,而且也很困难 - 也许您将来会想要预编译 CSS 等等。这是什么时候使用 Rack 中间件隐藏一些实现是个好主意。

module MySinatraApp

  # A remote file called banner2.jpg would have the relative path
  # in the app of "/images/extra/banner2.jpg"
  # and on being requested, this middleware/app would check if
  # the remote file is in the list you've given
  # if it is, a 307 redirect is issued.
  # If it isn't, then a 404. Use with Rack::Cascade to pass on
  # to another app that may serve a local version of the file.
  # @example
  #   use RemoteImageServer, 
  #       :asset_host => "//s3-eu-west-1.amazonaws.com"
  #       :files      => ["banner2.jpg", "blah.gif"]
  class RemoteImageServer
    DEFAULT_OPTIONS = {
      subdir:        "images/extra",
      cascade:       false # until I work it out more, see note at bottom
    }

    def initialize(app,options={})
      app, options = app, DEFAULT_OPTIONS.merge(options)
      @asset_host = options[:asset_host]
      files = options[:files]
      @subdir = options[:subdir]
      @http_path_files = files.map{|file| File.join @subdir, file }
    end

    def call( env )
      dup._call( env ) # for thread safety
    end

    def _call( env )
      request = Rack::Request.new env
      if request.path_info.start_with? @subdir
        response = Rack::Response.new env
        if @http_path_files.include? request.path_info
          response.redirect File.join(@asset_host,request.path_info), 307
          response.finish
        else
          if @options[:cascade]
            response.status = 404
            response.finish
          end
        end
      else
        @app.call env
      end
    end
  end

  class MainApp < Sinatra::Base do
    # other stuff here…
  end

end

您要么使用这个in the Sinatra Application,要么在机架文件中。对于这个我更喜欢后者并使用Rack::Cascade:

运行 Rack::Cascade.new([ MySinatraApp::RemoteImageServer, MySinatraApp::MainApp])(我不确定在使用级联时如何最好地传递选项,我可能需要考虑更多)。

  use RemoteImageServer, 
    :asset_host => "//s3-eu-west-1.amazonaws.com"
    :files      => ["banner2.jpg", "blah.gif"]
  run MySinatraApp::MainApp

这样,远程主机就“隐藏”在了相对 url 后面,您可以用本地文件替换远程文件,或者轻松更改远程提供程序。最后的 Sinatra 应用程序仍将提供其公用文件夹中的任何本地文件。不过,这段代码完全未经测试!可能有一个 Rack 中间件已经这样做了(Rack Static Fallback 可能很接近)。


编辑:通过 ERB 提供 CSS。

主要有两种方式:

  • 预编译 CSS 并通过 public_folder 提供。
  • 通过get 路线提供服务。

预编译 CSS

可能有一个 gem 或其他东西可以做到这一点(可能是一个 Guard 助手或其他东西),但这可以在控制台中工作:

require 'erb'
require 'tilt'
template = Tilt.new( "path/to/erb/file" )
File.open "app/public/stylesheets/main.css", "w" do |f|
  f.write template.render
end

由于编译后的 CSS 文件将驻留在 Sinatra 的公共目录中,因此它将作为静态文件提供。由于文件中有来自 Sinatra 的 aws_asset 帮助程序,因此您需要稍微更改它,或者在运行它之前在控制台中重新定义帮助程序,或者硬编码路径,或者 pass it a variable instead

从 Sinatra 获取路线提供服务

get "/css/main.css" do
  erb :main # it will server main.erb from the views directory
            # and it will have access to helpers.
end

由于是一个不会经常更改的文件,最好添加cache control headers

【讨论】:

  • 哇,谢谢伊恩,很好的回答,给了我一些新的东西,以前从未这样做过:)
  • 我也试过背景:url('')repeat #f2f2f2;但图像不显示?我还需要做什么,更改样式表的扩展名?
  • @Richlewis 该样式表中的其余 CSS 是否正常工作?你需要一个路由来提供它,或者将它预编译到公共目录中。
  • 是的,其余的 css 工作正常吗?你介意解释一下其余的吗?
  • @Richlewis 我已经为答案添加了一些解释。
猜你喜欢
  • 2012-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多