@@ -5,8 +5,6 @@ | |||
### Breaking | |||
- Taxonomies have been rewritten from scratch to allow custom ones with RSS and pagination | |||
- `get_taxonomy_url` has been renamed to `get_taxonomy` and will now return the full taxonomy | |||
instead of just the URL of a term | |||
- `order` sorting has been removed in favour of only having `weight` | |||
### Others | |||
@@ -23,6 +21,7 @@ instead of just the URL of a term | |||
- Add a 404 template | |||
- Enable preserve-order feature of Tera | |||
- Add an external link checker | |||
- Add `get_taxonomy` global function to return the full taxonomy | |||
## 0.3.4 (2018-06-22) | |||
@@ -26,7 +26,7 @@ in the `docs/content` folder of the repository. | |||
| Automatic header anchors | ✔ | ✕ | ✔ | ✔ | | |||
| Aliases | ✔ | ✕ | ✔ | ✔ | | |||
| Pagination | ✔ | ✕ | ✔ | ✔ | | |||
| Custom taxonomies | ✕ | ✕ | ✔ | ✕ | | |||
| Custom taxonomies | ✔ | ✕ | ✔ | ✕ | | |||
| Search | ✔ | ✕ | ✕ | ✔ | | |||
| Data files | ✕ | ✔ | ✔ | ✕ | | |||
@@ -302,6 +302,10 @@ impl Site { | |||
"get_taxonomy", | |||
global_fns::make_get_taxonomy(self.taxonomies.clone()), | |||
); | |||
self.tera.register_global_function( | |||
"get_taxonomy_url", | |||
global_fns::make_get_taxonomy_url(self.taxonomies.clone()), | |||
); | |||
} | |||
/// Add a page to the site | |||
@@ -139,6 +139,7 @@ pub fn make_get_taxonomy(all_taxonomies: Vec<Taxonomy>) -> GlobalFn { | |||
for taxonomy in all_taxonomies { | |||
taxonomies.insert(taxonomy.kind.name.clone(), taxonomy); | |||
} | |||
Box::new(move |args| -> Result<Value> { | |||
let kind = required_arg!( | |||
String, | |||
@@ -156,6 +157,42 @@ pub fn make_get_taxonomy(all_taxonomies: Vec<Taxonomy>) -> GlobalFn { | |||
}) | |||
} | |||
pub fn make_get_taxonomy_url(all_taxonomies: Vec<Taxonomy>) -> GlobalFn { | |||
let mut taxonomies = HashMap::new(); | |||
for taxonomy in all_taxonomies { | |||
taxonomies.insert(taxonomy.kind.name.clone(), taxonomy); | |||
} | |||
Box::new(move |args| -> Result<Value> { | |||
let kind = required_arg!( | |||
String, | |||
args.get("kind"), | |||
"`get_taxonomy_url` requires a `kind` argument with a string value" | |||
); | |||
let name = required_arg!( | |||
String, | |||
args.get("name"), | |||
"`get_taxonomy_url` requires a `name` argument with a string value" | |||
); | |||
let container = match taxonomies.get(&kind) { | |||
Some(c) => c, | |||
None => return Err( | |||
format!("`get_taxonomy_url` received an unknown taxonomy as kind: {}", kind).into() | |||
) | |||
}; | |||
for item in &container.items { | |||
if item.name == name { | |||
return Ok(to_value(item.permalink.clone()).unwrap()); | |||
} | |||
} | |||
Err( | |||
format!("`get_taxonomy_url`: couldn't find `{}` in `{}` taxonomy", name, kind).into() | |||
) | |||
}) | |||
} | |||
pub fn make_resize_image(imageproc: Arc<Mutex<imageproc::Processor>>) -> GlobalFn { | |||
static DEFAULT_OP: &'static str = "fill"; | |||
const DEFAULT_Q: u8 = 75; | |||
@@ -206,7 +243,7 @@ pub fn make_resize_image(imageproc: Arc<Mutex<imageproc::Processor>>) -> GlobalF | |||
#[cfg(test)] | |||
mod tests { | |||
use super::{make_get_url, make_get_taxonomy, make_trans}; | |||
use super::{make_get_url, make_get_taxonomy, make_get_taxonomy_url, make_trans}; | |||
use std::collections::HashMap; | |||
@@ -260,7 +297,7 @@ mod tests { | |||
fn can_get_taxonomy() { | |||
let taxo_config = TaxonomyConfig { name: "tags".to_string(), ..TaxonomyConfig::default() }; | |||
let tag = TaxonomyItem::new( | |||
"Prog amming", | |||
"Progamming", | |||
"tags", | |||
&Config::default(), | |||
vec![], | |||
@@ -281,6 +318,33 @@ mod tests { | |||
assert!(static_fn(args).is_err()); | |||
} | |||
#[test] | |||
fn can_get_taxonomy_url() { | |||
let taxo_config = TaxonomyConfig { name: "tags".to_string(), ..TaxonomyConfig::default() }; | |||
let tag = TaxonomyItem::new( | |||
"Programming", | |||
"tags", | |||
&Config::default(), | |||
vec![], | |||
); | |||
let tags = Taxonomy { | |||
kind: taxo_config, | |||
items: vec![tag], | |||
}; | |||
let static_fn = make_get_taxonomy_url(vec![tags.clone()]); | |||
// can find it correctly | |||
let mut args = HashMap::new(); | |||
args.insert("kind".to_string(), to_value("tags").unwrap()); | |||
args.insert("name".to_string(), to_value("Programming").unwrap()); | |||
assert_eq!(static_fn(args).unwrap(), "http://a-website.com/tags/prog-amming/"); | |||
// and errors if it can't find it | |||
let mut args = HashMap::new(); | |||
args.insert("kind".to_string(), to_value("tags").unwrap()); | |||
args.insert("name".to_string(), to_value("random").unwrap()); | |||
assert!(static_fn(args).is_err()); | |||
} | |||
#[test] | |||
fn can_translate_a_string() { | |||
let trans_config = r#" | |||
@@ -17,9 +17,9 @@ If the file is given any name *other* than `index.md` or `_index.md`, then it wi | |||
create a page with that name (without the `.md`). So naming a file in the root of your | |||
content directory `about.md` would also create a page at `[base_url]/about`. | |||
As you can see, creating an `about.md` file is exactly equivalent to creating an | |||
As you can see, creating an `about.md` file is exactly equivalent to creating an | |||
`about/index.md` file. The only difference between the two methods is that creating | |||
the `about` folder allows you to use asset colocation, as discussed in the | |||
the `about` folder allows you to use asset colocation, as discussed in the | |||
[Overview](./documentation/content/overview.md) section of this documentation. | |||
## Front-matter | |||
@@ -42,7 +42,7 @@ description = "" | |||
# Do not wrap dates in quotes, the line below only indicates that there is no default date. | |||
# If the section variable `sort_by` is set to `date`, then any page that lacks a `date` | |||
# will not be rendered. | |||
date = | |||
date = | |||
# The weight as defined in the Section page | |||
# If the section variable `sort_by` is set to `weight`, then any page that lacks a `weight` | |||
@@ -62,24 +62,23 @@ slug = "" | |||
# It should not start with a `/` and the slash will be removed if it does | |||
path = "" | |||
# An array of strings allowing you to group pages with them | |||
tags = [] | |||
# An overarching category name for that page, allowing you to group pages with it | |||
category = "" | |||
# Use aliases if you are moving content but want to redirect previous URLs to the | |||
# Use aliases if you are moving content but want to redirect previous URLs to the | |||
# current one. This takes an array of path, not URLs. | |||
aliases = [] | |||
# Whether the page should be in the search index. This is only used if | |||
# `build_search_index` is set to true in the config and the parent section | |||
# `build_search_index` is set to true in the config and the parent section | |||
# hasn't set `in_search_index` to false in its front-matter | |||
in_search_index = true | |||
# Template to use to render this page | |||
template = "page.html" | |||
# The taxonomies for that page. The keys need to be the same as the taxonomies | |||
# name configured in `config.toml` and the values an array of String like | |||
# tags = ["rust", "web"] | |||
[taxonomies] | |||
# Your own data | |||
[extra] | |||
+++ | |||
@@ -89,7 +88,7 @@ Some content | |||
## Summary | |||
You can ask Gutenberg to create a summary if you only want to show the first | |||
You can ask Gutenberg to create a summary if you only want to show the first | |||
paragraph of each page in a list for example. | |||
To do so, add <code><!-- more --></code> in your content at the point | |||
@@ -97,6 +96,6 @@ where you want the summary to end and the content up to that point will be also | |||
available separately in the | |||
[template](./documentation/templates/pages-sections.md#page-variables). | |||
An anchor link to this position named `continue-reading` is created so you can link | |||
An anchor link to this position named `continue-reading` is created so you can link | |||
directly to it if needed for example: | |||
`<a href="{{ page.permalink }}#continue-reading">Continue Reading</a>` |
@@ -16,7 +16,16 @@ For example the default would be page/1 | |||
- `rss`: if set to `true`, a RSS feed will be generated for each individual term. | |||
Once this is done, you can then set taxonomies in your content and Gutenberg will pick | |||
them up. | |||
them up: | |||
```toml | |||
+++ | |||
... | |||
[taxonomies] | |||
tags = ["rust", "web"] | |||
categories = ["programming"] | |||
+++ | |||
``` | |||
The taxonomy pages will only be created if at least one non-draft page is found and | |||
are available at the following paths: | |||
@@ -20,21 +20,21 @@ A few variables are available on all templates minus RSS and sitemap: | |||
- `current_url`: the full URL for that page | |||
## Standard Templates | |||
By default, Gutenberg will look for three templates: `index.html`, which is applied | |||
to the site homepage; `section.html`, which is applied to all sections (any HTML | |||
page generated by creating a directory within your `content` directory); and | |||
`page.html`, which is applied to all pages (any HTML page generated by creating a | |||
By default, Gutenberg will look for three templates: `index.html`, which is applied | |||
to the site homepage; `section.html`, which is applied to all sections (any HTML | |||
page generated by creating a directory within your `content` directory); and | |||
`page.html`, which is applied to all pages (any HTML page generated by creating a | |||
`.md` file within your `content` directory). | |||
The homepage is always a section (regardless of whether it contains other pages). | |||
Thus, the `index.html` and `section.html` templates both have access to the | |||
Thus, the `index.html` and `section.html` templates both have access to the | |||
section variables. The `page.html` template has access to the page variables. | |||
The page and section variables are described in more detail in the next section of this documentation. | |||
## Built-in Templates | |||
Gutenberg comes with three built-in templates: `rss.xml`, `sitemap.xml`, and | |||
Gutenberg comes with three built-in templates: `rss.xml`, `sitemap.xml`, and | |||
`robots.txt` (each described in their own section of this documentation). | |||
Additionally, themes can add their own templates, which will be applied if not | |||
Additionally, themes can add their own templates, which will be applied if not | |||
overridden. You can override built-in or theme templates by creating a template with | |||
same name in the correct path. For example, you can override the RSS template by | |||
creating a `templates/rss.xml` file. | |||
@@ -120,15 +120,22 @@ by passing `cachebust=true` to the `get_url` function. | |||
### `get_taxonomy_url` | |||
Gets the permalink for the tag or category given. | |||
Gets the permalink for the taxonomy item found. | |||
```jinja2 | |||
{% set url = get_taxonomy_url(kind="category", name=page.category) %} | |||
{% set url = get_taxonomy_url(kind="categories", name=page.taxonomies.category) %} | |||
``` | |||
The `name` will almost come from a variable but in case you want to do it manually, | |||
the value should be the same as the one in the front-matter, not the slugified version. | |||
### `get_taxonomy` | |||
Gets the whole taxonomy of a specific kind. | |||
```jinja2 | |||
{% set categories = get_taxonomy_url(kind="categories") %} | |||
``` | |||
### `trans` | |||
Gets the translation of the given `key`, for the `default_language` or the `language given | |||