1

左側に表示されている右側のコードを出力するスタイルガイドを作成しています。

%%を追加するとERBがエスケープされることを知っています

ブロックの内容を取得し、コードを2か所にレンダリングするヘルパーを作成しました。1つはhtmlを表示し、もう1つはhtmlを作成したソースERBを表示します。

問題は、ERBが必要な場所にHTMLを戻すことです。

ビューコード

<%= display_code do %>
  <%= link_to "Button", "/style_guide, class: "btn" %>
<% end %>

ヘルパーコード

module StyleGuideHelper
  def display_code(&block)
    content = with_output_buffer(&block)
    html = ""
    html << content_tag(:div, content, class: "rendered-code")
    html << content_tag(:div, escape_erb(content), class: "source-code-preview")
    html.html_safe
  end

  def escape_erb(code)
    code = code.gsub("%=", "%%=")
  end
end

期待される結果 ボタン<%= link_to "Button"、 "/ style_guide、class:" btn "%>

実際の結果 ボタンボタン

乾杯

4

2 に答える 2

0

以下のコードを使用すると、特定のブロックのコードを取得できます。

class ERBSource
  ERB = ::ActionView::Template::Handlers::ERB

  def self.for(block)
    new(block).source
  end

  attr_reader :block, :file, :line_number
  def initialize(block)
    @block = block
    @file, @line_number = *block.source_location
  end

  def source
    lines = File.readlines(file)

    relevant_lines = lines[(line_number - 1)..-1] || []

    extract_first_expression(relevant_lines)
  end

  private

  def extract_first_expression(lines)
    code = lines.slice[0,1].join # add the first two lines so it has to iterate less

    lines.each do |line|
      code << line
      return code if correct_syntax?(compile_erb(code))
    end
    raise SyntaxError, "unexpected $end"
  end

  def correct_syntax?(code)
    stderr = $stderr
    $stderr.reopen(IO::NULL)
    RubyVM::InstructionSequence.compile(code)
    $stderr.reopen(stderr)
    true
  rescue Exception
    $stderr.reopen(stderr)
    false
  end

  def compile_erb(code)
    ERB.erb_implementation.new(
      code,
      :escape => false,
      :trim => (ERB.erb_trim_mode == "-")
    ).src
  end
end

ヘルパーはこんな感じ

module StyleGuideHelper
  def render_example(name, &block)
    code = ERBSource.for(block)
    content_tag(:h2, name) +
      content_tag(:div, &block) +
      content_tag(:pre, content_tag(:code, code))
  end
end
于 2015-04-14T14:53:16.163 に答える
0

問題は、このヘルパーがブロック ( link_to "Button", ...) を実行することです。ブロック内のソース コードは表示されず、出力のみが表示されます。escape_erb結果の HTMLをキャプチャするために置き換えることができhますが、それを生成した ERB に戻ることはありません。

私が見ているように、あなたのオプションは次のとおりです。

  1. 例をパーシャルに分割し、a) パーシャルをレンダリングし、b) 基になるファイルを表示するヘルパーを作成します。
  2. ERB フラグメントを文字列 (heredocs?) として指定し、その文字列をヘルパーに渡し、ヘルパーに a) 評価してERB.new(string).result(binding)結果をレンダリングさせ、b) 文字列を表示させます。
  3. ビューのどの部分がヘルパーを呼び出したかをヘルパーに判断させ、.erb を十分に解析してブロックを見つけます。注意点として、表示される内容の正確な形式は、callersビューのコンパイル方法により予告なく変更される可能性があります。
  4. クレイジーなメタプログラミング juju を使用して、ERB コンテキストと、評価中のコードをインターセプトしてマークアップに戻す独自の特別なコンテキストの両方でブロックを評価するヘルパーを作成します。

...複雑さと成功確率のおおよその順序で並べ替えます。

于 2012-09-22T04:29:48.650 に答える