picocms / Pico

Pico is a stupidly simple, blazing fast, flat file CMS.
http://picocms.org/
MIT License
3.83k stars 614 forks source link

List of all articles divided by month, with if condition #527

Closed stefanocpp closed 4 years ago

stefanocpp commented 4 years ago

Hello,

my Pico installation runs a small blog I have fun writing on. The Archive page of my website has a list of all published articles, divided by month, and is updated manually by me every time I post a new article. This is how it looks like right now. For about one year now, I've tried to automate this process, with mixed fortunes, by using Twig. Here's what I've come up with so far

{% for i in range(0, 60) %}  
{% set prev_month = "now"|date("F y")%}  
    {% set prev_month = prev_month|date_modify("-" ~i~ "month")|date("F y") %}  
        <h2>{{prev_month}}</h2>
    {% for page in pages|sort_by("time")|reverse if page.time and not page.meta.unlisted %}
              {% if page.time|date("F y") == prev_month %}
                   <a href="{{page.url}}" title="{{page.meta.description}}">{{ page.title }}</a><br>
             {% endif %}
     {% endfor %}
{% endfor %}

this works, and I was very proud of having made it so far, but there are some issues, namely:

I have tried several different things with months of trial-and-error learning, plus some looking around, but haven't found a solution yet and I'm not explaining all of them here just for brevity sake. I'm asking it directly, in the end, because I think it could benefit somebody else too and could even be added to the cookbook if considered to be valuable enough.

I'd like to leverage only on page.time as a parameter, as all articles I've written so far have it. Going through all existing pages to add something in the YAML header would overcome the usefulness of automating this process.

Thank you very much, I've always learned something new reading issues ;)

PhrozenByte commented 4 years ago

You're actually pretty close. Use the (sorted) pages list (by the way: you should think about using Pico's new pages() function instead, see http://picocms.org/in-depth/features/pages-function/) for your loop and print new months as soon as they occur for the first time.

The following snippet is untested:

{% set current_month = "" %}
{% for page in pages|sort_by("time")|reverse if page.time and not page.meta.unlisted %}
    {% if page.time|date("Y-m") != current_month %}
        {% set current_month = page.time|date("Y-m") %}
        <h2>{{ page.time|date("F 'y") }}</h2>
    {% endif %}
    <a href="{{ page.url }}" title="{{ page.meta.description }}">{{ page.title }}</a><br>
{% endfor %}
stefanocpp commented 4 years ago

Thank you, it works! I love how elegant and succinct your code is with respect to mine. I'll study your snippet and ask if I don't understand something (if I may). I tried to read the linked pages months ago, but couldn't understand much. I'll give it another try, but how would the above code change if I were to use the new pages() function? So that I can study that too to understand the new function :) Thank you again <3

PhrozenByte commented 4 years ago

Assuming all pages you wanna list on that page are in folders like content/archive/<year>/<month>, you could use pages("archive", depth=2, depthOffset=2) instead of the raw pages list (i.e. {% for page in pages("archive", depth=2, depthOffset=2)|sort_by("time")|reverse %}).

stefanocpp commented 4 years ago

Thank you very much once again!

If you think it could be valuable, we could add this to the cookbook...

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in two days if no further activity occurs. Thank you for your contributions! :+1: