Sinatra 资产管道,无法使其工作
Sinatra asset pipeline, can't make it work
我按照 Sinatra 的页面文档中的建议将 Sprockets 与 Sinatra 一起使用,但我无法使其正常工作。
当我转到 localhost:4567
时,页面加载正确但没有样式。如果我转到 localhost:4567/assets/app.css
,我会收到一个未找到的错误。我想知道我缺少什么或者我使用 Sprockets 的方式有什么问题?
这是我的文件夹结构:
├── assets
│ ├── css
│ │ ├── app.css
│ │ ├── base.css
│ │ └── normalize.css
├── bin
│ └── app
├── lib
│ ├── app_assets.rb
│ └── main.rb
├── spec
│ ├── spec_helper.rb
│ └── main_spec.rb
├── views
│ └── index.erb
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── .rspec
└── .ruby-version
app.css
的内容是:
//= require normalize
//= require base
app_assets.rb
的内容是:
module AppAssets
def self.environment root_path
environment = Sprockets::Environment.new root_path
environment.append_path './assets/css/'
environment
# get assets
get '/assets/*' do
env['PATH_INFO'].sub!('/assets', '')
settings.environment.call(env)
end
end
end
lib/main.rb
的内容是:
require 'sinatra'
require 'sprockets'
require 'app_assets'
class Main < Sinatra::Base
set :views, "#{settings.root}/../views"
get '/' do
erb :index
end
end
文件 views/index.erb
包含行:
<link rel="stylesheet" href="assets/app.css">
而bin/app
的内容是:
#!/usr/bin/env ruby
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
require 'sinatra'
require 'sprockets'
require 'app_assets'
require 'main'
Main.run!
我 运行 输入:
$ bin/app
如有任何帮助,我们将不胜感激,我确定我做错了什么,但我看不出是什么。有人能看出来吗?
app_assets.rb
文件是这里的问题。当您在另一个文件中需要此文件时,不会自动包含您在该模块中定义的方法。您需要在需要 self.environment
方法存在的任何地方显式 include AppAssets
。
这里的第二个问题是 self.environment
不等同于 settings.environment
。如果我理解正确,您要做的是在包含模块时定义资产路由。要实现这一点,一种方法是对模块使用 included
挂钩。每次在上下文中包含模块时,此挂钩都会得到 运行。如果使用它,app_assets.rb
中的代码将变为:
module AppAssets
def self.included(klass)
environment = Sprockets::Environment.new klass.settings.root
# note the change to path. Since the file where this gets included
# is inside a sub-folder, we need to traverse to one level above.
environment.append_path '../assets/css/'
klass.set :environment, environment
klass.get '/assets/*' do
env['PATH_INFO'].sub!('/assets', '')
klass.settings.environment.call(env)
end
end
end
此挂钩的 klass
参数是包含此模块的 class。在我们的例子中,这是您在 main.rb
中描述的 Sinatra class。该文件看起来像:
class Main < Sinatra::Base
include AppAssets
# Same as what you have
end
有一篇关于在 Sinatra 中使用 Sprockets 的 Sinatra Recipes 文章:http://recipes.sinatrarb.com/p/asset_management/sprockets?#article
我按照 Sinatra 的页面文档中的建议将 Sprockets 与 Sinatra 一起使用,但我无法使其正常工作。
当我转到 localhost:4567
时,页面加载正确但没有样式。如果我转到 localhost:4567/assets/app.css
,我会收到一个未找到的错误。我想知道我缺少什么或者我使用 Sprockets 的方式有什么问题?
这是我的文件夹结构:
├── assets
│ ├── css
│ │ ├── app.css
│ │ ├── base.css
│ │ └── normalize.css
├── bin
│ └── app
├── lib
│ ├── app_assets.rb
│ └── main.rb
├── spec
│ ├── spec_helper.rb
│ └── main_spec.rb
├── views
│ └── index.erb
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── .rspec
└── .ruby-version
app.css
的内容是:
//= require normalize
//= require base
app_assets.rb
的内容是:
module AppAssets
def self.environment root_path
environment = Sprockets::Environment.new root_path
environment.append_path './assets/css/'
environment
# get assets
get '/assets/*' do
env['PATH_INFO'].sub!('/assets', '')
settings.environment.call(env)
end
end
end
lib/main.rb
的内容是:
require 'sinatra'
require 'sprockets'
require 'app_assets'
class Main < Sinatra::Base
set :views, "#{settings.root}/../views"
get '/' do
erb :index
end
end
文件 views/index.erb
包含行:
<link rel="stylesheet" href="assets/app.css">
而bin/app
的内容是:
#!/usr/bin/env ruby
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
require 'sinatra'
require 'sprockets'
require 'app_assets'
require 'main'
Main.run!
我 运行 输入:
$ bin/app
如有任何帮助,我们将不胜感激,我确定我做错了什么,但我看不出是什么。有人能看出来吗?
app_assets.rb
文件是这里的问题。当您在另一个文件中需要此文件时,不会自动包含您在该模块中定义的方法。您需要在需要 self.environment
方法存在的任何地方显式 include AppAssets
。
这里的第二个问题是 self.environment
不等同于 settings.environment
。如果我理解正确,您要做的是在包含模块时定义资产路由。要实现这一点,一种方法是对模块使用 included
挂钩。每次在上下文中包含模块时,此挂钩都会得到 运行。如果使用它,app_assets.rb
中的代码将变为:
module AppAssets
def self.included(klass)
environment = Sprockets::Environment.new klass.settings.root
# note the change to path. Since the file where this gets included
# is inside a sub-folder, we need to traverse to one level above.
environment.append_path '../assets/css/'
klass.set :environment, environment
klass.get '/assets/*' do
env['PATH_INFO'].sub!('/assets', '')
klass.settings.environment.call(env)
end
end
end
此挂钩的 klass
参数是包含此模块的 class。在我们的例子中,这是您在 main.rb
中描述的 Sinatra class。该文件看起来像:
class Main < Sinatra::Base
include AppAssets
# Same as what you have
end
有一篇关于在 Sinatra 中使用 Sprockets 的 Sinatra Recipes 文章:http://recipes.sinatrarb.com/p/asset_management/sprockets?#article