1. Mai 2008 in Ruby » Ruby on Rails
Alternative Anwendungen für Rails’ Partials
Komplexe globale Navigationen
Wenn die Inhalte der globalen Navigation einer Webanwendung von verschiedenen Bedingungen (Sitzungsstatus, Benutzerlevel, etc.) abhängen, kann der dafür nötige Quelltext schnell an Masse gewinnen und somit beispielsweise die Layout-Datei unnötig unübersichtlich machen. Um das zu verhindern, kommt die einfachste Partial-Anwendung hier zum Einsatz. Wir verzichten hierbei auf alle weiteren Attribute der render-Funktion:
<%= render :partial => 'navigation' %>
app/views/layouts/application.html.erb
Der Quelltext für die Navigation kann nun getrost in die Partial-Datei ausgelagert werden. Anpassungen sind nicht nötig.
<ul id="navigation"> <% @sections.each do |section| %> <li><%= link_to section.title, section %></li> <% end %> <% if logged_in? %> <li><%= link_to "Einstellungen", settings_path %></li> <li><%= link_to "Abmelden", logout_path %></li> <% else %> <li><%= link_to "Registrieren", signup_path %></li> <li><%= link_to "Anmelden", login_path %></li> <% end %> </ul>
app/views/layouts/_navigation.html.erb
Ähnliche Elemente smart wiedergeben
Nehmen wir an, eine Freunde-Seite eines Social Networking Service zeigt grundsätzlich alle Freunde eines Benutzers an.
<h2><% @user.gen_attr %> Freunde</h2> <p>Das sind alle Freunde von <%= @user.name %>.</p> <% unless @friendships.empty? %> <ul> <% @friendships.each do |friend| %> <li><%= link_to friend.name, friend %></li> <% end %> </ul> <% end %>
app/views/friendships/index.html.erb
Ein eingeloggter Benutzer soll auf seiner eigenen Freunde-Seite zusätzlich seine gesendeten und erhaltenen Freundschaftseinladungen sehen. Diese beiden Auflistungen sehen der eigentlichen Freunde-Liste sehr ähnlich. Hier eignet sich der Einsatz eines Partial mit vorbereiteten lokalen Variablen:
<!-- Alle Freunde -->
<%= render :partial => 'friend_list', :locals => {
:title => @user.attr_gen + ' Freunde',
:description => 'Das sind alle Freunde von ' + @user.name,
:friends => @friendships
} %>
<!-- Erhaltene Freundschaftsanfragen -->
<%= render :partial => 'friend_list', :locals => {
:title => 'Neue Freunde!',
:description => 'Diese Benutzer möchten deine Freunde werden:',
:friends => @requested_friendships
} %>
<!-- Gesendete Freundschaftsanfragen -->
<%= render :partial => 'friend_list', :locals => {
:title => 'Fast Freunde',
:description => 'Diese Benutzer müssen die Freundschaft mit dir noch bestätigen:',
:friends => @pending_friendships
} %>
app/views/friendships/index.html.erb
Alle Schlüssel-Wert-Paare des mit :locals übergebenen Hash sind im Partial nun als lokale Variablen verfügbar. Es spielt im Partial also keine Rolle, ob es sich nun um die Wiedergabe von bestehenden, erhaltenen oder gesendeten Freundschaften handelt:
<% unless friends.empty? %> <h2><%= title %></h2> <p><%= description %></p> <ul> <% friends.each do |friend| %> <li><%= link_to friend.name, friend %></li> <% end %> </ul> <% end %>
app/views/friendships/_friend_list.html.erb
Schnell wird klar, dass Partials unverzichtbar für übersichtlichen und wartbaren Code in Views sind. Ich hoffe, ich konnte euch anregen, eigene Ideen für den Einsatz von Partials zu entwickeln.
Kommentar hinzufügen
Du kannst dich hier frei äußern, jedoch solltest du dich dabei fair gegenüber den anderen Lesern, Dritten und dem Autor verhalten. Private Mitteilungen an Martin bitte per E-Mail an martin@labuschin.com. Danke.
2 Kommentare
Heinz am 5. Januar 2009 #
Hallo Martin,
die Idee mit der Navigation als partial hatte ich auch schon.
Ich hab's auch so gemacht wie Du, nämlich mit
<%= render :partial => 'navigation' %> im layouts/application.html.erb und habe die _navigation.html.erb in das gleiche Verzeichnis (layouts) gelegt.
Nur bei mir findet er das partial nicht, sondern sucht es immer im entsprechenden Unterverzeichnis der View die gerade angezeigt wird. In Deinem Beispiel wäre das dann etwa im views/friendships.
Ich habe es dann mit <%= render('layouts/_navigation') %> gemacht, was funktioniert.
Ich würde aber lieber die Partials nehmen, da ich hier auch Variablen übergeben kann.
Was muss ich denn einstellen, damit er das partial unter layouts sucht und nicht im Unterverzeichnis der gerade angezeigten View?
Danke
Heinz
Martin Labuschin am 5. Januar 2009 #
Du hast die Lösung eigentlich schon fast selbst gefunden. Durch die Pfad-Angabe 'layouts/navigation' wird immer das Partial aus dem layout-Verzeichnis genommen. Besser kann man es nicht lösen:
<%= render :partial => 'layouts/_navigation', :locals => { :foo => 'bar'} %>
Hilft dir das weiter?