Skip to content

Commit

Permalink
feat: Collections
Browse files Browse the repository at this point in the history
TODO:
- Implement pagination.
- Modify log output to be more helpful for end-users.
  • Loading branch information
emmyoh committed Jun 7, 2024
1 parent 3471047 commit 5170ba6
Show file tree
Hide file tree
Showing 19 changed files with 266 additions and 132 deletions.
22 changes: 11 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,23 @@ required-features = ["cli"]

[dependencies]
chrono = { version = "0.4.38", features = ["serde", "unstable-locales"] }
clap = { version = "4.5.4", features = ["derive", "cargo"], optional = true }
comrak = { version = "0.22.0", features = ["syntect", "shortcodes"], default-features = false }
clap = { version = "4.5.6", features = ["derive", "cargo"], optional = true }
comrak = { version = "0.24.1", features = ["syntect", "shortcodes"], default-features = false }
daggy = { version = "0.8.0", features = ["stable_dag"] }
toml = "0.8.12"
liquid = "0.26.4"
liquid-core = "0.26.4"
liquid-lib = { version = "0.26.4", features = ["all", "stdlib", "jekyll", "shopify", "extra"] }
serde = "1.0.198"
toml = "0.8.14"
liquid = "0.26.6"
liquid-core = "0.26.6"
liquid-lib = { version = "0.26.6", features = ["all", "stdlib", "jekyll", "shopify", "extra"] }
serde = "1.0.203"
sys-locale = "0.3.1"
latex2mathml = "0.2.3"
ahash = { version = "0.8.11", features = ["std", "serde", "runtime-rng"] }
mimalloc = { version = "0.1.41", optional = true }
mimalloc = { version = "0.1.42", optional = true }
ticky = { version = "1.0.2", optional = true }
miette = { version = "7.2.0", features = ["fancy", "syntect-highlighter"] }
thiserror = "1.0.59"
glob = { version = "0.3.1" }
tokio = { version = "1.37.0", features = ["full"], optional = true }
thiserror = "1.0.61"
glob = "0.3.1"
tokio = { version = "1.38.0", features = ["full"], optional = true }
futures = "0.3.30"
tracing-subscriber = { version = "0.3.18", optional = true }
tracing = "0.1.40"
Expand Down
57 changes: 57 additions & 0 deletions site/diary/collections_pagination.vox
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title = "Collections & Pagination"
date = 2024-06-07
layout = "post"
permalink = "date"
---

{% markdown %}

## Goals
- Supporting pages in multiple collections at once with path nesting.
- If a build has failed, don't immediately retry.
- Upgrading all direct dependencies.
- Implement pagination.
- Modify log output to be more helpful for end-users.

### Collections

To support this, `collections` must be renamed to `depends`, and `collection` to `collections`.

The rule: one collection per path component, and collections including each successive path component.
- Collection names must be represented as Liquid identifiers so they can be used in templating in dependent pages.
- Example: `books/fantasy/page.vox` is in `books`, `fantasy`, and `books_fantasy`.
- Example: `movies/fantasy/page.vox` is in `movies`, `fantasy`, and `movies_fantasy`.

### Retrying Builds

