I am trying to organize a list of blog post tags in Eleventy using Nunjucks based on the number of posts that each tag contains. Can you help me figure out

I currently manage a blog using Eleventy as the static site generator, with Nunjucks as the templating language.

One of the features on my site is a page that displays all the tags assigned to my posts in alphabetical order along with the number of posts per tag.

However, I am now looking to rearrange the tags based on their frequency, starting with the most-used tags at the top.

The code snippet responsible for generating the current alphabetical list with post counts is:

<section id="tags-number-of-posts">
  {% for tag2, posts2 in collections | dictsort %}
  {% set tag2Url %}/tags/{{ tag2 | slug }}/{% endset %}
   <a href="{{ tag2Url | url }}">{{ tag2 }} ({{ posts2 | length }})</a><br/>
  {% endfor %}
</section>

Currently, the displayed result looks like this:

Blender (1)
boats (2)
Bomb Factory (1)
bonfires (4)
books (3)

but I would prefer it to be sorted by frequency like this:

bonfires (4)
books (3)
boats (2)
Blender (1)
Bomb Factory (1)

(The live version can be viewed at: .)

I have attempted changing the dictsort to

sort(attribute="posts2.length")
, among other variations, but without success.

It seems that 'length' is not an attribute I can sort by directly. Is there a way to achieve this kind of sorting based on post counts? Should I consider incorporating lodash or employing a JavaScript function like map?

Answer №1

To achieve your desired outcome, consider utilizing Eleventy custom collections. By leveraging Javascript within the .eleventy.js file, you can accurately calculate the count of posts under each tag and subsequently organize the data based on post count.

While Eleventy doesn't automatically provide a pre-organized object of tags and posts, this information can be manually curated. However, it's important to note that duplicates in tags may result in inaccurate counts unless they are deduplicated cautiously.

// .eleventy.js
module.exports = function (eleventyConfig) {
  // ...

  // addCollection is used to create a new collection with arbitrary data (since v0.5.3)
  eleventyConfig.addCollection('bySize', (collectionApi) => {
    const allPosts = collectionApi.getAll()

    const countPostsByTag = new Map()
    allPosts.forEach((post) => {
      const tags = post.data.tags || []
      tags.forEach((tag) => {
        const count = countPostsByTag.get(tag) || 0
        countPostsByTag.set(tag, count + 1)
      })
    })

    const sortedArray = [...countPostsByTag].sort((a, b) => b[1] - a[1])

    return sortedArray
  })
  })

  return {
    // ...
  }
}

Once the sorting is done, Nunjucks can access this data using collections.bySize.

<section id="tags-number-of-posts">
    {% for tag, count in collections.bySize %}
        {% set tagUrl %}/tags/{{ tag | slug }}/{% endset %}
        <a href="{{ tagUrl | url }}">{{ tag }} ({{ count }})</a><br/>
    {% endfor %}
</section>

If you require the array of posts in addition to post counts within your collections object, adjustments can be made in the JavaScript code accordingly.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to invoke an Angular2 function from within a Google Map infowindow?

I am currently working on integrating Google Maps using javascript in a project, and I'm facing a challenge. I want to call an Angular2 function inside an infowindow as shown in the code snippet below. Pay attention to the infoContent variable that co ...

How many server queries does a single web application require?

As someone new to web app development, my main goal is to optimize speed as much as possible. I am faced with two options: The first option is to fetch data from the database individually every time a refresh is needed in the app. Alternatively, I c ...

Troubleshooting Java REST service integration in AngularJS for UPDATE and DELETE operations

After successfully implementing a REST service with Java and testing all HTTP methods using Postman, I decided to explore AngularJS. Upon integrating it to consume the REST service, I encountered issues specifically with the Delete and Put methods not func ...

Incorporating jquery-ui Datepicker with dynamic text input functionality

In my table list, I have multiple input fields with the jQuery datepicker implemented. Each input field is assigned the class "datepicker" and a unique ID number. When clicked on, the datepicker pops up allowing for date selection to be inserted into the f ...

The Vue.js router is malfunctioning

