您如何按包含标签的帖子数量对博客帖子标签列表进行排序(在 Eleventy 中使用 Nunjucks)?

Posted

技术标签:

【中文标题】您如何按包含标签的帖子数量对博客帖子标签列表进行排序(在 Eleventy 中使用 Nunjucks)?【英文标题】:How do you sort a list of blog post tags by the number of posts that contain the tag (using Nunjucks in Eleventy)? 【发布时间】:2021-11-10 20:41:36 【问题描述】:

我有一个用 Eleventy(静态站点生成器)构建的博客,使用 Nunjucks 作为模板语言。

我有一个页面列出了我分配给我的帖子的所有标签。它按字母顺序列出它们,每个标签的帖子数。

我还想做的是按频率顺序列出标签(最常用的标签在前)。

用于获取字母列表(带计数)的代码如下所示:

<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>

现在的结果是这样的:

搅拌机 (1) 船 (2) 炸弹工厂 (1) 篝火 (4) 书籍 (3)

但我希望它是:

篝火 (4) 书籍 (3) 船 (2) 搅拌机 (1) 炸弹工厂 (1)

(您可以在此部署预览站点查看实际结果:https://text-timeline--davidrhoden-basic.netlify.app/tagslist/。)

我尝试将dictsort 更改为sort(attribute="posts2.length"),以及其他可能有意义的排列,例如sort(attribute="length"),但没有任何效果。

我猜“长度”不是帖子本身的属性。所以也许像sort 这样的过滤器在这种情况下不起作用。

但是有没有办法按照这些帖子数对这个列表进行排序?肯定有的。我是否需要引入类似 lodash 的东西,或者像 map 这样的 javascript 函数?

【问题讨论】:

【参考方案1】:

您也许可以使用Eleventy custom collections 来做您想做的事。我们可以在.eleventy.js文件中使用Javascript来统计每个标签的帖子数,然后按照帖子数对数据进行排序。

由于 Eleventy 似乎没有给我们一个预先分组的标签和帖子对象,我们正在自己做。这确实意味着,如果您在一篇文章上放置重复的标签,它将被计算两次。可以对标签进行重复数据删除,但如果你小心的话,这应该不是问题。

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

  // addCollection receives the new collection's name and a
  // callback that can return any arbitrary data (since v0.5.3)
  eleventyConfig.addCollection('bySize', (collectionApi) => 
    // see https://www.11ty.dev/docs/collections/#getall()
    const allPosts = collectionApi.getAll()

    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
    const countPostsByTag = new Map()
    allPosts.forEach((post) => 
      // short circuit eval sets tags to an empty array if there are no tags set
      const tags = post.data.tags || []
      tags.forEach((tag) => 
        const count = countPostsByTag.get(tag) || 0
        countPostsByTag.set(tag, count + 1)
      )
    )

    // Maps are iterators so we spread it into an array to sort
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
    const sortedArray = [...countPostsByTag].sort((a, b) => b[1] - a[1])
    
    // this function returns an array of [tag, count] pairs sorted by count
    // [['bonfires', 4], ['books', 3], ['boats', 2], ...]
    return sortedArray
  )
  )

  return 
    // ...
  

然后我们可以通过collections.bySize 在 Nunjucks 中使用这些数据。

<section id="tags-number-of-posts">
    # we can still destructure the tag name and count even though it's an array #
    % for tag, count in collections.bySize %
        % set tagUrl %/tags/ tag | slug /% endset %
        <a href=" tagUrl | url "> tag  ( count )</a><br/>
    % endfor %
</section>

如果您需要在集合对象中包含帖子数组而不仅仅是帖子数量,也可以修改 JavaScript 来实现。

【讨论】:

我再也没有回来发表评论,但这对我来说效果很好。这是标签列表,按字母顺序或每个标签的帖子数排序:davidrhoden.com/tagslist

以上是关于您如何按包含标签的帖子数量对博客帖子标签列表进行排序(在 Eleventy 中使用 Nunjucks)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在包含图像和计数帖子的页面中创建列表标签

新的 Instagram API,如何按标签获取帖子

如何创建单个 Gatsby 页面以按标签/类别显示和过滤所有博客文章

如何在 Flask 视图中使用多对多字段?

sqlalchemy,使用反向包含(不在)子列值列表中进行选择

Wordpress 插件 - 按帖子数量对用户进行排名