开发者

How to escape value returned by a yield

I recently had a problem to escape value returned by a yield in a template.

In my layout, i yield the meta description so that i can define it from my template

<meta name="description" content="<%= yield :html_description %>" />

And here is my template, that unfortunatly, does not escape the value as expected:

<% content_for :html_description, 'hello "you" guy' %>
<meta name="description" content="hello "you" guy" />

I tried to escape it with the h() escaper, but it doesnt work开发者_StackOverflow社区:

<meta name="description" content="<%= h(yield :html_description) %>" />
<meta name="description" content="hello "you" guy" />

I also tried with escape_once(), but it does too much:

<meta name="description" content="<%= escape_once(yield :html_description) %>" />
<meta name="description" content="hello &amp;quot;you&amp;quot; guy" />

However, by concatenating the returned value with a string, it fixes the problem:

<meta name="description" content="<%= '' + (yield :html_description) %>" />
<meta name="description" content="hello &quot;you&quot; guy" />

Does anyone understand this behaviour?

Do you have a better solution than this concatenation that fix it by coincidence?

I'm using Rails 2.3.8 - Thanks!


For self-closed tags such as meta, img, or br, you can use the "tag" method.

<%= tag(:meta, :name => 'description', :content => yield(:html_description)) %>

This gives you

<meta content="&quot;I am surrounded by quotes&quot;" name="description" />


the 'h' function only escapes invalid html. The problem with your code is that quotes are not invalid html. Otherwise you couldn't have quotes anywhere in your webpage. "h" is there to do things like turn "<script>" into "&lt;script&gt;" instead.

so... *waves hand* this is not the method you are looking for.

What will probably solve it for you is actually using rails methods to create the meta-tag itself - and then rails will nicely escape it for you.

eg, if you tried the following:

<%= content_tag(:meta, nil, :name => 'description', :content => yield(:html_description)) %>

you'd end up with:

<meta content="hello &quot;you&quot; guy" name="description"></meta>

Update:

Oh, and the reason why string-concatenation does the trick is that the newer versions of Rails will html-safe what it considers to be a dirty string... however, it's a hack you don't need to us if you use a railsy way of generating the meta tag.


You can use the raw() method to do something like this:

<% microdata = "" %>
<% microdata = "itemscope itemtype='#{yield :itemtype}'" if content_for? :itemtype %>
<div class='container' <%= raw(microdata) %> >
</div>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