使用Alpine JS/11ty/Nunjucks筛选并显示最近两个即将到来的事件的实现问题
Alpine JS/11ty/Nunjucks筛选并显示最近两个即将到来的事件的实现问题
看起来你遇到的核心问题是先取前2个事件再过滤过期项的逻辑顺序错了——如果前两个事件里有已经过期的,前端用x-show隐藏后就只剩1个甚至0个显示,但实际上后面可能还有未过期的事件没被选中。
正确的思路应该是先在Nunjucks(也就是11ty的后端渲染阶段)完成以下三步:
- 过滤出所有未过期的事件(日期≥今天)
- 把这些未过期事件按日期从小到大排序(最近的排在最前面)
- 取排序后的前2个事件来渲染
这样前端拿到的直接就是符合要求的内容,不需要再用x-show做二次过滤,也不会出现显示数量不足的情况。具体实现代码如下:
<div class="flex-auto lg:w-1/3" x-data="{ currentDate: new Date().toISOString().slice(0, 10) }"> <h3>Our Next Events</h3> <!-- 修正了你原来标签闭合错误:把</p>改成了</h3> --> {% set today = "now" | date("YYYY-MM-DD") %} {# 1. 过滤出所有未过期的事件 #} {% set upcomingEvents = events.items | filter(item => item.date >= today) %} {# 2. 按日期升序排序(最近的事件排在最前面) #} {% set sortedUpcoming = upcomingEvents | sort(true, false, "date") %} {# 3. 取前2个事件 #} {% set nextTwoEvents = sortedUpcoming | slice(0, 2) %} {% for item in nextTwoEvents %} <h4 class="mb-6">{{ item.date | asPostDate }}<br>{{ item.description | safe }}</h4> {% endfor %} {# 可选:如果没有即将到来的事件,显示提示文案 #} {% if nextTwoEvents.length === 0 %} <p>No upcoming events scheduled at this time.</p> {% endif %} <p class="text-lg"> <a class="rounded-sm p-2 bg-yellow-800 px-4 cursor-pointer hover:font-normal px-10 text-md hover:bg-yellow-700 no-underline font-sans text-white" href="/events/#special">see all events</a> </p> </div>
关键逻辑说明:
{{ "now" | date("YYYY-MM-DD") }}:用11ty内置的date过滤器把当前日期转成和item.date一致的YYYY-MM-DD格式(如果你的item.date是ISO带时间的格式,比如2024-05-20T10:00:00Z,可以把today也转成YYYY-MM-DD,字符串直接比较就能判断日期先后)filter(item => item.date >= today):只保留日期大于等于今天的事件sort(true, false, "date"):true表示升序排序(最近的在前),最后一个参数是排序的字段dateslice(0, 2):截取排序后的前2个事件
这种后端提前处理的方式不仅能解决你现在的显示问题,还比前端用x-show隐藏更高效——不会把过期事件的HTML渲染到页面里,也减少了前端的逻辑判断。
备注:内容来源于stack exchange,提问作者Dan Sinker
相关产品推荐
相关产品推荐

