HugoDoks修改Flexsearch

之前在选择静态文档框架时找到了 Doks,但其搜索有问题,而且使用的人少,相关文章基本为 0 就搁置了,今天有空尝试解决了搜索问题,想来可以用起来了。

修改Flexsearch

这里中文支持主要是三个问题:

  1. 配置 Flexsearch,使搜索框架支持中文分词。

  2. 修正 Doks 搜索功能结果显示错误问题。

  3. 注释代码块导致的 js 文件加载出错

对于 Doks 的 child theme 是无法进行配置的,至少我没能找到相关配置文件,所以我直接使用的完整版。配置文件路径在:assets/js/index.js

对于第一个问题需要修改 FlexSearch 初始化的代码块:

var index = new FlexSearch.Document({
cache: 100,
document: {
    id: 'id',
    store: [
    "href", "title", "description"
    ],
    index: ["title", "description", "content"]
},
// Insert language specific settings below — e.g. Latin
encode: str => str.split("")
});

这是修改后的代码,改动主要在追加了一行 encode: str => str.split("") (这里和官方不一样,官方的使用后将只支持中文,因为replace是将非中文替换为空串),同时删除了一行:tokenize: “forward”, 可自行对比原文件。

对于第二个问题:这个原因在于显示结果时,只用了最外层循环导致结果显示不全,同时对于搜索结果的清除存在逻辑错误。主要函数为 index.js 中的 show_results() ,直接整块替换即可(这里检索的内容包括了title、description、以及content,可自行从数组中移除不需要进行检索的):

function show_results() {
  var value = this.value;
  var results = index.search(value, { limit: 5, index: ["title","content","description"], enrich: true });
  var entry, childs = suggestions.childNodes;

  suggestions.classList.remove("d-none");
  suggestions.innerHTML = "";
  results.forEach(function (res) {
    res.result.forEach(function (result) {
      entry = document.createElement("div");

      entry.innerHTML = "<a href><span></span><span></span></a>";

      (a = entry.querySelector("a")),
        (t = entry.querySelector("span:first-child")),
        (d = entry.querySelector("span:nth-child(2)"));

      console.log(results);

      a.href = result.doc.href;
      t.textContent = result.doc.title;
      d.textContent = result.doc.description;

      suggestions.appendChild(entry);
    });
  });
}

对于第三个问题,我表示很意外,一个开源项目,居然没人发现这个问题,直接删除中间那段注释代码即可:

其他部分未做修改。

此外关于 Flexsearch 的配置项,可通过右键直接查看部署后的 index.js 会看到其内容与以下代码相关:

这里举例说明一下:

document: {
    id: 'id',
    store: [
    "href", "title", "description"
    ],
    index: ["title", "description"]
    // index: ["title", "description", "content"]
},

可以看到,这里我注释了对于 content 字段的检索,那么在用的时候也就得由之前的

var results = index.search(value, { limit: 5, index: ["content"], enrich: true }); 

改为:

var results = index.search(value, { limit: 5, index: ["description"], enrich: true });

此时将主要由 description 字段进行检索匹配,以上。

配置问题

我这里修改完了之后还是不行,看了下 问题还是主要在assets/js/index.js 中间有个模版那里,这里配置:

 {{ $list := slice }}
  {{- if and (isset .Site.Params.options "searchsectionsindex") (not (eq (len .Site.Params.options.searchSectionsIndex) 0)) }}
  {{- if (in .Site.Params.options.searchSectionsIndex "ALL") }}
  {{- $list = .Site.Pages }}
  {{- else }}
  {{- $list = (where .Site.Pages "Type" "in" .Site.Params.options.searchSectionsIndex) }}
  {{- if (in .Site.Params.options.searchSectionsIndex "HomePage") }}
  {{ $list = $list | append .Site.Home }}
  {{- end }}
  {{- end }}
  {{- else }}
  {{- $list = (where .Site.Pages "Section" "docs") }}
  {{- end }}

  {{ $len := (len $list) -}}

上面是修改后的,主要修改了 Site.Params.options.searchSectionsIndex “ALL” 这一行,之前是eq,改成in,因为这个配置项是数组,明显不能用eq。 在params.toml中开启配置:

  searchSectionsIndex = ['ALL']

然后看页面上index.js就能编译出来这段模板了,index.add 会有很多页面。这里面我把content去掉了,因为加上content后index.js文件太大了。

  {{ range $index, $element := $list -}}
    index.add(
      {
        id: {{ $index }},
        href: "{{ .RelPermalink }}",
        title: {{ .Title | jsonify }},
        {{ with .Description -}}
          description: {{ . | jsonify }},
        {{ else -}}
          description: {{ .Summary | plainify | jsonify }},
        {{ end -}}
      }
    );
  {{ end -}}

参考:



请遵守《互联网环境法规》文明发言,欢迎讨论问题
扫码反馈

扫一扫,反馈当前页面

咨询反馈
扫码关注
返回顶部