From fb994c71d7d4ae5aa7875889077046db5bebde80 Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Mon, 29 Jun 2020 20:02:05 +0200 Subject: [PATCH] Make search index configurable Closes #961 --- CHANGELOG.md | 1 + Cargo.lock | 204 ++++++++++++------ components/config/src/config/mod.rs | 8 +- components/config/src/config/search.rs | 27 +++ components/config/src/config/slugify.rs | 1 - components/config/src/lib.rs | 4 +- components/search/Cargo.toml | 1 + components/search/src/lib.rs | 138 ++++++++++-- components/site/src/lib.rs | 12 +- docs/content/documentation/content/search.md | 4 + .../getting-started/configuration.md | 20 +- 11 files changed, 330 insertions(+), 90 deletions(-) create mode 100644 components/config/src/config/search.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c21902b..f909769d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Fix parsing of dates in arrays in `extra` - Add a `--force` argument to `zola init` to allow creating a Zola site in a non-empty directory - Make themes more flexible: `include` can now be used +- Make search index generation configurable ## 0.11.0 (2020-05-25) diff --git a/Cargo.lock b/Cargo.lock index 72c9c773..9d76ba38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,9 +8,9 @@ checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d" [[package]] name = "aho-corasick" -version = "0.7.10" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" dependencies = [ "memchr", ] @@ -36,7 +36,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -58,7 +58,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -75,15 +75,15 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" [[package]] name = "base64" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e223af0dc48c96d4f8342ec01a4974f139df863896b316681efd36742f22cc67" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] name = "bincode" -version = "1.2.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf" +checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d" dependencies = [ "byteorder", "serde", @@ -109,13 +109,10 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbcf92448676f82bb7a334c58bbce8b0d43580fb5362a9d608b18879d12a3d31" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", - "byte-tools", - "byteorder", "generic-array 0.14.2", ] @@ -176,15 +173,18 @@ dependencies = [ [[package]] name = "bytes" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" +checksum = "118cf036fbb97d0816e3c34b2d7a1e8cfc60f68fcf63d550ddbe9bd5f59c213b" +dependencies = [ + "loom", +] [[package]] name = "cc" -version = "1.0.54" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" +checksum = "b1be3409f94d7bdceeb5f5fac551039d9b3f00e25da7a74fc4d33400a0d96368" [[package]] name = "cfg-if" @@ -243,7 +243,7 @@ checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" dependencies = [ "atty", "lazy_static", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -261,6 +261,12 @@ dependencies = [ "utils", ] +[[package]] +name = "cpuid-bool" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d375c433320f6c5057ae04a04376eef4d04ce2801448cf8863a78da99107be4" + [[package]] name = "crc32fast" version = "1.2.0" @@ -347,7 +353,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a4ba686dff9fa4c1c9636ce1010b0cf98ceb421361b0bb3d6faeec43bd217a7" dependencies = [ "nix", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -470,7 +476,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -623,6 +629,19 @@ dependencies = [ "slab", ] +[[package]] +name = "generator" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add72f17bb81521258fcc8a7a3245b1e184e916bfbe34f0ea89558f440df5c68" +dependencies = [ + "cc", + "libc", + "log", + "rustc_version", + "winapi 0.3.9", +] + [[package]] name = "generic-array" version = "0.12.3" @@ -708,7 +727,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.5", "fnv", "futures-core", "futures-sink", @@ -759,7 +778,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.5", "fnv", "itoa", ] @@ -770,7 +789,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.5", "http", ] @@ -792,7 +811,7 @@ version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6e7655b9594024ad0ee439f3b5a7299369dc2a3f459b47c696f9ff676f9aa1f" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.5", "futures-channel", "futures-core", "futures-util", @@ -816,7 +835,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac965ea399ec3a25ac7d13b8affd4b8f39325cca00858ddf5eb29b79e6b14b08" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.5", "futures-util", "hyper", "log", @@ -840,7 +859,7 @@ dependencies = [ "percent-encoding", "tokio", "url", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -874,9 +893,9 @@ dependencies = [ [[package]] name = "image" -version = "0.23.5" +version = "0.23.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d534e95ad8b9d5aa614322d02352b4f1bf962254adcf02ac6f2def8be18498e8" +checksum = "b5b0553fec6407d63fe2975b794dfb099f3f790bdc958823851af37b26404ab4" dependencies = [ "bytemuck", "byteorder", @@ -1051,6 +1070,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "loom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ecc775857611e1df29abba5c41355cdf540e7e9d4acfdf0f355eefee82330b7" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", +] + [[package]] name = "lzw" version = "0.10.0" @@ -1219,7 +1249,7 @@ checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ "cfg-if", "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1256,7 +1286,7 @@ dependencies = [ "mio", "mio-extras", "walkdir", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1282,9 +1312,9 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138" dependencies = [ "autocfg", "num-integer", @@ -1344,13 +1374,19 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "open" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c283bf0114efea9e42f1a60edea9859e8c47528eae09d01df4b29c1e489cc48" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1493,7 +1529,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b336d94e8e4ce29bf15bba393164629764744c567e8ad306cc1fdd0119967fd" dependencies = [ - "base64 0.12.2", + "base64 0.12.3", "chrono", "indexmap", "line-wrap", @@ -1527,9 +1563,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "proc-macro-error" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" +checksum = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880" dependencies = [ "proc-macro-error-attr", "proc-macro2", @@ -1540,9 +1576,9 @@ dependencies = [ [[package]] name = "proc-macro-error-attr" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53" +checksum = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50" dependencies = [ "proc-macro2", "quote", @@ -1720,7 +1756,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1750,8 +1786,8 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b82c9238b305f26f53443e3a4bc8528d64b8d0bee408ec949eb7bf5635ec680" dependencies = [ - "base64 0.12.2", - "bytes 0.5.4", + "base64 0.12.3", + "bytes 0.5.5", "encoding_rs", "futures-core", "futures-util", @@ -1791,7 +1827,7 @@ dependencies = [ "spin", "untrusted", "web-sys", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1813,6 +1849,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + [[package]] name = "rustls" version = "0.17.0" @@ -1869,6 +1914,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "scoped-tls" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" + [[package]] name = "scoped_threadpool" version = "0.1.9" @@ -1896,6 +1947,7 @@ name = "search" version = "0.1.0" dependencies = [ "ammonia", + "config", "elasticlunr-rs", "errors", "lazy_static", @@ -1903,16 +1955,31 @@ dependencies = [ ] [[package]] -name = "serde" -version = "1.0.112" +name = "semver" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736aac72d1eafe8e5962d1d1c3d99b0df526015ba40915cb3c49d042e92ec243" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" [[package]] name = "serde_derive" -version = "1.0.112" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0343ce212ac0d3d6afd9391ac8e9c9efe06b533c8d33f660f6390cc4093f57" +checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" dependencies = [ "proc-macro2", "quote", @@ -1952,19 +2019,20 @@ dependencies = [ "block-buffer 0.7.3", "digest 0.8.1", "fake-simd", - "opaque-debug", + "opaque-debug 0.2.3", ] [[package]] name = "sha2" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72377440080fd008550fe9b441e854e43318db116f90181eef92e9ae9aedab48" +checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" dependencies = [ - "block-buffer 0.8.0", + "block-buffer 0.9.0", + "cfg-if", + "cpuid-bool", "digest 0.9.0", - "fake-simd", - "opaque-debug", + "opaque-debug 0.3.0", ] [[package]] @@ -2025,7 +2093,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -2097,9 +2165,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.31" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6" +checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" dependencies = [ "proc-macro2", "quote", @@ -2150,14 +2218,14 @@ dependencies = [ "rand", "redox_syscall", "remove_dir_all", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "templates" version = "0.1.0" dependencies = [ - "base64 0.12.2", + "base64 0.12.3", "config", "csv", "errors", @@ -2255,7 +2323,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -2270,7 +2338,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.5", "fnv", "futures-core", "iovec", @@ -2312,7 +2380,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.5", "futures-core", "futures-sink", "log", @@ -2444,9 +2512,9 @@ checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" [[package]] name = "unicode-xid" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "untrusted" @@ -2513,7 +2581,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" dependencies = [ "same-file", - "winapi 0.3.8", + "winapi 0.3.9", "winapi-util", ] @@ -2638,9 +2706,9 @@ checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", @@ -2664,7 +2732,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -2679,7 +2747,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] diff --git a/components/config/src/config/mod.rs b/components/config/src/config/mod.rs index 4825cd5c..c9a49d7d 100644 --- a/components/config/src/config/mod.rs +++ b/components/config/src/config/mod.rs @@ -1,7 +1,8 @@ pub mod languages; -pub mod taxonomies; pub mod link_checker; +pub mod search; pub mod slugify; +pub mod taxonomies; use std::collections::HashMap; use std::path::{Path, PathBuf}; @@ -26,7 +27,6 @@ pub enum Mode { Check, } - #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(default)] pub struct Config { @@ -99,6 +99,9 @@ pub struct Config { /// The setup for which slugification strategies to use for paths, taxonomies and anchors pub slugify: slugify::Slugify, + /// The search config, telling what to include in the search index + pub search: search::Search, + /// All user params set in [extra] in the config pub extra: HashMap, } @@ -303,6 +306,7 @@ impl Default for Config { extra_syntax_set: None, link_checker: link_checker::LinkChecker::default(), slugify: slugify::Slugify::default(), + search: search::Search::default(), extra: HashMap::new(), } } diff --git a/components/config/src/config/search.rs b/components/config/src/config/search.rs new file mode 100644 index 00000000..82d46c7a --- /dev/null +++ b/components/config/src/config/search.rs @@ -0,0 +1,27 @@ +use serde_derive::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(default)] +pub struct Search { + /// Include the title of the page in the search index. `true` by default. + pub include_title: bool, + /// Includes the whole content in the search index. Ok for small sites but becomes + /// too big on large sites. `true` by default. + pub include_content: bool, + /// Optionally truncate the content down to `n` chars. This might cut content in a word + pub truncate_content_length: Option, + /// Includes the description in the search index. When the site becomes too large, you can switch + /// to that instead. `false` by default + pub include_description: bool, +} + +impl Default for Search { + fn default() -> Self { + Search { + include_title: true, + include_content: true, + include_description: false, + truncate_content_length: None, + } + } +} diff --git a/components/config/src/config/slugify.rs b/components/config/src/config/slugify.rs index 67e87061..e3dd1615 100644 --- a/components/config/src/config/slugify.rs +++ b/components/config/src/config/slugify.rs @@ -2,7 +2,6 @@ use serde_derive::{Deserialize, Serialize}; use utils::slugs::SlugifyStrategy; - #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(default)] pub struct Slugify { diff --git a/components/config/src/lib.rs b/components/config/src/lib.rs index 45654a02..ada1bf1c 100644 --- a/components/config/src/lib.rs +++ b/components/config/src/lib.rs @@ -1,7 +1,9 @@ mod config; pub mod highlighting; mod theme; -pub use crate::config::{Config, languages::Language, link_checker::LinkChecker, taxonomies::Taxonomy}; +pub use crate::config::{ + languages::Language, link_checker::LinkChecker, taxonomies::Taxonomy, Config, +}; use std::path::Path; diff --git a/components/search/Cargo.toml b/components/search/Cargo.toml index 1f223c55..886c8f50 100644 --- a/components/search/Cargo.toml +++ b/components/search/Cargo.toml @@ -11,3 +11,4 @@ lazy_static = "1" errors = { path = "../errors" } library = { path = "../library" } +config = { path = "../config" } diff --git a/components/search/src/lib.rs b/components/search/src/lib.rs index 76eee5d9..c8314e5a 100644 --- a/components/search/src/lib.rs +++ b/components/search/src/lib.rs @@ -3,6 +3,7 @@ use std::collections::{HashMap, HashSet}; use elasticlunr::{Index, Language}; use lazy_static::lazy_static; +use config::Config; use errors::{bail, Result}; use library::{Library, Section}; @@ -25,11 +26,61 @@ lazy_static! { }; } +fn build_fields(config: &Config) -> Vec { + let mut fields = vec![]; + if config.search.include_title { + fields.push("title".to_owned()); + } + + if config.search.include_description { + fields.push("description".to_owned()); + } + + if config.search.include_content { + fields.push("body".to_owned()); + } + + fields +} + +fn fill_index( + config: &Config, + title: &Option, + description: &Option, + content: &str, +) -> Vec { + let mut row = vec![]; + + if config.search.include_title { + row.push(title.clone().unwrap_or_default()); + } + + if config.search.include_description { + row.push(description.clone().unwrap_or_default()); + } + + if config.search.include_content { + let body = AMMONIA.clean(&content).to_string(); + if let Some(truncate_len) = config.search.truncate_content_length { + // Not great for unicode + // TODO: fix it like the truncate in Tera + match body.char_indices().nth(truncate_len) { + None => row.push(body), + Some((idx, _)) => row.push((&body[..idx]).to_string()), + }; + } else { + row.push(body); + }; + } + + row +} + /// Returns the generated JSON index with all the documents of the site added using /// the language given /// Errors if the language given is not available in Elasticlunr /// TODO: is making `in_search_index` apply to subsections of a `false` section useful? -pub fn build_index(lang: &str, library: &Library) -> Result { +pub fn build_index(lang: &str, library: &Library, config: &Config) -> Result { let language = match Language::from_code(lang) { Some(l) => l, None => { @@ -37,18 +88,18 @@ pub fn build_index(lang: &str, library: &Library) -> Result { } }; - let mut index = Index::with_language(language, &["title", "body"]); + let mut index = Index::with_language(language, &build_fields(&config)); for section in library.sections_values() { if section.lang == lang { - add_section_to_index(&mut index, section, library); + add_section_to_index(&mut index, section, library, config); } } Ok(index.to_json()) } -fn add_section_to_index(index: &mut Index, section: &Section, library: &Library) { +fn add_section_to_index(index: &mut Index, section: &Section, library: &Library, config: &Config) { if !section.meta.in_search_index { return; } @@ -57,10 +108,7 @@ fn add_section_to_index(index: &mut Index, section: &Section, library: &Library) if section.meta.redirect_to.is_none() { index.add_doc( §ion.permalink, - &[ - §ion.meta.title.clone().unwrap_or_default(), - &AMMONIA.clean(§ion.content).to_string(), - ], + &fill_index(config, §ion.meta.title, §ion.meta.description, §ion.content), ); } @@ -72,10 +120,76 @@ fn add_section_to_index(index: &mut Index, section: &Section, library: &Library) index.add_doc( &page.permalink, - &[ - &page.meta.title.clone().unwrap_or_default(), - &AMMONIA.clean(&page.content).to_string(), - ], + &fill_index(config, &page.meta.title, &page.meta.description, &page.content), ); } } + +#[cfg(test)] +mod tests { + use super::*; + + use config::Config; + + #[test] + fn can_build_fields() { + let mut config = Config::default(); + let fields = build_fields(&config); + assert_eq!(fields, vec!["title", "body"]); + + config.search.include_content = false; + config.search.include_description = true; + let fields = build_fields(&config); + assert_eq!(fields, vec!["title", "description"]); + + config.search.include_content = true; + let fields = build_fields(&config); + assert_eq!(fields, vec!["title", "description", "body"]); + + config.search.include_title = false; + let fields = build_fields(&config); + assert_eq!(fields, vec!["description", "body"]); + } + + #[test] + fn can_fill_index_default() { + let config = Config::default(); + let title = Some("A title".to_string()); + let description = Some("A description".to_string()); + let content = "Some content".to_string(); + + let res = fill_index(&config, &title, &description, &content); + assert_eq!(res.len(), 2); + assert_eq!(res[0], title.unwrap()); + assert_eq!(res[1], content); + } + + #[test] + fn can_fill_index_description() { + let mut config = Config::default(); + config.search.include_description = true; + let title = Some("A title".to_string()); + let description = Some("A description".to_string()); + let content = "Some content".to_string(); + + let res = fill_index(&config, &title, &description, &content); + assert_eq!(res.len(), 3); + assert_eq!(res[0], title.unwrap()); + assert_eq!(res[1], description.unwrap()); + assert_eq!(res[2], content); + } + + #[test] + fn can_fill_index_truncated_content() { + let mut config = Config::default(); + config.search.truncate_content_length = Some(5); + let title = Some("A title".to_string()); + let description = Some("A description".to_string()); + let content = "Some content".to_string(); + + let res = fill_index(&config, &title, &description, &content); + assert_eq!(res.len(), 2); + assert_eq!(res[0], title.unwrap()); + assert_eq!(res[1], content[..5]); + } +} diff --git a/components/site/src/lib.rs b/components/site/src/lib.rs index a6cf93d3..19e9e449 100644 --- a/components/site/src/lib.rs +++ b/components/site/src/lib.rs @@ -810,7 +810,11 @@ impl Site { &self.output_path.join(&format!("search_index.{}.js", self.config.default_language)), &format!( "window.searchIndex = {};", - search::build_index(&self.config.default_language, &self.library.read().unwrap())? + search::build_index( + &self.config.default_language, + &self.library.read().unwrap(), + &self.config + )? ), )?; @@ -820,7 +824,11 @@ impl Site { &self.output_path.join(&format!("search_index.{}.js", &language.code)), &format!( "window.searchIndex = {};", - search::build_index(&language.code, &self.library.read().unwrap())? + search::build_index( + &language.code, + &self.library.read().unwrap(), + &self.config + )? ), )?; } diff --git a/docs/content/documentation/content/search.md b/docs/content/documentation/content/search.md index e46711b2..df29f773 100644 --- a/docs/content/documentation/content/search.md +++ b/docs/content/documentation/content/search.md @@ -20,3 +20,7 @@ After `zola build` or `zola serve`, you should see two files in your static dire As each site will be different, Zola makes no assumptions about your search function and doesn't provide the JavaScript/CSS code to do an actual search and display results. You can look at how this site implements it to get an idea: [search.js](https://github.com/getzola/zola/tree/master/docs/static/search.js). + +## Configuring the search index +In some cases, the default indexing strategy is not suitable. You can customise which fields to include and whether +to truncate the content in the [search configuration](@/documentation/getting-started/configuration.md). diff --git a/docs/content/documentation/getting-started/configuration.md b/docs/content/documentation/getting-started/configuration.md index 8c1b79c0..dc45918e 100644 --- a/docs/content/documentation/getting-started/configuration.md +++ b/docs/content/documentation/getting-started/configuration.md @@ -76,10 +76,6 @@ languages = [] # When set to "true", the Sass files in the `sass` directory are compiled. compile_sass = false -# When set to "true", a search index is built from the pages and section -# content for `default_language`. -build_search_index = false - # A list of glob patterns specifying asset files to ignore when the content # directory is processed. Defaults to none, which means that all asset files are # copied over to the `public` directory. @@ -121,6 +117,22 @@ paths = "on" taxonomies = "on" anchors = "on" +# When set to "true", a search index is built from the pages and section +# content for `default_language`. +build_search_index = false + +[search] +# Whether to include the title of the page/section in the index +include_title = true +# Whether to include the description of the page/section in the index +include_description = false +# Whether to include the rendered content of the page/section in the index +include_content = true +# At which character to truncate the content to. Useful if you have a lot of pages and the index would +# become too big to load on the site. Defaults to not being set. +# truncate_content_length = 100 + + # Optional translation object. Keys should be language codes. [translations]