Предыстория: из-за того, как почтовые клиенты (неправильно) обрабатывают стили, в макете почтовой программы Rails все стили должны быть встроены для каждого тега, поэтому макет получается многословным.
Итак, если у вас есть, например, блок информации, состоящий из 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 в приведенном выше примере), представление может просто указать 3 блока content_for (:foo, :bar и :foobar), а макет может иметь 3 соответствующих yield ( :foo, :bar и :foobar) следующим образом:
# example layout_yielding# 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.
...
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
в другом месте как переменную.