Sinatra资产管道无法使其发挥作用

时间:2016-06-12 11:54:25

标签: css ruby sinatra asset-pipeline sprockets

我正在使用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

任何帮助都会受到赞赏,我确定我做错了什么,但我看不清楚。任何人都可以发现它吗?

1 个答案:

答案 0 :(得分:2)

app_assets.rb文件是这里的问题。当您在另一个文件中需要此文件时,不会自动包含您在此模块中定义的方法。您需要在include AppAssets方法存在的任何地方明确self.environment

这里的第二个问题是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参数是包含此模块的类。在我们的例子中,这是您在main.rb中描述的Sinatra课程。该文件看起来像:

class Main < Sinatra::Base
  include AppAssets

  # Same as what you have
end

Sinatra Recipes有关使用Sprockets和Sinatra的文章:http://recipes.sinatrarb.com/p/asset_management/sprockets?#article