Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do you list all posts grouped by year? #1284

Closed
logicman opened this issue Jun 24, 2020 · 6 comments
Closed

How do you list all posts grouped by year? #1284

logicman opened this issue Jun 24, 2020 · 6 comments

Comments

@logicman
Copy link

I am using the Eleventy-base-blog and on the archive page it lists all the posts in chronological order.
This is the folder structure. All 2010 .md files are in the /posts/2010/ folder. And so on...

/posts/2010/
/posts/2011/
/posts/2012/
.....

The archived page works perfectly however, I want to group all 2010 posts together under the heading 2010. Then, all 2011 posts under 2011.....any idea how to achieve this or point me in the right direction?

Thanks!

@logicman
Copy link
Author

It works and I think I got this one with some nunjucks code :)
So, in my postlist.njk I wrote this:

<ol reversed>
{% set currentYear = "" %}
{% for post in postslist | reverse %}
{% if showYear %}
      {% set postYear = post.date.getFullYear() %}
      {% if currentYear != postYear %}
      {% set currentYear = postYear %}
      <h3>{{ postYear }}</h3>
      {% endif %}
{% endif %}
  <li class=" mb-10 list-none">
    <h2><a href="{{ post.url | url }}">{% if post.data.title %}{{ post.data.title }}{% else %}<code>{{ post.url }}</code>{% endif %}</a></h2>
  </li>
{% endfor %}
</ol>

And, in the archive.njk file I have this:

<h1>Blog</h1>
{% set showYear = true %}
{% set postslist = collections.posts %}
{% include "postslist.njk" %}

The output is:

2012
Blog post 1
Blog post 2

2011
Blog post 1
Blog post 2

2010
Blog post 1
Blog post 2

This way, my index.njk which also lists the latest 10 posts won't show the date as I don't have the showYear.

Is this the best way to achieve this?

Thanks!

@davidrhoden
Copy link

I don't know if it's the best way, but it solved my issue nicely. What's the correct way to get data to a layout so I can do a "groupby" on it? #15

@darekkay
Copy link

Another variant is described in #316

I came up with my own solution:

const _ = require("lodash");

eleventyConfig.addCollection("postsByYear", (collection) => {
  return _.chain(collection.getAllSorted())
    .groupBy((post) => post.date.getFullYear())
    .toPairs()
    .reverse()
    .value();
});
{% for year, yearPosts in collections.postsByYear %}
  <h2>{{ year }}</h2>
  <ul>
    {% for post in yearPosts | reverse %}
      <li>{{ post.data.title }}</li>
    {% endfor %}
  </ul>
{% endfor %}

I have written a blog post with more explanation.

@deerawan
Copy link

deerawan commented Feb 1, 2022

Based on @darekkay but without lodash

config.addCollection("postsByYear", (collection) => {
  const posts = collection.getFilteredByTag('post').reverse();
  const years = posts.map(post => post.date.getFullYear());
  const uniqueYears = [...new Set(years)];

  const postsByYear = uniqueYears.reduce((prev, year) => {
    const filteredPosts = posts.filter(post => post.date.getFullYear() === year);

    return [
      ...prev,
      [year, filteredPosts]
    ]
  }, []);

  return postsByYear;
});

@sasrit
Copy link

sasrit commented Jun 13, 2022

Hey everyone, I am currently using @darekkay s version and it works as intended, but I started to add multilingual support now. To sort by language I filter by folder. Is there a quick way to add a filter for a folder to that? Sorry, my javascript is too bad at the moment to figure that one out by myself, as I just started learning js. I guess I could create a folder for each year and get it this way, but there has to be a more sophisticated way to do that all at once, right?

my language filter atm:
eleventyConfig.addCollection("postsDE", function(collection) { return collection.getFilteredByGlob("./src/de/blog/**/*.md").filter((item) => { return !item.data.draft && item.date <= now; }).reverse() });

@zachleat
Copy link
Member

This is an automated message to let you know that a helpful response was posted to your issue and for the health of the repository issue tracker the issue will be closed. This is to help alleviate issues hanging open waiting for a response from the original poster.

If the response works to solve your problem—great! But if you’re still having problems, do not let the issue’s closing deter you if you have additional questions! Post another comment and we will reopen the issue. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants