3

たとえば、AWS から画像を提供するために Sinatra に css.erb ファイルを作成することは可能ですか。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 ファイルから背景画像を取得して、その画像を A​​WS からプルする方法です。

編集

現在のセットアップ

myapp.rb

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

レイアウト.erb

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

スタイル.css

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

}

ありがとう

4

1 に答える 1

3

これにはすでに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

これを Sinatra Applicationまたは rackup ファイルで使用します。これは後者の方がいいな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 を提供します。

主な方法は 2 つあります。

  • 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ヘルパーがあるので、少し変更する必要があります。実行する前にコンソールでヘルパーを再定義するか、パスをハードコーディングするか、代わりに変数を渡します

Sinatra の get ルートから提供する

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

これは頻繁に変更されることのないファイルであるため、キャッシュ コントロール ヘッダーを追加することをお勧めします。

于 2013-03-20T22:31:26.770 に答える