updated documentation
This commit is contained in:
parent
7c52f28aa7
commit
08e51665e0
1 changed files with 231 additions and 71 deletions
302
README.md
302
README.md
|
@ -1,26 +1,38 @@
|
||||||
<h1>Zona</h1>
|
<h1>zona</h1>
|
||||||
|
|
||||||
[Zona](https://sr.ht/~ficd/zona) is an opinionated static site generator written
|
[zona](https://sr.ht/~ficd/zona) is an _opinionated_ static site generator
|
||||||
in Python. From a structured directory of Markdown content, Zona builds a simple
|
written in Python. From a structured directory of Markdown content, zona builds
|
||||||
static website. It's designed to get out of your way and let you focus on
|
a simple static website. It's designed to get out of your way and let you focus
|
||||||
writing.
|
on writing.
|
||||||
|
|
||||||
**Note:** This project is in early development, and there are no versioned
|
**What do I mean by opinionated?** I built zona primarily for myself. I've tried
|
||||||
releases yet. For an example of a website built with Zona, please see
|
making it flexible by exposing many variables as possible to the template
|
||||||
[ficd.ca](https://ficd.ca)
|
engine. However, if you're looking for something stable, complete, and fully
|
||||||
|
configurable, zona may not be for you. If you want a minimal Markdown blog and
|
||||||
|
are comfortable with modifying `jinja2` templates and CSS, then you're in luck.
|
||||||
|
|
||||||
|
**Note:** This project is in early development, there are no versioned releases
|
||||||
|
yet, and breaking changes are likely. Versioned releases will be made and zona
|
||||||
|
will be published to PyPI once it's stable.
|
||||||
|
|
||||||
|
For an example of a website built with zona, please see
|
||||||
|
[ficd.ca](https://ficd.ca).
|
||||||
|
|
||||||
<!--toc:start-->
|
<!--toc:start-->
|
||||||
|
|
||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Usage](#usage)
|
||||||
|
- [Getting Started](#getting-started)
|
||||||
|
- [Site Layout](#site-layout)
|
||||||
- [Internal Link Resolution](#internal-link-resolution)
|
- [Internal Link Resolution](#internal-link-resolution)
|
||||||
- [Syntax Highlighting](#syntax-highlighting)
|
- [Syntax Highlighting](#syntax-highlighting)
|
||||||
- [Image Labels](#image-labels)
|
- [Image Labels](#image-labels)
|
||||||
- [Installation](#installation)
|
|
||||||
- [Usage](#usage)
|
|
||||||
- [Site Layout](#site-layout)
|
|
||||||
- [Frontmatter](#frontmatter)
|
- [Frontmatter](#frontmatter)
|
||||||
- [Configuration](#configuration)
|
- [Post List](#post-list)
|
||||||
|
- [Configuration](#configuration)
|
||||||
|
- [Sitemap](#sitemap)
|
||||||
|
- [Ignore List](#ignore-list)
|
||||||
|
- [Drafts](#drafts)
|
||||||
<!--toc:end-->
|
<!--toc:end-->
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
@ -33,16 +45,78 @@ releases yet. For an example of a website built with Zona, please see
|
||||||
- Easily configurable sitemap header.
|
- Easily configurable sitemap header.
|
||||||
- Site footer written in Markdown.
|
- Site footer written in Markdown.
|
||||||
- Smart site layout discovery.
|
- Smart site layout discovery.
|
||||||
- Blog posts automatically discovered and rendered accordingly (can be
|
- Blog posts are automatically discovered and rendered accordingly (can be
|
||||||
overridden in frontmatter).
|
overridden in frontmatter).
|
||||||
- Extended Markdown renderer:
|
- Extended Markdown renderer:
|
||||||
- Smart internal link resolution.
|
- Smart internal link resolution.
|
||||||
- Syntax highlighting.
|
- Syntax highlighting.
|
||||||
|
- Includes Kakoune syntax and [Ashen] highlighting.
|
||||||
- [Image labels](#image-labels).
|
- [Image labels](#image-labels).
|
||||||
|
- Many `python-markdown` extensions enabled, including footnotes, tables,
|
||||||
|
abbreviations, etc.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
zona is not yet packaged on PyPI. You may use `uv` to install it from this
|
||||||
|
repository:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
uv tool install 'git+https://git.sr.ht/~ficd/zona'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
_Note: you may provide the `--help` option to any subcommand to see the
|
||||||
|
available options and arguments._
|
||||||
|
|
||||||
|
### Getting Started
|
||||||
|
|
||||||
|
To set up a new website, create a new directory and run `zona init` inside of
|
||||||
|
it. This creates the required directory structure and writes the default
|
||||||
|
configuration file. The default templates and default stylesheet are also
|
||||||
|
written.
|
||||||
|
|
||||||
|
To build the website, run `zona build`. The project root is discovered according
|
||||||
|
to the location of `config.yml`. By default, the output directory is called
|
||||||
|
`public`, and saved inside the root directory.
|
||||||
|
|
||||||
|
To start a live preview session, execute `zona serve`. The server will run until
|
||||||
|
it's killed by the user, and the website is rebuilt if any source files are
|
||||||
|
modified. _Note: if you change `config.yml` or any templates, you will need to
|
||||||
|
restart the preview server_.
|
||||||
|
|
||||||
|
### Site Layout
|
||||||
|
|
||||||
|
The following demonstrates a simple zona project layout:
|
||||||
|
|
||||||
|
```
|
||||||
|
config.yml
|
||||||
|
content/
|
||||||
|
templates/
|
||||||
|
public/
|
||||||
|
```
|
||||||
|
|
||||||
|
The **root** of the zona **project** _must_ contain the configuration file,
|
||||||
|
`config.yml`, and a directory called `content`. A directory called `templates`
|
||||||
|
is optional, and prioritized if it exists. `public` is the built site output —
|
||||||
|
it's recommended to add this path to your `.gitignore`.
|
||||||
|
|
||||||
|
The `content` directory is the **root of the website**. Think of it as the
|
||||||
|
**content root**. For example, suppose your website is hosted at `example.com`.
|
||||||
|
`content/blog/index.md` corresponds to `example.com/blog`,
|
||||||
|
`content/blog/my-post.md` becomes `example.com/blog/my-post`, etc.
|
||||||
|
|
||||||
|
- Internal links are resolved **relative to the `content` directory.**
|
||||||
|
- Templates are resolved relative to the `template` directory.
|
||||||
|
|
||||||
|
Markdown files inside a certain directory (`content/blog` by default) are
|
||||||
|
automatically treated as _blog posts_. This means they are rendered with the
|
||||||
|
`page` template, and included in the `post_list`, which can be included in your
|
||||||
|
site using the `post_list` template.
|
||||||
|
|
||||||
### Internal Link Resolution
|
### Internal Link Resolution
|
||||||
|
|
||||||
When Zona encounters links in Markdown documents, it attempts to resolve them as
|
When zona encounters links in Markdown documents, it attempts to resolve them as
|
||||||
internal links. Links beginning with `/` are resolved relative to the content
|
internal links. Links beginning with `/` are resolved relative to the content
|
||||||
root; otherwise, they are resolved relative to the Markdown file. If the link
|
root; otherwise, they are resolved relative to the Markdown file. If the link
|
||||||
resolves to an existing file that is part of the website, it's replaced with an
|
resolves to an existing file that is part of the website, it's replaced with an
|
||||||
|
@ -51,11 +125,12 @@ appropriate web-server-friendly link. Otherwise, the link isn't changed.
|
||||||
For example, suppose the file `blog/post1.md` has a link `./post2.md`. The HTML
|
For example, suppose the file `blog/post1.md` has a link `./post2.md`. The HTML
|
||||||
output will contain the link `/blog/post2` (which corresponds to
|
output will contain the link `/blog/post2` (which corresponds to
|
||||||
`/blog/post2/index.html`). Link resolution is applied to _all_ internal links,
|
`/blog/post2/index.html`). Link resolution is applied to _all_ internal links,
|
||||||
including those pointing to static resources like images.
|
including those pointing to static resources like images. Links are only
|
||||||
|
modified if they point to a real file that's not included in the ignore list.
|
||||||
|
|
||||||
### Syntax Highlighting
|
### Syntax Highlighting
|
||||||
|
|
||||||
Zona uses [Pygments] to provide syntax highlighting for fenced code blocks. The
|
zona uses [Pygments] to provide syntax highlighting for fenced code blocks. The
|
||||||
following Pygments plugins are included:
|
following Pygments plugins are included:
|
||||||
|
|
||||||
- [pygments-kakoune](https://git.sr.ht/~ficd/pygments-kakoune)
|
- [pygments-kakoune](https://git.sr.ht/~ficd/pygments-kakoune)
|
||||||
|
@ -65,8 +140,9 @@ following Pygments plugins are included:
|
||||||
- An implementation of the [Ashen](https://git.sr.ht/~ficd/ashen) theme for
|
- An implementation of the [Ashen](https://git.sr.ht/~ficd/ashen) theme for
|
||||||
Pygments.
|
Pygments.
|
||||||
|
|
||||||
If you want to use any external Pygments styles or lexers, they must be available
|
If you want to use any external Pygments styles or lexers, they must be
|
||||||
in Zona's Python environment. For example, you can give Zona access to [Catppucin](https://github.com/catppuccin/python):
|
available in zona's Python environment. For example, you can give zona access to
|
||||||
|
[Catppucin](https://github.com/catppuccin/python):
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# config.yml
|
# config.yml
|
||||||
|
@ -75,16 +151,26 @@ markdown:
|
||||||
theme: catppucin-mocha
|
theme: catppucin-mocha
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, run Zona with the following `uv` command:
|
Then, run zona with the following `uv` command:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
uvx --with catppucin zona build
|
uvx --with catppucin zona build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Inline syntax highlighting is also provided via a `python-markdown` extension.
|
||||||
|
If you prefix inline code with a shebang followed by the language identifier, it
|
||||||
|
will be highlighted. For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
`#!python print(f"I love {foobar}!", end="")`
|
||||||
|
will be rendered as
|
||||||
|
`print(f"I love {foobar}!", end="")`
|
||||||
|
(the #!lang is stripped)
|
||||||
|
```
|
||||||
|
|
||||||
### Image Labels
|
### Image Labels
|
||||||
|
|
||||||
A feature unique to Zona is **image labels**. They make it easy to annotate
|
A feature unique to zona is **image labels**. They make it easy to annotate
|
||||||
images in your Markdown documents. The alt text Markdown element is rendered as
|
images in your Markdown documents. The alt text Markdown element is rendered as
|
||||||
the label — with support for inline Markdown. Consider this example:
|
the label — with support for inline Markdown. Consider this example:
|
||||||
|
|
||||||
|
@ -101,57 +187,131 @@ The above results in the following HTML:
|
||||||
```
|
```
|
||||||
|
|
||||||
The `image-container` class is provided as a convenience for styling. The
|
The `image-container` class is provided as a convenience for styling. The
|
||||||
default stylesheet centers the label under the image.
|
default stylesheet centers the label under the image. Note: _links_ inside image
|
||||||
|
captions are not currently supported. I am looking into a solution.
|
||||||
## Installation
|
|
||||||
|
|
||||||
Zona is not yet packaged on PyPI. You may use `uv` to install it from this
|
|
||||||
repository:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
uv tool install 'git+https://git.sr.ht/~ficd/zona'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
_Note: you may provide the `--help` option to any subcommand to see the
|
|
||||||
available options and arguments.
|
|
||||||
|
|
||||||
To set up a new website, create a new directory and run `zona init` inside of
|
|
||||||
it. This creates the required directory structure and writes the default
|
|
||||||
configuration file. The default templates and default stylesheet are also
|
|
||||||
written.
|
|
||||||
|
|
||||||
To build the website, run `zona build`. The project root is discovered according
|
|
||||||
to the location of `config.yml`. By default, the output directory is called
|
|
||||||
`public`, and saved inside the root directory.
|
|
||||||
|
|
||||||
To start a live preview session, execute `zona serve`. The server will run until
|
|
||||||
it's killed by the user, and the website is rebuilt if any source files are
|
|
||||||
modified.
|
|
||||||
|
|
||||||
### Site Layout
|
|
||||||
|
|
||||||
The **root** of the **Zona project** _must_ contain the configuration file,
|
|
||||||
`config.yml`, and a directory called `content`. A directory called `templates`
|
|
||||||
is optional, and prioritized if it exists. `public` is the built site output —
|
|
||||||
it's recommended to add this path to your `.gitignore`.
|
|
||||||
|
|
||||||
The `content` directory is the root of the website. For example, suppose your
|
|
||||||
website is hosted at `example.com`. `content/blog/index.md` corresponds to
|
|
||||||
`example.com/blog`, `content/blog/my-post.md` becomes
|
|
||||||
`example.com/blog/my-post`, etc. Internal links are resolved **relative to the
|
|
||||||
`content` directory.**
|
|
||||||
|
|
||||||
Markdown files inside a certain directory (`content/blog` by default) are
|
|
||||||
automatically treated as _blog posts_. This means they are rendered with the
|
|
||||||
`page.html` template, and included in the `post_list`, which can be included in
|
|
||||||
your site using the `post_list.html` template.
|
|
||||||
|
|
||||||
### Frontmatter
|
### Frontmatter
|
||||||
|
|
||||||
WIP
|
YAML frontmatter can be used to configure the metadata of documents. All of them
|
||||||
|
are optional. `none` is used when the option is unset. The following options are
|
||||||
|
available:
|
||||||
|
|
||||||
### Configuration
|
| Key | Type & Default | Description |
|
||||||
|
| ------------ | --------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||||
|
| `title` | `str` = title-cased filename. | Title of the page. |
|
||||||
|
| `date` | Date string = file modified time. | Displayed on blog posts and used for post_list sorting. |
|
||||||
|
| `show_title` | `bool` = `true` | Whether `metadata.title` should be included in the template. |
|
||||||
|
| `header` | `bool` = `true` | Whether the header sitemap should be rendered. |
|
||||||
|
| `footer` | `bool` = `true` | Whether the footer should be rendered. |
|
||||||
|
| `template` | `str \| none` = `none` | Template to use for this page. Relative to `templates/`, `.html` extension optional. |
|
||||||
|
| `post` | `bool \| none` = `none` | Whether this page is a **post**. `true`/`false` is _absolute_. Leave it unset for automatic detection. |
|
||||||
|
| `draft` | `bool` = `false` | Whether this page is a draft. See [drafts](#drafts) for more. |
|
||||||
|
|
||||||
WIP
|
**Note**: you can specify the date in any format that can be parsed by
|
||||||
|
[`python-dateutil`](https://pypi.org/project/python-dateutil/).
|
||||||
|
|
||||||
|
### Post List
|
||||||
|
|
||||||
|
Suppose you want `example.com/blog` to be a _post list_ page, and you want
|
||||||
|
`example.com/blog/my-post` to be a post. You would first create
|
||||||
|
`content/blog/index.md` and add the following frontmatter:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
title: Blog
|
||||||
|
post: false
|
||||||
|
template: post_list
|
||||||
|
|
||||||
|
Welcome to my blog! Please find a list of my posts below.
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
Setting `post: false` is necessary because, by default, all documents inside
|
||||||
|
`content/blog` are considered to be posts unless explicitly disabled in the
|
||||||
|
frontmatter. We don't want the post list to list _itself_ as a post.
|
||||||
|
|
||||||
|
Then, you'd create `content/blog/my-post.md` and populate it:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
title: My First Post
|
||||||
|
date: July 5, 2025
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
Because `my-post` is inside the `blog` directory, `post: true` is implied. If
|
||||||
|
you wanted to put it somewhere outside `blog`, you would need to set
|
||||||
|
`post: true` for it to be included in the post list.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Zona is configured in YAML format. The configuration file is called `config.yml`
|
||||||
|
and it **must** be located in the root of the project — in the same directory as
|
||||||
|
`content` and `templates`.
|
||||||
|
|
||||||
|
Your configuration will be merged with the defaults. `zona init` also writes a
|
||||||
|
copy of the default configuration to the correct location. If it exists, you'll
|
||||||
|
be prompted before overwriting it.
|
||||||
|
|
||||||
|
**Note:** Currently, not every configuration value is actually used. Only the
|
||||||
|
useful settings are listed here.
|
||||||
|
|
||||||
|
Please see the default configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
sitemap:
|
||||||
|
Home: /
|
||||||
|
ignore:
|
||||||
|
- .marksman.toml
|
||||||
|
markdown:
|
||||||
|
image_labels: true
|
||||||
|
tab_length: 2
|
||||||
|
syntax_highlighting:
|
||||||
|
enabled: true
|
||||||
|
theme: ashen
|
||||||
|
wrap: false
|
||||||
|
blog:
|
||||||
|
dir: blog
|
||||||
|
```
|
||||||
|
|
||||||
|
| Name | Description |
|
||||||
|
| -------------------------------------- | --------------------------------------------------------------------------------------------- |
|
||||||
|
| `sitemap` | Sitemap dictionary. See [Sitemap](#sitemap). |
|
||||||
|
| `ignore` | List of paths to ignore. See [Ignore List](#ignore-list). |
|
||||||
|
| `markdown.tab_length` | How many spaces should be considered an indentation level. |
|
||||||
|
| `markdown.syntax_highlighting.enabled` | Whether code should be highlighted. |
|
||||||
|
| `markdown.syntax_highlighting.theme` | [Pygments] style for highlighting. |
|
||||||
|
| `markdown.syntax_highlighting.wrap` | Whether the resulting code block should be word wrapped. |
|
||||||
|
| `blog.dir` | Name of a directory relative to `content/` whose children are automatically considered posts. |
|
||||||
|
|
||||||
|
### Sitemap
|
||||||
|
|
||||||
|
You can define a sitemap in the configuration file. This is a list of links that
|
||||||
|
will be rendered at the top of every page. The `sitemap` is a dictionary of
|
||||||
|
`string` to `string` pairs, where each key is the displayed text of the link,
|
||||||
|
and the value if the `href`. Consider this example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
sitemap:
|
||||||
|
Home: /
|
||||||
|
About: /about
|
||||||
|
Blog: /blog
|
||||||
|
Git: https://git.sr.ht/~ficd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ignore List
|
||||||
|
|
||||||
|
You can set a list of glob patterns in the [configuration](#configuration) that
|
||||||
|
should be ignored by zona. This is useful because zona makes a copy of _every_
|
||||||
|
file it encounters inside the `content` directory, regardless of its type. The
|
||||||
|
paths must be relative to the `content` directory.
|
||||||
|
|
||||||
|
### Drafts
|
||||||
|
|
||||||
|
zona allows you to begin writing content without including it in the final build
|
||||||
|
output. If you set `draft: true` in a page's frontmatter, it will be marked as a
|
||||||
|
draft. Drafts are completely excluded from `zona build` and `zona serve` unless
|
||||||
|
the `--draft` flag is specified.
|
||||||
|
|
||||||
|
[Ashen]: https://sr.ht/~ficd/ashen
|
||||||
|
[Pygments]: https://pygments.org/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue