我正在编写一个包含通过Thor启动的嵌入式Sinatra应用程序的库。我想在Sprockets::Environment
和/css
上安装/js
的实例,并将主应用映射到/
。使用Rack::URLMap
文件中的config.ru
可以很容易,但在这种情况下没有一个,因为我正在使用Sinatra::Application.run!
以编程方式启动Sinatra应用。我怎样才能做到这一点?
答案 0 :(得分:13)
实际上,这并不难。您需要做的就是将Sprockets::Environment
的实例分配给Sinatra配置变量,并定义一些路径来查找您感兴趣的资产。
这是一个基本的例子:
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
快乐的sprocketing!
答案 1 :(得分:5)
我最终通过使用Rack::URLMap
中的一些功能编写自定义中间件来实现这一目标。看起来大致如下:
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!
答案 2 :(得分:2)
以下是我如何将Sprockets集成到Sinatra中,使用类似Rails的目录布局,帮助和JS和CSS的缩小。
我选择写一个Sinatra扩展。此扩展程序封装了链轮的配置(路径,缩小,帮助程序),并且可以由应用程序注册。
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
在您的应用程序中使用扩展程序很简单:
class App < Sinatra::Base
register Sinatra::Assets
# ...
end
资产可以放在assets
或vendor/assets
中。例如,vendor/assets/jquery.js
可以通过逻辑名称引用,即http://localhost/assets/jquery.js
。
在上面的示例中,我使用的是sprockets-helpers,它提供了javascript_tag
等帮助程序。上面给出的配置假定在开发过程中,您希望扩展引用资产所需的资产(导致每个资产有多个标记)。