如何在Hugo中通过输入框筛选数值型标签(年份范围)
解决方案:用JavaScript实现Hugo年份范围筛选
Hugo是静态站点生成器,模板代码仅在构建阶段执行,无法在浏览器运行时获取输入框的值来触发模板逻辑。因此需要通过前端JavaScript实现运行时的筛选功能,具体步骤如下:
1. 更新HTML结构(添加双年份输入框)
替换原有单个输入框,新增年份上下限输入框和筛选按钮,同时调整结果展示容器:
<div class="year-filter"> <input id="min-year" type="number" placeholder="起始年份" class="form-control" /> <input id="max-year" type="number" placeholder="结束年份" class="form-control" /> <button id="filter-btn" class="btn btn-primary">筛选</button> </div> <!-- 筛选结果展示容器 --> <div id="filtered-results" class="container"></div> <!-- 原始全量标签列表(可默认显示或隐藏) --> <section id="menu" class="original-tags"> <ul> {{ range $key, $taxonomy := .Site.Taxonomies.tags }} <li> {{ $key }} </li> <ul> {{ range $taxonomy.Pages }} <li hugo-nav="{{ .RelPermalink}}"><a href="{{ .Permalink}}"> {{ .LinkTitle }} </a> </li> {{ end }} </ul> {{ end }} </ul> </section>
2. 预存分类数据到全局变量
在页面底部(</body>标签前)添加脚本,将Hugo生成的标签数据转为JavaScript可访问的对象:
<script> // 把Hugo的标签分类数据转为JS全局变量 window.taxonomyData = {{ .Site.Taxonomies.tags | jsonify }}; </script>
3. 编写JavaScript筛选逻辑
同样在页面底部添加筛选逻辑代码,实现输入值获取、范围验证、标签筛选和结果渲染:
<script> // 获取DOM元素 const minYearInput = document.getElementById('min-year'); const maxYearInput = document.getElementById('max-year'); const filterBtn = document.getElementById('filter-btn'); const resultsContainer = document.getElementById('filtered-results'); const originalTags = document.getElementById('menu'); // 核心筛选函数 function filterByYearRange() { // 转换输入值为数字 const minYear = parseInt(minYearInput.value); const maxYear = parseInt(maxYearInput.value); // 输入合法性验证 if (isNaN(minYear) || isNaN(maxYear) || minYear > maxYear) { resultsContainer.innerHTML = '<p>请输入有效的年份范围(起始年份 ≤ 结束年份)</p>'; return; } // 筛选符合范围的标签(假设标签为纯年份字符串,如"2020") const filteredTags = Object.entries(taxonomyData).filter(([tagName, pages]) => { const tagYear = parseInt(tagName); return !isNaN(tagYear) && tagYear >= minYear && tagYear <= maxYear; }); // 处理无匹配结果的情况 if (filteredTags.length === 0) { resultsContainer.innerHTML = '<p>该年份范围内没有匹配的标签</p>'; return; } // 构建结果HTML let resultHtml = '<ul>'; filteredTags.forEach(([tagName, pages]) => { resultHtml += `<li>${tagName}`; resultHtml += '<ul>'; pages.forEach(page => { resultHtml += `<li hugo-nav="${page.RelPermalink}"><a href="${page.Permalink}">${page.LinkTitle}</a></li>`; }); resultHtml += '</ul></li>'; }); resultHtml += '</ul>'; // 展示结果并隐藏原始列表 resultsContainer.innerHTML = resultHtml; originalTags.style.display = 'none'; } // 绑定触发事件:点击按钮或输入框回车 filterBtn.addEventListener('click', filterByYearRange); minYearInput.addEventListener('keydown', (e) => e.key === 'Enter' && filterByYearRange()); maxYearInput.addEventListener('keydown', (e) => e.key === 'Enter' && filterByYearRange()); </script>
补充说明
- 如果你的标签格式不是纯年份(如
year-2020),需要调整parseInt(tagName)的逻辑,比如通过正则提取数字部分:const tagYear = parseInt(tagName.match(/\d+/)[0]); - 可根据需求调整样式,比如输入框布局、结果展示的排版
- 若需要默认显示全量标签,可保持
originalTags默认显示,筛选后隐藏即可
内容的提问来源于stack exchange,提问作者Britta
相关产品推荐
相关产品推荐

