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 <southerntofu@thunix.net>
This commit is contained in:
parent
14366dafc6
commit
6950759eda
|
@ -1,5 +1,11 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## unreleased
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- internal links are now resolved in the `markdown` filter in the templates (#1296 #1316)
|
||||||
|
|
||||||
## 0.13.0 (2021-01-09)
|
## 0.13.0 (2021-01-09)
|
||||||
|
|
||||||
- Enable HTML minification
|
- Enable HTML minification
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub fn load_tera(path: &Path, config: &Config) -> Result<Tera> {
|
||||||
|
|
||||||
/// Adds global fns that are to be available to shortcodes while rendering markdown
|
/// Adds global fns that are to be available to shortcodes while rendering markdown
|
||||||
pub fn register_early_global_fns(site: &mut Site) {
|
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(
|
site.tera.register_function(
|
||||||
"get_url",
|
"get_url",
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::hash::BuildHasher;
|
use std::hash::BuildHasher;
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use base64::{decode, encode};
|
use base64::{decode, encode};
|
||||||
use config::Config;
|
use config::Config;
|
||||||
|
@ -9,17 +10,19 @@ use tera::{to_value, try_get_value, Filter as TeraFilter, Result as TeraResult,
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MarkdownFilter {
|
pub struct MarkdownFilter {
|
||||||
config: Config,
|
config: Config,
|
||||||
|
permalinks: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MarkdownFilter {
|
impl MarkdownFilter {
|
||||||
pub fn new(config: Config) -> Self {
|
pub fn new(config: Config, permalinks: HashMap<String, String>) -> Self {
|
||||||
Self { config }
|
Self { config, permalinks }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TeraFilter for MarkdownFilter {
|
impl TeraFilter for MarkdownFilter {
|
||||||
fn filter(&self, value: &Value, args: &HashMap<String, Value>) -> TeraResult<Value> {
|
fn filter(&self, value: &Value, args: &HashMap<String, Value>) -> TeraResult<Value> {
|
||||||
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 s = try_get_value!("markdown", "value", String, value);
|
||||||
let inline = match args.get("inline") {
|
let inline = match args.get("inline") {
|
||||||
Some(val) => try_get_value!("markdown", "inline", bool, val),
|
Some(val) => try_get_value!("markdown", "inline", bool, val),
|
||||||
|
@ -69,7 +72,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn markdown_filter() {
|
fn markdown_filter() {
|
||||||
let result = MarkdownFilter::new(Config::default())
|
let result = MarkdownFilter::new(Config::default(), HashMap::new())
|
||||||
.filter(&to_value(&"# Hey").unwrap(), &HashMap::new());
|
.filter(&to_value(&"# Hey").unwrap(), &HashMap::new());
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
assert_eq!(result.unwrap(), to_value(&"<h1 id=\"hey\">Hey</h1>\n").unwrap());
|
assert_eq!(result.unwrap(), to_value(&"<h1 id=\"hey\">Hey</h1>\n").unwrap());
|
||||||
|
@ -79,7 +82,7 @@ mod tests {
|
||||||
fn markdown_filter_inline() {
|
fn markdown_filter_inline() {
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("inline".to_string(), to_value(true).unwrap());
|
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(),
|
&to_value(&"Using `map`, `filter`, and `fold` instead of `for`").unwrap(),
|
||||||
&args,
|
&args,
|
||||||
);
|
);
|
||||||
|
@ -92,7 +95,7 @@ mod tests {
|
||||||
fn markdown_filter_inline_tables() {
|
fn markdown_filter_inline_tables() {
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("inline".to_string(), to_value(true).unwrap());
|
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(
|
&to_value(
|
||||||
&r#"
|
&r#"
|
||||||
|id|author_id| timestamp_created|title |content |
|
|id|author_id| timestamp_created|title |content |
|
||||||
|
@ -118,16 +121,26 @@ mod tests {
|
||||||
|
|
||||||
let md = "Hello <https://google.com> :smile: ...";
|
let md = "Hello <https://google.com> :smile: ...";
|
||||||
let result =
|
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!(result.is_ok());
|
||||||
assert_eq!(result.unwrap(), to_value(&"<p>Hello <a rel=\"noopener\" target=\"_blank\" href=\"https://google.com\">https://google.com</a> 😄 …</p>\n").unwrap());
|
assert_eq!(result.unwrap(), to_value(&"<p>Hello <a rel=\"noopener\" target=\"_blank\" href=\"https://google.com\">https://google.com</a> 😄 …</p>\n").unwrap());
|
||||||
|
|
||||||
let md = "```py\ni=0\n```";
|
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.is_ok());
|
||||||
assert!(result.unwrap().as_str().unwrap().contains("<pre style"));
|
assert!(result.unwrap().as_str().unwrap().contains("<pre style"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mardown_filter_can_use_internal_links() {
|
||||||
|
let mut permalinks = HashMap::new();
|
||||||
|
permalinks.insert("blog/_index.md".to_string(), "/foo/blog".to_string());
|
||||||
|
let md = "Hello. Check out [my blog](@/blog/_index.md)!";
|
||||||
|
let result = MarkdownFilter::new(Config::default(), permalinks).filter(&to_value(&md).unwrap(), &HashMap::new());
|
||||||
|
assert!(result.is_ok());
|
||||||
|
assert_eq!(result.unwrap(), to_value(&"<p>Hello. Check out <a href=\"/foo/blog\">my blog</a>!</p>\n").unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn base64_encode_filter() {
|
fn base64_encode_filter() {
|
||||||
// from https://tools.ietf.org/html/rfc4648#section-10
|
// from https://tools.ietf.org/html/rfc4648#section-10
|
||||||
|
|
|
@ -64,9 +64,7 @@ Zola adds a few filters in addition to [those](https://tera.netlify.com/docs/#fi
|
||||||
in Tera.
|
in Tera.
|
||||||
|
|
||||||
### markdown
|
### markdown
|
||||||
Converts the given variable to HTML using Markdown. This doesn't apply any of the
|
Converts the given variable to HTML using Markdown. Shortcodes won't work within this filter.
|
||||||
features that Zola adds to Markdown; for example, internal links and shortcodes won't work.
|
|
||||||
|
|
||||||
By default, the filter will wrap all text in a paragraph. To disable this behaviour, you can
|
By default, the filter will wrap all text in a paragraph. To disable this behaviour, you can
|
||||||
pass `true` to the inline argument:
|
pass `true` to the inline argument:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue