Change taxonomies to be sorted a-z and add permalinks
This commit is contained in:
parent
57b87aa50a
commit
952b6679ce
|
@ -15,6 +15,8 @@
|
||||||
- Add `class` variable to `gist` shortcode
|
- Add `class` variable to `gist` shortcode
|
||||||
- Add reading analytics to sections content
|
- Add reading analytics to sections content
|
||||||
- Add config to sitemap template
|
- Add config to sitemap template
|
||||||
|
- Add `permalink` to all taxonomy items (tags & categories)
|
||||||
|
- Tags in the tags page are now sorting alphabetically instead of by number of pages in them
|
||||||
|
|
||||||
## 0.1.3 (2017-08-31)
|
## 0.1.3 (2017-08-31)
|
||||||
|
|
||||||
|
|
|
@ -366,6 +366,7 @@ impl Site {
|
||||||
|
|
||||||
// TODO: can we pass a reference?
|
// TODO: can we pass a reference?
|
||||||
let (tags, categories) = Taxonomy::find_tags_and_categories(
|
let (tags, categories) = Taxonomy::find_tags_and_categories(
|
||||||
|
&self.config,
|
||||||
self.pages
|
self.pages
|
||||||
.values()
|
.values()
|
||||||
.filter(|p| !p.is_draft())
|
.filter(|p| !p.is_draft())
|
||||||
|
|
|
@ -32,18 +32,30 @@ pub enum TaxonomyKind {
|
||||||
pub struct TaxonomyItem {
|
pub struct TaxonomyItem {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub slug: String,
|
pub slug: String,
|
||||||
|
pub permalink: String,
|
||||||
pub pages: Vec<Page>,
|
pub pages: Vec<Page>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TaxonomyItem {
|
impl TaxonomyItem {
|
||||||
pub fn new(name: &str, pages: Vec<Page>) -> TaxonomyItem {
|
pub fn new(name: &str, kind: TaxonomyKind, config: &Config, pages: Vec<Page>) -> TaxonomyItem {
|
||||||
// We shouldn't have any pages without dates there
|
// Taxonomy are almost always used for blogs so we filter by dates
|
||||||
let (sorted_pages, _) = sort_pages(pages, SortBy::Date);
|
// and it's not like we can sort things across sections by anything other
|
||||||
|
// than dates
|
||||||
|
let (mut pages, ignored_pages) = sort_pages(pages, SortBy::Date);
|
||||||
|
let slug = slugify(name);
|
||||||
|
let permalink = {
|
||||||
|
let kind_path = if kind == TaxonomyKind::Tags { "tag" } else { "category" };
|
||||||
|
config.make_permalink(&format!("/{}/{}", kind_path, slug))
|
||||||
|
};
|
||||||
|
|
||||||
|
// We still append pages without dates at the end
|
||||||
|
pages.extend(ignored_pages);
|
||||||
|
|
||||||
TaxonomyItem {
|
TaxonomyItem {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
slug: slugify(name),
|
permalink,
|
||||||
pages: sorted_pages,
|
slug,
|
||||||
|
pages,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,21 +69,12 @@ pub struct Taxonomy {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Taxonomy {
|
impl Taxonomy {
|
||||||
// TODO: take a Vec<&'a Page> if it makes a difference in terms of perf for actual sites
|
pub fn find_tags_and_categories(config: &Config, all_pages: &[Page]) -> (Taxonomy, Taxonomy) {
|
||||||
pub fn find_tags_and_categories(all_pages: &[Page]) -> (Taxonomy, Taxonomy) {
|
|
||||||
let mut tags = HashMap::new();
|
let mut tags = HashMap::new();
|
||||||
let mut categories = HashMap::new();
|
let mut categories = HashMap::new();
|
||||||
|
|
||||||
// Find all the tags/categories first
|
// Find all the tags/categories first
|
||||||
for page in all_pages {
|
for page in all_pages {
|
||||||
// Don't consider pages without dates for tags/categories as that's the only thing
|
|
||||||
// we can sort pages with across sections
|
|
||||||
// If anyone sees that comment and wonder wtf, please open an issue as I can't think of
|
|
||||||
// usecases other than blog posts for built-in taxonomies
|
|
||||||
if page.meta.date.is_none() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref category) = page.meta.category {
|
if let Some(ref category) = page.meta.category {
|
||||||
categories
|
categories
|
||||||
.entry(category.to_string())
|
.entry(category.to_string())
|
||||||
|
@ -90,20 +93,20 @@ impl Taxonomy {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then make TaxonomyItem out of them, after sorting it
|
// Then make TaxonomyItem out of them, after sorting it
|
||||||
let tags_taxonomy = Taxonomy::new(TaxonomyKind::Tags, tags);
|
let tags_taxonomy = Taxonomy::new(TaxonomyKind::Tags, config, tags);
|
||||||
let categories_taxonomy = Taxonomy::new(TaxonomyKind::Categories, categories);
|
let categories_taxonomy = Taxonomy::new(TaxonomyKind::Categories, config, categories);
|
||||||
|
|
||||||
(tags_taxonomy, categories_taxonomy)
|
(tags_taxonomy, categories_taxonomy)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(kind: TaxonomyKind, items: HashMap<String, Vec<Page>>) -> Taxonomy {
|
fn new(kind: TaxonomyKind, config: &Config, items: HashMap<String, Vec<Page>>) -> Taxonomy {
|
||||||
let mut sorted_items = vec![];
|
let mut sorted_items = vec![];
|
||||||
for (name, pages) in &items {
|
for (name, pages) in &items {
|
||||||
sorted_items.push(
|
sorted_items.push(
|
||||||
TaxonomyItem::new(name, pages.clone())
|
TaxonomyItem::new(name, kind, config, pages.clone())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
sorted_items.sort_by(|a, b| b.pages.len().cmp(&a.pages.len()));
|
sorted_items.sort_by(|a, b| a.name.cmp(&b.name));
|
||||||
|
|
||||||
Taxonomy {
|
Taxonomy {
|
||||||
kind,
|
kind,
|
||||||
|
@ -157,3 +160,55 @@ impl Taxonomy {
|
||||||
.chain_err(|| format!("Failed to render {} page.", name))
|
.chain_err(|| format!("Failed to render {} page.", name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use config::Config;
|
||||||
|
use content::Page;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_make_taxonomies() {
|
||||||
|
let config = Config::default();
|
||||||
|
let mut page1 = Page::default();
|
||||||
|
page1.meta.tags = Some(vec!["rust".to_string(), "db".to_string()]);
|
||||||
|
page1.meta.category = Some("Programming tutorials".to_string());
|
||||||
|
let mut page2 = Page::default();
|
||||||
|
page2.meta.tags = Some(vec!["rust".to_string(), "js".to_string()]);
|
||||||
|
page2.meta.category = Some("Other".to_string());
|
||||||
|
let mut page3 = Page::default();
|
||||||
|
page3.meta.tags = Some(vec!["js".to_string()]);
|
||||||
|
let pages = vec![page1, page2, page3];
|
||||||
|
|
||||||
|
let (tags, categories) = Taxonomy::find_tags_and_categories(&config, &pages);
|
||||||
|
|
||||||
|
assert_eq!(tags.items.len(), 3);
|
||||||
|
assert_eq!(categories.items.len(), 2);
|
||||||
|
|
||||||
|
assert_eq!(tags.items[0].name, "db");
|
||||||
|
assert_eq!(tags.items[0].slug, "db");
|
||||||
|
assert_eq!(tags.items[0].permalink, "http://a-website.com/tag/db/");
|
||||||
|
assert_eq!(tags.items[0].pages.len(), 1);
|
||||||
|
|
||||||
|
assert_eq!(tags.items[1].name, "js");
|
||||||
|
assert_eq!(tags.items[1].slug, "js");
|
||||||
|
assert_eq!(tags.items[1].permalink, "http://a-website.com/tag/js/");
|
||||||
|
assert_eq!(tags.items[1].pages.len(), 2);
|
||||||
|
|
||||||
|
assert_eq!(tags.items[2].name, "rust");
|
||||||
|
assert_eq!(tags.items[2].slug, "rust");
|
||||||
|
assert_eq!(tags.items[2].permalink, "http://a-website.com/tag/rust/");
|
||||||
|
assert_eq!(tags.items[2].pages.len(), 2);
|
||||||
|
|
||||||
|
assert_eq!(categories.items[0].name, "Other");
|
||||||
|
assert_eq!(categories.items[0].slug, "other");
|
||||||
|
assert_eq!(categories.items[0].permalink, "http://a-website.com/category/other/");
|
||||||
|
assert_eq!(categories.items[0].pages.len(), 1);
|
||||||
|
|
||||||
|
assert_eq!(categories.items[1].name, "Programming tutorials");
|
||||||
|
assert_eq!(categories.items[1].slug, "programming-tutorials");
|
||||||
|
assert_eq!(categories.items[1].permalink, "http://a-website.com/category/programming-tutorials/");
|
||||||
|
assert_eq!(categories.items[1].pages.len(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -48,5 +48,5 @@ you can update your `config.toml` like so:
|
||||||
show_twitter = false
|
show_twitter = false
|
||||||
```
|
```
|
||||||
|
|
||||||
You can modify files directly in the `themes` directory but this will make updating harder and live reload won't work with those
|
You can modify files directly in the `themes` directory but this will make updating the theme harder and live reload won't work with those
|
||||||
files.
|
files.
|
||||||
|
|
Loading…
Reference in a new issue