Конвейер ассетов Rails — как включить ассет не в путь ассета?

Итак, я переделал это многослойное приложение, чтобы использовать конвейер ресурсов, представленный в Rails 3.1. По большей части это было на удивление просто, и я в восторге от возможности предварительной обработки, которая позволяет вам использовать встроенный Ruby в ваших файлах CSS/JS. Однако я столкнулся с серьезной проблемой, которую, несмотря на мощь Sprockets, решить сложно. Мое приложение можно запускать с любым количеством скинов (или, скорее, «идентификаций»), которое выбирается во время выполнения. Этот параметр «идентификация» устанавливает такие вещи, как каталог кеша, подключение к базе данных, пути просмотра и, конечно же, пути ресурсов. Несмотря на то, что все «удостоверения» могут иметь свою собственную таблицу стилей, существует также общая таблица стилей, которая используется во всех экземплярах. Таким образом, структура папок ресурсов выглядит примерно так:

В /app/assets/stylesheets/aplication.css.erb:

<% require_asset("shared.css") %>
<% require_asset("overrides.css") %>

Это загружает две таблицы стилей, и, что особенно важно, для их разрешения используются сконфигурированные пути ресурсов (вот почему я используйте директивы require_assetsвместо стандартных директив requireи include, поскольку они не затрагивают преобразователь). Он возвращает первые найденные совпадения и позволяет мне очень легко переопределить часть или весь стиль по умолчанию.Таким образом,

/app/assets/stylesheets/shared.css

можно переопределить, поместив файл с тем же именем в папку активов экземпляра

/app/assets/[identity]/stylesheets/shared.css

, и если такого файла не существует, он автоматически возвращается к общему.css по умолчанию.

Все работает блестяще — я использую ту же технику для Javascript, изображений и шрифтов, и все аккуратно обрабатывается и упаковывается во время предварительной компиляции. НО. Существует тип (бокового) наследования, которого я не могу достичь; иногдаскин для айдентики настолько похож на другой, что отличается всего несколькими дозами строк (например, идентичный макет, но с другой цветовой схемой), и я очень хочу иметь возможность сделать что-то вроде этого:

assets/stylesheets/application.css.erb:

<% require_asset("shared.css") %>
<% require_asset("overrides.css") %>

assets/current_identity/stylesheets/overrides.css:

<% require_asset("../../some_other_identity/stylesheets/overrides.css") %>
/* followed by the dosen or so lines that differ for this skin */
...

Это ОТСУТСТВУЕТ, потому что в текущем контексте «some_other_identity» отсутствует в путях ресурсов — Rails не находит файл в режиме разработки, и, конечно же, он не включается во время прекомпиляции. И если я включу его в путь к ресурсам, он загрузит неправильный overrides.css ( может быть только один ). Итак, я экспериментировал с размещением чего-то вроде этого в верхней части overrides.css:

<%= File.read(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css")) %>
/* rest of CSS */
...

И действительно, это работает так, как и ожидалось. НО. Поскольку теперь я использую конвейер ресурсов для обслуживания всех ресурсов, я больше не могу ссылаться на изображения в CSS с фиксированным путем — я должен использовать <%= assets_path("some_image.png") %>так что преобразователь пути может творить чудеса. Это означает, что мой overrides.cssна самом деле overrides.css.erb, и, конечно, предварительная обработка ERB не происходит, когда вы выполняете File.read().Итак, я застрял! Помощь! Любой?

Редактировать: Если я использую

<%= ERB.new(File.read(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css.erb"))).result %>

, он пытается разобрать ERB, но я получаю

undefined method `asset_path' for main:Object

, что, конечно же, связано с тем, что я использую assets_path("some_image.png")и т. д. в файле, который я пытаюсь включить.

6
задан John Schulze 24 June 2012 в 15:54
поделиться