From 6950759eda70391ff76d620c4da812743f7b32e0 Mon Sep 17 00:00:00 2001 From: southerntofu <52931252+southerntofu@users.noreply.github.com> Date: Wed, 20 Jan 2021 08:24:55 +0000 Subject: [PATCH] Internal links are supported in markdown filter (#1318) * Internal links are resolved in tera markdown filter (close #1296 #1316) * Add a test for internal links in markdown filter Co-authored-by: southerntofu --- CHANGELOG.md | 6 ++++ components/site/src/tpls.rs | 2 +- components/templates/src/filters.rs | 29 ++++++++++++++----- .../documentation/templates/overview.md | 4 +-- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 876bcc3f..05c2cdaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## unreleased + +### Features + +- internal links are now resolved in the `markdown` filter in the templates (#1296 #1316) + ## 0.13.0 (2021-01-09) - Enable HTML minification diff --git a/components/site/src/tpls.rs b/components/site/src/tpls.rs index 2b224b57..2e5295ef 100644 --- a/components/site/src/tpls.rs +++ b/components/site/src/tpls.rs @@ -50,7 +50,7 @@ pub fn load_tera(path: &Path, config: &Config) -> Result { /// Adds global fns that are to be available to shortcodes while rendering markdown pub fn register_early_global_fns(site: &mut Site) { - site.tera.register_filter("markdown", filters::MarkdownFilter::new(site.config.clone())); + site.tera.register_filter("markdown", filters::MarkdownFilter::new(site.config.clone(), site.permalinks.clone())); site.tera.register_function( "get_url", diff --git a/components/templates/src/filters.rs b/components/templates/src/filters.rs index c9b6d6cd..731ecfd2 100644 --- a/components/templates/src/filters.rs +++ b/components/templates/src/filters.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; use std::hash::BuildHasher; +use std::borrow::Cow; use base64::{decode, encode}; use config::Config; @@ -9,17 +10,19 @@ use tera::{to_value, try_get_value, Filter as TeraFilter, Result as TeraResult, #[derive(Debug)] pub struct MarkdownFilter { config: Config, + permalinks: HashMap, } impl MarkdownFilter { - pub fn new(config: Config) -> Self { - Self { config } + pub fn new(config: Config, permalinks: HashMap) -> Self { + Self { config, permalinks } } } impl TeraFilter for MarkdownFilter { fn filter(&self, value: &Value, args: &HashMap) -> TeraResult { - let context = RenderContext::from_config(&self.config); + let mut context = RenderContext::from_config(&self.config); + context.permalinks = Cow::Borrowed(&self.permalinks); let s = try_get_value!("markdown", "value", String, value); let inline = match args.get("inline") { Some(val) => try_get_value!("markdown", "inline", bool, val), @@ -69,7 +72,7 @@ mod tests { #[test] fn markdown_filter() { - let result = MarkdownFilter::new(Config::default()) + let result = MarkdownFilter::new(Config::default(), HashMap::new()) .filter(&to_value(&"# Hey").unwrap(), &HashMap::new()); assert!(result.is_ok()); assert_eq!(result.unwrap(), to_value(&"

Hey

\n").unwrap()); @@ -79,7 +82,7 @@ mod tests { fn markdown_filter_inline() { let mut args = HashMap::new(); args.insert("inline".to_string(), to_value(true).unwrap()); - let result = MarkdownFilter::new(Config::default()).filter( + let result = MarkdownFilter::new(Config::default(), HashMap::new()).filter( &to_value(&"Using `map`, `filter`, and `fold` instead of `for`").unwrap(), &args, ); @@ -92,7 +95,7 @@ mod tests { fn markdown_filter_inline_tables() { let mut args = HashMap::new(); args.insert("inline".to_string(), to_value(true).unwrap()); - let result = MarkdownFilter::new(Config::default()).filter( + let result = MarkdownFilter::new(Config::default(), HashMap::new()).filter( &to_value( &r#" |id|author_id| timestamp_created|title |content | @@ -118,16 +121,26 @@ mod tests { let md = "Hello :smile: ..."; let result = - MarkdownFilter::new(config.clone()).filter(&to_value(&md).unwrap(), &HashMap::new()); + MarkdownFilter::new(config.clone(), HashMap::new()).filter(&to_value(&md).unwrap(), &HashMap::new()); assert!(result.is_ok()); assert_eq!(result.unwrap(), to_value(&"

Hello https://google.com 😄 …

\n").unwrap()); let md = "```py\ni=0\n```"; - let result = MarkdownFilter::new(config).filter(&to_value(&md).unwrap(), &HashMap::new()); + let result = MarkdownFilter::new(config, HashMap::new()).filter(&to_value(&md).unwrap(), &HashMap::new()); assert!(result.is_ok()); assert!(result.unwrap().as_str().unwrap().contains("
Hello. Check out my blog!

\n").unwrap()); + } + #[test] fn base64_encode_filter() { // from https://tools.ietf.org/html/rfc4648#section-10 diff --git a/docs/content/documentation/templates/overview.md b/docs/content/documentation/templates/overview.md index 24fc0b5f..5b041980 100644 --- a/docs/content/documentation/templates/overview.md +++ b/docs/content/documentation/templates/overview.md @@ -64,9 +64,7 @@ Zola adds a few filters in addition to [those](https://tera.netlify.com/docs/#fi in Tera. ### markdown -Converts the given variable to HTML using Markdown. This doesn't apply any of the -features that Zola adds to Markdown; for example, internal links and shortcodes won't work. - +Converts the given variable to HTML using Markdown. Shortcodes won't work within this filter. By default, the filter will wrap all text in a paragraph. To disable this behaviour, you can pass `true` to the inline argument: