由于 Hexo 作为静态博客,会将所有 source/ 目录下的的 Markdown 文件渲染为 HTML 页面。有时我会喜欢在某个目录下放一个 readme 文档,比如 asset/ 目录,作为该目录存放资源的说明。但是我不想被搜索到,那么这时只需要将该目录写到 skip_render 下面,避免被渲染成 HTML 页面,如:

1
2
3
4
skip_render:
  - js/*
  - css/*
  - asset/*

还有一种方法是在文档的 front-matter 里面加上 indexing: false 避免该文档被索引到,但这也只限于 Markdown 类型文件。同样的,还有一种方法是在 _config.stellar.yml 中设置 search.local_search.field

1
2
3
4
5
6
7
search:
  service: local_search # local_search, algolia_search, todo...
  local_search: # 在 front-matter 中设置 indexing:false 来避免被搜索索引
    field: all # post, page, all
    path: /search.json # 搜索文件存放位置
    content: true # 是否搜索内容
    codeblock: true # 是否搜索代码块(需要content: true)

field 字段有三种值可以设置,分别为:post, page, all.
通过测试发现,field 设置为 page,就会搜索除了 post 以外的所有内容,所以实际情况如下:

  • post : 只有 layout 为 post 的内容

  • page: page + all others (除了 layout 为 post,还有 page ,wiki)

  • all: page + post + all others
    这里的 all others 就是除了 layout 为 post, page, wiki 以外的 Markdown 文件,加上其它类型文件,如 css 文件,js 文件。

综合来看,并不是仅仅通过 search.local_search.field 限制,或者 indexing 开关,或者 skip_render 就能避免某些文件被搜索到。它们需要配合使用才能达到预期效果,但这增加了使用负担。所以我想到的是改现有的代码。

通过读目前的代码,注意到三点:

    1. 产生搜索数据时,会先对文本 layout 做两种判断,一种是 post,一种是 page。这里的 page 的范围就是除了 post 之外的所有类型为 Markdown 的文档,包括 wiki, about 页面,friends 页面,more 页面等等。
    1. 其它非 Markdown 文件的 layout 也有值,其为 “false”。
    1. field 只支持单值,不支持如 field:["post","page"] 这样的设置。

所以我的代码更改逻辑有两点:

  1. 根据 layout 来判断是否需要进行搜索。如果不是 post,page,wiki 这三种之一,则不搜索。

  2. 第一点并不能满足所有的情况,只能排查非 Markdown 文件(非 Markdown 文件的 layout 都为 false)。而还有些 Markdown 文件,虽然可以通过 skip_render 设置不被渲染从而在网页上搜索不到。但是,大部分情况是需要渲染的,也就是会有相应的 HTML 页面。如果还是不想被搜索到呢?在 front-matter 里面加上 indexing: false,是个方法。但是还有没有别的方法呢?你可能不会每次都想到要在文档前面加上一句 indexing: false。更好的方法是来源于 skip_render ,于是类似的就有 skip_search。可以设置某个目录,或多个目录。这样不管这些目录下有多少个文件,都可以跳过搜索啦。而不用在里面的每个文档前面添加 indexing 设置项。

所以代码更改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
diff --git a/scripts/generators/search.js b/scripts/generators/search.js
index ea6cb15..b289f58 100644
--- a/scripts/generators/search.js
+++ b/scripts/generators/search.js
@@ -60,8 +60,28 @@ hexo.extend.generator.register('search_json_generator', function (locals) {
return temp_post
}

+ function matchAndExit(path, patterns) {
+ for (let pattern of patterns) {
+ const regexPattern = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
+ if (path.match(regexPattern)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
if (posts) {
posts.each(function(post) {
+ var layout_list = ["post"]
+ if (!layout_list.includes(post.layout)) {
+ return
+ }
+ // matched skip_search list, skip to search
+ if (matchAndExit(post.path, cfg.skip_search)) {
+ return
+ }
if (post.indexing == false) return
let temp_post = generateJson(post)
res.push(temp_post)
@@ -69,6 +89,15 @@ hexo.extend.generator.register('search_json_generator', function (locals) {
}
if (pages) {
pages.each(function(page) {
+ var layout_list = ["page", "wiki"]
+ if (!layout_list.includes(page.layout)) {
+ return
+ }
+ if (matchAndExit(page.path, cfg.skip_search)) {
+ return
+ }
if (page.indexing == false) return
let temp_post = generateJson(page)
res.push(temp_post)

配置文件可以这样写:

1
2
3
4
5
6
7
8
9
10
11
search:
service: local_search # local_search, algolia_search, todo...
local_search: # 在 front-matter 中设置 indexing:false 来避免被搜索索引
field: all # post, page, all
path: /search.json # 搜索文件存放位置
content: true # 是否搜索内容
codeblock: true # 是否搜索代码块(需要content: true)
skip_search: # 指定 path 中的内容不被搜索。
- js/*
- css/*
- asset/*

实际测试来看,符合我的预期。