This was always the intended behaviour. The mistake was in accidentally checking for a [`JoinError`](https://docs.rs/tokio/latest/tokio/task/struct.JoinError.html) when the build thread had completed, rather than checking for errors from the build thread.

### Upgrading Dependencies

Notably, this brought my implementation of Jekyll's sorting filter, which was merged into the Liquid Rust implementation.

### Pagination

Pages may have a `pagination` frontmatter value, containing:
* `pagination.collection`: the name of a collection in a page's `depends` list
* `pagination.page_size`: the maximum number of collection pages per page

Pages using pagination are copied in memory, with each copy being supplied different `pagination.page_number` values.
The `pagination.page_number` is used in a page's `permalink`, and can be used with `pagination.page_size`:
- to calculate the starting index in the collection for the current page
- to calculate the total number of pages
- to determine the URL of any page
- to calculate the remaining number of pages
- This requires the length of the paginated collection as well

---

## Future Goals
- Parallelising as much as possible.
- Removing code that was commented out.
- Documenting the CLI code.
- Creating a logo for Vox.
- Incorporating snippets into DAG construction.

{% endmarkdown %}
4 changes: 2 additions & 2 deletions site/diary/inheritance_guide.vox
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ permalink = "date"

This site is used to debug changes to Vox. First, the `global.url` of the site is changed, then this command is used to rebuild & serve:
```sh
clear; rm -rf ./output; ./prebuild.sh; vox serve -d -w -vv
clear; rm -rf ./output; ./prebuild.sh; vox serve -d -s -w -vv
```

---
Expand All @@ -23,7 +23,7 @@ Today's agenda:
- Implementing partial date-times.
- Redesigning layout inheritance.
- In layout inheritance, the lowest layout should include chained parent contexts up to the first non-layout page.
- Fixing the `{% raw %}{{ markdown }}{% endraw %}` block.
- Fixing the `{% raw %}{% markdown %}{% endraw %}` block.
- Finishing the user guide.
- Modifying code according to lints.
- Improving syntax highlighting.
Expand Down
2 changes: 1 addition & 1 deletion site/global.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ description = "A performant static site generator built to scale."
author = "Emil Sayahi"
locale = "en_US"
url = "https://emmyoh.github.io/vox"
# url = "http://localhost:80"
# url = "http://localhost"
18 changes: 11 additions & 7 deletions site/guide/frontmatter.vox
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ There are a variety of shorthand options for the `permalink` field:

| Shorthand | Expanded |
|------------|--------------------------------------------------------------------------------------------------------------------------|
| `date` | `/{{ page.collection }}/{{ page.date.year }}/{{ page.date.month }}/{{ page.date.day }}/{{ page.data.title }}.html` |
| `pretty` | `/{{ page.collection }}/{{ page.date.year }}/{{ page.date.month }}/{{ page.date.day }}/{{ page.data.title }}/index.html` |
| `ordinal` | `/{{ page.collection }}/{{ page.date.year }}/{{ page.date.y_day }}/{{ page.data.title }}.html` |
| `weekdate` | `/{{ page.collection }}/{{ page.date.year }}/W{{ page.date.week }}/{{ page.date.short_day }}/{{ page.data.title }}.html` |
| `none` | `/{{ page.collection }}/{{ page.data.title }}.html` |
| `date` | `{{ page.collections.last }}/{{ page.date.year }}/{{ page.date.month }}/{{ page.date.day }}/{{ page.data.title }}.html` |
| `pretty` | `{{ page.collections.last }}/{{ page.date.year }}/{{ page.date.month }}/{{ page.date.day }}/{{ page.data.title }}/index.html` |
| `ordinal` | `{{ page.collections.last }}/{{ page.date.year }}/{{ page.date.y_day }}/{{ page.data.title }}.html` |
| `weekdate` | `{{ page.collections.last }}/{{ page.date.year }}/W{{ page.date.week }}/{{ page.date.short_day }}/{{ page.data.title }}.html` |
| `none` | `{{ page.collections.last }}/{{ page.data.title }}.html` |

{% endraw %}

Expand All @@ -58,13 +58,17 @@ Suppose you're trying to build an index page for your blog. Its frontmatter will
```toml
---
layout = "default"
collections = ["posts"]
depends = ["posts"]
permalink = "index.html"
---
```
{% endraw %}

The `collections` property indicates the page collections that this page depends on. A templating context is provided for each requested collection; in this example, there will be a `posts` context containing all pages in the `posts` collection.
The `depends` property indicates the page collections that this page depends on. A templating context is provided for each requested collection; in this example, there will be a `posts` context containing all pages in the `posts` collection.

The collections a page is in is defined by a page's path, with one collection per path component, and collections including each successive path component as well. For example:
* `books/fantasy/page.vox` is in `books`, `fantasy`, and `books_fantasy`.
* `movies/fantasy/page.vox` is in `movies`, `fantasy`, and `movies_fantasy`.

## Data
All other fields fall under a page's `data` property.
Expand Down
8 changes: 8 additions & 0 deletions site/layouts/default.vox
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
<a href="{{ global.url }}" title="Home">{{ global.title }}</a>
<small>{{ global.description }}</small>
</h3>
{% assign output_name = page.url | split: "/" | last %}
{% if output_name != 'index.html' %}
{% if page.collections.first %}
<h4>
<a href="{{ global.url | append: "/" | append: page.collections.first | append: "/index.html" }}" title="Back to index">⟵ {{ page.collections.first | capitalize }}</a>
</h4>
{% endif %}
{% endif %}
</header>
<main id="skip-target">
{{ layouts | map: "rendered" | first }}
Expand Down
2 changes: 1 addition & 1 deletion site/pages/blog_atom.vox
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
collections = ["blog"]
depends = ["blog"]
permalink = "blog/atom.xml"
---
{% include atom.voxs posts = blog %}
4 changes: 2 additions & 2 deletions site/pages/blog_index.vox
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout = "default"
collections = ["blog"]
depends = ["blog"]
permalink = "blog/index.html"
---
{% assign posts = blog | sort: "date" %}
{% assign posts = blog | sort: "date.rfc_3339" | reverse %}
{% include index.voxs posts = posts minimal = true %}
2 changes: 1 addition & 1 deletion site/pages/diary_atom.vox
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
collections = ["diary"]
depends = ["diary"]
permalink = "diary/atom.xml"
---
{% include atom.voxs posts = diary %}
4 changes: 2 additions & 2 deletions site/pages/diary_index.vox
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout = "default"
collections = ["diary"]
depends = ["diary"]
permalink = "diary/index.html"
---
{% assign posts = diary | sort: "date" %}
{% assign posts = diary | sort: "date.rfc_3339" | reverse %}
{% include index.voxs posts = posts minimal = true %}
2 changes: 1 addition & 1 deletion site/pages/guide_index.vox
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
layout = "default"
collections = ["guide"]
depends = ["guide"]
permalink = "guide/index.html"
---
{% assign posts = guide | sort: "data.title" | reverse %}
Expand Down
9 changes: 5 additions & 4 deletions site/snippets/atom.voxs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@
<feed xmlns="http://www.w3.org/2005/Atom">

<title>{{ global.title }}</title>
<updated>{{ meta.date.rfc_3339 }}</updated>
<link href="{{ '/atom.xml' | prepend: global.url }}" rel="self"/>
<link href="{{ global.url }}/"/>
<id>{{ global.url }}</id>
<id>{{ global.url }}/</id>
<author>
<name>{{ global.author }}</name>
</author>

{% for post in include.posts %}
<entry>
<title>{{ post.data.title | escape }}</title>
<link href="{{ post.url | escape | prepend: global.url }}"/>
<link href="{{ post.url | url_encode | prepend: "/" | prepend: global.url }}"/>
{% if post.date %}
<updated>{{ post.date.rfc_2822 }}</updated>
<updated>{{ post.date.rfc_3339 }}</updated>
{% endif %}
<id>{{ post.url | escape }}</id>
<id>{{ post.url | url_encode | prepend: "/" | prepend: global.url }}</id>
<content type="html">{{ post.rendered | escape }}</content>
</entry>
{% endfor %}
Expand Down
4 changes: 2 additions & 2 deletions site/snippets/index.voxs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{% for post in include.posts %}
<article class="post">
<h1 class="post-title">
<a href="{{ post.url | prepend: global.url }}">
<a href="{{ post.url | prepend: "/" | prepend: global.url }}">
{{ post.data.title }}
</a>
</h1>
Expand All @@ -16,7 +16,7 @@
{% for post in include.posts %}
<article class="post">
<h1 class="post-title">
<a href="{{ post.url | prepend: global.url }}">
<a href="{{ post.url | prepend: "/" | prepend: global.url }}">
{{ post.data.title }}
</a>
</h1>
Expand Down
24 changes: 13 additions & 11 deletions src/builds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl Build {
if Page::is_layout_path(label.clone())? {
node.look.fill_color = Some(Color::fast("#FFDFBA"));
} else {
match Page::get_collection_name_from_path(label)? {
match Page::get_collections_from_path(label)? {
Some(_) => {
node.look.fill_color = Some(Color::fast("#DAFFBA"));
}
Expand Down Expand Up @@ -303,18 +303,20 @@ impl Build {
// If the parent page is in a collection this page depends on, make note of it.
EdgeType::Collection => {
let parent_path = parent_page.to_path_string();
let collection_name = parent_page.get_collection_name()?.unwrap();
let collection_names = parent_page.get_collections()?.unwrap();
info!(
"Parent page ({:?}) is in collection: {:?}",
parent_path, collection_name
"Parent page ({:?}) is in collections: {:?}",
parent_path, collection_names
);
if collection_pages.contains_key(&collection_name) {
collection_pages
.get_mut(&collection_name)
.unwrap()
.push(parent.1);
} else {
collection_pages.insert(collection_name.clone(), vec![parent.1]);
for collection_name in collection_names {
if collection_pages.contains_key(&collection_name) {
collection_pages
.get_mut(&collection_name)
.unwrap()
.push(parent.1);
} else {
collection_pages.insert(collection_name.clone(), vec![parent.1]);
}
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@ pub struct DateNotValid {
#[diagnostic(
code(page::invalid_collections_property),
url(docsrs),
help("Please ensure that your `collections` property is a list of collections this page depends on.")
help(
"Please ensure that your `depends` property is a list of collections this page depends on."
)
)]
/// Invalid list of dependent collections.
pub struct InvalidCollectionsProperty {
pub struct InvalidDependsProperty {
#[source_code]
/// The page with the invalid `collections` property.
/// The page with the invalid `depends` property.
pub src: NamedSource<String>,
}
Loading

0 comments on commit 5170ba6

Please sign in to comment.