4

コードと出力を表示するスタイルガイドに取り組んでいます。現在、コードを1回だけ記述する必要があるように構成されており、次のように、未加工バージョンと解釈済みバージョンの両方で表示されます。

<% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
  #{ image_tag 'image.png' }
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>

<%= raw code %>
<%= content_tag :pre, code, class: "prettyprint linenums" %>

これは素晴らしく、保守もかなり簡単です。image_tag上記の例のように、問題はレールヘルパーにあります。ビューの例では、画像がdivに正しく表示され、コードの例では、関連するHTMLが表示されます。この場合、関連するHTMLにはアンカータグが含まれていimage_tagます。これは、呼び出し自体ではなく、メソッドの結果です。

結果ではなく、ヘルパーメソッドを表示するコード例を使用したいと思います。ファイルにサンプルコードを指定し、ファイルをレンダリングまたは読み取ることで、これを機能させることができます。上記のように変数でコードを指定することでこれを機能させたいのですが、ERBブロック内の文字列内でERB区切り文字を機能させることができないようです。最も単純なケースでさえ、<% foo = '<%= bar %>' %>まったく機能しません。公式ドキュメント<%% %%>の詳細を使用して(% %たとえば)構文を試してみましたが、あまり成功しませんでした。

この問題に関して私が見つけた唯一の情報は、を使用したここ<%= "<" + "%=" %> link_to <%= image.css_tag.humanize %> <%= "%" + ">" %> %>にあります。これは、このユースケースでは機能しません(あるとしても)。

それで、ERB文字列にERB終了区切り文字()を含む文字列を指定する方法はありますか%>、それとも少し不格好なファイル読み取り方法を使用して立ち往生していますか?ありがとう!

編集:

私が最終的にやりたいのは、これの動作バージョンです:

<%# Idealized code - does not work %>
<% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
  <% image_tag 'image.png' %>
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>

したがって、<%= raw code %>次のように出力されます(続行されます)。

<div>
  <img src="/images/image.png" alt="Image" />
</div>

そして<%= content_tag :pre, code, class: "prettyprint linenums" %>出力します:

<pre class="prettyprint linenums">
  <div>
    <% image_tag 'image.png' %>
  </div>  
</pre>

変数を使用するときに現在実行していることの代わりに、次のようになります。

<pre class="prettyprint linenums">
  <div>
    <img src="/images/image.png" alt="Image" />
  </div>
</pre>

ユーザーがコード例をコピーして新しいビューに貼り付けることができるようにしたいのですが、HTMLをそれらを生成するヘルパーに変換し直す必要はありません。私が基本的に必要としているのは、文字列ごとに(または)変化するの'と同じように、代替のERB区切り文字だと思います。最終的なERB区切り文字が文字列内で発生している場合でも、実際にはブロックの終わりとして処理されているようです。の最も単純なケースは、私が達成したいことをいくらか示しています。ジェネレーターでは、"%q{}<% foo = '<%= bar %>' %><% foo = '<%%= bar %>' %>(または同様のもの)、その場でERBとして処理しないように指示します。これはすべて、ファイルから読み取る場合、または純粋なrbファイル(ヘルパーなど)でも正常に機能しますが、この場合は、ビューに配置するのが最も理にかなっています。これは、ファイルから簡単に操作できるようにするためです。デザイナー。

4

1 に答える 1

5

私があなたを正しく理解しているなら、あなたの本当の問題は、補間に関する限り、ヒアドキュメントが二重引用符のように振る舞うことです。したがって、必要なのは一重引用符のように動作する引用符メカニズムだけです。Rubyには多くの文字列引用メカニズムがあり、特に次のようなものがあります%q{...}

<% code = %q{
<div>
  #{ image_tag 'image.png' }
</div>  
} %>

必要に応じて、他の区切り文字を使用できます。、、%q|...|など%q(...)。もちろん変更はありますが、少なくとも補間の問題について心配する必要はありません。

本当にヒアドキュメントを使用したい場合は、ヒアドキュメントターミネータを引用符で指定すると、対応する引用符のスタイルがコンテンツに適用されます。

<% code = <<'PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR'
<div>
  #{ image_tag 'image.png' }
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>

の単一引用符は、単一引用符の<<'PLACE...'規則(つまり、補間なし)がヒアドキュメントのコンテンツに適用されることを指定します。


もちろん、そのようなものはどれも、次のような組み込みERBでは機能しません。

<% code = %q{
<div>
  <% ... %>
</div>  
} %>

ERBパーサーは、最初の部分%>を外側の<% code...部分の終了区切り文字と見なすためです。恐れることはありません。大規模なハッキングや過度の作業を伴わずに機能する計画があると思います。

いくつかの予備知識

上記を使用すると、異なる区切り文字を使用したERBである独自のテンプレート形式を追加できます。また、通常のERB処理で混乱が生じる前に、Railsにこの新しい形式を使用して「特別な」セクションを処理させることができます。

まず、Tiltを接続する必要があります。Tiltのインストールを見ると、下部lib/tilt/erb.rbにErubisのものが表示されますTilt::ErubisTemplate。サブクラス化して、たとえばオプションを追加し、スーパークラスにパントするオーバーライドをTilt::ErubisTemplate提供できるはずです。次に、これをRails初期化子のTiltとSprocketsに次のように登録します。prepare:pattern => '<!--% %-->'

Tilt.register(Your::Template::Subclass, 'klerb') # "kl" for "kludge" :)
Rails.application.assets.register_engine('.klerb', Your::Template::Subclass)

これで、アプリケーションはテンプレート区切り文字として.klerbファイルを処理できるようになります。<!--% ... %-->また、次のような名前を使用してklerbをerbとチェーンすることもできpancakes.html.erb.klerb、ファイルはERBの前にklerbを通過します。これは、次のようなテンプレート(というファイル内whatever.html.erb.klerb)を意味します。

<!--% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
  <% image_tag 'image.png' %>
</div>  
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%-->
<!--%= "code = escape_the_erb_as_needed(%q{#{code}})" %-->
<% do_normal_erb_stuff %>

正しいことをします。

escape_the_erb_as_neededもちろん、機能を実装するにはヘルパーが必要です。少し実験することで、何をどのように逃がす必要があるかを整理するのに役立つはずです。

これらはすべて少し複雑に見えるかもしれませんが、非常に簡単です。TiltとSprocketsを使用してカスタムテンプレート処理ステップを追加しましたが、最終的には非常に単純であることがわかりました。どの簡単なことをするのかを理解するのに少し手間がかかりましたが、私はすでにあなたのためにその仕事をしました:

  1. Tilt::Templateサブクラス、あなたはピギーバッキングによってこれを取得しTilt::ErubisTemplateます。
  2. を呼び出してTiltに登録しTilt.registerます。
  3. を呼び出してSprocketsに登録しRails.application.assets.register_engineます。
  4. ..。
  5. 利益。
于 2012-11-07T03:33:25.310 に答える