cobalt-org / cobalt.rs

Static site generator written in Rust
cobalt-org.github.io/
Apache License 2.0
1.38k stars 102 forks source link

Date-driven indexes #354

Closed waywardmonkeys closed 6 years ago

waywardmonkeys commented 6 years ago

I'd like to be able to have index files generated in the various year, month and day directories for my posts.

That way, visiting these pages would show the posts as one might expect:

Is this possible with Cobalt? I didn't see anything for that in the docs.

epage commented 6 years ago

This isn't supported yet but I want to be able to support it. The interesting thing will be deciding how users define these.

I think Taxonomy templates are the closest thing in Hugo https://gohugo.io/templates/taxonomy-templates/

I think this is the closest thing in Gutenberg https://www.getgutenberg.io/documentation/content/table-of-contents/

epage commented 6 years ago

Other use cases besides date

Tags introduces the interesting situation of them not being ordered, so /tags/cat/awww and /tags/awww/cat probably both need to exist.

epage commented 6 years ago

Considerations

Generally I've been trying to minimize configuration when it doesn't get in the way of the user getting their job done and I try to minimize duplicated information as long as it doesn't make the users job hard.

epage commented 6 years ago

We should also support pagination with this.

Closing https://github.com/cobalt-org/cobalt.rs/issues/219 in favor of this because I'm guessing we won't want to support pagination generally.

Geobert commented 6 years ago

Once I have a first working version of my blog with current cobalt 0.11.1, I think the first feature I'll need will be pagination :) Does anyone have started this?

epage commented 6 years ago

No one has started this from what I've heard. The first step is gathering requirements, seeing how others handle this, and creating a proposal.

Geobert commented 6 years ago

On tags, usually there is no point of having multiple tags in url as they are not ordered. Only generate url for one tag at a time. Otherwise we can end up with a combinatorial number of pages to generate.

For categories, as they have a hierarchy, we can have multiples categories in a url, if they are related.

For pagination some config is needed (same as Jekyll)):

paginate: 5 # nb items
paginate_path: "/page:num" # to allow path customization

these will apply to all paginations /tags/cat/index.html and we will have /tags/cat/page2/index.html

if we want specific settings for tags or categories, we should have a way to override defaults:

tags:
    paginate: 15 
    paginate_path: "/p:num"

categories:
    paginate: 20
    paginate_path: "/p:num"

For all these, no permalink, this concept is contradictory with pagination and tags/categories.

pagination will create a paginator: Jekyll style: https://jekyllrb.com/docs/pagination/

or Gutenberg style: https://www.getgutenberg.io/documentation/templates/pagination/

I don't like Hugo paginator object for some reason, maybe the hasNext field feels bloated when a nil in prev/next is enough.

But I like Hugo generating the paginator in a lazy fashion: https://gohugo.io/templates/pagination/

Setting Paginate to a positive value will split the list pages for the homepage, sections and taxonomies into chunks of that size. But note that the generation of the pagination pages for sections, taxonomies and homepage is lazy — the pages will not be created if not referenced by a .Paginator (see below).

epage commented 6 years ago

Thanks for starting to look into this!

Below I explore some questions we'll need to address in coming up with this proposal

these will apply to all paginations /tags/cat/index.html and we will have /tags/cat/page2/index.html

More generally

Plus my questions in my earlier post

epage commented 6 years ago

On tags, usually there is no point of having multiple tags in url as they are not ordered. Only generate url for one tag at a time. Otherwise we can end up with a combinatorial number of pages to generate.

I do see value in anding tags. I have mixed feelings about whether we should actually support it or not. If we do, I don't think we need to support it in the first release of this.

epage commented 6 years ago

if we want specific settings for tags or categories, we should have a way to override defaults:

paginate_path: "/p:num"

FYI we're calling them permalinks and they use liquid templating: /p{{num}}

Geobert commented 6 years ago

How do we define the hierarchy?

If I got this right, categories have a hierarchy by definition: https://github.com/cobalt-org/cobalt.rs/issues/131#issuecomment-313689334

For tags, if we want anding, maybe something simple like alphabetical order so we can decrease the combinatorial number by two ^^'

How do we define the permalink?

It seems the paginate_path takes care of it

How does the user access the child pages? How does the user access the child indexes?

Paginator object

Should an index include all its immediate children pages or all descendants?

Jekyll/Gutenberg gives access to immediate children, Hugo has a query language to dig deeper

Could be globally configurable

Could be configurable in frontmatter

Could be differentiated by variables on the item

Could offer variables for both cases

For the moment I've put a global conf, overridable for tags and categories

How would a user tell cobalt what they are paginating on?

For the moment, I'm thinking something like Jekyll: everything is paginated once the configuration has been switched on.

It looks like you are planning on supporting mixing tags and categories?

I wasn't planning on this, I was thinking /tags and /categories as permalinks.

