Как сделать if / else в HAML без повторения кода с отступом - PullRequest
16 голосов
/ 11 августа 2010

В зависимости от того, вошел ли пользователь в систему или нет, я хотел бы напечатать другой тип тега% body.

Вот как я сейчас это делаю:

- if defined? @user
  %body(data-account="#{@user.account}")
    %h1 Welcome
    -# all my content
- else
  %body
    %h1 Welcome
    -# all my content

Как видите, там много дублированного кода. Как я могу устранить это? Я уже пробовал следующее:

- if defined? @user
  %body(data-account="#{@user.account}")
- else
  %body
  %h1 Welcome
  -# all my content

К сожалению, это не работает, поскольку HAML интерпретирует его так, как будто% h1 и его содержимое являются частью оператора else, что, конечно, не так.

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

Ответы [ 6 ]

13 голосов
/ 11 августа 2010

Я не думаю, что вы можете избежать проблемы с отступом из-за способа, которым HAML автоматически присваивает инструкцию "end", но вместо этого вы можете вставить оператор if в сам тег body -

%body{:data_account => (defined? @user ? @user.account : nil)}

в отличие от

%body(data-account="#{@user.account}")

Не супер-красиво, но менее уродливо, чем повторять весь блок!

12 голосов
/ 11 августа 2010
!!!
 - @user = "jed" #=> stubbing out an instance
%html
  %head
    - string = defined?(@user) ? "#{@user}" : nil #=> for demo only, wrap this in a helper method
    %title{'data-account' => string}
  %body
    =yield
4 голосов
/ 12 августа 2010

Элегантное решение HAML - это помощники

class ApplicationHelper...

  def body_for_user(user, &blk)
    return content_tag(:body, :'data-account' => user.account, &blk) if user
    content_tag(:body, &blk)
  end

end

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

О,чтобы использовать это, по вашему мнению измените %body(...) на = body_for_user @user do

1 голос
/ 05 февраля 2012

Для тех, кто ищет ответ на проблему Ruby if / else с HAML, я так и обошел эту проблему:

%tr{ id: (line_item == @current_item) ? "current_item" : nil }
  %td= button_to '-', decrement_line_item_path(line_item), method: :put, remote: true
  %td #{line_item.quantity}×
  %td= line_item.product.title
  %td.item_price= number_to_currency(line_item.total_price)
1 голос
/ 12 августа 2010

Напишите помощника следующим образом:

def body_attributes
  {}.tap do |hash|
    hash[:data] = {}
    hash[:data][:account] = @user.account if @user
    # add any other attributes for the body tag here
  end
end

Затем вызовите помощника из элемента body:

%body{ body_attributes }
  %h1 Welcome
  -# all my content
0 голосов
/ 14 ноября 2013

Обычно я устанавливаю переменную @@ menu на контроллере, затем в layout.hal с поддержкой bootstrap я определяю:

  ...
  %body
    .navbar.navbar-fixed-top
      .navbar-inner
        .container
          %a.btn.btn-navbar{"data-target" => ".nav-collapse", "data-toggle" => "collapse"}
            %span.icon-bar
            %span.icon-bar
            %span.icon-bar
          %a.brand{:href => "/"} AwesomeApp
          .nav-collapse
            %ul.nav
              %li{:class => @@menu == 'home' && :active}
                %a{:href => "/"} Home
              %li{:class => @@menu == 'about' && :active}
                %a{:href => "/about"} About
              %li{:class => @@menu == 'contact' && :active}
                %a{:href => "/contact"} Contact

когда я устанавливаю @@ menu в 'about', он будет отображаться:1004 *

  <body>
    <div class='navbar navbar-fixed-top'>
      <div class='navbar-inner'>
        <div class='container'>
          <a class='btn btn-navbar' data-target='.nav-collapse' data-toggle='collapse'>
            <span class='icon-bar'></span>
            <span class='icon-bar'></span>
            <span class='icon-bar'></span>
          </a>
          <a class='brand' href='/'>AwesomeApp</a>
          <div class='nav-collapse'>
            <ul class='nav'>
              <li>
                <a href='/'>Home</a>
              </li>
              <li class='active'>
                <a href='/about'>About</a>
              </li>
              <li>
                <a href='/contact'>Contact</a>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
...