After searching through several posts on Stackoverflow about issues with routes not functioning properly, I have yet to find a solution for why my routes are not working. This is how my router looks: import Vue from 'vue' import Router from &ap ...

Is it possible for users to circumvent limitations on specific routes or pages in a Vue.js application by exploiting the fact that all the code is processed on the client

When developing a single page application utilizing technologies like Firebase, do API keys remain hidden from users since all code is executed on the client side? Additionally, given that users are limited to specific routes or pages based on conditions ...

Initiating a file download using HTML

When I try to initiate a download by specifying the filename, instead of downloading, it opens in a new tab. The code snippet below shows what I am currently using. Additionally, I am working on Chrome Browser. <!DOCTYPE html> <html> < ...

The issue of the selection option not being cleared after being set to 0 persists in JavaScript

I am facing an issue where I need to reset the select option to `0` when another option is selected. I have tried the code below for this purpose. if (varALPO1MobNum == "0") { var selectElement = $(&apo ...

I can't seem to retrieve any values from the API other than "chicken"

Is there a way to make the search bar in my recipe app look for recipes that I provide, rather than fetching data from useState? Any suggestions on how I can achieve this? import React, { useEffect, useState } from 'react'; import Recipe from &ap ...

Showcase fullcalendar events that span across multiple rows and columns

Within my Angular application, I am utilizing the Angular UI Calendar in conjunction with Fullcalendar to display user events. Currently, when a user interacts with an event by clicking on it, only a portion of the event is highlighted. This becomes probl ...

Exploring data elements using iteration in JavaScript

Here is some code that is functioning properly: Morris.Bar({ element: 'barchart', axes: true, data: [ json.bar.bar1 ], xkey: 'x', ykeys: ['y', 'z', ' ...

Experiencing problems with malfunctioning javascript tabs

As a beginner user and coder, I'm currently working on creating a portfolio website. I had the idea to implement tabs that would allow for content swapping, but unfortunately, I'm having trouble getting the JavaScript to function correctly. I at ...

Tips for Enhancing JavaScript Performance

Is there a way to enhance my JavaScript code like this: $(window).scroll(function() { if ($('#sec1').isVisible()) { $('.js-nav a.m1').addClass('active'); } else { $('.js-nav a.m1').removeClas ...

Is there a problem with addEventListener returning false?

What does keeping the third parameter as false in the line below signify? var el = document.getElementById("outside"); el.addEventListener("click", modifyText, false); ...

Exploring Symfony2 controller integration with Javascript arguments

I am currently working on a project with Symfony2 and I have a question regarding receiving arguments from a template in a controller. My goal is to take the value of the argument and store it in the database. The argument's value will be generated by ...

Exploring the Power of jQuery Deferreds and Promises through Multiple getJSON Requests

I'm currently exploring the concept of jquery deferred/promises. I have a decent grasp on how to handle one ajax call, but I'm struggling with managing multiple ajax calls simultaneously. Here is a link to a jsfiddle showcasing my attempt: http:/ ...

Implementing pagination within nested ng-repeat in Angular app

I am currently utilizing Angular along with the Material library in my project. I am facing an issue with two nested ng-repeat loops within md-tables. The problem lies in the fact that the variable is getting overridden with each request in the nested loop ...

Pressing the button will activate the Ctrl+z and Ctrl+y key commands

I have created two separate buttons for triggering actions equivalent to pressing Ctrl+z and Ctrl+y. I am attempting to make these actions occur with the click of a single button. However, when trying to set up the functionality to trigger Ctrl+z and Ctr ...

Wheelnav.js implementing a dynamic bouncing animation

I'm currently in the process of working on a pie menu with wheelnav.js and everything is going smoothly so far. However, I can't seem to find any information in the wheelnav.js documentation on how to eliminate the bouncing effect when a menu cho ...

Improving sharing functionality across multiple VuGen scripts executed through Performance Center

I have multiple VuGen scripts that utilize the Web/HTTP protocol with javascript. Currently, I am using VuGen 12.53 (patch 4) and have a common login.js action in all of my scripts. Whenever I need to make changes to the login action, I have to update ever ...