As the name implies, inherited templates make template lookup follow the controller inheritance heirarchy if it can’t find a template for the current controller.Najłatwiej będzie to opisać fragmentami kodu.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>MySite</title> | |
<%= stylesheet_link_tag "application" %> | |
<%= javascript_include_tag "application" %> | |
<%= csrf_meta_tags %> | |
</head> | |
<body> | |
<div id="container"> | |
<div id="menu"> | |
<ul> | |
<li><%= link_to "Homepage", root_path %></li> | |
<li><%= link_to "News", news_path %></li> | |
<li><%= link_to "Contact", contact_path %></li> | |
</ul> | |
</div> | |
</div> | |
</body> | |
</html> |
Fragment kodu, który odpowiada za menu możemy przenieść do katalogu app/views/application, ponieważ każdy kontroler dziedziczy po ApplicationController.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="menu"> | |
<%= render "menu" %> | |
</div> | |
<!-- app/views/application/_menu.html.erb --> | |
<ul> | |
<li><%= link_to "Homepage", root_path %></li> | |
<li><%= link_to "News", news_path %></li> | |
<li><%= link_to "Contact", contact_path %></li> | |
</ul> |
Do tej pory wszystko wygląda wspaniale. Co jednak, jeżeli chcielibyśmy dodać jedną pozycję w menu np. dla NewsController? Nic prostrzego. Tworzymy app/views/news/_menu.html.erb w którym dodajemy link. Wspaniale! Co jednak, jeżeli mamy bardzo rozbudowane menu a dla jednego kontrolera chcemy dodać 1 (JEDNĄ!) pozycję? Tak! Musimy skopiować cały plik i dodać tylko ten 1 link. Don't Repeat Yourself pełną gębą.
System szablonów (nie mówię o języku szablonów, ale bardziej o tym jak działa mechanizm ich ładowania, przekazywania do nich zmiennych itd.) w Rails nigdy mnie nie powalał. Dużo bardziej podoba mi się ten znany z Django. Mamy w nim tzw. bloki. Przenosząc ten mechanizm na nasz przykład mielibyśmy blok menu w głównym szablonie (application.html.erb) i bloki rozszerzające go w poszczególnych szablonach. Wyglądałoby to mniej więcej tak:
Prawda że wygodniej, schludniej i bardziej DRY?
* Briana Banks (ur. 21 maja 1978 w Monachium) - niemiecka aktorka występująca w filmach pornograficznych. [wikipedia.org] [która zdecydowanie nie jest dry (sucha) - autor]
Przecież w Rails robi to się elegancko za pomocą kombinacji content_for i yield. NIe wiem jak w tym kretyńskim Bloggerze formatować kod w komentarzu, więc wklejam to tu https://gist.github.com/1023798
OdpowiedzUsuńWiem, że da się to uzyskać przez content_for, ale dalej nie jest to aż tak dobre rozwiązanie jak w Django. Poza tym nie jest to element wprowadzonego właśnie template inheritance.
OdpowiedzUsuńPoza tym czytałem gdzieś (wydaje mi się, że na blogu Yehudy) opinię, która nie zalecała używania tego rozwiązania.
W sumie jak zapoznałem się trochę bardziej z content_for (wcześniej nie było mi jakoś potrzebne) to przyznaję racje :)
OdpowiedzUsuńDalej tylko nie rozumiem tego podniecania się template inheritance.