Coder Social home page Coder Social logo

hinoki's Introduction

Hinoki

A simple, yet very flexible static site generator.

It's early days for this project, and this readme is currently all there is in terms of documentation. Feel free to open issues for anything that is unclear!

Features

  • Templating (with MiniJinja)
    • Use of template expressions in content files
  • Markdown to HTML conversion
    • Syntax highlighting
    • Footnotes
    • Other markdown features like tables
  • TOML frontmatter
  • Custom defaults for frontmatter via path patterns
  • Pagination
  • Development server
  • SCSS compilation
  • Page summaries

How to install

At this time, no binaries are being distributed yet.

Since hinoki is written in Rust, you need a Rust toolchain to build it yourself. You can use cargo install --git https://github.com/jplatte/hinoki to build and install it to ~/.cargo/bin/.

How to use

The basic structure for a site you build with hinoki is this:

├ config.toml  # Basic configuration
├ build        # Default output directory
├ content      # Content of the site, e.g. markdown files
└ theme
  ├ assets     # Static files
  ├ sublime    # Sublime `.tmTheme` files
  └ templates  # MiniJinja templates

After installing it, you can run hinoki build in such a directory to populate the output directory.

Configuration

Lots of things that you would configure globally with other static site generators are configured on a per-file basis with hinoki. To make this ergonomic, you can apply any file settings to many files at once using config.toml's files section. There are also a few other things you can set in this file, as shown in the example below:

# The output directory.
#
# Default value: `build`
output_dir = "public"

# Convert all .md content files to HTML.
[content."*.md"]
process = "markdown_to_html"

[content."blog/*"]
template = "blog_article.html"
# It is also possible to use basic templating for paths and titles.
# This uses a MiniJinja engine with `{{` and `}}` shortened to `{` and `}`.
date = "{source_file_stem|date_prefix}"
slug = "{source_file_stem|strip_date_prefix}"
# The path template will be expanded last (regardless of its position in the
# frontmatter / defaults) and can use `slug`, `date` and `title`, possibly more
# other fields in the future.
path = "/{date|dateformat(format='[year]/[month]')}/{slug}/index.html"

# This section is for arbitrary user-defined data.
#
# Unknown fields outside of this table will cause errors, so typos get caught.
[extra]
# Available as `config.extra.author` in template code.
author = "Erika Mustermann"

Frontmatter

Since some configuration options make a lot more sense to be specified on individual files and one global config file doesn't scale very well, you can also place configuration in content files themselves.

This is done using TOML "frontmatter", that is an embedded TOML document at the start of the file. It is introduced by starting the file with a line that contains exactly +++, followed by the TOML document which is then terminated with another +++ line.

Here is the full set of things you can currently configure through frontmatter (or config.toml):

# Set this page to be a draft.
#
# This excludes it from build output by default.
# Use the `--drafts` command-line option to include draft pages.
draft = true
# Path of the template to use for this page.
#
# Relative to the `theme/templates` directory.
template = "my_tpl.html"
# What kind of processing should be done on the content, if any.
#
# For now, only markdown to HTML conversion is available.
process = "markdown_to_html"
# Syntax highlighting theme for markdown code blocks.
#
# If there is only one `.tmTheme` file in `theme/sublime`, it will be used by
# default, i.e. there is no need to specify this field anywhere.
syntax_highlight_theme = "visual-studio-dark"
# Custom rendered path for this page.
path = "/blog/{slug}.html"
# Page title.
title = "Foo"
# Page date.
date = 2023-03-03
# Custom slug for this page.
slug = "bar"

hinoki's People

Contributors

jplatte avatar

Stargazers

Ribbon avatar Jamy avatar  avatar  avatar 7heo avatar  avatar  avatar qb avatar

Watchers

 avatar Marcel avatar  avatar

hinoki's Issues

SCSS compilation

An important feature for medium to large sites, in my opinion.

Automated tests

Currently, hinoki doesn't have a single unit / integration test. That should change 😅

Pandoc as a content processor

This would allow writing content in a variety of different input languages / flavors of those languages (for instance it supports six different markdown flavors, ignoring one that's deprecated). It would also allow using advanced features that practically only exist inside pandoc such as embedding citations in markdown.

Citations

Apparently mdbook has a plugin for it, and pandoc also supports citations in markdown so it's not as uncommon as I would have thought. A natural solution user-wise could be to have a template function cite(&str) that generates markdown, however then the footnote generated by that function would have to be hoisted into the parent markdown document if templated-markdown (#1) is solved the way I'm thinking right now, which makes this pretty nasty.

Alternatively, "native" support for citations in markdown with the default markdown-to-HTML processor (pulldown_cmark) could just be declared out-of-scope, in which case citations could still be supported via pandoc (#10), though that would likely have its own downsides, in particular requiring users to have it installed because I'm definitely not going to embed it somehow.

Markdown filter

Just looking to finish my port of blog.turbo.fish, I noticed that I'm using Zola's markdown filter (for putting some sidebar contents in config.extra, which tbh is slightly weird, but I wanna keep for now) and this has no equivalent in Hinoki yet.

Aliases

… might be a feature to copy from Zola.

RSS / Atom feeds

I don't know yet whether more features are required for rendering something like Zola's default RSS theme.

After that, I wonder whether Hinoki should also ship something like builtin templates.

Static assets

Pretty much every SSG has a concept of a static / assets directory where you can put static files that should just be copied into the output directory without any processing.

Since processing is in general opt-in in hinoki, I could do away with this concept but I kind of like it for organization, so I think it should be a thing.

Allow reading date from filename

Same as #3: Currently using this for blog.turbo.fish, but easy enough to move away from if it turns out hard to fit into Hinoki's design (which shouldn't be the case though).

Add a development server

  • using hyper, tower-http, minijinja-autoreload, inotify
  • optional at compile time
    • it should still be hinted at in --help output if compiled out
  • debounce inotify events required to handle file moves correctly? (consider public path remains the same, could there be spurious conflicts?)

Footnotes

Might be as easy as enabling the corresponding flag in pulldown_cmark.

Allow custom sublime syntax files

Custom sublime theme files are already supported. At least initially I really don't want the burden of bundling more than the default set of syntaxes, but that means for blog.turbo.fish the theme needs to include support for TOML highlighting.

Recreate SyntaxHighlighter when sublime files change

Currently, hinoki serve rebuilds almost everything when file changes are detected, but for efficiency reasons the previous SyntaxHighlighter is reused. It should be recreated when one of the files that influences it (in sublime) changes.

Summaries

Zola has support for generating a summary of a page based on a <!-- more --> marker in the content, to display it in overviews. Used on https://matrix.org/blog/ for example. If #6 is implemented the way I'm thinking right now, this is complicated further as a page listing subdirectory pages wants metadata it gets to include summaries. Maybe there are even use cases where people want to render a snippet of the previous and next pages, but I think I'd rather just not support that.

Implementation note: PageMetadata could just contain an optional field for the summary which is set to None by the functions that get the previous and next page.

Allow minijinja expressions to be used in content

Should be opt-in, i.e. something like process_content = "templated_markdown_to_html", both so it's less surprising and so we don't have to do the more complicated markdown+templates parsing, compiling the template after markdown expansion and so on if users don't want to use that capability.

Depends on mitsuhiko/minijinja#368.

Get (links to) "next" and "previous" page

Just realized that I use this for my blog and it doesn't really fit into the design I've been going with, where pages in a directory are fully parsed and rendered in parallel.

However, since frontmatter reading and content rendering are independent steps, I think it should be possible to adjust the file processing to submit the content rendering work as a background task and return right afterwards, which would allow a function for getting metadata of the next / previous page to block until all metadata for the directory is available. I am not certain how summaries, which are based on the content, fit into this though. I'll create a separate issue for that.

Improve metadata templating

  • Add date_prefix, strip_date_prefix filters
  • Add slugify filter
  • Allow templating slug
  • Skip template processing if no { in string

For paths specifically:

  • Enforce leading /
  • What about implicit index.html after trailing /?

Date formatting

This is really more a MiniJinja / Tera parity thing, but if not implemented in MiniJinja, could be added as a filter inside hinoki.

MiniJinja issue: mitsuhiko/minijinja#378

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.