2012-05-14 6 views
10

Ich schreibe eine Bibliothek mit einer eingebetteten Sinatra-App, die über Thor gestartet wurde. Ich möchte Instanzen von Sprockets::Environment unter /css und /js einbinden und die Hauptanwendung auf / mappen lassen. Dies wäre einfach mit Rack::URLMap in einer config.ru Datei, aber in diesem Fall gibt es keine, weil ich die Sinatra-App programmgesteuert mit Sinatra::Application.run! starte. Wie kann ich das erreichen?Wie verwende ich Kettenräder mit Sinatra ohne eine Rackup-Datei?

Antwort

5

Ich habe es getan, indem ich eine benutzerdefinierte Middleware mit einigen der Funktionalität von Rack::URLMap geschrieben habe. Es sieht in etwa wie folgt aus:

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

Eigentlich ist das nicht so schwer. Alles, was Sie tun müssen, ist eine Instanz von Sprockets::Environment zu einer Sinatra Konfigurationsvariable zuweisen und einige Pfade definieren, die Vermögenswerte suchen Sie interessiert sind

Hier ist ein einfaches Beispiel:.

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 

Glückliches sprocketing!

+0

Danke dafür - genau das, was ich gesucht habe. – theTRON

+0

Immer glücklich zu helfen! –

+0

Dies funktioniert, wie alle Beispiele von Sinatra-Kettenrädern, die ich gesehen habe, nicht (oder funktioniert nicht mehr). Hat sich etwas in Kettenrädern geändert? – Ian

2

Hier ist, wie ich integrierte Ketten in Sinatra mit Rails artigen Verzeichnisstruktur, Helfer und minification für JS und CSS.

Ich entschied mich, eine Sinatra-Erweiterung zu schreiben. Diese Erweiterung kapselt die Konfiguration von Kettenrädern (Pfade, Verkleinerung, Helfer) und kann von der Anwendung registriert werden.

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 

die Erweiterung in Ihrer Anwendung zu verwenden ist einfach:

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

Assets können in assets oder vendor/assets platziert werden. Zum Beispiel kann vendor/assets/jquery.js durch einen logischen Namen referenziert werden, d. H. http://localhost/assets/jquery.js.

Im obigen Beispiel verwende ich sprockets-helpers, die Helfer wie javascript_tag bietet. Die oben angegebene Konfiguration geht davon aus, dass Sie in der Entwicklung die vom referenzierten Asset benötigten Assets erweitern möchten (was zu mehreren Tags pro Asset führt).

Verwandte Themen