2008-09-24 4 views
4

Imaginez avoir deux contrôleurs RESTful (UsersController, OffersController) et un PagesController (utilisé pour le contenu statique tel que index, about et ainsi de suite) dans votre application.Besoin d'un conseil: structure des vues Rails pour les sous-menus?

Vous avez les routes suivantes définies:

map.with_options :controller => 'pages' do |pages| 
    pages.root :action => 'index'  # static home page 
    pages.about :action => 'about' # static about page 
    # maybe more static pages... 
end 
map.resources :users # RESTful UsersController 
map.resources :posts # RESTful PostsController 

Votre mise en page de l'application ressemble à ceci:

<html> 
    <head> 
    <title>Demo Application</title> 
    </head> 
    <body> 
    <ul id="menu"> 
     <li> 
     <%= link_to 'Home', root_path %> 
     </li> 
     <li> 
     <%= link_to 'Offers', offers_path %> 
     <ul id="submenu> 
      <li><%= link_to 'Search', 'path/to/search' %></li> 
      <li>maybe more links...</li> 
     </ul> 
     </li> 
     <li> 
     <%= link_to 'About', about_path %> 
     </li> 
     <li> 
     <%= link_to 'Admin', users_path %> 
     <ul id="submenu"> 
      <li><%= link_to 'New User', new_user_path %></li> 
      <li><%= link_to 'New Offer', new_offer_path %></li> 
      <li>maybe more links</li> 
     </ul> 
     </li> 
    </li> 
    <%= yield %> 
    </body> 
</html> 

Le problème avec la mise en page est que je ne veux qu'une seule #submenu pour être visible à tout moment . Tous les autres sous-menus peuvent être complètement ignorés (ils n'ont pas besoin d'être rendus). Prenez le menu Admin par exemple: Ce menu doit être actif pour tous les chemins RESTful de l'application, sauf offers_path. Actif signifie que le sous-menu est visible.

La seule solution à laquelle je peux penser pour y parvenir est de construire des conditions très compliquées si c'est compliqué (vraiment compliqué à écrire et à maintenir). Je suis à la recherche d'une solution élégante?

J'espère que quelqu'un comprend ma question - s'il y a quelque chose de flou, commentez simplement la question et je vais l'expliquer plus en détail.

Répondre

6

Une chose que vous pourriez jouer avec est le rendement et content_for , utilisé avec quelques partiels pour les menus. Par exemple, vous pouvez mettre chaque section du menu dans une partielle, puis modifier votre mise en page à quelque chose comme:

<%= yield(:menu) %> 

Vous pouvez alors préciser dans votre point de vue content_for et mettre ce que vous voulez dans partials le menu. Si ce n'est pas spécifié, il ne sera pas rendu.

<% content_for(:menu) do %> 
    <%= render :partial => 'layouts/menu' %> 
    <%= render :partial => 'layouts/search_menu' %> 
    etc... 
<% end %> 

Si vous utilisez beaucoup des mêmes menus dans la plupart des pages, spécifiez une valeur par défaut dans votre mise en page si aucun rendement (: menu) se trouve.

<%= yield(:menu) || render :partial => 'layouts/menu_default' %> 

Enregistre beaucoup de frappe. :) J'ai trouvé que c'était une bonne façon de gérer les choses.

1

Typiquement, je voudrais abstraire la fonctionnalité de menu de sorte que j'ai une méthode d'aide pour rendre le menu Admin. De cette façon, il est possible de lancer autant de logique dans l'assistant que vous le souhaitez sans nuire à votre logique de vue.

Ainsi, votre aide pourrait ressembler (pardonnez le rubis/rails pseudo-code, il a été un mois ou deux depuis que je touchais):

def render_admin_menu() 
    if !current_path.contains('offer') 
    render :partial => 'shared/admin_menu' 
    end 
end 
+0

Merci pour vos commentaires. Cependant, déplacer le problème à un assistant n'est pas une vraie solution. D'un autre côté, c'est en effet une amélioration et je ne m'attendais pas à trouver une solution élégante de toute façon de sitôt. Peut-être que quelqu'un d'autre a un meilleur tour ... –

Questions connexes