javascript - 创建 Ruby Gem 以将 HTML/JavaScript 插入主应用程序

标签 javascript ruby-on-rails ruby gem

我创建了一个 Rails Engine轻松包含用于 Rails 应用程序的 JavaScript 插件。问题是这个插件实际上只用于开发,当将应用程序推向生产时,开发人员需要删除 javascript list 文件中的 require marx,然后在 JavaScript 中进行实际调用。

我希望做的是允许开发人员使用 gem 'marxjs-rails', group::development 将其添加到 Gemfile 并设置一些在 config/application.rbconfig/environments/development.rb 中配置插件设置。

然后 gem 应该将 html 插入父应用程序:

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

我一直在尝试使用一种辅助方法来插入 html,但我无法将其作为 html 插入。 Rails 继续对 HTML 进行转义。虽然我不太喜欢这条路。

我一直在查看 jasmine-gemrack-olark 作为示例,但无法完全正常工作。

更新

这不是我真正想要的解决方案,但这可能会对其他人有所帮助,并且在我找到更好的方法之前我一直在使用它。您可以查看整个代码 here但我会给你亮点:

# 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

和 View 助手:

# 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 来防止 rails 转义 html .我还将 options 变量绑定(bind)到 binding 对象以将其发送到模板。

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

最后,在我的主要 Rails 应用程序中,我在 application.html.haml 中调用了 render_marxjs(controls: 'toggle-all')(如果您愿意,也可以是 .erb )

同样,我仍在寻找可以帮助我在没有 View 辅助方法的情况下处理此问题并且能够通过环境文件设置一些配置的人,但我希望这可能对某些人有所帮助...

最佳答案

您可以在不创建引擎的情况下实现这一点。

  • 添加名为 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
    
  • 将 gem 添加到 Gemfile

    gem 'marxjs-rails', group: :development
    

关于javascript - 创建 Ruby Gem 以将 HTML/JavaScript 插入主应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31105185/

相关文章:

javascript - 进行属性查找时,javascript 如何处理 `this`?

javascript - 使用包含所有脚本的 jQuery 的动态内容

javascript - 如何在javascript中创建cookie并在mvc3的 Controller 中使用

ruby-on-rails - 搜索具有多个值的多个字段

ruby-on-rails - rails 模型 : How to make field read only in Rails model?

ruby-on-rails - 重定向 ruby​​ 脚本的 shell 输出

ruby-on-rails - 在运行 bundle install 时,在 1.9 兼容模式下使用 jruby 创建新的 rails 项目挂起

javascript - 如何在点击时进行面向对象的 Canvas 元素比较?

javascript - 在 rails 上无限滚动

ruby-on-rails - Rails 3. 创建生产数据库