Создание Ruby Gem для вставки HTML/JavaScript в основное приложение

Я создаю Rails Engine, чтобы легко включить плагин JavaScript для приложений rails. Проблема в том, что этот плагин действительно предназначен только для разработки, а при нажатии приложения на производство разработчику необходимо удалить require marx в файле манифест javascript, а затем фактический вызов в JavaScript.

То, что я надеюсь сделать, это позволить разработчику просто добавить это в Gemfile с помощью gem 'marxjs-rails', group: :development и настроить некоторые конфигурации в config/application.rb или config/environment/development.rb для настроек плагина.

Затем камень должен вставить html в родительское приложение:

<script src='marx.js'></script>
<script>
  var marx = new Marx()
</script>

Я играл со вспомогательным методом, чтобы вставить html, но я не могу заставить его вставить его как html. Rails продолжает скрывать HTML. Хотя мне не нравится этот путь каким-то образом.

Я рассматривал жемчужину и стойку-оларк в качестве примеров, но не могу заставить ничего работать.

UPDATE

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

# lib/marxjs/rails.rb
require "marxjs/rails/version"
require "marxjs/view_helpers"

module Marxjs
  module Rails
    class Engine < ::Rails::Engine
      initializer "marxjs.view_helpers" do
        ActionView::Base.send :include, ViewHelpers
      end
    end
  end
end

и помощники вида:

# lib/marxjs/view_helpers.rb
require 'erb'

module Marxjs
  module ViewHelpers
    include ActionView::Helpers::OutputSafetyHelper

    def render_marxjs options={}, dev_only=true
      if dev_only == false || (dev_only && ::Rails.env.development?)
        binding.local_variable_set(:options, options.to_json)
        template_file = ::File.read(::File.expand_path('../templates/marxjs.erb', __FILE__))
        raw ERB.new(template_file).result(binding)
      end
    end
  end
end

Самая большая вещь, которую нужно забрать здесь, - это include ActionView::Helpers::OutputSafetyHelper, а также require 'erb' Это дает нам возможность загружать файл erb шаблона и использовать ERB.new для его рендеринга и использовать raw, чтобы сохранить рельсы от экранирования html. Я также связал переменную options с объектом binding, чтобы отправить ее в шаблон.

<script src="assets/marx.js"></script>
<script>
  var marx = new Marx(<%= options %>);
</script>

и, наконец, в моем основном приложении rails я вызываю render_marxjs(controls: 'toggle-all') в application.html.haml(или .erb, если хотите)

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

Ответ 1

Вы можете достичь этого, не создавая движок.

  • Добавьте файл с именем lib/marxjs/script_inserter.rb

    module Marxjs
      module ScriptInserter
        BODY_TAG = %r{</body>}
    
        JS_SCRIPT = %q{
          <script src='marx.js'></script>
          <script>
            var marx = new Marx()
          </script>    
        }
    
        def insert_marxjs
          if (
            response.content_type == 'text/html' &&
            response.body.match(BODY_TAG)
          )
            response.body = response.body.gsub(BODY_TAG, JS_SCRIPT + '\\0')
          end      
        end
      end
    end
    
  • Добавить lib/marxjs/railtie.rb

    module Marxjs
      class Railtie < Rails::Railtie
        initializer "marxjs-rails" do |app|
          ActionController::Base.send :include Marxjs::ScriptInserter      
          ActionController::Base.after_filter :insert_marxjs
        end
      end
    end
    
  • Обновить lib/marxjs/rails.rb

    require "marxjs/rails/version"
    require "marxjs/view_helpers"
    require "marxjs/script_inserter"
    
    # move rails initialization code to railtie.rb
    
  • Добавьте драгоценный камень в Gemfile

    gem 'marxjs-rails', group: :development
    

Ответ 3

Для меня лучше всего добавить движок во всех средах, но его нужно отдельно на application.html.haml:

= javascript_include_tag "mark.js" if Rails.env.development?

Обязательно добавьте его в свой файл config/application.rb, чтобы его скомпилировать:

config.assets.precompile += %w( mark.js )