The search feature uses JavaScript to look for keyword matches in a JSON file. The results show instant matches, but it doesn't provide a search results page like Google. Also, sometimes invalid formatting can break the JSON file.
About search
The search is configured through the search.json file in the root directory. The search is a simple search that looks at content in pages. It looks at titles, summaries, keywords, and tags.
However, the search doesn’t work like google — you can’t hit return and see a list of results on the search results page, with the keywords in bold. Instead, this search shows a list of page titles that contain keyword matches. It’s fast, but simple.
Excluding pages from search
By default, every page is included in the search. Depending on the type of content you’re including, you may find that some pages will break the JSON formatting. If that happens, then the search will no longer work.
If you want to exclude a page from search add search: exclude
in the page’s frontmatter.
Troubleshooting search
You should exclude any files from search that you don’t want appearing in the search results. For example, if you have a tooltips.json file or prince-list.txt, don’t include it, as the formatting will break the JSON format.
If any formatting in the search.json file is invalid (in the build), search won’t work. You’ll know that search isn’t working if no results appear when you start typing in the search box.
If this happens, go directly to the search.json file in your browser, and then copy the content. Go to a JSON validator and paste in the content. Look for the line causing trouble. Edit the file to either exclude the page from search or fix the syntax so that it doesn’t invalidate the JSON. (Note that tabs in the body will invalidate JSON.)
The search.json file already tries to strip out content that would otherwise make the JSON invalid.
Including the body field in search
I’ve found that include the body
field in the search creates too many problems, and so I’ve removed body
from the search. You can see the results of including the body
by adding this along with the other fields in search.json:
"body": "{{ page.content | strip_html | strip_newlines | replace: '\', '\\\\' | replace: '"', '\\"' | replace: '^t', ' ' }}",
Note that the last replace, | replace: '^t', ' '
, looks for any tab character and replaces it with four spaces. (Tab characters invalidate JSON.) If you run into other problematic formatting, you can use regex expressions to find and replace the content. See Regular Expressions for details on finding and replacing code.
It’s possible that the formatting may not account for all the scenarios that would invalidate the JSON. (Sometimes it’s an extra comma after the last item that makes it invalid.)
Note that including the body in the search creates other problems as well. The search results show the most immediate matches in the JSON file. If several topics have matches for the keyword in the body, these matches might appear before other files that have matches in the title, summary, or keywords. This is because this simple search does not provide any weighting mechanisms for the content.
Customizing search results
At some point, you may want to customize the search results more. Here’s a little more detail that will be helpful. The search.json file retrieves various page values:
---
title: search
layout: none
search: exclude
---
[
{% for page in site.pages %}
{% unless page.search == "exclude" %}
{
"title": "{{ page.title | escape }}",
"tags": "{{ page.tags }}",
"keywords": "{{page.keywords}}",
"url": "{{ page.url | remove: "/"}}",
"summary": "{{page.summary | strip }}"
},
{% endunless %}
{% endfor %}
{% for post in site.posts %}
{
"title": "{{ post.title | escape }}",
"tags": "{{ post.tags }}",
"keywords": "{{post.keywords}}",
"url": "{{ post.url }}",
"summary": "{{post.summary | strip }}"
}
{% unless forloop.last %},{% endunless %}
{% endfor %}
]
The _includes/topnav.html file then makes use of these values:
<li>
<!--start search-->
<div id="search-demo-container">
<input type="text" id="search-input" placeholder="搜索你感兴趣的文档...">
<ul id="results-container"></ul>
</div>
<script src="js/jekyll-search.js" type="text/javascript"></script>
<script type="text/javascript">
SimpleJekyllSearch.init({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
dataSource: 'search.json',
searchResultTemplate: '<li><a href="{url}" title="Search configuration">{title}</a></li>',
noResultsText: '没有找到相关检索结果。',
limit: 10,
fuzzy: true,
})
</script>
<!--end search-->
</li>
Where you see {url}
and {title}
, the search is retrieving the values for these as specified in the search.json file.
More robust search
For more robust search, consider integrating either Algolia or Swifttype.
orzh-introduction
X-WAF-README
nginx-lua-module-zh-wiki
orange_about
pra_flame_how
orzh-introduction
X-WAF-README
nginx-lua-module-zh-wiki
orange_about
titlepage
tocpage
p1_landing_page
p1_sample1
p1_sample2
p1_sample3
p1_sample4
p1_sample5
p1_sample6
p1_sample7
titlepage
tocpage
p2_landing_page
p2_sample1
p2_sample2
p2_sample3
p2_sample4
p2_sample5
p2_sample6
p2_sample7
p2_sample8
p2_sample9
p2_sample10
p2_sample11
p2_sample12
p2_sample13
p2_sample14
titlepage
tocpage
p1_landing_page
p1_sample1
p1_sample2
p1_sample3
p1_sample4
p1_sample5
p1_sample6
p1_sample7
titlepage
tocpage
X-WAF-README
xwaf_installation
xwaf_depoly
xwaf_README
xwaf_advanced_readme
xwaf_getting_started
xwaf_faqs_readme
xwaf_roadmap
titlepage
tocpage
nginx-lua-module-zh-wiki
titlepage
tocpage
orange_api_server
orange_build_plugin
orange_dashboard_usage
orange_README
orange_basic_auth
orange_basic_info
orange_divide
orange_key_auth
orange_monitor
orange_rate_limiting
orange_redirect
orange_rewrite
orange_stat
orange_waf
orange_condition
orange_expression
orange_extraction
orange_extractor
orange_handle
orange_judge
orange_rule
orange_about
orange_contributing
orange_issues
orange_usages
titlepage
tocpage
add_new_lua_api
cosocket
get_req_body
get_url_param
helloworld
how_request_http
inline_var
install
install_on_centos
install_on_ubuntu
install_on_windows
install_osx
log_response
outtest
response
safe_sql
share_var
simple_api
sub_request
work_with_location
array_size
break
brief
build_env
call_user_func_array
capture
class
control_structrues
dot_diff
dummy_var
FFI
file
for
function_before_use
function_define
function_descrip
function_parameter
function_result
if_else
local
main
math_library
metatable
module_is_evil
module
not_nill
not_use_lib
not_use_module
object_oriented
operator
re
repeat
string_library
table_library
time_date_function
what_jit
while
pra_flame_how
pra_flame_install
pra_flame_what
pra_flame_when
pra_ngx_lua_allow_deny
pra_ngx_lua_block_io
pra_ngx_lua_cache
pra_ngx_lua_capture
pra_ngx_lua_continue_after_eof
pra_ngx_lua_debug
pra_ngx_lua_ffi
pra_ngx_lua_hot_load
pra_ngx_lua_how_one_instance_time
pra_ngx_lua_how_use_third_lib
pra_ngx_lua_keepalive
pra_ngx_lua_log
pra_ngx_lua_lua-limit
pra_ngx_lua_lua_opt
pra_ngx_lua_lua-variable-scope
pra_ngx_lua_on_abort
pra_ngx_lua_phase
pra_ngx_lua_resolve_the_domain_name
pra_ngx_lua_shared_get_keys
pra_ngx_lua_sleep
pra_ngx_lua_timer
pra_ngx_lua_use_case
pra_ngx_lua_whats_cosocket
pra_redis_auth_connect
pra_redis_dynamic_redis_module_method
pra_redis_out_package
pra_redis_pipeline
pra_redis_pub_sub_package
pra_redis_script
pra_redis_select-keeplive
pra_postgres_health_check
pra_postgres_how_to_use
pra_postgres_not_support_transaction
pra_postgres_sql_inject
pra_postgres_timeout
pra_nginx_balancer
pra_nginx_co-work_of_location
pra_nginx_if_is_evil
pra_nginx_match_uri
pra_nginx_nginx_brief
pra_nginx_nginx_local_pcre
pra_nginx_nginx_log
pra_nginx_nginx
pra_nginx_pitfalls_and_common_mistakes
pra_nginx_reverse_proxy
pra_nginx_static_file
titlepage
tocpage
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_scan_port
candylab_common_sites_log_system
candylab_graylog_clickhouse
candylab_clickhouse_basic
candylab_logs_and_gateway
candylab_sec_system_arch
candylab_logs_dsl_waf
candylab_opensock_list
candylab_opensock_practice
candylab_opensock_email
candylab_base_on_openresty_waf
candylab_dsl_waf
candylab_honeypot_system
candylab_monitor_redis
candylab_threat_replay
candylab_pcap_monitor
candylab_monitor_website
candylab_openrestyplus_waf
candylab_windows_bigdata
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
candylab_clickhouse_basic
mydoc_hyperlinks.html#automatedlinks
mydoc_hyperlinks.html#bookmarklinks
mydoc_pages.html#someIdTag
news
nginx-lua-module-zh-wiki
nginx-development-guide-zh
orange_about
X-WAF-README
pra_flame_how