Yield

Witam,

czy znacie jakiś dobry manual z zastosowaniem yielda? Bo dokumentacja railsów mówi tylko tyle: http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html
Chciałbym na przykład wiedzieć, czy jest możliwość sprawdzenia, czy istnieje jakiś yield. W layoucie chcę mieć jakiś div wrapper w okół yielda danego, ale tylko wtedy gdy takowy istnieje.

Pozdrawiam,
Yax

Jest coś takiego Kernel#block_given? http://apidock.com/ruby/Kernel/block_given%3F

def method if block_given? yield end end
O coś takiego chodziło?

Tak w kwestiach terminologicznych - nie ma sensu mówić o “istnieniu yeilda” :slight_smile: Jak już to można zastanawiać się, czy do jakiejś metody został przekazany blok, który może być wywołany (za pomocą słowa kluczowego yield).

Więcej: Ruby intro - struktury języka - bloki.

[code=RUBY]

Tickets: <%= controller.action_name %> <%= stylesheet_link_tag 'stylesheet' %>
Root

<%= yield :title %>

<%= yield :info %>
    <% unless flash[:notice].nil? -%>
      <p id="flash-notice"><%= flash[:notice] %></p>
    <% end -%>
    <% unless flash[:warning].nil? -%>
      <p id="flash-warning"><%= flash[:warning] %></p>
    <% end -%>

    <%= yield %>

  </div>
  <div id="footer"></div>
 
</body>
[/code] To jest przykładowy layout, mam tam yield :info które siedzi w divie "left". Chciałbym, żeby po wyrenderowaniu strony, jeżeli nie przekazano nic za pomocą [code=RUBY]<% content_for :info do %> Cośtam <% end %>[/code] nie został w ogóle umieszczony w jej kodzie div "left".

Mam nadzieję, że to wyjaśnienie lepiej przedstawia o co mi chodzi :wink:

EDIT:
Przyszło mi do głowy, że mógłbym chyba sprawdzić za pomocą @content_for_info.nil? Ale zastosowanie tej zmiennej jest depracated…

To nie prościej umieścić to w samym “content_for”?

[code=ruby]<% content_for :info do %>

Cośtam
<% end %>[/code] Jest to niezgodne z zasadą DRY, ale z drugiej strony unikasz brzydkiego if-a.

Inne rozwiązanie może polegać na domyślnym ukryci tego div-a, a odkryciu go w tym samym szablonie, w którym definiowane jest content_for.

Ja bym to zrobił w helperze:

def info content = yield(:info) unless content.blank? content_tag(:div, content, :id => "left") end end
I taka pedantyczna uwaga co do html/css. Nie powinno się w dokumencie stosować nazw typu left/right, bo po to się używa cssa, żeby móc łatwo pozmieniać wygląd bez ingerencji w htmla. I się okaże, że taki right ma być po lewej, a left po prawej, to będzie bajzel :wink:

Chyba skorzystam z metody drogusa, ładna i przejrzysta. A uwaga o html/css jest całkiem sensowna :wink: Dzięki za pomoc.

Niestety metoda drogusa nie działa. no block given na linii z wywołaniem helpera.

Właściwie po przemyśleniu widzę, że to nie mogłoby działać :wink: A ubzdurało mi się, że coś takiego robiłem.

Czyli pozostaje Ci trochę brzydsze:

[code] def info(content)
unless content.blank?
content_tag(:div, content, :id => “left”)
end
end

i w widoku

<%= info(yield(:info)) %>[/code]