В настоящее время у меня есть приложение 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, так как конфигурация по умолчанию смогла найти все активы