jekyll - pages - liquid language
Jekyll/Liquid Templating: ¿Cómo agrupar publicaciones de blog por año? (6)
Estoy reescribiendo mi blog para usar Jekyll. Jekyll usa el lenguaje Liquid Templating, lo que hace que sea un poco más difícil aprender a personalizar.
Me gustaría agrupar mi lista de publicaciones de blog por año. ¿Cómo escribiría el código de Liquid para poder hacer esto?
{% for post in site.posts %}
<li><!-- display post year here (but only once, per year) --></li>
<li>
<a href="{{ post.url }}">{{ post.title }}</a>
</li>
{% endfor %}
Algunas de las soluciones anteriores son muy complejas, pero luego como señaló que podemos aumentar el filtro group_by_exp de Jekyll. También me gustó la solución, pero lo que necesitaba estaba agrupado por Año y luego dentro de esa lista agrupada por Mes. Así que, lo pellizqué un poco.
{% assign postsByYear = site.posts | group_by_exp:"post", "post.date | date: ''%Y''" %}
{% for year in postsByYear %}
<h1>{{ year.name }}</h1>
{% assign postsByMonth = year.items | group_by_exp:"post", "post.date | date: ''%B''" %}
{% for month in postsByMonth %}
<h2>{{ month.name }}</h2>
<ul>
{% for post in month.items %}
<li><a href="{{ post.url }}">{{ post.title }}-{{ post.date }}</a></li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
Estas soluciones anteriores son fantásticas, pero afortunadamente a finales de 2016, Jekyll agregó un filtro group_by_exp
que puede hacer esto mucho más limpio.
{% assign postsByYear =
site.posts | group_by_exp:"post", "post.date | date: ''%Y''" %}
{% for year in postsByYear %}
<h1>{{ year.name }}</h1>
<ul>
{% for post in year.items %}
<li><a href="{{ post.url }}">{{ post.title }}-{{ post.date }}</a></li>
{% endfor %}
</ul>
{% endfor %}
La documentación se puede encontrar en la página de Plantillas Jekyll .
Se puede hacer con mucho, mucho menos código líquido que en las respuestas existentes:
{% for post in site.posts %}
{% assign currentdate = post.date | date: "%Y" %}
{% if currentdate != date %}
<li id="y{{currentdate}}">{{ currentdate }}</li>
{% assign date = currentdate %}
{% endif %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
Esto devolverá exactamente el HTML especificado en su pregunta:
<li id="y2013">2013</li>
<li><a href="/2013/01/01/foo/">foo</a></li>
<li id="y2012">2012</li>
<li><a href="/2012/02/01/bar/">bar</a></li>
<li><a href="/2012/01/01/baz/">baz</a></li>
Sin embargo, esta no es la solución óptima, ya que los números de año son "solo" elementos de la lista también.
No es mucho más que un código líquido para poner el año en un titular y comenzar un nuevo <ul>
para las publicaciones de cada año:
{% for post in site.posts %}
{% assign currentdate = post.date | date: "%Y" %}
{% if currentdate != date %}
{% unless forloop.first %}</ul>{% endunless %}
<h1 id="y{{post.date | date: "%Y"}}">{{ currentdate }}</h1>
<ul>
{% assign date = currentdate %}
{% endif %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% if forloop.last %}</ul>{% endif %}
{% endfor %}
El HTML generado:
<h1 id="y2013">2013</h1>
<ul>
<li><a href="/2013/01/01/foo/">foo</a></li>
</ul>
<h1 id="y2012">2012</h1>
<ul>
<li><a href="/2012/02/01/bar/">bar</a></li>
<li><a href="/2012/01/01/baz/">baz</a></li>
</ul>
También puede agrupar por mes y año (para que los titulares sean February 2012
, January 2012
etc.).
Para hacer esto, solo necesita reemplazar la date: "%Y"
(en la segunda línea de los dos ejemplos anteriores) por date: "%B %Y"
.
( %B
es el nombre completo del mes, consulte la documentation )
Si quieres desglosarlo por año, aquí está el código:
{% for post in site.posts %}
{% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
{% capture next_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %}
{% if forloop.first %}
<h2 id="{{ this_year }}-ref">{{this_year}}</h2>
<ul>
{% endif %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% if forloop.last %}
</ul>
{% else %}
{% if this_year != next_year %}
</ul>
<h2 id="{{ next_year }}-ref">{{next_year}}</h2>
<ul>
{% endif %}
{% endif %}
{% endfor %}
Si desea desglosarlo en años y meses, se puede lograr así:
{% for post in site.posts %}
{% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
{% capture this_month %}{{ post.date | date: "%B" }}{% endcapture %}
{% capture next_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %}
{% capture next_month %}{{ post.previous.date | date: "%B" }}{% endcapture %}
{% if forloop.first %}
<h2 id="{{ this_year }}-ref">{{this_year}}</h2>
<h3 id="{{ this_year }}-{{ this_month }}-ref">{{ this_month }}</h3>
<ul>
{% endif %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% if forloop.last %}
</ul>
{% else %}
{% if this_year != next_year %}
</ul>
<h2 id="{{ next_year }}-ref">{{next_year}}</h2>
<h3 id="{{ next_year }}-{{ next_month }}-ref">{{ next_month }}</h3>
<ul>
{% else %}
{% if this_month != next_month %}
</ul>
<h3 id="{{ this_year }}-{{ next_month }}-ref">{{ next_month }}</h3>
<ul>
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
Es solo una cuestión de dónde haces el corte en el bucle.
Tratar:
{% for post in site.posts %}
{% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
{% if forloop.first %}
<h2 id="{{ this_year }}-ref">{{this_year}}</h2>
<ul class="posts">
{% else %}
{% if this_year != last_year %}
</ul>
<h2 id="{{ this_year }}-ref">{{this_year}}</h2>
<ul class="posts">
{% endif %}
{% endif %}
<li>
<span class="post-date">{{ post.date | date_to_string }} »</span>
<a href="{{ post.url }}">{{ post.title }}</a>
</li>
{% if forloop.last %}
</ul>
{% endif %}
{% capture last_year %}{{ this_year }}{% endcapture %}
{% endfor %}
<ul>
{% for post in site.posts %}
{% assign year = post.date | date: "%Y" %}
{% if year != prev_year %}
<h3>{{year}}</h3>
{% endif %}
<li>
<span>{{ post.date | date: "%B %e, %Y" }}</span>
<a href="{{ post.url }}">{{ post.title }}</a>
</li>
{% assign prev_year = year %}
{% endfor %}
</ul>