如何在Eleventy模板循环中排序全局数据并优化访问?
解决Eleventy+Liquid站点的两个数据处理问题
问题2:优化数据访问方式(解决{% for key,val in books %}非法标签错误)
当src/_data/books目录下存放多个独立JSON文件时,Eleventy会自动将这些文件合并为键值对对象(键为JSON文件名,值为文件内容)。出现非法标签错误,大概率是所用Liquid版本不支持key, val的对象遍历语法,或是数据结构处理方式不对。
两种可行解决方法:
将对象转为数组遍历
在.eleventy.js中添加自定义过滤器,把books对象转换成包含文件名和内容的数组:module.exports = function(eleventyConfig) { eleventyConfig.addFilter('objToArray', function(obj) { return Object.entries(obj).map(([key, value]) => ({ filename: key, ...value })); }); };模板中调用方式:
{% assign booksArray = books | objToArray %} {% for book in booksArray %} <!-- 直接访问book.title、book.date等属性,无需book[1] --> <h3>{{ book.title }}</h3> <p>发布日期:{{ book.date }}</p> {% endfor %}升级Liquid或调整Eleventy配置
若项目依赖的liquidjs版本低于v9.0,可能不支持for key, val in object语法。可以升级依赖,或在.eleventy.js中指定使用新版Liquid引擎:const Liquid = require("liquidjs"); module.exports = function(eleventyConfig) { let liquidEngine = new Liquid({ dynamicPartials: true, strictFilters: true }); eleventyConfig.setLiquidOptions({ engine: liquidEngine }); };配置完成后即可直接遍历对象:
{% for filename, book in books %} <h3>{{ book.title }}</h3> {% endfor %}
问题1:修复sortByDate过滤器不生效的问题
自定义过滤器失效通常是因为注册错误、日期字段类型不对、排序逻辑有误这三类原因。
正确实现步骤:
注册正确的日期排序过滤器
在.eleventy.js中添加过滤器,注意要把JSON中的日期字符串转为Date对象再做比较:module.exports = function(eleventyConfig) { eleventyConfig.addFilter('sortByDate', function(collection) { return collection.sort((a, b) => { // 假设JSON中日期字段为date,格式如"2024-05-20" const dateA = new Date(a.date); const dateB = new Date(b.date); // 降序排列(最新内容在前),升序则改为dateA - dateB return dateB - dateA; }); }); };结合数组转换使用过滤器
先将books对象转为数组,再应用排序过滤器:{% assign sortedBooks = books | objToArray | sortByDate %} {% for book in sortedBooks %} <div> <h4>{{ book.title }}</h4> <p>{{ book.date }}</p> </div> {% endfor %}排查常见坑点
- 确认JSON中的日期格式合法(如
YYYY-MM-DD),否则new Date()会返回无效日期,导致排序混乱。 - 检查过滤器名称拼写是否完全一致(模板与
.eleventy.js中的名称必须匹配)。 - 确保排序的目标是数组,原始对象无法直接使用排序过滤器。
- 确认JSON中的日期格式合法(如
内容的提问来源于stack exchange,提问作者Chris Barr
相关产品推荐
相关产品推荐

