переключение столбцов компоновки на основе контроллера - PullRequest
0 голосов
/ 17 января 2012

так что в основном мое приложение выглядит так

<!DOCTYPE html>
<html>
<head>
    ...
</head>
<body>
<div id="content">
    <div id="content_left">
        // Some Stuff
    </div>

    <div id="content_right">
        <%= yield %>
    </div>
</div>
</body>
</html>

Теперь я хочу переключиться между макетом из двух столбцов и макетом из одного столбца на основе контроллера (в лучшем случае: также на основе метода iиспользуя).

между телом и контентом, а также в его заголовке, слишком много вещей, чтобы просто создать второй макет и добавить это как вызов layout в моем контроллере без слишком большого дублирования кода.

я бы хотел сделать что-то вроде этого:

все должны использовать это

<!DOCTYPE html>
<html>
<head>
    ...
</head>
<body>
 // much stuff
 <%= yield %>
</body>
</html>

и теперь я могу переключаться между двумя раскладками, например

single_col

<div id="content">
    <%= yield %>
</div>

или two_column

<div id="content">
    <div id="content_left">
        // Some Stuff
    </div>

    <div id="content_right">
        <%= yield %>
    </div>
</div>

, а затем в последнем выходе должно быть представление, которое связано с моим контроллером и методом.

isЕсть простой способ добиться этого?

спасибо за все подсказки.

ПОЖАЛУЙСТА, оставьте комментарий, если что-то неясно.

Ответы [ 8 ]

2 голосов
/ 17 января 2012

Поместите разные части макетов в партиалы!Затем вы визуализируете частичные данные на основе того, что находится в params[:controller] и params[:action].Например:

<% if params[:controller] == "controller_name" %>
     <%= render 'partial_name1' %>
<% else %>
     <%= render 'partial_name2' %>
<% end %>

params[:controller] и params[:action] всегда доступны!Это пример, чтобы показать вам, как это работает.Разумеется, в этой точке зрения не должно быть никакой логики!

1 голос
/ 25 января 2012

Я думаю, что вы ищете способ использовать общий макет с двумя вложенными макетами внутри, вот и все:

добавьте это в ваш application_helper.rb

  # Allows easy using nested layouts
  def inside_layout(layout = 'application', &block)
    render :inline => capture_haml(&block), :layout => "layouts/#{layout}"
  end

Макеты / application.html.haml

!!!
%html
  %head
    -# your header content
  %body
    .content
      = yield

Макеты / single_column.html.haml

= inside_layout do
  .middle
    = yield        

Макеты / two_column.html.haml

= inside_layout do
  .left
    -# your shared left content
  .right
    = yield        

макеты столбцов теперь можно использовать как обычные макеты, так что вы можете просто установить их в своем контроллере

layout "single_column"

Примечание: вся разметка находится в HAML драгоценном камне, который я очень рекомендую.

надеюсь, это поможет :) 1022 *

1 голос
/ 22 января 2012

Вы можете использовать два макета, которые будут отображать как пароли верхнего, так и нижнего колонтитула, содержащие то, что является общим для обоих.

ИЛИ вы используете <% = yield: sidebar%>, а затем вводите что-то

<% content_for(:sidebar) do %>
  some stuff here
<% end %>

Взгляните на раздел руководства по Rails об этом здесь.

0 голосов
/ 26 января 2012

Я обычно помещаю классы в элемент body для контроллера и имени действия, так как это удобно во многих отношениях.Вот пример, основанный на этой стратегии:

...
<body class="<%= controller_name %> <%= action_name %>">
<div id="content">
    <div id="sidebar">
        // Some Stuff
    </div>

    <div id="main">
        <%= yield %>
    </div>
</div>
</body>
...

, тогда нужно получить правильный CSS.Если у вас был контроллер 'posts', боковая панель обычно видна, и вы хотите скрыть ее:

