Как мне динамически требовать активы в конвейере ресурсов Rails 3.1? - PullRequest
11 голосов
/ 09 декабря 2011

У меня есть система на основе плагинов, которую я использую для разработки приложений в Rails.Каждый плагин реализует движок с компонентами MVC и т. Д. Основное приложение - это просто пустой жгут, который делегирует всю работу установленным плагинам.

В настоящее время я обновляюсь до Rails 3.1 с Rails 2.3.5и пытаюсь заставить конвейер ресурсов работать с моей платформой.

Проблема, с которой я сталкиваюсь, заключается в том, чтобы программно запрашивать активы моего плагина, например, в манифесте application.js.

Я могу вручную добавить их так:

//= require <plugin_manifest_path>

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

<%=
Rails.plugins.collect do |plugin|
  "//= require #{plugin}"
end.join("\n")
%>

Но я обнаружил, что фаза требования / директивы компиляции конвейера ресурсов происходит до расширения ERB, поэтому сгенерированные комментарии просто заканчиваются как комментарии.

Есть ли другой механизм для включения путей для компиляции, который мог бы работать?Любой способ предварительно обработать файл манифеста до , когда начинается обработка директивы?

Если я не могу придумать ничего лучшего, мне, возможно, придется написать задачу грабли / развертывания, которая генерируетфайл манифеста plugin.js при развертывании, но я бы хотел что-то более понятное и элегантное, если это возможно.Спасибо!

РЕДАКТИРОВАТЬ : Решение найдено, опубликует полное решение, как только stackoverflow позволит мне.См комментарии ниже в то же время ...

1 Ответ

13 голосов
/ 10 декабря 2011

ОК, вот решение:

Внутренне конвейер ресурсов (он же Sprockets) требует директивных вызовов context.require_asset(), чтобы фактически требовать любой путь, указанный в директиве. Оказывается, это означает, что метод require_asset присутствует и доступен во время расширения ERB. Итак, правильное решение было:

// ... Standard application.js stuff here ...
//= require_tree .
<%
Rails.plugins.each do |plugin|
  require_asset(plugin.to_s)
end
%>

Добавил, что в, и все работало, как ожидалось. Уф!

Если вам интересен этот бит Rails.plugins, я добавил расширение для модуля Rails, чтобы получить фактический список плагинов, которые загружаются в порядке загрузки на основе config.plugins. Для полноты вот это:

module Rails
  def self.plugins
    # Get sorted list of all installed plugins
    all = Dir.glob(Rails.path('vendor/plugins/*/init.rb')).collect {|p| p.extract(/\/([^\/]+)\/init.rb$/) }
    all.sort!
    all.collect! {|p| p.to_sym }

    # Get our load order specification
    load_order = Rails.application.config.plugins

    # Split the load order out, and re-assemble replacing the :all keyword with the
    # set of plugins not in head or tail
    head, tail = load_order.split(:all)
    all -= head
    all -= tail

    # All set!
    head + all + tail
  end
end

И последняя деталь - создание файла манифеста <plugin_name>.js в каталоге каждого плагина app / assets / javascripts.

Надеюсь, это кому-нибудь поможет!

...