Fix slugified taxonomies rendering

Closes #1177
This commit is contained in:
Vincent Prouillet 2020-09-21 21:43:02 +02:00
parent f9ae897190
commit b313c97ceb
16 changed files with 294 additions and 159 deletions

View file

@ -1,7 +1,10 @@
# Changelog
## 0.13.0 (unreleased)
## 0.12.1 (unreleased)
- Add line
- Fix the new `zola serve` being broken on Windows
- Fix slugified taxonomies not being rendered at the right path
## 0.12.0 (2020-09-04)

View file

@ -17,10 +17,7 @@ lazy_static! {
}
/// Returns the highlighter and whether it was found in the extra or not
pub fn get_highlighter(
language: Option<&str>,
config: &Config
) -> (HighlightLines<'static>, bool) {
pub fn get_highlighter(language: Option<&str>, config: &Config) -> (HighlightLines<'static>, bool) {
let theme = &THEME_SET.themes[&config.highlight_theme];
let mut in_extra = false;

View file

@ -103,7 +103,7 @@ impl<'a> Paginator<'a> {
paginate_reversed: false,
root: PaginationRoot::Taxonomy(taxonomy, item),
permalink: item.permalink.clone(),
path: format!("/{}/{}/", taxonomy.kind.name, item.slug),
path: format!("/{}/{}/", taxonomy.slug, item.slug),
paginate_path: taxonomy
.kind
.paginate_path
@ -129,7 +129,7 @@ impl<'a> Paginator<'a> {
}
for key in self.all_pages.to_mut().iter_mut() {
let page = library.get_page_by_key(key.clone());
let page = library.get_page_by_key(*key);
current_page.push(page.to_serialized_basic(library));
if current_page.len() == self.paginate_by {
@ -416,7 +416,11 @@ mod tests {
permalink: "https://vincent.is/tags/something/".to_string(),
pages: library.pages().keys().collect(),
};
let taxonomy = Taxonomy { kind: taxonomy_def, items: vec![taxonomy_item.clone()] };
let taxonomy = Taxonomy {
kind: taxonomy_def,
slug: "tags".to_string(),
items: vec![taxonomy_item.clone()],
};
let paginator = Paginator::from_taxonomy(&taxonomy, &taxonomy_item, &library);
assert_eq!(paginator.pagers.len(), 2);
@ -431,6 +435,39 @@ mod tests {
assert_eq!(paginator.pagers[1].path, "/tags/something/page/2/");
}
#[test]
fn test_can_create_paginator_for_slugified_taxonomy() {
let (_, library) = create_library(false, 3, false);
let taxonomy_def = TaxonomyConfig {
name: "some tags".to_string(),
paginate_by: Some(2),
..TaxonomyConfig::default()
};
let taxonomy_item = TaxonomyItem {
name: "Something".to_string(),
slug: "something".to_string(),
permalink: "https://vincent.is/some-tags/something/".to_string(),
pages: library.pages().keys().collect(),
};
let taxonomy = Taxonomy {
kind: taxonomy_def,
slug: "some-tags".to_string(),
items: vec![taxonomy_item.clone()],
};
let paginator = Paginator::from_taxonomy(&taxonomy, &taxonomy_item, &library);
assert_eq!(paginator.pagers.len(), 2);
assert_eq!(paginator.pagers[0].index, 1);
assert_eq!(paginator.pagers[0].pages.len(), 2);
assert_eq!(paginator.pagers[0].permalink, "https://vincent.is/some-tags/something/");
assert_eq!(paginator.pagers[0].path, "/some-tags/something/");
assert_eq!(paginator.pagers[1].index, 2);
assert_eq!(paginator.pagers[1].pages.len(), 2);
assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/some-tags/something/page/2/");
assert_eq!(paginator.pagers[1].path, "/some-tags/something/page/2/");
}
// https://github.com/getzola/zola/issues/866
#[test]
fn works_with_empty_paginate_path() {

View file

@ -53,6 +53,7 @@ impl TaxonomyItem {
pub fn new(
name: &str,
taxonomy: &TaxonomyConfig,
taxo_slug: &str,
config: &Config,
keys: Vec<DefaultKey>,
library: &Library,
@ -72,7 +73,6 @@ impl TaxonomyItem {
.collect();
let (mut pages, ignored_pages) = sort_pages_by_date(data);
let item_slug = slugify_paths(name, config.slugify.taxonomies);
let taxo_slug = slugify_paths(&taxonomy.name, config.slugify.taxonomies);
let permalink = if taxonomy.lang != config.default_language {
config.make_permalink(&format!("/{}/{}/{}", taxonomy.lang, taxo_slug, item_slug))
} else {
@ -118,6 +118,7 @@ impl<'a> SerializedTaxonomy<'a> {
#[derive(Debug, Clone, PartialEq)]
pub struct Taxonomy {
pub kind: TaxonomyConfig,
pub slug: String,
// this vec is sorted by the count of item
pub items: Vec<TaxonomyItem>,
}
@ -130,8 +131,9 @@ impl Taxonomy {
library: &Library,
) -> Taxonomy {
let mut sorted_items = vec![];
let slug = slugify_paths(&kind.name, config.slugify.taxonomies);
for (name, pages) in items {
sorted_items.push(TaxonomyItem::new(&name, &kind, config, pages, library));
sorted_items.push(TaxonomyItem::new(&name, &kind, &slug, config, pages, library));
}
//sorted_items.sort_by(|a, b| a.name.cmp(&b.name));
sorted_items.sort_by(|a, b| match a.slug.cmp(&b.slug) {
@ -150,7 +152,7 @@ impl Taxonomy {
false
}
});
Taxonomy { kind, items: sorted_items }
Taxonomy { kind, slug, items: sorted_items }
}
pub fn len(&self) -> usize {

View file

@ -1,11 +1,11 @@
use syntect::html::{IncludeBackground, styled_line_to_highlighted_html};
use syntect::easy::HighlightLines;
use syntect::parsing::SyntaxSet;
use syntect::highlighting::{Color, Theme, Style};
use config::Config;
use config::highlighting::{get_highlighter, SYNTAX_SET, THEME_SET};
use config::Config;
use std::cmp::min;
use std::collections::HashSet;
use syntect::easy::HighlightLines;
use syntect::highlighting::{Color, Style, Theme};
use syntect::html::{styled_line_to_highlighted_html, IncludeBackground};
use syntect::parsing::SyntaxSet;
use super::fence::{FenceSettings, Range};
@ -22,11 +22,7 @@ pub struct CodeBlock<'config> {
}
impl<'config> CodeBlock<'config> {
pub fn new(
fence_info: &str,
config: &'config Config,
background: IncludeBackground,
) -> Self {
pub fn new(fence_info: &str, config: &'config Config, background: IncludeBackground) -> Self {
let fence_info = FenceSettings::new(fence_info);
let theme = &THEME_SET.themes[&config.highlight_theme];
let (highlighter, in_extra) = get_highlighter(fence_info.language, config);
@ -45,10 +41,8 @@ impl<'config> CodeBlock<'config> {
}
pub fn highlight(&mut self, text: &str) -> String {
let highlighted = self.highlighter.highlight(
text,
self.extra_syntax_set.unwrap_or(&SYNTAX_SET),
);
let highlighted =
self.highlighter.highlight(text, self.extra_syntax_set.unwrap_or(&SYNTAX_SET));
let line_boundaries = self.find_line_boundaries(&highlighted);
// First we make sure that `highlighted` is split at every line
@ -61,9 +55,8 @@ impl<'config> CodeBlock<'config> {
// we don't use it later.
let mut highlighted = perform_split(&highlighted, line_boundaries);
let hl_background = self.theme.settings.line_highlight
.unwrap_or(Color { r: 255, g: 255, b: 0, a: 0 });
let hl_background =
self.theme.settings.line_highlight.unwrap_or(Color { r: 255, g: 255, b: 0, a: 0 });
let hl_lines = self.get_highlighted_lines();
color_highlighted_lines(&mut highlighted, &hl_lines, hl_background);
@ -76,10 +69,7 @@ impl<'config> CodeBlock<'config> {
for (vec_idx, (_style, s)) in styled.iter().enumerate() {
for (str_idx, character) in s.char_indices() {
if character == '\n' {
boundaries.push(StyledIdx {
vec_idx,
str_idx,
});
boundaries.push(StyledIdx { vec_idx, str_idx });
}
}
}
@ -90,7 +80,7 @@ impl<'config> CodeBlock<'config> {
fn get_highlighted_lines(&self) -> HashSet<usize> {
let mut lines = HashSet::new();
for range in &self.highlight_lines {
for line in range.from ..= min(range.to, self.num_lines) {
for line in range.from..=min(range.to, self.num_lines) {
// Ranges are one-indexed
lines.insert(line.saturating_sub(1));
}
@ -123,7 +113,7 @@ fn get_str_idx_if_vec_idx_is(idx: Option<&StyledIdx>, vec_idx: usize) -> Option<
/// the `StyledIdx` type.
fn perform_split<'b>(
split: &[(Style, &'b str)],
line_boundaries: Vec<StyledIdx>
line_boundaries: Vec<StyledIdx>,
) -> Vec<(Style, &'b str)> {
let mut result = Vec::new();
@ -172,11 +162,7 @@ fn perform_split<'b>(
result
}
fn color_highlighted_lines(
data: &mut [(Style, &str)],
lines: &HashSet<usize>,
background: Color,
) {
fn color_highlighted_lines(data: &mut [(Style, &str)], lines: &HashSet<usize>, background: Color) {
if lines.is_empty() {
return;
}

View file

@ -9,22 +9,16 @@ impl Range {
match s.find('-') {
Some(dash) => {
let mut from = s[..dash].parse().ok()?;
let mut to = s[dash+1..].parse().ok()?;
let mut to = s[dash + 1..].parse().ok()?;
if to < from {
std::mem::swap(&mut from, &mut to);
}
Some(Range {
from,
to,
})
},
Some(Range { from, to })
}
None => {
let val = s.parse().ok()?;
Some(Range {
from: val,
to: val,
})
},
Some(Range { from: val, to: val })
}
}
}
}
@ -37,11 +31,7 @@ pub struct FenceSettings<'a> {
}
impl<'a> FenceSettings<'a> {
pub fn new(fence_info: &'a str) -> Self {
let mut me = Self {
language: None,
line_numbers: false,
highlight_lines: Vec::new(),
};
let mut me = Self { language: None, line_numbers: false, highlight_lines: Vec::new() };
for token in FenceIter::new(fence_info) {
match token {
@ -67,9 +57,7 @@ struct FenceIter<'a> {
}
impl<'a> FenceIter<'a> {
fn new(fence_info: &'a str) -> Self {
Self {
split: fence_info.split(','),
}
Self { split: fence_info.split(',') }
}
}
@ -92,10 +80,10 @@ impl<'a> Iterator for FenceIter<'a> {
}
}
return Some(FenceToken::HighlightLines(ranges));
},
}
lang => {
return Some(FenceToken::Language(lang));
},
}
}
}
}

View file

@ -5,8 +5,6 @@ use tera::Tera;
use config::Config;
use front_matter::InsertAnchor;
use rendering::{render_content, RenderContext};
use templates::ZOLA_TERA;
use utils::slugs::SlugifyStrategy;
macro_rules! colored_html_line {
( @no $s:expr ) => {{
@ -41,19 +39,26 @@ fn hl_lines_simple() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=2
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@no "foo",
@hl "bar",
@no "bar\nbaz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@no "foo",
@hl "bar",
@no "bar\nbaz",
)
);
}
#[test]
@ -63,19 +68,26 @@ fn hl_lines_in_middle() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=2-3
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@no "foo",
@hl "bar\nbar",
@no "baz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@no "foo",
@hl "bar\nbar",
@no "baz",
)
);
}
#[test]
@ -85,17 +97,24 @@ fn hl_lines_all() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=1-4
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@hl "foo\nbar\nbar\nbaz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@hl "foo\nbar\nbar\nbaz",
)
);
}
#[test]
@ -105,18 +124,25 @@ fn hl_lines_start_from_one() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=1-3
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@hl "foo\nbar\nbar",
@no "baz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@hl "foo\nbar\nbar",
@no "baz",
)
);
}
#[test]
@ -126,18 +152,25 @@ fn hl_lines_start_from_zero() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=0-3
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@hl "foo\nbar\nbar",
@no "baz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@hl "foo\nbar\nbar",
@no "baz",
)
);
}
#[test]
@ -147,18 +180,25 @@ fn hl_lines_end() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=3-4
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@no "foo\nbar",
@hl "bar\nbaz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@no "foo\nbar",
@hl "bar\nbaz",
)
);
}
#[test]
@ -168,18 +208,25 @@ fn hl_lines_end_out_of_bounds() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=3-4294967295
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@no "foo\nbar",
@hl "bar\nbaz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@no "foo\nbar",
@hl "bar\nbaz",
)
);
}
#[test]
@ -189,18 +236,25 @@ fn hl_lines_overlap() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=2-3 1-2
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@hl "foo\nbar\nbar",
@no "baz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@hl "foo\nbar\nbar",
@no "baz",
)
);
}
#[test]
fn hl_lines_multiple() {
@ -209,18 +263,25 @@ fn hl_lines_multiple() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=2-3,hl_lines=1-2
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@hl "foo\nbar\nbar",
@no "baz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@hl "foo\nbar\nbar",
@no "baz",
)
);
}
#[test]
@ -230,18 +291,25 @@ fn hl_lines_extra_spaces() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
``` hl_lines = 2 - 3 1 - 2
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@hl "foo\nbar\nbar",
@no "baz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@hl "foo\nbar\nbar",
@no "baz",
)
);
}
#[test]
@ -251,19 +319,26 @@ fn hl_lines_int_and_range() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=1 3-4
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@hl "foo",
@no "bar",
@hl "bar\nbaz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@hl "foo",
@no "bar",
@hl "bar\nbaz",
)
);
}
#[test]
@ -273,22 +348,28 @@ fn hl_lines_single_line_range() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=2-2
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@no "foo",
@hl "bar",
@no "bar\nbaz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@no "foo",
@hl "bar",
@no "bar\nbaz",
)
);
}
#[test]
fn hl_lines_reverse_range() {
let tera_ctx = Tera::default();
@ -296,17 +377,24 @@ fn hl_lines_reverse_range() {
let mut config = Config::default();
config.highlight_code = true;
let context = RenderContext::new(&tera_ctx, &config, "", &permalinks_ctx, InsertAnchor::None);
let res = render_content(r#"
let res = render_content(
r#"
```hl_lines=3-2
foo
bar
bar
baz
```
"#, &context).unwrap();
assert_eq!(res.body, colored_html!(
@no "foo",
@hl "bar\nbar",
@no "baz",
));
"#,
&context,
)
.unwrap();
assert_eq!(
res.body,
colored_html!(
@no "foo",
@hl "bar\nbar",
@no "baz",
)
);
}

View file

@ -452,12 +452,17 @@ impl Site {
let cfg = &Cfg { minify_js: false };
let mut input_bytes = html.as_bytes().to_vec();
match with_friendly_error(&mut input_bytes, cfg) {
Ok(_len) => match std::str::from_utf8(&mut input_bytes) {
Ok(_len) => match std::str::from_utf8(&input_bytes) {
Ok(result) => Ok(result.to_string()),
Err(err) => bail!("Failed to convert bytes to string : {}", err),
},
Err(minify_error) => {
bail!("Failed to truncate html at character {}: {} \n {}", minify_error.position, minify_error.message, minify_error.code_context);
bail!(
"Failed to truncate html at character {}: {} \n {}",
minify_error.position,
minify_error.message,
minify_error.code_context
);
}
}
}
@ -548,7 +553,7 @@ impl Site {
let site_path =
if filename != "index.html" { site_path.join(filename) } else { site_path };
&SITE_CONTENT.write().unwrap().insert(site_path, final_content);
SITE_CONTENT.write().unwrap().insert(site_path, final_content);
}
}
@ -763,7 +768,7 @@ impl Site {
components.push(taxonomy.kind.lang.as_ref());
}
components.push(taxonomy.kind.name.as_ref());
components.push(taxonomy.slug.as_ref());
let list_output =
taxonomy.render_all_terms(&self.tera, &self.config, &self.library.read().unwrap())?;
@ -793,7 +798,7 @@ impl Site {
if taxonomy.kind.feed {
self.render_feed(
item.pages.iter().map(|p| library.get_page_by_key(*p)).collect(),
Some(&PathBuf::from(format!("{}/{}", taxonomy.kind.name, item.slug))),
Some(&PathBuf::from(format!("{}/{}", taxonomy.slug, item.slug))),
if self.config.is_multilingual() && !taxonomy.kind.lang.is_empty() {
&taxonomy.kind.lang
} else {

View file

@ -154,6 +154,10 @@ fn can_build_site_without_live_reload() {
assert_eq!(file_exists!(public, "categories/index.html"), true);
assert_eq!(file_exists!(public, "categories/a-category/index.html"), true);
assert_eq!(file_exists!(public, "categories/a-category/atom.xml"), true);
// and podcast_authors (https://github.com/getzola/zola/issues/1177)
assert_eq!(file_exists!(public, "podcast-authors/index.html"), true);
assert_eq!(file_exists!(public, "podcast-authors/some-person/index.html"), true);
assert_eq!(file_exists!(public, "podcast-authors/some-person/atom.xml"), true);
// But no tags
assert_eq!(file_exists!(public, "tags/index.html"), false);

View file

@ -572,6 +572,7 @@ mod tests {
let tag = TaxonomyItem::new(
"Programming",
&taxo_config,
"tags",
&config,
vec![],
&library.read().unwrap(),
@ -579,12 +580,14 @@ mod tests {
let tag_fr = TaxonomyItem::new(
"Programmation",
&taxo_config_fr,
"tags",
&config,
vec![],
&library.read().unwrap(),
);
let tags = Taxonomy { kind: taxo_config, items: vec![tag] };
let tags_fr = Taxonomy { kind: taxo_config_fr, items: vec![tag_fr] };
let tags = Taxonomy { kind: taxo_config, slug: "tags".to_string(), items: vec![tag] };
let tags_fr =
Taxonomy { kind: taxo_config_fr, slug: "tags".to_string(), items: vec![tag_fr] };
let taxonomies = vec![tags.clone(), tags_fr.clone()];
let static_fn =
@ -647,10 +650,12 @@ mod tests {
..TaxonomyConfig::default()
};
let library = Library::new(0, 0, false);
let tag = TaxonomyItem::new("Programming", &taxo_config, &config, vec![], &library);
let tag_fr = TaxonomyItem::new("Programmation", &taxo_config_fr, &config, vec![], &library);
let tags = Taxonomy { kind: taxo_config, items: vec![tag] };
let tags_fr = Taxonomy { kind: taxo_config_fr, items: vec![tag_fr] };
let tag = TaxonomyItem::new("Programming", &taxo_config, "tags", &config, vec![], &library);
let tag_fr =
TaxonomyItem::new("Programmation", &taxo_config_fr, "tags", &config, vec![], &library);
let tags = Taxonomy { kind: taxo_config, slug: "tags".to_string(), items: vec![tag] };
let tags_fr =
Taxonomy { kind: taxo_config_fr, slug: "tags".to_string(), items: vec![tag_fr] };
let taxonomies = vec![tags.clone(), tags_fr.clone()];
let static_fn =

View file

@ -94,7 +94,7 @@ async fn handle_request(req: Request<Body>, root: PathBuf) -> Result<Response<Bo
ResolveResult::MethodNotMatched => return Ok(method_not_allowed()),
ResolveResult::NotFound | ResolveResult::UriNotMatched => {
let not_found_path = RelativePath::new("404.html");
let content_404 = SITE_CONTENT.read().unwrap().get(not_found_path).map(|x| x.clone());
let content_404 = SITE_CONTENT.read().unwrap().get(not_found_path).cloned();
return Ok(not_found(content_404));
}
_ => (),

View file

@ -16,7 +16,7 @@ fn main() {
"." => env::current_dir().unwrap(),
path => PathBuf::from(path)
.canonicalize()
.expect(&format!("Cannot find root directory: {}", path)),
.unwrap_or_else(|_| panic!("Cannot find root directory: {}", path)),
};
let config_file = match matches.value_of("config") {
Some(path) => PathBuf::from(path),

View file

@ -4,16 +4,21 @@ highlight_code = true
compile_sass = true
generate_feed = true
theme = "sample"
slugify_paths = true
taxonomies = [
{name = "categories", feed = true},
{name = "podcast_authors", feed = true},
]
extra_syntaxes = ["syntaxes"]
ignored_content = ["*/ignored.md"]
[slugify]
paths = "on"
taxonomies = "on"
anchors = "on"
[link_checker]
skip_prefixes = [
"http://[2001:db8::]/",

View file

@ -5,6 +5,7 @@ date = 2017-01-01
[taxonomies]
categories = ["a-category"]
podcast_authors = ["Some Person"]
+++
# A title

View file

@ -0,0 +1,4 @@
{% for term in terms %}
{{ term.name }} {{ term.slug }} {{ term.pages | length }}
{% endfor %}
Current path: {{ current_path }}

View file

@ -0,0 +1,10 @@
Category: {{ term.name }}
{% for page in term.pages %}
<article>
<h3 class="post__title"><a href="{{ page.permalink }}">{{ page.title }}</a></h3>
</article>
{% endfor %}
Current path: {{ current_path }}