Ruby Liquid 模板引擎中的模数(或缺乏模数)
我正在 Jekyll 网站上工作,并尝试输出嵌套在行 div 中的三列 div。 Liquid 使得这个使用他们的 cycle
过滤器非常简单:
{% 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 %}
但是,这只在有 3、6、9 等帖子时才真正有效。当帖子总数不是三的倍数时,
永远不会关闭 - for 循环在结束标记可以作为以下内容的一部分输出之前结束关闭行
循环。在 Ruby、PHP 或任何其他语言中,我可以使用模运算符轻松修复此问题,因此除了 close rows
循环之外,我还会在 时输出
代码>如果site.categories.size % 3 == 0。然而,Liquid 因为它是一种安全的模板语言,所以不支持模数。
当帖子总数不是三的倍数时,我还能做些什么来正确关闭
?I'm working on a Jekyll site and am trying to output three column divs nested in a row div. Liquid makes this pretty easy with their cycle
filter:
{% 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 %}
However, this only really works when there are 3, 6, 9, etc. posts. When the total number of posts is not a multiple of three, the <div class="row">
never gets closed--the for loop ends before the closing tag can be output as part of the close rows
cycle.
In Ruby, PHP, or any other language I could easily fix this with a modulus operator, so in addition to close rows
cycle I would output </div>
when if site.categories.size % 3 == 0
. However, Liquid, because it's a safe templating language, doesn't support the modulus.
What else can I do to properly close <div class="row">
when the total number of posts is not a multiple of three?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我发现这种方法非常有效!
I've found this way to work great!
对于您的具体示例,您可以使用
{% Cycle 'close rows': nil, '', '' %}
在{% endfor %}
之后。For your specific example, you could use
{% cycle 'close rows': nil, '</div>', '</div>' %}
after the{% endfor %}
.目前唯一的方法是编写一个液体过滤器来实现这一点。在代码中适当的位置注册过滤器(如果使用 Rails 和不使用 Rails,则在不同的位置)。
在您的项目/lib目录中添加liquid_filters.rb:
之后您可以在模板中使用它,如下所示:
{{ 变量 | mod:5 }}
如果您需要将它用于某些逻辑,您可以捕获该值。
只是我注意到捕获的值是一个字符串,因此为了比较它,您使用
The only way for now is to write a liquid filter to accomplish this. Register the filter somewhere in your code where it's appropriate (it's in different places if using with rails and without them).
In you projects /lib directory add liquid_filters.rb:
After that you can use it like following in your templates:
{{ variable | mod:5 }}
And if you need to use it for some logic you can capture the value.
Just I've noticed that captured value is a string so in order to compare it you use
我在 for 循环中使用了另一个技巧:在你的情况下没用,如果你只是想要一个模来确定你的行是否已经结束并且你需要一个新行,就像我一样,那么很有用。
在这个例子中,我将使用一行 4 项:
不是很好,但很简单。
I used another trick in a for loop : useless in your case, useful if you just want a modulo in order to find out if your line has ended and you need a new row, like I did.
In this example I'll go with a line of 4 items :
Not very nice, but easy.
我意识到这个问题已经为提问者解决了,但我最近在 Liquid 中遇到了这种情况,我想我会提供我的解决方案,以防它可以帮助有类似标记要求的人。
就我而言,我已经通过了一个 if 语句来验证至少有一个帖子,因此我在循环外创建了第一个“行”div。我也在 for 循环之后关闭它。这可以防止帖子少于三个的情况。
每三篇帖子后,cycle 将关闭当前行并打开一个新行
除非
该帖子是 forloop 中的最后一篇,在这种情况下我们不想打开一个新行,并且让包装将其关闭。
I realize the question has been solved for the asker, but I recently came upon this kind of situation in Liquid and thought I'd provide my solution in case it helps someone with similar markup requirements.
In my case, I've already passed an if statement verifying that there is at least one post, so I created the first "row" div outside the loop. I also close it after the for loop. This protects against a case where there are less than three posts.
After every three posts, cycle will close the current row and open up a new one
unless
the post was the last one in the forloop, in which case we don't want to open a new row, and let the wrapping</div>
close it up.我从这篇文章中学到了很多东西,这是我在整个项目中使用的三种模式。它与 Bootstrap 配合也很好。只需更改以下代码中的列类即可。除了列之外,相同的模式还可以应用于模数有用的其他场景,例如奇偶行。希望它对某人有帮助 -
四列:
三列:
两列:
I learned a lot from this post, and these are three patterns I used throughout my project. It worked great with Bootstrap too. Just change the column class in the following code. Instead of columns, the same patterns can be applied to other scenarios where modulo is useful, such as odd-even rows. Hope it helps someone -
Four columns:
Three columns:
Two columns:
IIRC Liquid 不会阻止模运算,只会阻止
%
字符。您可以在不使用%
运算符的情况下执行模数运算。例如,14.modulo(3) => 2
而不是14 % 3
。IIRC Liquid doesn't block the modulo operation, only the
%
character. You can perform a modulus without using the%
operator. For example,14.modulo(3) => 2
instead of14 % 3
.