Merge pull request #352 from codesections/delete_order

Remove `order` and add `heavier`/`later`
This commit is contained in:
Vincent Prouillet 2018-07-31 15:08:58 +02:00 committed by GitHub
commit be439d7bfb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 210 additions and 199 deletions

View file

@ -11,7 +11,7 @@ use std::collections::HashMap;
use config::Config;
use tera::Tera;
use front_matter::{SortBy, InsertAnchor};
use content::{Page, sort_pages, populate_previous_and_next_pages};
use content::{Page, sort_pages, populate_siblings};
fn create_pages(number: usize, sort_by: SortBy) -> Vec<Page> {
@ -128,17 +128,17 @@ fn bench_sorting_order(b: &mut test::Bencher) {
}
#[bench]
fn bench_populate_previous_and_next_pages(b: &mut test::Bencher) {
fn bench_populate_siblings(b: &mut test::Bencher) {
let pages = create_pages(250, SortBy::Order);
let (sorted_pages, _) = sort_pages(pages, SortBy::Order);
b.iter(|| populate_previous_and_next_pages(&sorted_pages.clone()));
b.iter(|| populate_siblings(&sorted_pages.clone()));
}
#[bench]
fn bench_page_render_html(b: &mut test::Bencher) {
let pages = create_pages(10, SortBy::Order);
let (mut sorted_pages, _) = sort_pages(pages, SortBy::Order);
sorted_pages = populate_previous_and_next_pages(&sorted_pages);
sorted_pages = populate_siblings(&sorted_pages);
let config = Config::default();
let mut tera = Tera::default();

View file

@ -26,4 +26,4 @@ mod sorting;
pub use file_info::FileInfo;
pub use page::Page;
pub use section::Section;
pub use sorting::{sort_pages, populate_previous_and_next_pages};
pub use sorting::{sort_pages, populate_siblings};

View file

@ -44,10 +44,14 @@ pub struct Page {
/// When <!-- more --> is found in the text, will take the content up to that part
/// as summary
pub summary: Option<String>,
/// The previous page, by whatever sorting is used for the index/section
pub previous: Option<Box<Page>>,
/// The next page, by whatever sorting is used for the index/section
pub next: Option<Box<Page>>,
/// The earlier page, for pages sorted by date
pub earlier: Option<Box<Page>>,
/// The later page, for pages sorted by date
pub later: Option<Box<Page>>,
/// The lighter page, for pages sorted by weight
pub lighter: Option<Box<Page>>,
/// The heavier page, for pages sorted by weight
pub heavier: Option<Box<Page>>,
/// Toc made from the headers of the markdown file
pub toc: Vec<Header>,
}
@ -68,8 +72,10 @@ impl Page {
components: vec![],
permalink: "".to_string(),
summary: None,
previous: None,
next: None,
earlier: None,
later: None,
lighter: None,
heavier: None,
toc: vec![],
}
}
@ -229,8 +235,10 @@ impl Default for Page {
components: vec![],
permalink: "".to_string(),
summary: None,
previous: None,
next: None,
earlier: None,
later: None,
lighter: None,
heavier: None,
toc: vec![],
}
}
@ -263,8 +271,10 @@ impl ser::Serialize for Page {
let (word_count, reading_time) = get_reading_analytics(&self.raw_content);
state.serialize_field("word_count", &word_count)?;
state.serialize_field("reading_time", &reading_time)?;
state.serialize_field("previous", &self.previous)?;
state.serialize_field("next", &self.next)?;
state.serialize_field("earlier", &self.earlier)?;
state.serialize_field("later", &self.later)?;
state.serialize_field("lighter", &self.lighter)?;
state.serialize_field("heavier", &self.heavier)?;
state.serialize_field("toc", &self.toc)?;
state.serialize_field("draft", &self.is_draft())?;
let assets = self.serialize_assets();

View file

@ -7,7 +7,7 @@ use front_matter::SortBy;
/// Sort pages by the given criteria
///
/// Any pages that doesn't have a the required field when the sorting method is other than none
/// Any pages that doesn't have a required field when the sorting method is other than none
/// will be ignored.
pub fn sort_pages(pages: Vec<Page>, sort_by: SortBy) -> (Vec<Page>, Vec<Page>) {
if sort_by == SortBy::None {
@ -19,7 +19,6 @@ pub fn sort_pages(pages: Vec<Page>, sort_by: SortBy) -> (Vec<Page>, Vec<Page>) {
.partition(|page| {
match sort_by {
SortBy::Date => page.meta.date.is_some(),
SortBy::Order => page.meta.order.is_some(),
SortBy::Weight => page.meta.weight.is_some(),
_ => unreachable!()
}
@ -36,16 +35,6 @@ pub fn sort_pages(pages: Vec<Page>, sort_by: SortBy) -> (Vec<Page>, Vec<Page>) {
}
})
},
SortBy::Order => {
can_be_sorted.par_sort_unstable_by(|a, b| {
let ord = b.meta.order().cmp(&a.meta.order());
if ord == Ordering::Equal {
a.permalink.cmp(&b.permalink)
} else {
ord
}
})
},
SortBy::Weight => {
can_be_sorted.par_sort_unstable_by(|a, b| {
let ord = a.meta.weight().cmp(&b.meta.weight());
@ -64,7 +53,7 @@ pub fn sort_pages(pages: Vec<Page>, sort_by: SortBy) -> (Vec<Page>, Vec<Page>) {
/// Horribly inefficient way to set previous and next on each pages that skips drafts
/// So many clones
pub fn populate_previous_and_next_pages(input: &[Page]) -> Vec<Page> {
pub fn populate_siblings(input: &[Page], sort_by: SortBy) -> Vec<Page> {
let mut res = Vec::with_capacity(input.len());
// The input is already sorted
@ -91,9 +80,20 @@ pub fn populate_previous_and_next_pages(input: &[Page]) -> Vec<Page> {
// Remove prev/next otherwise we serialise the whole thing...
let mut next_page = input[j].clone();
next_page.previous = None;
next_page.next = None;
new_page.next = Some(Box::new(next_page));
match sort_by {
SortBy::Weight => {
next_page.lighter = None;
next_page.heavier = None;
new_page.lighter = Some(Box::new(next_page));
},
SortBy::Date => {
next_page.earlier = None;
next_page.later = None;
new_page.later = Some(Box::new(next_page));
},
SortBy::None => {}
}
break;
}
}
@ -113,9 +113,20 @@ pub fn populate_previous_and_next_pages(input: &[Page]) -> Vec<Page> {
// Remove prev/next otherwise we serialise the whole thing...
let mut previous_page = input[j].clone();
previous_page.previous = None;
previous_page.next = None;
new_page.previous = Some(Box::new(previous_page));
match sort_by {
SortBy::Weight => {
previous_page.lighter = None;
previous_page.heavier = None;
new_page.heavier = Some(Box::new(previous_page));
},
SortBy::Date => {
previous_page.earlier = None;
previous_page.later = None;
new_page.earlier = Some(Box::new(previous_page));
},
SortBy::None => {
}
}
break;
}
}
@ -129,7 +140,7 @@ pub fn populate_previous_and_next_pages(input: &[Page]) -> Vec<Page> {
mod tests {
use front_matter::{PageFrontMatter, SortBy};
use page::Page;
use super::{sort_pages, populate_previous_and_next_pages};
use super::{sort_pages, populate_siblings};
fn create_page_with_date(date: &str) -> Page {
let mut front_matter = PageFrontMatter::default();
@ -137,22 +148,6 @@ mod tests {
Page::new("content/hello.md", front_matter)
}
fn create_page_with_order(order: usize, filename: &str) -> Page {
let mut front_matter = PageFrontMatter::default();
front_matter.order = Some(order);
let mut p = Page::new("content/".to_string() + filename, front_matter);
// Faking a permalink to test sorting with equal order
p.permalink = filename.to_string();
p
}
fn create_draft_page_with_order(order: usize) -> Page {
let mut front_matter = PageFrontMatter::default();
front_matter.order = Some(order);
front_matter.draft = true;
Page::new("content/hello.md", front_matter)
}
fn create_page_with_weight(weight: usize) -> Page {
let mut front_matter = PageFrontMatter::default();
front_matter.weight = Some(weight);
@ -173,37 +168,6 @@ mod tests {
assert_eq!(pages[2].clone().meta.date.unwrap().to_string(), "2017-01-01");
}
#[test]
fn can_sort_by_order() {
let input = vec![
create_page_with_order(2, "hello.md"),
create_page_with_order(3, "hello2.md"),
create_page_with_order(1, "hello3.md"),
];
let (pages, _) = sort_pages(input, SortBy::Order);
// Should be sorted by order
assert_eq!(pages[0].clone().meta.order.unwrap(), 3);
assert_eq!(pages[1].clone().meta.order.unwrap(), 2);
assert_eq!(pages[2].clone().meta.order.unwrap(), 1);
}
#[test]
fn can_sort_by_order_uses_permalink_to_break_ties() {
let input = vec![
create_page_with_order(3, "b.md"),
create_page_with_order(3, "a.md"),
create_page_with_order(3, "c.md"),
];
let (pages, _) = sort_pages(input, SortBy::Order);
// Should be sorted by order
assert_eq!(pages[0].clone().meta.order.unwrap(), 3);
assert_eq!(pages[0].clone().permalink, "a.md");
assert_eq!(pages[1].clone().meta.order.unwrap(), 3);
assert_eq!(pages[1].clone().permalink, "b.md");
assert_eq!(pages[2].clone().meta.order.unwrap(), 3);
assert_eq!(pages[2].clone().permalink, "c.md");
}
#[test]
fn can_sort_by_weight() {
let input = vec![
@ -221,80 +185,48 @@ mod tests {
#[test]
fn can_sort_by_none() {
let input = vec![
create_page_with_order(2, "a.md"),
create_page_with_order(3, "a.md"),
create_page_with_order(1, "a.md"),
create_page_with_weight(2),
create_page_with_weight(3),
create_page_with_weight(1),
];
let (pages, _) = sort_pages(input, SortBy::None);
// Should be sorted by date
assert_eq!(pages[0].clone().meta.order.unwrap(), 2);
assert_eq!(pages[1].clone().meta.order.unwrap(), 3);
assert_eq!(pages[2].clone().meta.order.unwrap(), 1);
assert_eq!(pages[0].clone().meta.weight.unwrap(), 2);
assert_eq!(pages[1].clone().meta.weight.unwrap(), 3);
assert_eq!(pages[2].clone().meta.weight.unwrap(), 1);
}
#[test]
fn ignore_page_with_missing_field() {
let input = vec![
create_page_with_order(2, "a.md"),
create_page_with_order(3, "a.md"),
create_page_with_weight(2),
create_page_with_weight(3),
create_page_with_date("2019-01-01"),
];
let (pages, unsorted) = sort_pages(input, SortBy::Order);
let (pages, unsorted) = sort_pages(input, SortBy::Weight);
assert_eq!(pages.len(), 2);
assert_eq!(unsorted.len(), 1);
}
#[test]
fn can_populate_previous_and_next_pages() {
fn can_populate_siblings() {
let input = vec![
create_page_with_order(1, "a.md"),
create_page_with_order(2, "b.md"),
create_page_with_order(3, "a.md"),
create_page_with_weight(1),
create_page_with_weight(2),
create_page_with_weight(3),
];
let pages = populate_previous_and_next_pages(&input);
let pages = populate_siblings(&input, SortBy::Weight);
assert!(pages[0].clone().next.is_none());
assert!(pages[0].clone().previous.is_some());
assert_eq!(pages[0].clone().previous.unwrap().meta.order.unwrap(), 2);
assert!(pages[0].clone().lighter.is_none());
assert!(pages[0].clone().heavier.is_some());
assert_eq!(pages[0].clone().heavier.unwrap().meta.weight.unwrap(), 2);
assert!(pages[1].clone().next.is_some());
assert!(pages[1].clone().previous.is_some());
assert_eq!(pages[1].clone().previous.unwrap().meta.order.unwrap(), 3);
assert_eq!(pages[1].clone().next.unwrap().meta.order.unwrap(), 1);
assert!(pages[1].clone().heavier.is_some());
assert!(pages[1].clone().lighter.is_some());
assert_eq!(pages[1].clone().lighter.unwrap().meta.weight.unwrap(), 1);
assert_eq!(pages[1].clone().heavier.unwrap().meta.weight.unwrap(), 3);
assert!(pages[2].clone().next.is_some());
assert!(pages[2].clone().previous.is_none());
assert_eq!(pages[2].clone().next.unwrap().meta.order.unwrap(), 2);
}
#[test]
fn can_populate_previous_and_next_pages_skip_drafts() {
let input = vec![
create_draft_page_with_order(0),
create_page_with_order(1, "a.md"),
create_page_with_order(2, "b.md"),
create_page_with_order(3, "c.md"),
create_draft_page_with_order(4),
];
let pages = populate_previous_and_next_pages(&input);
assert!(pages[0].clone().next.is_none());
assert!(pages[0].clone().previous.is_none());
assert!(pages[1].clone().next.is_none());
assert!(pages[1].clone().previous.is_some());
assert_eq!(pages[1].clone().previous.unwrap().meta.order.unwrap(), 2);
assert!(pages[2].clone().next.is_some());
assert!(pages[2].clone().previous.is_some());
assert_eq!(pages[2].clone().previous.unwrap().meta.order.unwrap(), 3);
assert_eq!(pages[2].clone().next.unwrap().meta.order.unwrap(), 1);
assert!(pages[3].clone().next.is_some());
assert!(pages[3].clone().previous.is_none());
assert_eq!(pages[3].clone().next.unwrap().meta.order.unwrap(), 2);
assert!(pages[4].clone().next.is_none());
assert!(pages[4].clone().previous.is_none());
assert!(pages[2].clone().lighter.is_some());
assert!(pages[2].clone().heavier.is_none());
assert_eq!(pages[2].clone().lighter.unwrap().meta.weight.unwrap(), 2);
}
}

View file

@ -30,8 +30,6 @@ lazy_static! {
pub enum SortBy {
/// Most recent to oldest
Date,
/// Lower order comes last
Order,
/// Lower weight comes first
Weight,
/// No sorting

View file

@ -79,7 +79,7 @@ fn can_rebuild_after_simple_change_to_page_content() {
let file_path = edit_file!(site_path, "content/rebuild/first.md", br#"
+++
title = "first"
order = 1
weight = 1
date = 2017-01-01
+++
@ -97,7 +97,7 @@ fn can_rebuild_after_title_change_page_global_func_usage() {
let file_path = edit_file!(site_path, "content/rebuild/first.md", br#"
+++
title = "Premier"
order = 10
weight = 10
date = 2017-01-01
+++
@ -115,12 +115,12 @@ fn can_rebuild_after_sort_change_in_section() {
let file_path = edit_file!(site_path, "content/rebuild/_index.md", br#"
+++
paginate_by = 1
sort_by = "order"
sort_by = "weight"
template = "rebuild.html"
+++
"#);
let res = after_content_change(&mut site, &file_path);
assert!(res.is_ok());
assert!(file_contains!(site_path, "public/rebuild/index.html", "<h1>second</h1><h1>first</h1>"));
assert!(file_contains!(site_path, "public/rebuild/index.html", "<h1>first</h1><h1>second</h1>"));
}

View file

@ -36,7 +36,7 @@ use config::{Config, get_config};
use utils::fs::{create_file, copy_directory, create_directory, ensure_directory_exists};
use utils::templates::{render_template, rewrite_theme_paths};
use utils::net::get_available_port;
use content::{Page, Section, populate_previous_and_next_pages, sort_pages};
use content::{Page, Section, populate_siblings, sort_pages};
use templates::{GUTENBERG_TERA, global_fns, render_redirect_template};
use front_matter::{SortBy, InsertAnchor};
use taxonomies::{Taxonomy, find_taxonomies};
@ -401,7 +401,7 @@ impl Site {
}
let pages = mem::replace(&mut section.pages, vec![]);
let (sorted_pages, cannot_be_sorted_pages) = sort_pages(pages, section.meta.sort_by);
section.pages = populate_previous_and_next_pages(&sorted_pages);
section.pages = populate_siblings(&sorted_pages, section.meta.sort_by);
section.ignored_pages = cannot_be_sorted_pages;
}
}

View file

@ -6,6 +6,22 @@ weight = 30
A page is any file ending with `.md` in the `content` directory, except files
named `_index.md`.
If a file ending with `.md` is named `index.md`, then it will generate a page
with the name of the containing folder (for example, `/content/about/index.md` would
create a page at `[base_url]/about`). (Note the lack of an underscore; if the file
were named `_index.md`, then it would create a **section** at `[base_url]/about`, as
discussed in the prior part of this documentation. But naming the file `index.md` will
create a **page** at `[base_url]/about`).
If the file is given any name *other* than `index.md` or `_index.md`, then it will
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
`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
[Overview](./documentation/content/overview.md) section of this documentation.
## Front-matter
The front-matter is a set of metadata embedded in a file. In Gutenberg,
@ -13,7 +29,8 @@ it is at the beginning of the file, surrounded by `+++` and uses TOML.
While none of the front-matter variables are mandatory, the opening and closing `+++` are required.
Here is an example page with all the variables available:
Here is an example page with all the variables available. The values provided below are the default
values.
```md
+++
@ -22,9 +39,16 @@ description = ""
# The date of the post.
# 2 formats are allowed: YYYY-MM-DD (2012-10-02) and RFC3339 (2002-10-02T15:00:00Z)
# Do not wrap dates in quotes, the line below only indicates that there is no default date
# 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 =
# 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`
# will not be rendered.
weight = 0
# A draft page will not be present in prev/next pagination
draft = false
@ -38,24 +62,14 @@ slug = ""
# It should not start with a `/` and the slash will be removed if it does
path = ""
# A dict of taxonomies: the key is the name of the taxonomy which must match
# one of the taxonomy defined in `config.toml` and the value is a list of
# strings
[taxonomies]
# An array of strings allowing you to group pages with them
tags = []
# The order as defined in the Section page
order = 0
# The weight as defined in the Section page
weight = 0
# 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
# current one. Each element in the array of aliases may take one of two forms:
# * "some/alias/path", which will generate "some/alias/path/index.html"
# * "some/alias/path.html", which will generate "some/alias/path.html"
#
# The former is useful if your previous site had the form "example.com/some/alias/path",
# the latter is useful if your previous site had the form "example.com/some/alias/path.html"
# 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

View file

@ -3,22 +3,32 @@ title = "Section"
weight = 20
+++
A section is automatically created when a folder is found in the `content` section, unless it only
contains a `index.md` file and is actually a page with assets.
A section is created whenever a folder (or subfolder) in the `content` section contains an
`_index.md` file. If a folder does not contain an `_index.md` file, no section will be
created, but markdown files within that folder will still create pages (known as orphan pages).
You can add `_index.md` file to a folder to augment a section and give it some metadata and/or content.
The index page is actually a section created automatically like any other: you can add metadata
and content by adding `_index.md` at the root of the `content` folder.
The index page (i.e., the page displayed when a user browses to your `base_url`) is a section,
which is created whether or not you add an `_index.md` file at the root of your `content` folder.
If you do not create an `_index.md` file in your content directory, this main content section will
not have any content or metadata. If you would like to add content or metadata, you can add an
`_index.md` file at the root of the `content` folder and edit it just as you would edit any other
`_index.md` file; your `index.html` template will then have access to that content and metadata.
## Front-matter
The `_index.md` file within a folder defines the content and metadata for that section. To set
the metadata, add front matter to the file.
The front-matter is a set of metadata embedded in a file. In Gutenberg,
it is at the beginning of the file, surrounded by `+++` and uses TOML.
After the closing `+++`, you can add content that will be parsed as markdown and will be available
to your templates through the `section.content` variable.
While none of the front-matter variables are mandatory, the opening and closing `+++` are required.
Here is an example `_index.md` with all the variables available:
Here is an example `_index.md` with all the variables available. The values provided below are the
default values.
```md
@ -27,7 +37,7 @@ title = ""
description = ""
# Whether to sort by "date", "order", "weight" or "none". More on that below
# Whether to sort pages by "date", "weight", or "none". More on that below
sort_by = "none"
# Used by the parent section to order its subsections.
@ -83,22 +93,66 @@ You can also change the pagination path (the word displayed while paginated in t
by setting the `paginate_path` variable, which defaults to `page`.
## Sorting
Sections' pages can be sorted three different ways, not counting the unsorted default and
is enabled by setting the `sort_by` front-matter variable.
It is very common for Gutenberg templates to iterate over pages or sections
to display all pages/sections a given directory. Consider a very simple
example: a `blog` directory with three files: `blog/Post_1.md`,
`blog/Post_2.md`, and `blog/Post_3.md`. To iterate over these posts and
create a list of links to the posts, a simple template might look like this:
Any page that cannot be sorted, for example if missing the date variable while sorting by `date`, will be ignored and
won't be rendered. The terminal will warn you if this is happening.
```j2
{% for post in section.pages %}
<h1><a href="{{ post.permalink }}">{{ post.title }}</a></h1>
{% endfor %}
```
If several pages have the same date/weight/order, their permalink will be used to break the tie following
an alphabetical order.
This would iterate over the posts, and would do so in a specific order
based on the `sort_by` variable set in the `_index.md` page for the
containing section. The `sort_by` variable can be given three values: `date`,
`weight`, and `none`. If no `sort_by` method is set, the pages will be
sorted in the `none` order, which is not intended to be used for sorted content.
Any page that is missing the data it needs to be sorted will be ignored and
won't be rendered. For example, if a page is missing the date variable the
containing section sets `sort_by = "date"`, then that page will be ignored.
The terminal will warn you if this is happening.
If several pages have the same date/weight/order, their permalink will be used
to break the tie following an alphabetical order.
## Sorting Pages
The `sort_by` front-matter variable can have the following values:
### `date`
This will sort all pages by their `date` field, from the most recent to the oldest.
This will sort all pages by their `date` field, from the most recent (at the
top of the list) to the oldest (at the bottom of the list). Each page will
get `page.earlier` and `page.later` variables that contain the pages with
earlier and later dates, respectively.
### `weight`
This will be sort all pages by their `weight` field. Heavier weights fall at the bottom: 5 would be before 10.
This will be sort all pages by their `weight` field, from lightest weight
(at the top of the list) to heaviest (at the bottom of the list). Each
page gets `page.lighter` and `page.heavier` variables that contain the
pages with lighter and heavier weights, respectively.
### `order`
This will be sort all pages by their `order` field. Order is the opposite of weight, think of it as enumerating
the content: this is my first post, my second, etc. A page with `order: 5` will appear after a page with `order: 10` in the sorted list.
When iterating through pages, you may wish to use the Tera `reverse` filter,
which reverses the order of the pages. Thus, after using the `reverse` filter,
pages sorted by weight will be sorted from lightest (at the top) to heaviest
(at the bottom); pages sorted by date will be sorted from oldest (at the top)
to newest (at the bottom).
`reverse` has no effect on `page.later`/`page.earlier`/`page.heavier`/`page.lighter`.
## Sorting Subsections
Sorting sections is a bit less flexible: sections are always sorted by `weight`,
and do not have any variables that point to the next heavier/lighter sections.
Based on this, by default the lightest (lowest `weight`) subsections will be at
the top of the list and the heaviest (highest `weight`) will be at the top;
the `reverse` filter reverses this order.
**Note**: Unlike pages, permalinks will **not** be used to break ties between
equally weighted sections. Thus, if the `weight` variable for your section is not set (or if it
is set in a way that produces ties), then your sections will be sorted in
**random** order. Moreover, that order is determined at build time and will
change with each site rebuild. Thus, if there is any chance that you will
iterate over your sections, you should always assign them weight.

View file

@ -32,9 +32,12 @@ extra: HashMap<String, Any>;
word_count: Number;
// Based on https://help.medium.com/hc/en-us/articles/214991667-Read-time
reading_time: Number;
// `previous` and `next` are only filled if the content can be sorted
previous: Page?;
next: Page?;
// `earlier` and `later` are only populated if the section variable `sort_by` is set to `date`
earlier: Page?;
later: Page?;
// `heavier` and `lighter` are only populated if the section variable `sort_by` is set to `weight`
heavier: Page?;
lighter: Page?;
// See the Table of contents section below for more details
toc: Array<Header>;
// Year/month/day is only set if the page has a date and month/day are 1-indexed

View file

@ -1,6 +1,6 @@
+++
title = "DevOps"
sort_by = "order"
sort_by = "weight"
redirect_to = "posts/tutorials/devops/docker"
weight = 10
+++

View file

@ -1,6 +1,6 @@
+++
title = "Docker"
order = 1
weight = 1
date = 2017-01-01
+++

View file

@ -1,6 +1,6 @@
+++
title = "Nix"
order = 2
weight = 2
date = 2017-01-01
+++

View file

@ -1,5 +1,5 @@
+++
title = "Programming"
sort_by = "order"
sort_by = "weight"
weight = 1
+++

View file

@ -1,6 +1,6 @@
+++
title = "Python tutorial"
order = 1
weight = 1
date = 2017-01-01
+++

View file

@ -1,6 +1,6 @@
+++
title = "Rust"
order = 2
weight = 2
date = 2017-01-01
+++

View file

@ -1,5 +1,5 @@
+++
paginate_by = 1
sort_by = "order"
sort_by = "weight"
template = "rebuild.html"
+++

View file

@ -1,6 +1,6 @@
+++
title = "first"
order = 10
weight = 10
date = 2017-01-01
+++

View file

@ -1,6 +1,6 @@
+++
title = "second"
order = 100
weight = 100
date = 2016-01-01
+++