jekyll - site - Para bucle, envuelve cada dos mensajes en un div
liquid tutorial (9)
Básicamente, estoy usando Jekyll (que usa el lenguaje de plantillas Liquid ) y estoy tratando de escribir un bucle for
que envuelve cada dos elementos en un div
.
Este es mi bucle actual:
<div>
{% for post in site.posts %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endfor %}
</div>
Lo que daría como resultado cuatro publicaciones como esta:
<div>
<a href="#">Title</a>
<a href="#">Title</a>
<a href="#">Title</a>
<a href="#">Title</a>
</div>
Mi salida deseada para cuatro publicaciones es:
<div>
<a href="#">Title</a>
<a href="#">Title</a>
</div>
<div>
<a href="#">Title</a>
<a href="#">Title</a>
</div>
¿Cómo puedo lograr esto?
Acabo de encontrar esto ( gist.github.com/leemachin/2366832 ) que es una solución mucho mejor que las publicadas en otras respuestas, teniendo en cuenta que necesitará este complemento ( https://gist.github.com/leemachin/2366832#file-modulo-filter-rb ) para que funcione:
{% for post in paginator.posts %}
{% capture modulo %}{{ forloop.index0 | mod:2 }}{% endcapture %}
{% if modulo == ''0'' or forloop.first %}
<div>
{% endif %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% if modulo == ''1'' or forloop.last %}
</div>
{% endif %}
{% endfor %}
Con la ayuda de @ smilinmonki666, he conseguido que esto funcione, y aquí está el código final con el que fui:
{% assign current_page_posts = paginator.posts | size %}
{% if current_page_posts > 0 %}
<div>
<div>
{% for post in paginator.posts %}
{% if forloop.index == 1 %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endif %}
{% if forloop.index == 2 %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endif %}
{% endfor %}
</div>
{% if current_page_posts > 2 %}
<div>
{% for post in paginator.posts %}
{% if forloop.index == 3 %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endif %}
{% if forloop.index == 4 %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endif %}
{% endfor %}
</div>
{% endif %}
</div>
{% endif %}
Después de ver la solución de Christian, actualicé mi código (basado en pug) para:
.blog
.container
.row
.col-xs-0
.col-xs-12
h1 Blog
p Summit blog with latest news, thinking and participant''s posts.
.col-xs-0
| {% for page in site.posts %}
| {% assign loopindex = forloop.index | modulo: 2 %}
| {% if loopindex == 1 %}
.row
| {% endif %}
span
.col-xs-6.col-sm-6
.card
.card-top
+ add-title
+ add-author
.card-block
+ add-snippet
| {% endfor %}
Ok, he hecho un intento rápido sin un estilo adecuado, pero esto debería funcionar:
<div>
{% for post in paginator.posts %}
{% case forloop.index %}
<div>
{% when 1 %}
<a href="">{{ post.title }}</a>
{% when 2 %}
<a href="">{{ post.title }}</a>
</div>
<div>
{% when 3 %}
<a href="">{{ post.title }}</a>
{% when 4 %}
<a href="">{{ post.title }}</a>
</div>
{% endcase %}
{% endfor %}
</div>
Prueba este:
<div>
{% for post in paginator.posts %}
<div>
{% if forloop.index == 1 %}
<a href="">{{ post.title }}</a>
{% endif %}
{% if forloop.index == 2 %}
<a href="">{{ post.title }}</a>
{% endif %}
</div>
<div>
{% if forloop.index == 3 %}
<a href="">{{ post.title }}</a>
{% endif %}
{% if forloop.index == 4 %}
<a href="">{{ post.title }}</a>
{% endif %}
</div>
{% endfor %}
</div>
Puede hacer esto con la etiqueta de cycle
como se describe en https://shopify.github.io/liquid/tags/iteration/
{% for post in site.posts %}
{% cycle ''<div>'', '''' %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% cycle '''', ''</div>'' %}
{% endfor %}
salidas
<div>
<a href="#">Title</a>
<a href="#">Title</a>
</div>
<div>
<a href="#">Title</a>
<a href="#">Title</a>
</div>
Realmente debería concentrarme en lo que estoy haciendo, pero duro con una niña de un año que me da todos sus juguetes ...: D
El código debería funcionar ahora:
<div>
<div>
{% for post in paginator.posts %}
{% if forloop.index == 1 %}
<a href="">{{ post.title }}</a>
{% endif %}
{% if forloop.index == 2 %}
<a href="">{{ post.title }}</a>
{% endif %}
{% endfor %}
</div>
<div>
{% for post in paginator.posts %}
{% if forloop.index == 3 %}
<a href="">{{ post.title }}</a>
{% endif %}
{% if forloop.index == 4 %}
<a href="">{{ post.title }}</a>
{% endif %}
{% endfor %}
</div>
</div>
Debe dar el html de:
<div>
<div>
<a href="">Title 1</a>
<a href="">Title 2</a>
</div>
<div>
<a href="">Title 3</a>
<a href="">Title 4</a>
</div>
</div>
Sé que llego tarde al juego, pero encontré que lo que siento es una solución bastante elegante que no se siente mal.
Con los parámetros de limit
y offset
bucle, podemos iterar una fila a la vez, N publicaciones por fila.
Primero, contamos el número de filas que necesitaremos enumerar:
{% assign rows = site.posts.size | divided_by: 2.0 | ceil %}
El equivalente de Ruby sería rows = (posts.size / 2.0).ceil
(los números impares obtienen su propia fila).
A continuación, vamos a iterar sobre las filas:
{% for i in (1..rows) %}
<div>
Ahora necesitamos calcular el desplazamiento de la colección con (i - 1) * 2
(utilizando forloop.index0
):
{% assign offset = forloop.index0 | times: 2 %}
Luego podemos iterar sobre la porción de publicaciones que comienzan en el desplazamiento de la fila (equivalente a las posts[offset, 2]
en Ruby):
{% for post in site.posts limit:2 offset:offset %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endfor %}
Cierre el elemento div
fila y para bucle:
</div>
{% endfor %}
¡Eso es!
En Ruby, esto sería:
rows = (posts.size / 2.0).ceil # the number of rows
(1..rows).each do |i|
offset = (i - 1) * 2
# <div>
posts[offset, 2].each do |post|
# <a href="#{post.url}>#{post.title}</a>
end
# </div>
end
Todos juntos ahora, en Liquid:
{% assign rows = site.posts.size | divided_by: 2.0 | ceil %}
{% for i in (1..rows) %}
{% assign offset = forloop.index0 | times: 2 %}
<div>
{% for post in site.posts limit:2 offset:offset %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endfor %}
</div>
{% endfor %}
¡Espero que esto ayude a alguien!
Si el número de <div>
sy publicaciones es fijo (lo que parece ser el caso en función de la respuesta que seleccionó) , hay una manera más corta de obtener la misma salida: usando limit
y offset
:
(Enfoque de Liquid para la paginación)
<div>
{% for post in site.posts limit: 2 %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endfor %}
</div>
<div>
{% for post in site.posts limit: 2 offset: 2 %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endfor %}
</div>
Aún mejor solución:
Si el número de publicaciones no es fijo (por lo tanto, cuando tiene 100 publicaciones, quiere 50 <div>
s con dos publicaciones cada una) , entonces puede usar forloop.index
(que ya se mencionó en la mayoría de las otras respuestas) , y use modulo
para averiguar si el índice actual es par o impar:
{% for post in site.posts %}
{% assign loopindex = forloop.index | modulo: 2 %}
{% if loopindex == 1 %}
<div>
<a href="{{ post.url }}">{{ post.title }}</a>
{% else %}
<a href="{{ post.url }}">{{ post.title }}</a>
</div>
{% endif %}
{% endfor %}
Esto también devuelve la salida deseada, pero funciona para cualquier cantidad de publicaciones.