Can a user define precedence and if so, how? (are tags under categories or the other way)

So, no, as I wasn't planning to mix them ^^

have you come up with a proposal for how to declare a page is an index?

Nope, it was a first post to see your thoughs ^^ I need to think about it, I'm not even sure of understanding what's an index ^^'

How does indexing by published_date work?

good question, need to see how an index is build currently. What do we have as indexes at the moment?

I do see value in anding tags. I have mixed feelings about whether we should actually support it or not. If we do, I don't think we need to support it in the first release of this.

I see the value too, it's just the combinatorial that scares me. Maybe a config to limit how many tags are andable at one time? With a warning on the terminal if the number is greater than 2 tags?

epage commented 6 years ago

How do we define the hierarchy?

This was more about

On a related note:

Nope, it was a first post to see your thoughs ^^ I need to think about it, I'm not even sure of understanding what's an index ^^'

By index, I mean a page that the user writes where they intend to list out every item within the section of the hierarchy they are in.

Some systems treat the index as a special page. Other systems don't care and it can be any page.

My expectation has been that index and pagination configuration would end up living in the index's frontmatter. It could then be globally configured by setting default frontmatter fields. That doesn't mean it has to.

If every page can be an index/paginated, we'll need to watch out for how people can globally define default frontmatter for this without turning every page into an index.

It seems the paginate_path takes care of it

  1. Why not just use the permalink
  2. This question is meant to be more about defining the whole behavior and not just the field used.
    • What are the variables and how do they behave under different situations?
    • If any page can be an index, how do you differentiate between the current page's category vs the category is is a part of? Same with tags and published_date

How does the user access the child pages? How does the user access the child indexes?

Paginator object

What does this paginator object look like? Of the ones you linked, I didn't see anything regarding child indexes. Also, how does pagination apply to child indexes? Not at all?

For the moment, I'm thinking something like Jekyll: everything is paginated once the configuration has been switched on.

We'll want to eventually write up specifically how this applies to cobalt, particularly the fact that the jekyll paginator is no longer developed though there seems to be other paginator plugins

Geobert commented 6 years ago

How do you select what you are indexing (published date, tags, category)

some configuration in _cobalt?

index: [date, tags, category]

or maybe

index:
    date:
        per_page: 10
        permalink: "/{{ year }}/{{ month }}/p{{ num }}"
    tags:
        per_page: 20
        permalink: "/tags/{{ tag }}/p{{ num }}"
    categories:
        per_page: 20
        permalink: "/categories/{{ categories }}/p{{ num }}"

where categories are defined like in https://github.com/cobalt-org/cobalt.rs/issues/131

so we'll have /categories/MainCat1/SubCat1/p{{ num }}, /categories/MainCat1/SubCat2/p{{ num }}, /categories/MainCat2/SubCat3/p{{ num }}

If we support nested indexing, how do you define it

Nested? Now that I understand what an index is, what do you mean by nesting them? An index listing by date that include another .liquid file that is an index listing on tags for exemple?

My expectation has been that index and pagination configuration would end up living in the index's frontmatter. It could then be globally configured by setting default frontmatter fields. That doesn't mean it has to.

So a page will be an index if it has index/pagination configuration in its frontmatter? But in this case, how the global config will behave?

What are the variables and how do they behave under different situations? If any page can be an index, how do you differentiate between the current page's category vs the category is is a part of? Same with tags and published_date What does this paginator object look like? Of the ones you linked, I didn't see anything regarding child indexes. Also, how does pagination apply to child indexes? Not at all?

paginator.date.posts : all posts ordered by dates
paginator.date.next_page/prev_page : permalink to next/prev page

paginator.date.[year].posts : all posts for year
paginator.date.[year].next_page/prev_page

paginator.date.[year][month] : all posts for month
paginator.date.[year][month].next_page/prev_page

paginator.tags.[tag].posts : all posts for tag
paginator.tags.[tag1][tag2].posts : all posts that have both tag1 and tag2
paginator.tags.[tag].next_page/prev_page
paginator.tags._all : all the tags

I don't know if [tag1][tag2] is feasible or not but this is a first try :)

epage commented 6 years ago

Thanks for continuing to look into this!

Could you collect all of your thoughts into an RFC issue so we can see how all of the pieces fit together?

Geobert commented 6 years ago

What's an RFC issue?

epage commented 6 years ago

Basically open an issue that is just us planning this feature. The issue will be the proposal and we'll edit it as we refine the idea.

Kind of like what I've been doing with https://github.com/cobalt-org/cobalt.rs/issues/301 and other planning issues.

Geobert commented 6 years ago

At least, catched some time to do this https://github.com/cobalt-org/cobalt.rs/issues/395 ^^

Geobert commented 6 years ago

Shall we close this and do it in #395 ?

epage commented 6 years ago

Yeah, seems like we could close this for #395.