Per*_*mal 9 ruby-on-rails ruby-on-rails-3.1 asset-pipeline
我目前有一个Rails 3.1应用程序,可以为多个不同的客户托管多个站点.每个站点都由一个模型表示,该模型知道域名和存储资产的路径,以及其他一些信息.
我一直app/sites/domain-name用作存储特定于某个站点的资产,视图和语言环境的位置,并且正在运行自定义中间件和控制器操作,用于修改Sprockets的加载路径,设置视图路径等等.
中间件(使用config.middleware.use "Configurator"in 加载application.rb):
class Configurator
  def initialize(app)
    @app = app
  end
  def call(env)
    @env = env
    clear_existing_paths
    prepend_local_assets
    @app.call(env)
  end
  def current_site
    # find site using @env
  end
  def current_site_path
    Rails.root.join('app', 'sites', current_site.path)
  end
  def clear_existing_paths
    paths = Rails.application.assets.paths
    Rails.application.assets.clear_paths
    paths.each do |path|
      next if path.include?("app/sites/")
      Rails.application.assets.append_path path
    end
  end
  def prepend_local_assets
    path = current_site_path.join('assets')
    return unless Dir.exists?(path)
    ['images', 'javascripts', 'misc', 'stylesheets'].each do |subdir|
      asset_dir = path.join(subdir).to_s
      next unless Dir.exists?(asset_dir)
      next if     Rails.application.assets.paths.include? asset_dir
      Rails.application.assets.prepend_path asset_dir
    end
  end
end
Run Code Online (Sandbox Code Playgroud)
资产位来自application.rb:
module MyApp
  class Application < Rails::Application
    ...
    config.middleware.use "Configurator"
    config.assets.enabled = true 
    config.assets.version = '1.0'
  end
end
Run Code Online (Sandbox Code Playgroud)
而且environments/production.rb:
MyApp::Application.configure do
  config.serve_static_assets = false
  config.assets.compress = true
  config.assets.compile = true
  config.assets.digest = true
  # Defaults to Rails.root.join("public/assets")
  # config.assets.manifest = YOUR_PATH
end
Run Code Online (Sandbox Code Playgroud)
问题是,虽然这个设置有效,但它阻止我预编译未与整个应用程序共享的资产,从而使它们从外观上反复生成.
有什么方法可以告诉预编译器找到位于这里的资产,并创建这些资产的版本吗?每个站点都有一个site.css.scss和site.js.coffee可能需要的网站目录内的其他资产文件.如果我可以预编译它会很好public/assets/domain-name/site.(js|css),所以当我需要进一步优化时,我可以轻松地为资产设置一个单独的子域
在实施了Brian提出的建议后,我最终得到了
存储在主要样式表/ javascript中app/sites/<sitename>/assets/<shortname>/site.css|js,sitename该站点的域名在哪里,并且shortname是域的主要部分,没有子域或com | org | net | ccTLD.
修改了所有视图和样式表以预先添加shortname到我的资产路径.
在config/application.rb:
{ "sitename" => "shortname", ... }.each_pair do |domain, short|
  %w{stylesheets javascripts}.each do |dir|
    config.assets.paths << Rails.root.join("app/sites/#{domain}/assets/#{dir}").to_s
  end # Had to specify each dir to make it work
  config.assets.precompile += ["#{short}/site.css", "#{short}/site.js"]
end
Run Code Online (Sandbox Code Playgroud)
运行rake assets:precompile此操作时,会创建public/assets/shortname充满该站点的所有资产,并且public/assets还拥有所有共享资产.适合我的需求.
由于一切都结束了public/assets,我能够删除 - Configurator中间件,因为默认配置能够找到所有资产
我认为问题是,通过将每个站点添加为路径,sprockets只找到第一个site.scss
我用罗盘试过这个,但对于普通的链轮来说应该是一样的.我没有尝试过你的配置器方法,但看起来很容易使我的安排适应它.
您可以将app/sites/*更改为更标准的文件排列吗?
./app/assets/javascripts/application.js
./app/assets/stylesheets/screen.css.scss
./app/assets/stylesheets/othersite/screen.css.scss
Run Code Online (Sandbox Code Playgroud)
更改您的config/application.rb,并添加您的每个站点.这将在每个主机上预生成所有样式:
config.assets.precompile += ['screen.css', 'othersite/screen.css']
Run Code Online (Sandbox Code Playgroud)
在您的视图/布局/应用程序中,您需要配置sitename的路径:
= stylesheet_link_tag '[your sitename here]/screen'
Run Code Online (Sandbox Code Playgroud)
在我耙资产之后:清理和预编译,我在公开场合看到这个:
./assets/othersite/screen.css
./assets/othersite/screen.css.gz
./assets/screen.css
./assets/screen.css.gz
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           4842 次  |  
        
|   最近记录:  |