2010-02-11 20 views
20

Tôi đang làm việc trên trang web Jekyll và đang cố gắng xuất ba div cột được lồng trong một hàng div. Liquid làm cho điều này khá dễ dàng với bộ lọc cycle của họ:Modulus (hoặc thiếu chúng) trong công cụ tạo khuôn lỏng của Ruby

{% for p in site.categories.post %} 
    {% cycle 'add rows': '<div class="row">', nil, nil %} 
     <div class="column"> 
      <a href="{{ p.url }}">{{ p.title }}</a> 
     </div> 
    {% cycle 'close rows': nil, nil, '</div>' %} 
{% endfor %} 

Tuy nhiên, điều này chỉ thực sự hoạt động khi có 3, 6, 9, vv bài đăng nào. Khi tổng số bài viết không phải là bội số của ba, thì <div class="row"> không bao giờ bị đóng - vòng lặp for kết thúc trước khi thẻ đóng có thể xuất ra như một phần của chu kỳ close rows.

Trong Ruby, PHP, hoặc bất kỳ ngôn ngữ nào khác tôi có thể dễ dàng sửa lỗi này với một nhà điều hành mô đun, vì vậy ngoài việc close rows chu kỳ tôi sẽ ra </div> khi if site.categories.size % 3 == 0. Tuy nhiên, Liquid, bởi vì nó là một ngôn ngữ templating an toàn, không hỗ trợ modulus.

Tôi có thể làm gì khác để đóng đúng <div class="row"> khi tổng số bài đăng không phải là bội số của ba bài đăng?

Trả lời

13

Ví dụ cụ thể của bạn, bạn có thể sử dụng {% cycle 'close rows': nil, '</div>', '</div>' %} sau {% endfor %}.

+0

Điều đó hoạt động hoàn hảo! Cảm ơn! – Andrew

1

IIRC Chất lỏng không chặn hoạt động modulo, chỉ có ký tự %. Bạn có thể thực hiện mô-đun mà không cần sử dụng toán tử %. Ví dụ: 14.modulo(3) => 2 thay vì 14 % 3.

+0

Điều đó có ý nghĩa, vì tất cả các hàm số học khác được tóm tắt như thế, nhưng tiếc là không phải công việc 'modulo' hoặc' modulus'… – Andrew

+0

Vâng. Chỉ cần kiểm tra mã nguồn. Đáng buồn thay, không có 'modulo'. Tôi sẽ phải có thể nĩa nó và thêm nó vào hoặc một cái gì đó. Giải pháp hiện tại của tôi là một mớ hỗn độn: 'trừ khi tổng == 3 hoặc tổng == 6 hoặc tổng == 9 hoặc tổng == 12 hoặc tổng == 15…' – Andrew

+1

'x.modulo (y)' chỉ là một bí danh cho ' x.divmod (y) [1] '. Nếu 'divmod' được cho phép, bạn có thể sử dụng biểu mẫu đó. Hoặc, bạn luôn có thể cuộn hàm modulo của riêng bạn: 'x - (x/y)' (sử dụng bất kỳ phiên bản trừu tượng nào của toán tử số học mà bạn cần). – bta

8

Cách duy nhất bây giờ là viết bộ lọc chất lỏng để thực hiện việc này. Đăng ký bộ lọc ở đâu đó trong mã của bạn, nơi nó phù hợp (nó ở những nơi khác nhau nếu sử dụng với đường ray và không có chúng).

lỏng :: Template.register_filter (LiquidFilters)

Trong bạn dự án/thư mục lib thêm liquid_filters.rb:

module LiquidFilters 
    # makes modulus operation available to templates 
    def mod(data, param) 
    data % param 
    end 
end 

Sau đó bạn có thể sử dụng nó như sau trong mẫu của bạn : {{biến | mod: 5}}

Và nếu bạn cần sử dụng nó cho một số logic bạn có thể nắm bắt giá trị.

{% capture modulus %}{{ variable | mod:5 }}{% endcapture %} 

Chỉ cần tôi đã nhận thấy rằng giá trị bị bắt là một chuỗi như vậy để so sánh nó bạn sử dụng

{% if modulus == "0" %} 
.. 
{% endif %} 
+0