body.posts { #sidebar { display: none; } };

Если вы хотите, чтобы он отображался только иногда, вы можете инвертировать логику, чтобы она обычно скрывалась, затем переопределите с более конкретной областью, чтобы показать это.Или у вас может быть один столбец для всех действий «индекса», два столбца для всего остального и т. Д.

Недостатком этого, и это немаловажно, является то, что ваши представления связаны с именем контроллера,Т.е. эта стратегия нарушает принцип «говори, не спрашивай».Я все еще думаю, что оно того стоит, так как я еще не сталкивался с неприятным рефакторингом, связанным с этим кодом.Обычно это просто изменить пару экземпляров имени контроллера в ex."posts.css.scss" при переименовании файла;ничего страшного.Просто что-то взвесить.

Кроме того, обратите внимание, что я выбрал более описательные названия классов.«Левый» и «правый» эфемерны, как показывает ваш пример.«Боковая панель» и «главная» могут быть не тем, что у вас есть, но я постараюсь описать, что в них содержится, если это возможно.

0 голосов
/ 26 января 2012

Я использую вспомогательный метод для динамической установки боковой панели, которую вы можете использовать согласно вашему требованию.

<div id="main_content" class="<%= main_content_css_class %>">
   <%= yield %>
</div>
<div id="sidebar" class="<%= sidebar_css_class %>">
  <%= yield :sidebar %>
</div>

In Helper

def sidebar_enabled?
 current_page = "#{controller.controller_name}.#{controller.action_name}"
 current_controller = controller.controller_name
 pages = %w(home)
 return pages.include?(current_page) || pages.include?(current_controller)

end

def main_content_css_class
  sidebar_enabled? ? "grid_12" : "grid_16"
end

# Returns the CSS class for the 'sidebar' div depending on sidebar requirement
def sidebar_css_class
   sidebar_enabled? ? "grid_4" : "dont-show"
end 

Использование вашего кода также более чисто и легко поддерживается.

0 голосов
/ 25 января 2012

Я предполагаю, что в вашем одиночном столбце у вас нет информации для вашего content_left.И в двух колонках у вас есть информация как для content_left, так и для content_right.Есть много способов, но я рекомендую что-то, что полностью контролируется CSS .

Классы CSS будут похожи на следующие

#content_left{
    float: left;
    background-color: red;
}
#content_right{
        background-color: green;
}
#content {
    margin: 0 auto;
    width: 80%;
}

Теперь обратите внимание ... if content_leftdiv пуст, тогда content_right div расширится до полной ширины.И вы готовы с одной колонки.И если у вас есть данные в content_left, они будут отображаться соответственно.

0 голосов
/ 24 января 2012

Вы можете использовать sub_layouts

Class IndexController < ApplicationController

  def index

    def sub_layout
      "left"
    end

   end

 end

Добавить вложенные макеты в /app/view/shared/layouts/sub/_mysublayout.haml или .erb

в / app / views / layouts/application.haml/.erb * ваш основной файл макета *

= render: частичный => "layouts / sub / # {controller.sub_layout}" *

С некоторой проверкой nils с помощью команды rescueЕсли вы можете заставить этот под шаблон загружать макет, скажем, правого или левого столбца, используйте это с большой выгодой в моих приложениях.Это значительно экономит время и дает вам дополнительную гибкость при настройке макета на основе действий.

0 голосов
/ 17 января 2012

Вы можете использовать несколько макетов в проекте рельсов. Вы можете иметь 2 столбца и один столбец один.

Чтобы указать используемый макет, укажите его в методе контроллера.

def index
  respond_to do |format|
    if current_user
      format.html {render 'pages/index', :layout => 'home'}# index.html.erb
    else
      format.html {render 'pages/landingpage', :layout => 'landingpage'}# index.html.erb
    end
  end
end

Например, вышеприведенный контроллер отобразит представления index.html.erb и landingpage.html.erb на основе значения current_user. Вы также можете предоставить параметр макета только для render, например render :layout => 'home'

Вы также можете взглянуть на вложенные макеты , но я никогда не работал с ними.

...