2012-05-14 27 views
10

Tôi đang viết thư viện có ứng dụng Sinatra được nhúng được khởi chạy qua Thor. Tôi muốn gắn các phiên bản của Sprockets::Environment tại /css/js và để ứng dụng chính được ánh xạ tới /. Điều này sẽ dễ dàng khi sử dụng Rack::URLMap trong tệp config.ru, nhưng trong trường hợp này không có một vì tôi đang bắt đầu ứng dụng Sinatra theo lập trình với Sinatra::Application.run!. Làm thế nào tôi có thể đạt được điều này?Làm thế nào để sử dụng Sprockets với Sinatra mà không có một tập tin rackup?

Trả lời

5

Tôi đã kết thúc bằng cách viết một phần mềm trung gian tùy chỉnh với một số chức năng từ Rack::URLMap. Nó trông giống như thế này:

require "sprockets" 
require "sinatra/base" 

class SprocketsMiddleware 
    attr_reader :app, :prefix, :sprockets 

    def initialize(app, prefix) 
    @app = app 
    @prefix = prefix 
    @sprockets = Sprockets::Environment.new 

    yield sprockets if block_given? 
    end 

    def call(env) 
    path_info = env["PATH_INFO"] 
    if path_info =~ prefix 
     env["PATH_INFO"].sub!(prefix, "") 
     sprockets.call(env) 
    else 
     app.call(env) 
    end 
    ensure 
    env["PATH_INFO"] = path_info 
    end 
end 

class App < Sinatra::Base 
    use SprocketsMiddleware, %r{/assets} do |env| 
    env.append_path "assets/css" 
    env.append_path "assets/js" 
    end 
end 

App.run! 
13

Thực ra, điều này không khó. Tất cả bạn cần làm là gán một thể hiện của Sprockets::Environment cho một biến cấu hình Sinatra và xác định một số đường dẫn để tìm kiếm các tài sản mà bạn quan tâm

Dưới đây là một ví dụ cơ bản:.

require "sass" 
require "haml" 
require "erubis" 
require "sinatra" 
require "sprockets" 

set :assets, Sprockets::Environment.new 

# Configure sprockets 
settings.assets.append_path "app/javascripts" 
settings.assets.append_path "app/stylesheets" 

# For compressed JS and CSS output 
require "yui/compressor" 
settings.assets.js_compressor = YUI::JavaScriptCompressor.new 
settings.assets.css_compressor = YUI::CssCompressor.new 

get "/" do 
    haml :index 
end 

get "/javascripts/:file.js" do 
    content_type "application/javascript" 
    settings.assets["#{params[:file]}.js"] 
end 

get "/stylesheets/:file.css" do 
    content_type "text/css" 
    settings.assets["#{params[:file]}.css"] 
end 

Chúc mừng sprocketing!

+0

Cảm ơn vì điều này - chính xác những gì tôi đang tìm kiếm. – theTRON

+0

Luôn sẵn sàng trợ giúp! –

+0

Điều này, giống như tất cả các ví dụ sinatra-sprockets tôi đã nhìn thấy, không hoạt động (hoặc, không còn hoạt động). Có cái gì đó trong sprockets thay đổi? – Ian

2

Đây là cách tôi tích hợp Sprockets vào Sinatra với bố cục thư mục giống như Rails, trợ giúp và rút gọn cho JS và CSS.

Tôi đã chọn viết phần mở rộng Sinatra. Phần mở rộng này đóng gói cấu hình của sprockets (đường dẫn, minification, helpers) và có thể được đăng ký bởi ứng dụng.

module Sinatra 
    module Assets 
    extend Sinatra::Extension 

    configure do 
     set :assets, Sprockets::Environment.new(root).tap { |assets| 
     %w(assets vendor/assets).each do |base| 
      %w(images javascripts stylesheets).each do |type| 
      assets.append_path File.join(base, type) 
      end 
     end 
     if production? 
      assets.js_compressor = Closure::Compiler.new 
      assets.css_compressor = YUI::CssCompressor.new 
      uid = Digest::MD5.hexdigest(File.dirname(__FILE__))[0,8] 
      assets.cache = Sprockets::Cache::FileStore.new("/tmp/sinatra-#{uid}") 
     else 
      assets.cache = nil 
     end 
     } 
    end 

    get "/assets/*" do 
     env["PATH_INFO"].sub!(%r{^/assets}, "") 
     expires Time.now + (365*24*60*60) if settings.production? 
     settings.assets.call(env) 
    end 

    helpers do 
     include Sprockets::Helpers 

     Sprockets::Helpers.configure do |config| 
     config.expand = development? 
     config.digest = production? 
     end 

     def assets_environment 
     settings.assets 
     end 
    end 
    end 
end 

Sử dụng phần mở rộng trong ứng dụng của bạn rất đơn giản:

class App < Sinatra::Base 
    register Sinatra::Assets 
    # ... 
end 

Tài sản có thể được đặt trong assets, hoặc vendor/assets. Ví dụ: vendor/assets/jquery.js có thể được tham chiếu theo tên lôgíc, ví dụ: http://localhost/assets/jquery.js.

Trong ví dụ trên, tôi đang sử dụng sprockets-helpers, cung cấp những người trợ giúp như javascript_tag. Cấu hình được đưa ra ở trên giả định rằng trong quá trình phát triển, bạn muốn mở rộng nội dung được yêu cầu bởi nội dung được tham chiếu (dẫn đến nhiều thẻ cho mỗi nội dung).

Các vấn đề liên quan