Rails asset pipeline-как включить актив не в путь к активу?
Итак, я преобразовал это мое приложение с несколькими оболочками, чтобы использовать конвейер активов, представленный в Rails 3.1. По большей части это было удивительно легко, и я влюблен в возможность предварительной обработки, которая позволяет использовать встроенный Ruby в ваших CSS/JS файлах. Однако я столкнулся с серьезной проблемой, которую, несмотря на мощь звездочек, трудно решить. Мое приложение может быть запущено с любым количеством скинов (или, скорее," идентичностей"), которые выбираются во время выполнения. Этот параметр" идентичность" настраивает такие вещи, как каталог кэша, подключение к базе данных, пути просмотра - и действительно пути активов. В то время как все "идентичности" могут иметь свою собственную таблицу стилей, существует также общая, которая используется во всех экземплярах. Таким образом, структура папок assets выглядит примерно так:
In / 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.
Все это работает блестяще - я использую ту же технику для Javascripts, изображений и шрифтов, и все становится аккуратно обрабатывается и упаковывается во время предварительной компиляции. НО. Существует тип (бокового) наследования, которого я не могу достичь; иногда кожа для идентичности настолько похожа на другую, что различаются только несколько линий dosen (например, идентичная компоновка, но с другой цветовой схемой), и я действительно хочу иметь возможность сделать что-то вроде этого:
Активы / таблицы стилей / приложения.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 не находит файл в режиме dev, и, конечно, он не включается во время предварительной компиляции. И если я включаю его в путь активов, он загружает неправильные переопределения.css (может быть только один). Так что я экспериментировал с тем, чтобы поместить что-то вроде этого в верхней части переопределений.css:
<%= File.read(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css")) %>
/* rest of CSS */
...
И действительно, это работает так, как и ожидалось. НО. Потому что теперь я использую активы конвейер для обслуживания всех активов я больше не могу ссылаться на изображения в CSS с фиксированным путем - я должен использовать <%= asset_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
Что, конечно, связано с тем, что я использую asset_path("some_image.png")
etc в файле, который я пытаюсь включать.
1 ответ:
Хорошо, после нескольких часов поиска я наткнулся на список доступных вспомогательных методов в Sprockets - это сэкономило бы мне много времени, если бы это было связано с man-страницей Sprockets на GitHub (есть ссылка, но она указывает на #FIXME). Из документов API Sprockets:
(Object) evaluate(path, options = {})
- читает
path
и запускает процессоры в файле.- это позволяет захватить результат актива и включить его непосредственно в другой.
<%= evaluate "bar.js" %>
Бинго! Я изменил свою директиву include на:
<%= evaluate(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css.erb")) %>
И CSS обрабатывается и результаты вставляются, именно так, как я хотел, чтобы это работало.