2010-08-11 22 views
16

Tùy thuộc vào việc người dùng có đăng nhập hay không, tôi muốn in một loại% body-tag khác.Cách thực hiện if/else trong HAML mà không lặp lại mã thụt lề

Đây là cách tôi đang làm điều đó:

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

Như bạn có thể thấy có rất nhiều mã trùng lặp trong đó. Làm thế nào tôi có thể loại bỏ điều này? Tôi đã thử như sau:

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

Thật không may, điều này không làm việc kể từ HAML diễn giải nó như nếu h1% và nội dung là một phần của người khác-tuyên bố, trong đó tất nhiên họ không.

Bất kỳ ý tưởng nào về cách giải quyết vấn đề này? Tôi chạy trong vấn đề này tất cả các thời gian, vì vậy tôi không thể tưởng tượng không có một giải pháp đơn giản cho nó.

+0

Có phải nội dung '% body' thứ hai nằm trong' else' hay không? –

+0

Có, nó nên. Nhưng% h1 và nội dung không nên. – Marc

Trả lời

12
!!! 
- @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 
+0

Marc - mà không nhìn thấy câu trả lời khác của @bahabil trước khi tôi đăng, cũng sẽ làm việc, hoặc khi bạn hỏi về việc không thiết lập thuộc tính data-account khi @ user.nil ?, điều này sẽ làm điều đó, nó sẽ không đưa khóa trong nếu chuỗi là nil. chuỗi có thể là một cuộc gọi phương thức trợ giúp trong trình trợ giúp xem của bạn. –

+0

Cảm ơn, hoạt động tuyệt vời! Các dấu ngoặc đơn cho định nghĩa? -method thực sự giải quyết vấn đề tôi gặp phải với câu trả lời của bhaibel. – Marc

+0

Tôi có thể xác định phương thức trợ giúp ở đâu? – Lokesh

13

Tôi không nghĩ rằng bạn có thể tránh được những vấn đề thụt đầu dòng, vì cách HAML autoassigns sự "kết thúc" tuyên bố, nhưng bạn thay vì có thể đẩy câu lệnh if vào thẻ cơ thể bản thân -

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

trái ngược với

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

Không siêu đẹp, nhưng ít xấu xí hơn lặp lại toàn bộ khối!

+1

Tôi không thể tưởng tượng HAML có một giải pháp thanh lịch cho một trường hợp sử dụng phổ biến như vậy. Nếu nó thực sự là trường hợp tôi có thể phải xem xét chuyển sang HTML thường xuyên một lần nữa. Dù sao, cảm ơn đề xuất của bạn. Có thể bỏ qua thuộc tính 'data-account'-hoàn toàn nếu @user không được xác định không? – Marc

+0

Mã này sẽ làm điều đó - thiết lập: data_account => nil (mà điều này không, gián tiếp) sẽ dẫn HAML bỏ qua thuộc tính và tạo một thẻ body đơn giản. – bhaibel

+0

Mã trả về như sau: Vì vậy, thay vì thực hiện biểu thức và trả về giá trị của nó, nó chỉ hiển thị từ 'biểu thức'. (Và không, @ user.account! = 'Expression') – Marc

4

giải pháp thanh lịch HAML là những người giúp đỡ

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 

Các nhà khai thác ternary mô tả ở trên là đầy đủ hơn cho tình hình cụ thể này, nhưng đối với những thứ phức tạp hơn, thoát ra khỏi những người giúp đỡ.

Oh, sử dụng điều này, theo quan điểm của bạn thay đổi %body(...) để = body_for_user @user do

+0

Tôi quên đề cập đến nó một cách rõ ràng trong bài viết mở đầu của mình, nhưng tôi không sử dụng Rails nhưng Sinatra, không có phương thức content_tag. Tôi có thể bắt chước nó, nhưng tôi giữ nó càng đơn giản càng tốt. Cảm ơn đề xuất mặc dù. Nó sẽ hữu ích trong các dự án Rails của tôi. – Marc

1

Viết một helper như thế này:

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 

Sau đó gọi helper từ các yếu tố cơ thể:

%body{ body_attributes } 
    %h1 Welcome 
    -# all my content 
+0

Xem http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html#attribute_methods để biết thêm thông tin về các phương pháp thuộc tính. –

+0

Tôi có thể làm điều gì đó sai, nhưng điều này chỉ trả về: – Marc

+0

Ví dụ cập nhật. Bạn cần dấu ngoặc nhọn xung quanh tên phương thức (tôi đã sử dụng dấu ngoặc đơn). –

1

Đối với bất cứ ai tìm kiếm một câu trả lời cho Ruby nếu/else vấn đề với HAML này là cách tôi làm việc xung quanh nó:

%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) 
0

Tôi thường thiết lập @@ biến menu ở bộ điều khiển, sau đó trong layout.haml bootstrap cho phép tôi xác định:

... 
    %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 

khi tôi đặt @@ menu để 'about' nó sẽ render:

<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> 
+0

Tôi không thấy lớp 'giới thiệu' đang được áp dụng ... bạn có chắc chắn đây là sau khi bạn đặt biến @@ menu không? –

+0

@v_mitchell: có "@@ menu == 'về toán tử ternary" &&: active "trả về: active nếu @@ menu bằng' about 'string. – andrej

Các vấn đề liên quan