Question Jekyll / Liquid Templating: Comment grouper les articles de blog par année?


Je réécris mon blog pour utiliser Jekyll. Jekyll utilise le langage de modélisation liquide, ce qui rend un peu plus difficile l'apprentissage de la personnalisation.

Je voudrais grouper ma liste d'articles de blog par année. Comment pourrais-je écrire le code Liquid pour pouvoir le faire?

{% 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 %}

29
2017-09-30 04:02


origine


Réponses:


Si vous voulez le décomposer par année, voici le code:

{% 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 vous voulez le décomposer en année et mois, vous pouvez le faire comme ceci:

{% 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 %}

C'est seulement une question de savoir où vous faites la coupe sur la boucle.


29
2017-09-30 21:56



Cela peut être fait avec beaucoup, beaucoup moins de code liquide que dans les réponses existantes:

{% 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 %}

Cela retournera exactement le HTML spécifié dans votre question:

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

Cependant, ce n'est pas la solution optimale, car les numéros d'année sont également des éléments de liste "seulement".
Ce n'est pas beaucoup plus de code liquide pour mettre l'année en vedette et pour commencer une nouvelle <ul> pour les postes de chaque année:

{% 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 %}

Le HTML généré:

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

Vous pouvez également regrouper par mois et par année à la place (pour que les gros titres soient February 2012, January 2012 etc).

Pour ce faire, il vous suffit de remplacer date: "%Y"  (dans la deuxième ligne des deux exemples ci-dessus) par date: "%B %Y".
(%B est le nom du mois complet, voir le Documentation)


50
2017-12-25 23:01



Ces solutions précédentes sont fantastiques mais heureusement à la fin de 2016, Jekyll a ajouté un group_by_exp filtre qui peut le faire beaucoup plus proprement.

{% 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 documentation peut être trouvée sur le Page Modèles Jekyll.


16
2018-04-03 17:39



Certaines solutions ci-dessus sont très complexes mais comme @Trevor a souligné que nous pouvons dégager Jekyll group_by_exp filtre. J'ai aussi aimé la solution, mais ce dont j'avais besoin était groupé par année et ensuite par liste groupée par mois. Donc, je l'ai un peu modifié.

{% 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 %}

6
2018-05-22 14:22



Essayer:

{% 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 }} &raquo;</span>
      <a href="{{ post.url }}">{{ post.title }}</a>
    </li>

  {% if forloop.last %}
    </ul>
  {% endif %}

  {% capture last_year %}{{ this_year }}{% endcapture %}
{% endfor %}

2
2017-10-05 21:36



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

0
2017-08-23 18:32