Đây là câu trả lời hay nhất. – ptrin

+1

Đó là một thực sự shitty, nhưng giải pháp làm việc! Cảm ơn bạn :) –

3

tôi đã sử dụng một trick trong một vòng lặp for: vô dụng trong trường hợp của bạn, hữu ích nếu bạn chỉ muốn một modulo để tìm hiểu xem dòng của bạn đã kết thúc chưa và bạn cần một hàng mới, như tôi đã làm.

Trong ví dụ này, tôi sẽ đi với một dòng của 4 hạng mục:

{% assign currentRow = 1 %} 
# enter the for loop ... then, with 4 as the divisor: 
{% if forloop.index == 4 * currentRow %} 
    # do whatever you want 
    {% assign currentRow = currentRow + 1 %} 
{% endif %} 
# exit the for loop 

Không phải rất tốt đẹp, nhưng dễ dàng.

12

Tôi đã tìm thấy cách này để làm việc tuyệt vời!

{% assign mod = forloop.index0 | modulo:4 %} 
{% if mod == 0 %} 
    <!-- Do stuff --> 
{% endif %} 
+0

Modulo phải đã được thêm vào trong các phiên bản Jekyll sau. Điều này chắc chắn hoạt động trong dự án của tôi. – ThisClark

1

Tôi đã học được rất nhiều từ bài đăng này và đây là ba mẫu tôi đã sử dụng trong suốt dự án của mình. Nó hoạt động rất tốt với Bootstrap. Chỉ cần thay đổi lớp cột trong đoạn mã sau. Thay vì cột, các mô hình tương tự có thể được áp dụng cho các tình huống khác, nơi modulo là hữu ích, chẳng hạn như hàng lẻ chẵn. Hy vọng nó sẽ giúp người -

Bốn cột:

<div class="container"> 
    {% for post in site.posts %} 
     {% cycle 'add row' : '<div class="row">', nil, nil, nil %} 
      <div class="column"> 
       <!-- liquid tags here --> 
      </div> 
     {% cycle 'end row' : nil, nil, nil, '</div>' %} 
    {% endfor %} 
    {% cycle 'end row' : nil, '</div>', '</div>', '</div>' %} 
</div> 

Ba cột:

<div class="container"> 
    {% for post in site.posts %} 
     {% cycle 'add row' : '<div class="row">', nil, nil %} 
      <div class="column"> 
       <!-- liquid tags here --> 
      </div> 
     {% cycle 'end row' : nil, nil, '</div>' %} 
    {% endfor %} 
    {% cycle 'end row' : nil, '</div>', '</div>' %} 
</div> 

Hai cột:

<div class="container"> 
    {% for post in site.posts %} 
     {% cycle 'add row' : '<div class="row">', nil %} 
      <div class="column"> 
       <!-- liquid tags here --> 
      </div> 
     {% cycle 'end row' : nil, '</div>' %} 
    {% endfor %} 
    {% cycle 'end row' : nil, '</div>' %} 
</div> 
3

Tôi nhận ra câu hỏi đã được giải quyết cho hỏi, nhưng gần đây tôi bắt gặp tình huống này ở dạng lỏng và nghĩ rằng tôi muốn cung cấp giải pháp của tôi trong trường hợp nó giúp người có yêu cầu đánh dấu tương tự.

Trong trường hợp của tôi, tôi đã thông qua một tuyên bố nếu xác minh rằng có ít nhất một bài, vì vậy tôi đã tạo ra đầu tiên "hàng" div bên ngoài vòng lặp. Tôi cũng đóng nó sau vòng lặp for. Điều này bảo vệ chống lại một trường hợp có ít hơn ba bài viết.

<div class="row"> 

    {% for p in posts %} 
     <div class="column"> 
      <!-- Post code here --> 
     </div> 
     {% unless forloop.last %} 
      {% cycle '', '', '</div><div class="row">' %} 
     {% endunless %} 
    {% endfor %} 

</div> 

Sau mỗi ba bài viết, chu kỳ sẽ đóng hàng hiện tại và mở ra một cái mới unless bài viết là chiếc cuối cùng trong forloop, trong trường hợp mà chúng tôi không muốn mở một hàng mới, và để cho các gói </div> đóng nó lên.

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