开发者

Rails app with multiple page layouts - how to DRY up?

I have a Rails-based site with a basic two-column layout. On the right is a sidebar with different (let's just say) vertical widgets. Depending on what page you visit, the widgets can be included, excluded, and in different order. For ex:

Main Page (Application)

PAGE CONTENT...

SIDEBAR

  • Widget A
  • Widget B
  • Widget C

Page X

PAGE CONTENT...

SIDEBAR

  • Widget D
  • Widget A
  • Widget C

Page Y

PAGE CONTENT...

SIDEBAR

  • Widget E
  • Widget A
  • Widget B
  • Widget C

Right now the way that I'm displaying the page-specific widgets is not very DRY. I'm creating a layout for each page, then copying and pasting the same HTML partials and widget partials over and over. For ex:

application.html.erb

<%= render :partial => 'shared/html_header' %>

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

    <%= render :partial => "shared/head" %>     

    <body>                        
        <div id="outer">

            <%= render :partial => 'shared/banner' %>
            <%= render :partial => 'shared/nav' %>

            <div id="main">
                <table cellpadding="0" cellspacing="0" border="0" style="width:100%;">
                  <tr style="vertical-align:top;">

                   <td style="width:759px;">
                    <%= render :partial => 'shared/content' %>
                  </td>

                        <td><%= image_tag("spacer.gif", :width => "5") %></td>

                        <td style="width:252px;">
                            <%= render :partial => 'shared/widget_a' %>
                            <%= image_tag("spacer.gif", :height => "10") %>

                            <%= render :partial => 'shared/widget_b' %>
                            <%= image_tag("spacer.gif", :height => "10") %>

                            <%= render :partial => 'shared/widget_c' %>
                            <%= image_tag("spacer.gif", :height => "10") %>

                        </td>
                    </tr>
                </table>
            </div>
            <%= render :partial => 'shared/footer' %>
        </div>
            <%= render :partial => 'shared/user_voice_widget_script' %>
            <%= render :partial => 'shared/google_analytics_script' %开发者_运维问答>
    </body> 
</html>

I basically just repeat this pattern for the other page layouts, but with the page-specific widgets. Doesn't seem too DRY.

I'm thinking there has to be a more efficient way to do this. Any suggestions?


You can use a single layout file which defines the two column structure for all your pages and then use Rail's content_for helper to contextually populate your sidebar, depending on the page visited. Then the only page specific information is the sidebar detail, not the whole layout being repeated over and over.

In your (single) application layout:

<td style="width:252px;">
  <%= yield :sidebar %>
</td>

Somewhere in your pages:

<% content_for :sidebar do %>
  <%= render :partial => 'shared/widget_a' %>
  <%= image_tag("spacer.gif", :height => "10") %>

  ...

<% end %>

If enough of the widget combinations occur frequently together you could consider putting their render directives together into partials and using those in your content_for block.

The general technique is described here

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