picocms / Pico

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

Sort pages and add title for any letter change #630

Closed digitalinferno closed 2 years ago

digitalinferno commented 2 years ago

When we use for page in pages() we can obtain something like this?

c
- carpage
- catpage
d
- dogpage
f
- foopage
- fuupage
mayamcdougall commented 2 years ago

I can't give an in-depth answer to this one right now, as I've got to get ready to head out in a few.

It'd definitely be doable with some extra Twig logic.

Check out the Twig Docs if you haven't, as they're really helpful. Twig is WAY more powerful than it has any right to be. 😉

A good place to start might be the using starts with test to check if a page's title starts with the current letter.

If your site isn't already sorted alphabetically by title, the |sort_by filter can sort your pages temporarily for you.

Maybe use an array of letters (["a","b","c"...]) somewhere in there and as you're looping, check if the page starts with the current letter. If not, advance the current letter until it matches, then print the heading for that letter and continue.

I can probably help you work through this later tonight if you'd like. In the meantime this is more of a brainstorm, but if it gives you the push you need to get started then great. 😁

Talk to you about it soon. 👋🏻

digitalinferno commented 2 years ago

Thanks for the hint, I have spotted a solution in twig (valid for various type of list):

    {% set last = '' %}
    {% for page in pages|sort %}
        {% for i in range ('A', 'Z') %}
        {% if page|capitalize starts with i  and i != last%} {% set last = i %}{{ i }} {% endif %}
        {% endfor %}
        ... {{ page.xxx }} ...
    {% endfor %}

If necessary we can add a cycle for titles starting with numbers.

mayamcdougall commented 2 years ago

Ooo, very nice. I forgot about range, as I don't use it much. I actually had no idea it could make a range of letters too. 😳

(The Twig docs are really great, huh? We really need to link to them more in the Docs, because it's usually the first place I send people. 😅 )

Doesn't that need to be page.title|capitalize? Also, you'll want to use Pico's |sort_by filter, which is specifically made for sorting pages.

{% for page in pages(depth=null)|sort_by("title") %}

The rest looks great though. I've got no idea if pages(depth=null) is any faster than just using the pages variable in this case. Also, you may or may not want the depthOffset=-1 parameter too, if you also wanted to include your home index page... so maybe it does just make more sense to just stick with pages in this case for simplicity. 🤔

(Mostly just wanted to include the pages() function in the example. 😅)

So yeah, a loop like this one would be where you'd see the slowdown we discussed in #631, since you're looping over ALL your pages. But again... it shouldn't be a real issue unless you had a LOT of pages (in which case you'd probably add logic so that this code only runs if someone pulls up a specific "site map" page or wherever it's going to be put).

As a quick aside about logic like that: Even though Pico has a Template metadata property for rendering separate layouts per-page, I really don't use it much myself. Having multiple "Templates" always felt like a lot of duplicated effort, so I tend to just use if logic to decide which parts of my page I need, within the main template.

That, mixed with breaking things out into separate files and pulling them in with {% include %} tends to be my approach to developing for Pico. Complicated loops and logic can't slow things down if they're only run when needed, after all. 😉

If necessary we can add a cycle for titles starting with numbers.

You could probably just do something like range ('0', '9')|merge(range ('A', 'Z')) (or the other way around if you wanted letters first).

Anyway. Seems like you've got it under control, so just let me know if you get stuck anywhere. 😁

digitalinferno commented 2 years ago

I put capitalize (and sort too) just like a placeholder. If you sort anything else it avoids missing point (otherwise if you have meta like NBA, Nasa and nascar the last one is off the N list)

mayamcdougall commented 2 years ago

I think maybe you misunderstood. It wasn't capitalize that I was questioning.

I was saying it should probably be page.title, not page there. 😉

I get that this was just your brainstorming though, and not the finished code.

digitalinferno commented 2 years ago

Sorry, my fault :) page.title is the right code.