2017-02-16 5 views
0

배경 : 이메일 클라이언트 (스타일)가 스타일을 처리하는 방식 때문에 레일스 메일러 레이아웃에서 모든 스타일을 각 태그에 대해 인라인해야하므로 레이아웃이 길어집니다.레일 뷰에서 content_for 배열을 지정하여 뷰와 레이아웃이 모두 DRY가 될 수 있습니까?

예를 들어 같은 스타일의 행에 3 개의 단락 (% p)으로 구성된 정보 블록이있는 경우 해당 스타일을 각각 5 개에 적용해야합니다.

# 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 개 대응 수율을 가질 수있다 (는 foobar : foo에, : 바 등)가보기 단순히 3 개 content_for 블록을 지정할 수 (상기 예에서는 3) 단락의 공지 최대 수 있다면

: 이런는 foobar) : : foo는 : 바,

# 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] 

쉬운,하지만 문제 방법 : 쉽게 할 수 무엇이 뷰 하나에게로 가지고있다

# 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. 
: 자신의 동일한 스타일로 모든 N 단락을 포함
content_for이 같은 N 번 반복

하지만 (a) 코드가 매우 건조하고 (b) 인라인 스타일이 단일 레이아웃과 해당 레이아웃을 사용하는 잠재적으로 수십개의보기 사이에 퍼져 있기 때문에 코드 스틱처럼 악취가납니다. 당신이 장소를 많이 바꿀 필요가있는 "스타일"을 바꾸거나 다른 곳의 스타일을 문자열이나 상수로 정의하십시오. 다른 곳에서는 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 %> 

또는 당신이 정말로, 당신은 당신의보기에서 스타일을 누르고 각 인스턴스에 대해 사용할 수 있습니다들이이 경우에 있어야 할 수있는 충분히 수용 할 장소 도우미에서 스타일을 원하지 않는 경우 : content_tag 같은 태그 도우미를 사용하여 실수로 인용 폐쇄에 문제가 발생하지 않도록 의미하는, 적절하게 내용을 피할 것

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

참고.

+0

이것은 단단한 접근 방법이지만 IMO는 가능한 경우 - 스타일 시트를 제시하는 레이아웃 만 사용하여 내용과 스타일을 완전히 분리하는 것이 좋습니다. 나는 누군가가 대답으로 제안 할 수 있기를 바랍니다. 가능하다면 일종의 "반복 가능한 content_for"구조가 완벽 할 것입니다. – jpwynn

+0

@jpwynn 나는 원래 질문이 어떤 표시라도 * 적은 * 분리를 주장하고 있다고 생각합니다. 어떤 경우에, 나는 당신에게 업데이트에서 덜 우아한 옵션을 제공했습니다. – coreyward