Rails 3.1 Asset Pipeline не прекомпилирует файлы из другого каталога - PullRequest
9 голосов
/ 13 февраля 2012

В настоящее время у меня есть приложение Rails 3.1, в котором размещено несколько сайтов для нескольких разных клиентов. Каждый сайт представлен моделью, которая знает имя домена и путь, по которому хранятся активы, а также некоторую другую информацию.

Я использовал app/sites/domain-name в качестве места для хранения ресурсов, представлений и локалей, специфичных для данного сайта, и выполняю пользовательское промежуточное ПО и действия контроллера для изменения пути загрузки для Sprockets, настройки представления дорожки и пр.

промежуточное программное обеспечение (загружается с использованием config.middleware.use "Configurator" в 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

биты активов из application.rb:

module MyApp
  class Application < Rails::Application
    ...
    config.middleware.use "Configurator"

    config.assets.enabled = true 
    config.assets.version = '1.0'
  end
end

А 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

Проблема в том, что, хотя эта установка работает, она не позволяет мне предварительно скомпилировать ресурсы, которые не являются общими для всего приложения, заставляя их генерироваться снова и снова, исходя из его внешнего вида.

Можно ли как-то сказать прекомпилятору найти ресурсы, расположенные здесь, и также создать их версию? Каждый сайт имеет файл site.css.scss и site.js.coffee, для которого могут потребоваться другие ресурсы внутри директории сайта. Было бы неплохо, если бы я мог предварительно скомпилировать его в public/assets/domain-name/site.(js|css), чтобы я мог легко настроить отдельный поддомен для активов в будущем, когда мне нужно будет оптимизировать

Окончательное решение (2012-02-22)

После реализации того, что было предложено Брайаном, я получил

Основная таблица стилей / 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

При запуске rake assets:precompile создается public/assets/shortname, заполненный всеми активами для этого сайта, и public/assets также имеет все общие ресурсы. Прекрасно работает для моих нужд.

И так как все закончилось в public/assets, я смог удалить Configurator -mddleware, так как конфигурация по умолчанию смогла найти все активы

Ответы [ 2 ]

7 голосов
/ 21 февраля 2012

Думаю, проблема в том, что, добавляя каждый сайт в качестве пути, звездочки находят только первый сайт. Scss

Я пробовал это с использованием компаса, но он должен быть таким же для простых звездочек.Я не пробовал ваш подход к конфигуратору, но адаптировать мое расположение к нему выглядит просто.

Можете ли вы изменить свое приложение / sites / * на более стандартное расположение файлов?

./app/assets/javascripts/application.js
./app/assets/stylesheets/screen.css.scss
./app/assets/stylesheets/othersite/screen.css.scss

Измените ваш config / application.rb и добавьте каждый из ваших сайтов.Это предварительно сгенерирует все стили на каждом из ваших хостов:

config.assets.precompile += ['screen.css', 'othersite/screen.css']

В вашем представлении / раскладках / приложении вам нужно будет настроить путь к sitename:

= stylesheet_link_tag '[your sitename here]/screen'

ПослеЯ разгребаю ресурсы: очищаю и прекомпилирую, вижу это публично:

./assets/othersite/screen.css
./assets/othersite/screen.css.gz
./assets/screen.css
./assets/screen.css.gz
1 голос
/ 16 февраля 2012

Похоже, что Rails удается найти активы, по крайней мере, когда я изменил config/environments/production.rb, чтобы включить

config.assets.precompile += %w( site.js site.css )

и config/application.rb, чтобы включить

config.assets.paths << Rails.root.join("app/sites/sitename/assets/stylesheets").to_s

Это дает мне предварительно скомпилированныйверсия, но только для первого сайта, чтобы иметь site.css.Я предполагаю, что переименование их в sitename.css или добавление дополнительного подкаталога sitename/site.css также может сработать.

...