feat(search): add more params for search and improve search index (#279)
This commit is contained in:
4
.github/ISSUE_TEMPLATE/config.yml
vendored
4
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,5 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: Theme Documentation
|
- name: Theme Documentation 主题文档
|
||||||
url: https://hugoloveit.com/categories/documentation/
|
url: https://hugoloveit.com/categories/documentation/
|
||||||
about: Please read the documentation carefully.
|
about: Please read the documentation carefully. 请先仔细阅读主题文档.
|
||||||
|
|||||||
10
.github/ISSUE_TEMPLATE/feature-request.md
vendored
10
.github/ISSUE_TEMPLATE/feature-request.md
vendored
@@ -9,13 +9,13 @@ assignees: dillonzq
|
|||||||
|
|
||||||
### Describe the feature you want 描述你的功能需求
|
### Describe the feature you want 描述你的功能需求
|
||||||
|
|
||||||
- Feature 1
|
- Feature 1 功能需求 1
|
||||||
I want this feature to solve ...
|
I want this feature to solve ... 我希望这个功能解决 ...
|
||||||
- Feature 2
|
- Feature 2 功能需求 2
|
||||||
I want this feature to solve ...
|
I want this feature to solve ... 我希望这个功能解决 ...
|
||||||
- ...
|
- ...
|
||||||
|
|
||||||
### Useful reference 有价值的参考
|
### Useful reference 有价值的参考
|
||||||
|
|
||||||
If available, provide useful links to fulfill the feature.
|
If available, provide useful links to fulfill the feature.
|
||||||
如果可以的话, 提供实现这个功能的参考链接.
|
如果可以的话, 提供实现这个功能的相关参考链接.
|
||||||
|
|||||||
15
README.md
15
README.md
@@ -113,14 +113,13 @@ I hope you will LoveIt ❤️!
|
|||||||
* **Dynamic scroll** supported by [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll)
|
* **Dynamic scroll** supported by [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll)
|
||||||
* ...
|
* ...
|
||||||
|
|
||||||
## Documentation
|
## [Documentation](https://hugoloveit.com/categories/documentation/)
|
||||||
|
|
||||||
* [Documentation Page](https://hugoloveit.com/categories/documentation/)
|
Build Documentation Locally:
|
||||||
* Build Documentation Locally:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
hugo server --source=exampleSite
|
hugo server --source=exampleSite
|
||||||
```
|
```
|
||||||
|
|
||||||
## Multilingual and i18n
|
## Multilingual and i18n
|
||||||
|
|
||||||
@@ -134,6 +133,10 @@ LoveIt supports the following languages:
|
|||||||
* Italian
|
* Italian
|
||||||
* [Contribute with a new language](https://github.com/dillonzq/LoveIt/pulls)
|
* [Contribute with a new language](https://github.com/dillonzq/LoveIt/pulls)
|
||||||
|
|
||||||
|
[Languages Compatibility](https://hugoloveit.com/theme-documentation-basics/#language-compatibility)
|
||||||
|
|
||||||
|
## [Roadmap](https://github.com/dillonzq/LoveIt/projects/1)
|
||||||
|
|
||||||
## Questions, ideas, bugs, pull requests
|
## Questions, ideas, bugs, pull requests
|
||||||
|
|
||||||
All feedback is welcome! Head over to the [issue tracker](https://github.com/dillonzq/LoveIt/issues).
|
All feedback is welcome! Head over to the [issue tracker](https://github.com/dillonzq/LoveIt/issues).
|
||||||
|
|||||||
@@ -108,14 +108,13 @@
|
|||||||
* 支持基于 [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll) 的**滚动动画**
|
* 支持基于 [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll) 的**滚动动画**
|
||||||
* ...
|
* ...
|
||||||
|
|
||||||
## 文档
|
## [文档](https://hugoloveit.com/zh-cn/categories/documentation/)
|
||||||
|
|
||||||
* [文档页面](https://hugoloveit.com/zh-cn/categories/documentation/)
|
在本地构建文档:
|
||||||
* 在本地构建文档:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
hugo server --source=exampleSite
|
hugo server --source=exampleSite
|
||||||
```
|
```
|
||||||
|
|
||||||
## 多语言和国际化
|
## 多语言和国际化
|
||||||
|
|
||||||
@@ -129,6 +128,10 @@ LoveIt 支持下列语言:
|
|||||||
* 意大利语
|
* 意大利语
|
||||||
* [贡献一种新的语言](https://github.com/dillonzq/LoveIt/pulls)
|
* [贡献一种新的语言](https://github.com/dillonzq/LoveIt/pulls)
|
||||||
|
|
||||||
|
[语言兼容性](https://hugoloveit.com/zh-cn/theme-documentation-basics/#language-compatibility)
|
||||||
|
|
||||||
|
## [路线图](https://github.com/dillonzq/LoveIt/projects/1)
|
||||||
|
|
||||||
## 问题、想法、 bugs 和 PRs
|
## 问题、想法、 bugs 和 PRs
|
||||||
|
|
||||||
所有的反馈都是欢迎的!详见 [issue tracker](https://github.com/dillonzq/LoveIt/issues)。
|
所有的反馈都是欢迎的!详见 [issue tracker](https://github.com/dillonzq/LoveIt/issues)。
|
||||||
|
|||||||
4
assets/js/theme.min.js
vendored
4
assets/js/theme.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -114,10 +114,14 @@ enableEmoji = true
|
|||||||
enable = true
|
enable = true
|
||||||
# type of search engine ("lunr", "algolia")
|
# type of search engine ("lunr", "algolia")
|
||||||
type = "algolia"
|
type = "algolia"
|
||||||
# index length of the content
|
# max index length of the chunked content
|
||||||
contentLength = 5000
|
contentLength = 5000
|
||||||
# placeholder of the search bar
|
# placeholder of the search bar
|
||||||
placeholder = ""
|
placeholder = ""
|
||||||
|
# max number of results length
|
||||||
|
maxResultLength = 10
|
||||||
|
# HTML tag name of the highlight part in results
|
||||||
|
highlightTag = "em"
|
||||||
[languages.en.params.search.algolia]
|
[languages.en.params.search.algolia]
|
||||||
index = "index.en"
|
index = "index.en"
|
||||||
appID = "PASDMWALPK"
|
appID = "PASDMWALPK"
|
||||||
@@ -303,10 +307,14 @@ enableEmoji = true
|
|||||||
enable = true
|
enable = true
|
||||||
# 搜索引擎的类型 ("lunr", "algolia")
|
# 搜索引擎的类型 ("lunr", "algolia")
|
||||||
type = "algolia"
|
type = "algolia"
|
||||||
# 文章内容索引长度
|
# 文章内容最长索引长度
|
||||||
contentLength = 5000
|
contentLength = 5000
|
||||||
# 搜索框的占位提示语
|
# 搜索框的占位提示语
|
||||||
placeholder = ""
|
placeholder = ""
|
||||||
|
# 最大结果数目
|
||||||
|
maxResultLength = 10
|
||||||
|
# 搜索结果中高亮部分的 HTML 标签
|
||||||
|
highlightTag = "em"
|
||||||
[languages.zh-cn.params.search.algolia]
|
[languages.zh-cn.params.search.algolia]
|
||||||
index = "index.zh-cn"
|
index = "index.zh-cn"
|
||||||
appID = "PASDMWALPK"
|
appID = "PASDMWALPK"
|
||||||
@@ -488,10 +496,14 @@ enableEmoji = true
|
|||||||
enable = true
|
enable = true
|
||||||
# type of search engine ("lunr", "algolia")
|
# type of search engine ("lunr", "algolia")
|
||||||
type = "algolia"
|
type = "algolia"
|
||||||
# index length of the content
|
# max index length of the chunked content
|
||||||
contentLength = 5000
|
contentLength = 5000
|
||||||
# placeholder of the search bar
|
# placeholder of the search bar
|
||||||
placeholder = ""
|
placeholder = ""
|
||||||
|
# max number of results length
|
||||||
|
maxResultLength = 10
|
||||||
|
# HTML tag name of the highlight part in results
|
||||||
|
highlightTag = "em"
|
||||||
[languages.fr.params.search.algolia]
|
[languages.fr.params.search.algolia]
|
||||||
index = "index.fr"
|
index = "index.fr"
|
||||||
appID = "PASDMWALPK"
|
appID = "PASDMWALPK"
|
||||||
|
|||||||
@@ -221,10 +221,14 @@ Please open the code block below to view the complete sample configuration :(far
|
|||||||
enable = true
|
enable = true
|
||||||
# type of search engine ("lunr", "algolia")
|
# type of search engine ("lunr", "algolia")
|
||||||
type = "lunr"
|
type = "lunr"
|
||||||
# index length of the content
|
# max index length of the chunked content
|
||||||
contentLength = 5000
|
contentLength = 5000
|
||||||
# placeholder of the search bar
|
# placeholder of the search bar
|
||||||
placeholder = ""
|
placeholder = ""
|
||||||
|
# {{< version 0.2.1 >}} max number of results length
|
||||||
|
maxResultLength = 10
|
||||||
|
# {{< version 0.2.1 >}} HTML tag name of the highlight part in results
|
||||||
|
highlightTag = "em"
|
||||||
[params.search.algolia]
|
[params.search.algolia]
|
||||||
index = ""
|
index = ""
|
||||||
appID = ""
|
appID = ""
|
||||||
@@ -955,25 +959,35 @@ Here is the search configuration in your [site configuration](#site-configuratio
|
|||||||
enable = true
|
enable = true
|
||||||
# type of search engine ("lunr", "algolia")
|
# type of search engine ("lunr", "algolia")
|
||||||
type = "lunr"
|
type = "lunr"
|
||||||
# index length of the content
|
# max index length of the chunked content
|
||||||
contentLength = 5000
|
contentLength = 5000
|
||||||
|
# placeholder of the search bar
|
||||||
|
placeholder = ""
|
||||||
|
# {{< version 0.2.1 >}} max number of results length
|
||||||
|
maxResultLength = 10
|
||||||
|
# {{< version 0.2.1 >}} HTML tag name of the highlight part in results
|
||||||
|
highlightTag = "em"
|
||||||
[params.search.algolia]
|
[params.search.algolia]
|
||||||
index = ""
|
index = ""
|
||||||
appID = ""
|
appID = ""
|
||||||
searchKey = ""
|
searchKey = ""
|
||||||
```
|
```
|
||||||
|
|
||||||
{{< admonition note "How to choose the type of search engine?" >}}
|
{{< admonition note "How to choose search engine?" >}}
|
||||||
The following is a comparison of two search engines:
|
The following is a comparison of two search engines:
|
||||||
|
|
||||||
* `lunr`: simple, no need to synchronize `index.json`, no limit for `contentLength`,
|
* `lunr`: simple, no need to synchronize `index.json`, no limit for `contentLength`,
|
||||||
but high bandwidth and low performance (Especially for Chinese which needs a large segmentit library)
|
but high bandwidth and low performance (Especially for Chinese which needs a large segmentit library)
|
||||||
* `algolia`: high performance and low bandwidth, but need to synchronize `index.json` and limit for `contentLength`
|
* `algolia`: high performance and low bandwidth, but need to synchronize `index.json` and limit for `contentLength`
|
||||||
|
|
||||||
|
{{< version 0.2.1 >}} The content of the post is separated by `h2` HTML tag to improve query performance and basically implement full-text search.
|
||||||
|
`contentLength` is used to limit the max index length of the part starting with `h2` HTML tag.
|
||||||
{{< /admonition >}}
|
{{< /admonition >}}
|
||||||
|
|
||||||
{{< admonition tip "Tips about algolia" >}}
|
{{< admonition tip "Tips about algolia" >}}
|
||||||
You need to upload `index.json` files to algolia to activate searching.
|
You need to upload `index.json` files to algolia to activate searching.
|
||||||
You could upload the `index.json` files by browsers but a script may be a better choice.
|
You could upload the `index.json` files by browsers but a CLI tool may be better.
|
||||||
|
[Algolia Atomic](https://github.com/chrisdmacrae/atomic-algolia) is a good choice.
|
||||||
To be compatible with Hugo multilingual mode,
|
To be compatible with Hugo multilingual mode,
|
||||||
you need to upload different `index.json` for each language to the different index of algolia, such as `zh-cn/index.json` or `fr/index.json`...
|
you need to upload different `index.json` for each language to the different index of algolia, such as `zh-cn/index.json` or `fr/index.json`...
|
||||||
{{< /admonition >}}
|
{{< /admonition >}}
|
||||||
|
|||||||
@@ -226,10 +226,14 @@ Please open the code block below to view the complete sample configuration :(far
|
|||||||
enable = true
|
enable = true
|
||||||
# type of search engine ("lunr", "algolia")
|
# type of search engine ("lunr", "algolia")
|
||||||
type = "lunr"
|
type = "lunr"
|
||||||
# index length of the content
|
# max index length of the chunked content
|
||||||
contentLength = 5000
|
contentLength = 5000
|
||||||
# placeholder of the search bar
|
# placeholder of the search bar
|
||||||
placeholder = ""
|
placeholder = ""
|
||||||
|
# {{< version 0.2.1 >}} max number of results length
|
||||||
|
maxResultLength = 10
|
||||||
|
# {{< version 0.2.1 >}} HTML tag name of the highlight part in results
|
||||||
|
highlightTag = "em"
|
||||||
[params.search.algolia]
|
[params.search.algolia]
|
||||||
index = ""
|
index = ""
|
||||||
appID = ""
|
appID = ""
|
||||||
@@ -960,25 +964,35 @@ Here is the search configuration in your [site configuration](#site-configuratio
|
|||||||
enable = true
|
enable = true
|
||||||
# type of search engine ("lunr", "algolia")
|
# type of search engine ("lunr", "algolia")
|
||||||
type = "lunr"
|
type = "lunr"
|
||||||
# index length of the content
|
# max index length of the chunked content
|
||||||
contentLength = 5000
|
contentLength = 5000
|
||||||
|
# placeholder of the search bar
|
||||||
|
placeholder = ""
|
||||||
|
# {{< version 0.2.1 >}} max number of results length
|
||||||
|
maxResultLength = 10
|
||||||
|
# {{< version 0.2.1 >}} HTML tag name of the highlight part in results
|
||||||
|
highlightTag = "em"
|
||||||
[params.search.algolia]
|
[params.search.algolia]
|
||||||
index = ""
|
index = ""
|
||||||
appID = ""
|
appID = ""
|
||||||
searchKey = ""
|
searchKey = ""
|
||||||
```
|
```
|
||||||
|
|
||||||
{{< admonition note "How to choose the type of search engine?" >}}
|
{{< admonition note "How to choose search engine?" >}}
|
||||||
The following is a comparison of two search engines:
|
The following is a comparison of two search engines:
|
||||||
|
|
||||||
* `lunr`: simple, no need to synchronize `index.json`, no limit for `contentLength`,
|
* `lunr`: simple, no need to synchronize `index.json`, no limit for `contentLength`,
|
||||||
but high bandwidth and low performance (Especially for Chinese which needs a large segmentit library)
|
but high bandwidth and low performance (Especially for Chinese which needs a large segmentit library)
|
||||||
* `algolia`: high performance and low bandwidth, but need to synchronize `index.json` and limit for `contentLength`
|
* `algolia`: high performance and low bandwidth, but need to synchronize `index.json` and limit for `contentLength`
|
||||||
|
|
||||||
|
{{< version 0.2.1 >}} The content of the post is separated by `h2` HTML tag to improve query performance and basically implement full-text search.
|
||||||
|
`contentLength` is used to limit the max index length of the part starting with `h2` HTML tag.
|
||||||
{{< /admonition >}}
|
{{< /admonition >}}
|
||||||
|
|
||||||
{{< admonition tip "Tips about algolia" >}}
|
{{< admonition tip "Tips about algolia" >}}
|
||||||
You need to upload `index.json` files to algolia to activate searching.
|
You need to upload `index.json` files to algolia to activate searching.
|
||||||
You could upload the `index.json` files by browsers but a script may be a better choice.
|
You could upload the `index.json` files by browsers but a CLI tool may be better.
|
||||||
|
[Algolia Atomic](https://github.com/chrisdmacrae/atomic-algolia) is a good choice.
|
||||||
To be compatible with Hugo multilingual mode,
|
To be compatible with Hugo multilingual mode,
|
||||||
you need to upload different `index.json` for each language to the different index of algolia, such as `zh-cn/index.json` or `fr/index.json`...
|
you need to upload different `index.json` for each language to the different index of algolia, such as `zh-cn/index.json` or `fr/index.json`...
|
||||||
{{< /admonition >}}
|
{{< /admonition >}}
|
||||||
|
|||||||
@@ -224,10 +224,14 @@ hugo
|
|||||||
enable = true
|
enable = true
|
||||||
# 搜索引擎的类型 ("lunr", "algolia")
|
# 搜索引擎的类型 ("lunr", "algolia")
|
||||||
type = "lunr"
|
type = "lunr"
|
||||||
# 文章内容索引长度
|
# 文章内容最长索引长度
|
||||||
contentLength = 5000
|
contentLength = 5000
|
||||||
# 搜索框的占位提示语
|
# 搜索框的占位提示语
|
||||||
placeholder = ""
|
placeholder = ""
|
||||||
|
# 最大结果数目
|
||||||
|
maxResultLength = 10
|
||||||
|
# 搜索结果中高亮部分的 HTML 标签
|
||||||
|
highlightTag = "em"
|
||||||
[params.search.algolia]
|
[params.search.algolia]
|
||||||
index = ""
|
index = ""
|
||||||
appID = ""
|
appID = ""
|
||||||
@@ -938,7 +942,7 @@ defaultContentLanguage = "zh-cn"
|
|||||||
|
|
||||||
{{< version 0.2.0 >}}
|
{{< version 0.2.0 >}}
|
||||||
|
|
||||||
基于 [Lunr.js](https://lunrjs.com/) 或 [algolia](https://www.algolia.com/), **LoveIt** 主支持搜索功能.
|
基于 [Lunr.js](https://lunrjs.com/) 或 [algolia](https://www.algolia.com/), **LoveIt** 主题支持搜索功能.
|
||||||
|
|
||||||
### 5.1 输出配置
|
### 5.1 输出配置
|
||||||
|
|
||||||
@@ -958,24 +962,34 @@ defaultContentLanguage = "zh-cn"
|
|||||||
```toml
|
```toml
|
||||||
[params.search]
|
[params.search]
|
||||||
enable = true
|
enable = true
|
||||||
# type of search engine ("lunr", "algolia")
|
# 搜索引擎的类型 ("lunr", "algolia")
|
||||||
type = "lunr"
|
type = "lunr"
|
||||||
# index length of the content
|
# 文章内容最长索引长度
|
||||||
contentLength = 5000
|
contentLength = 5000
|
||||||
|
# 搜索框的占位提示语
|
||||||
|
placeholder = ""
|
||||||
|
# 最大结果数目
|
||||||
|
maxResultLength = 10
|
||||||
|
# 搜索结果中高亮部分的 HTML 标签
|
||||||
|
highlightTag = "em"
|
||||||
[params.search.algolia]
|
[params.search.algolia]
|
||||||
index = ""
|
index = ""
|
||||||
appID = ""
|
appID = ""
|
||||||
searchKey = ""
|
searchKey = ""
|
||||||
```
|
```
|
||||||
|
|
||||||
{{< admonition note "怎样选择搜索引擎的类型?" >}}
|
{{< admonition note "怎样选择搜索引擎?" >}}
|
||||||
以下是两种搜索引擎的对比:
|
以下是两种搜索引擎的对比:
|
||||||
|
|
||||||
* `lunr`: 简单, 无需同步 `index.json`, 没有 `contentLength` 的限制, 但占用带宽大且性能低 (特别是中文需要一个较大的分词依赖库)
|
* `lunr`: 简单, 无需同步 `index.json`, 没有 `contentLength` 的限制, 但占用带宽大且性能低 (特别是中文需要一个较大的分词依赖库)
|
||||||
* `algolia`: 高性能并且占用带宽低, 但需要同步 `index.json` 且有 `contentLength` 的限制
|
* `algolia`: 高性能并且占用带宽低, 但需要同步 `index.json` 且有 `contentLength` 的限制
|
||||||
|
|
||||||
|
{{< version 0.2.1 >}} 文章内容被 `h2` HTML 标签切分来提供查询效果并且基本实现全文搜索.
|
||||||
|
`contentLength` 用来限制 `h2` HTML 标签开头的内容部分的最大长度.
|
||||||
{{< /admonition >}}
|
{{< /admonition >}}
|
||||||
|
|
||||||
{{< admonition tip "关于 algolia 的使用技巧" >}}
|
{{< admonition tip "关于 algolia 的使用技巧" >}}
|
||||||
你需要上传 `index.json` 到 algolia 来激活搜索功能. 你可以使用浏览器来上传 `index.json` 文件但是一个自动化的脚本可能是更好的选择.
|
你需要上传 `index.json` 到 algolia 来激活搜索功能. 你可以使用浏览器来上传 `index.json` 文件但是一个自动化的脚本可能效果更好.
|
||||||
|
[Algolia Atomic](https://github.com/chrisdmacrae/atomic-algolia) 是一个不错的选择.
|
||||||
为了兼容 Hugo 的多语言模式, 你需要上传不同语言的 `index.json` 文件到对应的 algolia index, 例如 `zh-cn/index.json` 或 `fr/index.json`...
|
为了兼容 Hugo 的多语言模式, 你需要上传不同语言的 `index.json` 文件到对应的 algolia index, 例如 `zh-cn/index.json` 或 `fr/index.json`...
|
||||||
{{< /admonition >}}
|
{{< /admonition >}}
|
||||||
|
|||||||
@@ -6,16 +6,25 @@
|
|||||||
{{- $pages = where $pages "Params.hiddenfromsearch" "!=" true -}}
|
{{- $pages = where $pages "Params.hiddenfromsearch" "!=" true -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- range $pages -}}
|
{{- range $pages -}}
|
||||||
{{- $one := dict "objectID" .RelPermalink "uri" .RelPermalink "title" .Title "description" (.Description | default "") -}}
|
{{- $uri := .RelPermalink -}}
|
||||||
{{- $tags := .Params.tags | default slice -}}
|
{{- $meta := dict "uri" $uri "title" .Title "tags" .Params.tags "categories" .Params.categories -}}
|
||||||
{{- $one = delimit $tags "\n" | dict "tags" | merge $one -}}
|
{{- $meta = .PublishDate.Format ($.Site.Params.dateFormat | default "2006-01-02") | dict "date" | merge $meta -}}
|
||||||
{{- $publish_date := .PublishDate.Format (.Site.Params.dateFormat | default "2006-01-02") -}}
|
{{- with .Description -}}
|
||||||
{{- $one = dict "date" $publish_date | merge $one -}}
|
{{- $index = $index | append (dict "content" . "objectID" $uri | merge $meta) -}}
|
||||||
{{- $content := .RawContent | htmlEscape -}}
|
{{- end -}}
|
||||||
{{- if gt .Site.Params.search.contentLength 0 -}}
|
{{- $params := .Params | merge $.Site.Params.page -}}
|
||||||
{{- $content = substr $content 0 .Site.Params.search.contentLength -}}
|
{{- $content := dict "content" .Content "ruby" $params.ruby "fraction" $params.fraction "fontawesome" $params.fontawesome | partial "function/content.html" -}}
|
||||||
|
{{- range $i, $chunked := split $content "<h2 id=" -}}
|
||||||
|
{{- if gt $i 0 -}}
|
||||||
|
{{- $chunked = printf "<h2 id=%s" $chunked -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- $chunked = $chunked | plainify | htmlUnescape | replaceRE `[\n ]+` ` ` -}}
|
||||||
|
{{- if gt $.Site.Params.search.contentLength 0 -}}
|
||||||
|
{{- $chunked = substr $chunked 0 $.Site.Params.search.contentLength -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- $one := printf "%s:%d" $uri $i | dict "content" $chunked "objectID" | merge $meta -}}
|
||||||
|
{{- $index = $index | append $one -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- $one = dict "content" $content | merge $one -}}
|
|
||||||
{{- $index = $index | append $one -}}
|
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{- $index | jsonify | safeJS -}}
|
{{- $index | jsonify | safeJS -}}
|
||||||
|
|||||||
@@ -167,6 +167,10 @@
|
|||||||
{{- partial "plugin/stylesheet.html" . -}}
|
{{- partial "plugin/stylesheet.html" . -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- with (.Scratch.Get "this").styleArr -}}
|
||||||
|
<style>{{ delimit . "" | safeCSS }}</style>
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.config = {{ $config | jsonify | safeJS }};
|
window.config = {{ $config | jsonify | safeJS }};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
{{- $width := cond .IsNamedParams (.Get "width") (.Get 0) | default "100%" -}}
|
{{- $width := cond .IsNamedParams (.Get "width") (.Get 0) | default "100%" -}}
|
||||||
{{- $height := cond .IsNamedParams (.Get "height") (.Get 1) | default "30rem" -}}
|
{{- $height := cond .IsNamedParams (.Get "height") (.Get 1) | default "30rem" -}}
|
||||||
<div class="echarts" id="{{ $id }}" style="width: {{ $width }}; height: {{ $height }};"></div>
|
<div class="echarts" id="{{ $id }}" style="width: {{ $width }}; height: {{ $height }};"></div>
|
||||||
{{- dict "echarts" true | merge (.Page.Scratch.Get "this") | .Page.Scratch.Set "this" -}}
|
{{- .Page.Scratch.SetInMap "this" "echarts" true -}}
|
||||||
|
|||||||
@@ -30,4 +30,4 @@
|
|||||||
{{- $options := dict "lng" $lng "lat" $lat "zoom" $zoom "marked" $marked "lightStyle" $lightStyle "darkStyle" $darkStyle "geolocate" $geolocate "navigation" $navigation "scale" $scale "fullscreen" $fullscreen -}}
|
{{- $options := dict "lng" $lng "lat" $lat "zoom" $zoom "marked" $marked "lightStyle" $lightStyle "darkStyle" $darkStyle "geolocate" $geolocate "navigation" $navigation "scale" $scale "fullscreen" $fullscreen -}}
|
||||||
{{- $id := partial "function/id.html" (dict "content" $options "scratch" .Page.Scratch) -}}
|
{{- $id := partial "function/id.html" (dict "content" $options "scratch" .Page.Scratch) -}}
|
||||||
<div class="mapbox" id="{{ $id }}" style="width: {{ $width }}; height: {{ $height }};"></div>
|
<div class="mapbox" id="{{ $id }}" style="width: {{ $width }}; height: {{ $height }};"></div>
|
||||||
{{- dict "mapbox" true | merge (.Page.Scratch.Get "this") | .Page.Scratch.Set "this" -}}
|
{{- .Page.Scratch.SetInMap "this" "mapbox" true -}}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{{- $id := partial "function/id.html" (dict "content" (trim .Inner "\n") "scratch" .Page.Scratch) -}}
|
{{- $id := partial "function/id.html" (dict "content" (trim .Inner "\n") "scratch" .Page.Scratch) -}}
|
||||||
<div class="mermaid" id="{{ $id }}"></div>
|
<div class="mermaid" id="{{ $id }}"></div>
|
||||||
{{- dict "mermaid" true | merge (.Page.Scratch.Get "this") | .Page.Scratch.Set "this" -}}
|
{{- .Page.Scratch.SetInMap "this" "mermaid" true -}}
|
||||||
|
|||||||
@@ -39,4 +39,4 @@
|
|||||||
{{- else -}}
|
{{- else -}}
|
||||||
<meting-js server="{{ .Get 0 }}" type="{{ .Get 1 }}" id="{{ .Get 2 }}" theme="{{ $theme }}"></meting-js>
|
<meting-js server="{{ .Get 0 }}" type="{{ .Get 1 }}" id="{{ .Get 2 }}" theme="{{ $theme }}"></meting-js>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- dict "music" true | merge (.Page.Scratch.Get "this") | .Page.Scratch.Set "this" -}}
|
{{- .Page.Scratch.SetInMap "this" "music" true -}}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
{{- $content := .Inner | .Page.RenderString -}}
|
{{- $content := .Inner | .Page.RenderString -}}
|
||||||
{{- $id := partial "function/id.html" (dict "content" $content) -}}
|
{{- $id := partial "function/id.html" (dict "content" $content) -}}
|
||||||
{{- $tag := .Get 1 | default "div" -}}
|
{{- $tag := .Get 1 | default "div" -}}
|
||||||
|
{{- printf `<%s id="%s">%s</%s>` $tag $id $content $tag | safeHTML -}}
|
||||||
|
|
||||||
{{- $style := .Get 0 | printf "#%s{%s}" $id -}}
|
{{- $style := .Get 0 | printf "#%s{%s}" $id -}}
|
||||||
{{- $res := resources.FromString (printf "temp/%s.scss" $id) $style -}}
|
{{- $res := resources.FromString (printf "temp/%s.scss" $id) $style -}}
|
||||||
{{- $res = $res | toCSS (dict "targetPath" (printf "temp/%s.css" $id)) -}}
|
{{- $res = $res | toCSS (dict "targetPath" (printf "temp/%s.css" $id)) -}}
|
||||||
{{- printf `<%s id="%s">%s</%s>` $tag $id $content $tag | safeHTML -}}
|
{{- $styleArr := (.Page.Scratch.Get "this").styleArr | default slice -}}
|
||||||
<style>{{ $res.Content | safeCSS }}</style>
|
{{- $styleArr | append $res.Content | .Page.Scratch.SetInMap "this" "styleArr" -}}
|
||||||
|
|||||||
@@ -22,9 +22,10 @@
|
|||||||
{{- $content = trim $content "\n" -}}
|
{{- $content = trim $content "\n" -}}
|
||||||
{{- $id := partial "function/id.html" (dict "content" $content "scratch" .Page.Scratch) -}}
|
{{- $id := partial "function/id.html" (dict "content" $content "scratch" .Page.Scratch) -}}
|
||||||
{{- $key := .Get "group" | string | default $id -}}
|
{{- $key := .Get "group" | string | default $id -}}
|
||||||
{{- $group := index ((.Page.Scratch.Get "this").typeitMap | default dict) $key -}}
|
{{- $typeitMap := (.Page.Scratch.Get "this").typeitMap | default dict -}}
|
||||||
|
{{- $group := index $typeitMap $key -}}
|
||||||
{{- $group = $group | default slice | append $id -}}
|
{{- $group = $group | default slice | append $id -}}
|
||||||
{{- dict $key $group | dict "typeitMap" | merge (.Page.Scratch.Get "this") | .Page.Scratch.Set "this" -}}
|
{{- dict $key $group | merge $typeitMap | .Page.Scratch.SetInMap "this" "typeitMap" -}}
|
||||||
|
|
||||||
<div class="typeit">
|
<div class="typeit">
|
||||||
{{- printf `<%s id="%s" class="%s"></%s>` $tag $id (delimit $classList " ") $tag | safeHTML -}}
|
{{- printf `<%s id="%s" class="%s"></%s>` $tag $id (delimit $classList " ") $tag | safeHTML -}}
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ class Theme {
|
|||||||
|
|
||||||
initSearch() {
|
initSearch() {
|
||||||
const searchConfig = this.config.search;
|
const searchConfig = this.config.search;
|
||||||
|
if (!searchConfig.maxResultLength) searchConfig.maxResultLength = 10;
|
||||||
|
if (!searchConfig.highlightTag) searchConfig.highlightTag = 'em';
|
||||||
const isMobile = this.util.isMobile();
|
const isMobile = this.util.isMobile();
|
||||||
if (!searchConfig || isMobile && this._searchMobileOnce || !isMobile && this._searchDesktopOnce) return;
|
if (!searchConfig || isMobile && this._searchMobileOnce || !isMobile && this._searchDesktopOnce) return;
|
||||||
const classSuffix = isMobile ? 'mobile' : 'desktop';
|
const classSuffix = isMobile ? 'mobile' : 'desktop';
|
||||||
@@ -173,15 +175,14 @@ class Theme {
|
|||||||
if (searchConfig.type === 'lunr') {
|
if (searchConfig.type === 'lunr') {
|
||||||
const search = () => {
|
const search = () => {
|
||||||
if (lunr.queryHandler) query = lunr.queryHandler(query);
|
if (lunr.queryHandler) query = lunr.queryHandler(query);
|
||||||
return this._index.search(query).slice(0, 12).map(({ ref, matchData: { metadata } }) => {
|
const results = {};
|
||||||
|
this._index.search(query).forEach(({ ref, matchData: { metadata } }) => {
|
||||||
const matchData = this._indexData[ref];
|
const matchData = this._indexData[ref];
|
||||||
let { title, content: context } = matchData;
|
let { uri, title, content: context } = matchData;
|
||||||
|
if (results[uri]) return;
|
||||||
let position = 0;
|
let position = 0;
|
||||||
Object.values(metadata).forEach(({ description, content }) => {
|
Object.values(metadata).forEach(({ content }) => {
|
||||||
if (description) {
|
if (content) {
|
||||||
context = matchData.description;
|
|
||||||
position = -1;
|
|
||||||
} else if (content) {
|
|
||||||
const matchPosition = content.position[0][0];
|
const matchPosition = content.position[0][0];
|
||||||
if (matchPosition < position || position === 0) position = matchPosition;
|
if (matchPosition < position || position === 0) position = matchPosition;
|
||||||
}
|
}
|
||||||
@@ -194,16 +195,17 @@ class Theme {
|
|||||||
context = context.substr(0, CONTEXT_LENGTH);
|
context = context.substr(0, CONTEXT_LENGTH);
|
||||||
}
|
}
|
||||||
Object.keys(metadata).forEach(key => {
|
Object.keys(metadata).forEach(key => {
|
||||||
title = title.replace(new RegExp(`(${key})`, 'gi'), '<em>$1</em>');
|
title = title.replace(new RegExp(`(${key})`, 'gi'), `<${searchConfig.highlightTag}>$1</${searchConfig.highlightTag}>`);
|
||||||
context = context.replace(new RegExp(`(${key})`, 'gi'), '<em>$1</em>');
|
context = context.replace(new RegExp(`(${key})`, 'gi'), `<${searchConfig.highlightTag}>$1</${searchConfig.highlightTag}>`);
|
||||||
});
|
});
|
||||||
return {
|
results[uri] = {
|
||||||
'uri': matchData.uri,
|
'uri': uri,
|
||||||
'title' : title,
|
'title' : title,
|
||||||
'date' : matchData.date,
|
'date' : matchData.date,
|
||||||
'context' : context,
|
'context' : context,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
return Object.values(results).slice(0, searchConfig.maxResultLength);
|
||||||
}
|
}
|
||||||
if (!this._index) {
|
if (!this._index) {
|
||||||
fetch(searchConfig.lunrIndexURL)
|
fetch(searchConfig.lunrIndexURL)
|
||||||
@@ -212,14 +214,14 @@ class Theme {
|
|||||||
const indexData = {};
|
const indexData = {};
|
||||||
this._index = lunr(function () {
|
this._index = lunr(function () {
|
||||||
if (searchConfig.lunrLanguageCode) this.use(lunr[searchConfig.lunrLanguageCode]);
|
if (searchConfig.lunrLanguageCode) this.use(lunr[searchConfig.lunrLanguageCode]);
|
||||||
this.ref('uri');
|
this.ref('objectID');
|
||||||
this.field('title', { boost: 50 });
|
this.field('title', { boost: 50 });
|
||||||
this.field('tags', { boost: 20 });
|
this.field('tags', { boost: 20 });
|
||||||
this.field('description', { boost: 10 });
|
this.field('categories', { boost: 20 });
|
||||||
this.field('content', { boost: 5 });
|
this.field('content', { boost: 10 });
|
||||||
this.metadataWhitelist = ['position'];
|
this.metadataWhitelist = ['position'];
|
||||||
data.forEach((record) => {
|
data.forEach((record) => {
|
||||||
indexData[record.uri] = record;
|
indexData[record.objectID] = record;
|
||||||
this.add(record);
|
this.add(record);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -231,18 +233,28 @@ class Theme {
|
|||||||
});
|
});
|
||||||
} else finish(search());
|
} else finish(search());
|
||||||
} else if (searchConfig.type === 'algolia') {
|
} else if (searchConfig.type === 'algolia') {
|
||||||
$searchLoading.style.display = 'inline';
|
|
||||||
$searchClear.style.display = 'none';
|
|
||||||
this._algoliaIndex = this._algoliaIndex || algoliasearch(searchConfig.algoliaAppID, searchConfig.algoliaSearchKey).initIndex(searchConfig.algoliaIndex);
|
this._algoliaIndex = this._algoliaIndex || algoliasearch(searchConfig.algoliaAppID, searchConfig.algoliaSearchKey).initIndex(searchConfig.algoliaIndex);
|
||||||
this._algoliaIndex
|
this._algoliaIndex
|
||||||
.search(query, { offset: 0, length: 12, attributesToHighlight: ['title', 'content'] })
|
.search(query, {
|
||||||
|
offset: 0,
|
||||||
|
length: searchConfig.maxResultLength * 3,
|
||||||
|
attributesToHighlight: ['title'],
|
||||||
|
attributesToSnippet: ['content:30'],
|
||||||
|
highlightPreTag: `<${searchConfig.highlightTag}>`,
|
||||||
|
highlightPostTag: `</${searchConfig.highlightTag}>`,
|
||||||
|
})
|
||||||
.then(({ hits }) => {
|
.then(({ hits }) => {
|
||||||
finish(hits.map(({ uri, date, _highlightResult: { title, content } }) => ({
|
const results = {};
|
||||||
uri: uri,
|
hits.forEach(({ uri, date, _highlightResult: { title }, _snippetResult: { content } }) => {
|
||||||
title: title.value,
|
if (results[uri]) return;
|
||||||
date: date,
|
results[uri] = {
|
||||||
context: content.value,
|
uri: uri,
|
||||||
})));
|
title: title.value,
|
||||||
|
date: date,
|
||||||
|
context: content.value,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
finish(Object.values(results));
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|||||||
Reference in New Issue
Block a user