2017-02-16 16 views
0

Фон: Из-за того, как стили дескриптора электронной почты (неправильные), в макете рассылки Rails, все стили должны быть встроены для каждого тега, поэтому макет является подробным.Может ли вид Rails указать массив content_for, так что просмотр и макет DRY?

Итак, если у вас есть блок информации, состоящий из 3 абзацев (% p) в строке с тем же стилем, этот стиль должен применяться к каждой из пяти.

# example of hard_coded_mailer_layout.html.haml 
... 
%p{style: "some very very long style declaration"} 
    This sentence is about Foo. 
%p{style: "the SAME REPEATED very very long style declaration"} 
    This sentence is about Bar. 
%p{style: "yes, again, the SAME repeated long style declaration"} 
    This sentence is about FooBar. 
... 

Итак, теперь рассмотрим случай, когда текст на счет конкретных и поставляется с точки зрения (вместо того, чтобы быть жестко закодированы в макете).

Если это известного максимального количества пунктов (3 в приведенном выше примере) представление может просто указать-content_for блоки (: Foo,: бар, а также: Foobar) и расположение может иметь 3, соответствующие выходов (: Foo,: бар, а также: Foobar), как это:

# example layout_yielding_3_blocks.html.haml 
... 
- if content_for?(:foo) 
    %p{style: "some very very long style declaration"} 
    = yield :foo 
- if content_for?(:bar) 
    %p{style: "the SAME REPEATED very very long style declaration"} 
    = yield :bar 
- if content_for?(:foobar) 
    %p{style: "yes, again, the SAME repeated long style declaration"} 
    = yield :foobar 
... 

# corresponding view 
- content_for :foo do 
    Your account has 2 Foos. 
- content_for :bar do 
    Your account has 8 Bars. 
- content_for :foobar do 
    Your account has 0 FooBars. 
... 

Вопрос: а когда вы хотите передать переменное количество пунктов в макете, но до сих пор макет применить стиль? Есть ли способ, чтобы представление указывало массив элементов N content_for, так что макет может просто перебирать их? Конкретно что-то вроде этого:

# desired view... is it possible? 
- content_for :info[0] do 
    Your account has 2 Foos. 
- content_for :info[1] do 
    Your account has 8 Bars. 
- content_for info[2] do 
    Your account has 0 FooBars. 
... 

так, что макет может выглядеть следующим образом:

# desired corresponding layout, can something like this be done? 
... 
- yield(:info).each_with_index do |para, i| 
    %p{style: "some very very long style declaration"} 
    = (yield(:info))[i] 

Простой, но проблематичный способ: Что это легко сделать, это иметь в взгляд, одной content_for, который содержит все N абзацев с их идентичными стилями, повторяемыми N раз, например:

# current way of doing it (bad for 2 reasons below) 
- content_for :all_info do 
    %p{style: "some very very long style declaration"} 
    Your account has 2 Foos. 
    %p{style: "the SAME REPEATED very very long style declaration"} 
    Your account has 8 Bars. 
    %p{style: "yes, again, the SAME repeated long style declaration"} 
    Your account has 0 FooBars. 

, но это воняет (как в кодовом вонючести), потому что (а) оно очень не суровое и даже хуже (б) теперь встроенные стили распространяются между одним макетом и потенциально десятками просмотров, которые используют этот макет ... если вы измените «стиль», вам нужно изменить его на множество мест или определить стиль в другом месте как строку или константу с именем email_para_style_info в другом месте в качестве переменной.

ответ

0

Создайте и используйте вместо этого помощник.

module EmailHtmlHelper 
    def account_message(content = nil, &block) 
    content_tag :p, content, style: account_message_styles, &block 
    end 

    def account_message_styles 
    %{ 
     font-size: 1.2em; 
     color: #c0ffee; 
    }.tr("\n", '') 
    end 
end 

<%= account_message 'Your account has 2 Foos.' %> 

<%= account_message do %> 
    A longer, 
    more complex 
    <span>message</span> 
    <%= link_to 'here', foo_url %> 
<% end %> 

Или, если вы действительно не хотите стилей в качестве помощника, который является вполне приемлемым местом для них, чтобы быть в этом случае, вы можете просто нажать стили в вашей точке зрения и использовать их для каждого экземпляра:

<% "color: blue;".tap do |inline_styles| %> 
    <%= content_tag :p, 'Status: Open', style: inline_styles %> 
    <%= content_tag :p, 'Balance: $100', style: inline_styles %> 
<% end %> 

Обратите внимание, что с помощью тегов хелпер как content_tag избежит содержания надлежащим образом, а это значит, избежать проблем с случайным закрытием котировки.

+0

Это надежный подход, но лучше ИМО будет - если возможно - полное разделение контента и стиля, с макетом (только), представляющим таблицу стилей. Это то, что я надеюсь, что кто-то может предложить в качестве ответа. Какая-то конструкция «Iterable content_for» была бы идеальной, если это было возможно. – jpwynn

+0

@jpwynn Я думаю, вы утверждаете, что * меньше * разделение, если ваш исходный вопрос - это какое-либо указание. В этом случае я предоставил вам менее элегантный вариант обновления. – coreyward