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

Emotion, material-ui, and typescript may lead to excessively deep type instantiation that could potentially be infinite

I encountered an issue when styling a component imported from the Material-UI library using the styled API (@emotion/styled). Error:(19, 5) TS2589: Type instantiation is excessively deep and possibly infinite. Despite attempting to downgrade to typescript ...

Differentiate among comparable values through placement regex

I'm currently tackling a challenge involving regex as I work on breaking down shorthand CSS code for the font property. Here is my progress thus far: var style = decl.val.match(/\s*(?:\s*(normal|italic|oblique)){1}/i); style = style ? style ...

Improving code efficiency for checkboxes in upcoming TypeScript versions

Is it possible to create a single checkbox component and dynamically pass different values to it without repeating code? I have set up these checkboxes to help me check the maximum and minimum values of some API data. const[checkValMax, setCheckValMax]= u ...

Is there a way for me to programmatically modify a .env file using an npm script?

Currently, I'm managing a project with a .env file that contains confidential information. One of the key elements in this file is 'STATUS'. Just to clarify, this pertains to a Discord bot, The value assigned to the 'STATUS' var ...

Is it best practice to initialize loaded scripts before the JQuery .load callback is called or should it be done after the .ready callback in the loaded script?

When I click a button in my main document, I load the content of a specific div using jQuery: $("#my_div").load(function() { alert("Content Loaded"); }); The loaded content contains a script: <script> alert("Initial Alert from External Script" ...

The deployment of my Node application on Heroku is causing an error message: node-waf is not

I've been trying to deploy my Node.js application on Heroku by linking it to my Github repository and deploying the master branch. Despite experimenting with various methods, I keep encountering the same error every time. You can view the detailed b ...

How to retrieve a string from a regular expression in Javascript without [Object object] output

Within my code, there exists a parent form component and a child component used for auto-completing text input. The Parent component passes an array of objects named autoCompTxt, consisting of name and id fields, to the Child component. //Parent: const [ob ...

Incorporating JavaScript unit tests into an established website

I am facing a challenge with testing my JavaScript functions in the context of a specific webpage. These functions are tightly integrated with the UI elements on the page, so I need to be able to unit-test the entire webpage and not just the functions them ...

"Using JavaScript to trigger a button click event, and then

I have a question that I think may sound silly, but here it is. I have this code snippet: <script type="text/javascript"> $(document).ready(function(){ var email_value = prompt('Please enter your email address'); if(email_value !== null){ ...

Using JSF 2.1 for Ajax autocomplete with server search triggered only when user pauses typing

Currently, I am working on developing an autocomplete feature that involves database search based on user input events (specifically onkeyup) in a <h:inputText />. There are two specific preconditions that need to be met for the application to perfo ...

Encountering the AngularJS .Net Core routing $injector:modulerr error

I'm currently learning about .Net Core and AngularJS by following tutorials. However, I've encountered an error while attempting to implement client routing in the newest version of .Net Core with default configuration. The AngularJS error I rece ...

Using Backbone to Handle Different Data Formats

I have a unique text file containing date-time data in the format below: 2014-03-14T16:32 2014-03-15T13:04 2014-03-16T06:44 ... I want to use this static file as a read-only data source for my backbone collection. However, the current format is not suita ...

Why is the autocomplete minlength and maxheight not functioning properly in MVC?

After entering a value in the text field, data from the database appears but adjusting the height and width of the list box seems to be a challenge. I have set the parameters like minLength: 0, maxItem: 5, but it doesn't seem to make a difference. ...

Show information retrieved from fetch api

Hi there! I've been trying to fetch data from the Avascan API and display it on my HTML page, but so far, I haven't had any luck. I've experimented with using the Fetch API, JSON, and AJAX methods, but none of them seem to work for me. Do yo ...

I am facing an issue where an AJAX post to Express is not returning any data to req.query. I have tried various solutions but nothing seems to

I have encountered an issue with my setup where the body is empty when sending data through ajax. In Chrome's network tab, I can see the post and content with the correct payload: {"EventName":"asd","PrivacyLevel":1,"TypeInt":1,"ExpectedDate":"asd"," ...

Is there a way to retrieve metadata from a web URL, like how Facebook automatically displays information when we share a URL in a status update?

Is there a way to fetch metadata such as title, logo, and description from a website URL using AngularJS or JavaScript? I am looking for a solution similar to Facebook's status update feature that automatically loads metadata when you paste a website ...

Dealing with encoding problems in Node.JS when parsing JSON data with UTF-

I have developed a small script that allows me to fetch keyword suggestions from the Google search API. One major issue I am facing is when the response contains special characters (such as à é ù etc.): my application returns unreadable keywords like: ...

Enhancing PHP function speed through pre-compilation with Ajax

I am curious about compiling server side functions in PHP with Ajax, specifically when multiple asynchronous calls are made to the same server side script. Let's consider a PHP script called "msg.php": <?php function msg(){ $list1 = "hello world ...

Discovering the magic of activating a JavaScript function on jQuery hover

I need to call a JavaScript function when hovering over an li element. var Divhtml='<div>hover</div>'; $('li a').hover(function(){ $(this).html(Divhtml); //I want to trigger hovercall(); wh ...

Guide to generating customized CSS styles on-the-fly in Vue (similar to Angular's dynamic styling capabilities)

When working with Angular, we have the capability to dynamically set CSS properties. For example: <style ng-if="color"> .theme-color { color: {{color}}; } .theme-background-color { background-color: {{color}}; } .theme-border-color { border-color: { ...