かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Haml タグのあるテキスト中のスペースをコントロールしたい

とあるプロジェクトのお手伝いをしていてHamlに入門しました。
雰囲気pugなんであまり変わらないかなとというイメージだったのですが、テキスト中にタグを入れてスペースが必要だったりすると結構メンドーだったのでメモ

タグの前後にスペースのあるテキストを作りたい

こんな感じの出力にしたい

<p>もちかえなさい。<em><a href="oshamoji">おしゃもじ</a></em><strong>マイク</strong></p>

何も考えずにマークアップ

%p
  もちかえさなさい。
  %em
    = link_to 'oshamoji' do
      おしゃもじ
    を
    %strong マイク
    に。

👇出力

<p>
もちかえさなさい。
<em>
<a href="oshamoji">おしゃもじ
</a></em><strong>マイク</strong>
に。
</p>

インラインなテキスト内で改行されていてイケてません。ブラウザで見ると改行されている部分にスペースっぽいものが生じてしまいレイアウトのバグにもなりそうです。

<, >で不要な改行を消し、スペースは= ""で作成する

タグの後に<, >を書くと改行コードが削除されるようです。
<はタグの内側、>はタグの外側の改行を削除。
意図して付けたいスペースは = "文字列"でスペースを作ってやればOK

%p<
  = "もちかえさなさい。"
  %em<>
    = link_to 'oshamoji' do
      おしゃもじ
  = ''
  %strong<> マイク
  = ' に。'

👇出力

<p>もちかえさなさい。<em><a href="oshamoji">おしゃもじ</a></em><strong>マイク</strong> に。</p>

#{} 文字列展開を使う

リンクなどコントローラーから渡したいような物だけ変数にしちゃって、文字列展開で表示させる方法

 - link = link_to 'おしゃもじ', 'oshamoji'
%p!= "もちかえさなさい。<em>#{link}</em> を <strong>マイク</strong> に。"

👇出力

<p>もちかえさなさい。<em><a href="oshamoji">おしゃもじ</a></em><strong>マイク</strong> に。</p>

但しlink_todoブロックを使っていると、リンク文字列の後に改行コードが入ってしまうので、厳密に改行コードを消そうと思うと、リンクタグだけ変数に入れていると親のタグに<>を指定してもリンク内の改行コードを消すことが出来ないので無理っぽい

- link = link_to 'oshamoji' do
  おしゃもじ
%p!= "もちかえさなさい。<em>#{link}</em> を <strong>マイク</strong> に。"
%p<
  = "もちかえさなさい。"
  %em<>= "#{link}"
  != " を <strong>マイク</strong> に。"

👇出力

<p>もちかえさなさい。<em><a href="oshamoji">おしゃもじ
</a></em><strong>マイク</strong> に。</p>
<p>もちかえさなさい。<em><a href="oshamoji">おしゃもじ
</a></em><strong>マイク</strong> に。</p>

surround で文中に入れる方法

surroundを使うと前後に文字を挿入できるのですが、前後に入れる文字列にHTMLタグを使う事ができないみたいで、タグが複数あると難しそうです。(見通しも良くないと思いますし...

%p<
  = surround "もちかえさなさい。", " を <strong>マイク</strong> に。" do
    %em<= link_to 'おしゃもじ', 'oshamoji'

👇出力

<p>もちかえさなさい。<em><a href="oshamoji">おしゃもじ</a></em>&lt;strong&gt;マイク&lt;/strong&gt; に。
</p>

最後にも改行コードが入っちゃいます…

%p<
  = surround "もちかえさなさい。", " を <strong>マイク</strong> に。" do
    %em<= link_to 'oshamoji' do
      おしゃもじ

とするとエラーになってしまったのですが、surroundのdoブロック内に別のブロックを持つことはできないのでしょうか? (少し扱いづらいな... という印象です

感想

なんというかHamlはテキスト中にタグ入れるより、勝手に入る改行コードに難儀してストレス感じそうそうというイメージを持ちました。
長いテキストコンテンツだと、結局 !=で直接HTML書いてリンク先のURLとかだけhref="#{link_url}"な文字列で入れてしまうのが望んだ出力になるんじゃないかなー。結局HTML直打ちだね!という感想。

おまけ Hamlエスケープせずに文字列を出力する方法

!= ""を使う

%p!= "<em>星宮いちご</em>"
%p= "<em>星宮いちご</em>"

👇

<p><em>星宮いちご</em></p>
<p>&lt;em&gt;星宮いちご&lt;/em&gt;</p>

!=, =の直前にスペースを入れるとうまくいかない

これはpugと同じ感じだった。
がSlimってRubyのテンプレートは==だったので記法似てるけど割と罠…

また、Slimだとデフォルトで改行コード無しで、<, >があると改行になるらしい… 個人的にはインライン要素はデフォルトで改行コード無しの方がinline-blockしたときの変な隙間とか発生しないから良いと思った。


[参考]

現場で使える Ruby on Rails 5速習実践ガイド

現場で使える Ruby on Rails 5速習実践ガイド