An open API service indexing awesome lists of open source software.

https://github.com/dahlia/jikji

Small static site generator toolkit
https://github.com/dahlia/jikji

deno static-site-generator typescript

Last synced: 25 days ago
JSON representation

Small static site generator toolkit

Awesome Lists containing this project

README

        

Jikji: small static site generator toolkit
==========================================

[![JSR][JSR badge]][JSR]
[![LGPL 3.0][License badge]](./LICENSE)
[![GitHub Actions][GitHub Actions status badge]][GitHub Actions]
[![Codecov][Codecov badge]][Codecov]

Jikji is a small toolkit for building your own static site generators on [Deno].

Currently, it provides the below *composable building blocks*:

- Parallel generation
- Partial generation
- Flexible permalinks
- Watch changes & reload
- First-class support for [content negotiation] on type & language
- Markdown (powered by [markdown-it])
- EJS/ETS template engine (powered by [dejs])
- [SCSS] stylesheet preprocessor

[JSR badge]: https://jsr.io/badges/@hongminhee/jikji
[JSR]: https://jsr.io/@hongminhee/jikji
[License badge]: https://img.shields.io/github/license/dahlia/jikji
[GitHub Actions]: https://github.com/dahlia/jikji/actions/workflows/main.yaml
[GitHub Actions status badge]: https://github.com/dahlia/jikji/actions/workflows/main.yaml/badge.svg
[Codecov badge]: https://codecov.io/gh/dahlia/jikji/branch/main/graph/badge.svg?token=UBDX4Inrz6
[Codecov]: https://codecov.io/gh/dahlia/jikji
[Deno]: https://deno.com/
[content negotiation]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation
[markdown-it]: https://github.com/markdown-it/markdown-it
[dejs]: https://github.com/syumai/dejs
[SCSS]: https://sass-lang.com/

Example
-------

~~~~ typescript
import {
intoDirectory,
scanFiles,
rebase,
writeFiles
} from "https://deno.land/x/jikji/mod.ts";
import { markdown } from "https://deno.land/x/jikji/markdown.ts";

const baseUrl = new URL("http://localhost:8000/");
const outDir = "public_html";

// Scans for Markdown files in the posts/ directory:
await scanFiles(["posts/**/*.md"])
// Renders posts written in Markdown to HTML:
.transform(markdown(), { type: "text/markdown" })
// Makes permalinks like posts/foobar/ instead of posts/foobar.md
.move(intoDirectory())
// Maps the current directory to the target URL :
// E.g., ./posts/foobar.md -> https://example.com/posts/foobar/
.move(rebase("posts/", baseUrl))
// Writes the files to the output directory (public_html/):
.forEach(writeFiles(outDir, baseUrl));
// If you want watch mode, use forEachWithReloading() instead:
// .forEachWithReloading(writeFiles(outDir, baseUrl));
~~~~

More realistic examples are placed in the [*examples/* directory](examples/).

Key concepts
------------

Building blocks that Jikji provides are based on the following concepts:

- [`Pipeline`] represents the entire steps from the input to the output.
It's like a stream of zero or more `Resource`s. Its whole process is
lazy so that if some parts don't need to be generated again they are even
not loaded at all.
(In the above example, a new `Pipeline` is acquired using `scanFiles()`
function, but `scanFiles()` does not immediately list files nor load
their contents.)
- [`Resource`] represents an abstract resource which is mapped to a unique
`path`. Its `path` is a rather URL than a filesystem path, which means
it has a scheme like `https` or `file` and can end with a slash.
(Note that `intoDirectory()` function turns *posts/foobar.md* into
*posts/foobar/* in the above example.) `Resource` also can has multiple
representations for [content negotiation] on type and language.
- [`Content`] represents an actual content which can belong to `Resource`s
as a representation. The `ContentBody` can be lazily loaded and either
a Unicode text or binary data. They are typed through IANA [`MediaType`s]
(formerly known as MIME types). Optionally, they can have their
RFC 5656 [`LanguageTag`] to describe their natural language. If you want
you can put additional `metadata` like `title` or `published` as well.
- [`ResourceTransformer`] transforms a `Resource` into a modified `Resource`.
It purposes to change multiple `Resources` into new ones in immutable style
by being passed to `Pipeline#map()` method.
- [`PathTransformer`] transforms a `URL` into a modified `URL`. It purposes
to change multiple `Resource`s `path`s into new ones in immutable style by
being passed to `Pipeline#move()` method.
(In the above example, `intoDirectory()` and `rebase()` functions return
`PathTransformer`s.)
- [`ContentTransformer`] transforms a `Content` into a modified `Content`.
It purposes to change multiple representations of `Resource`s into new ones
in immutable style by being passed to `Pipeline#transform()` method.
(In the above example, `markdown()` function returns a
`ContentTransformer`.)

See also [API docs].

[`Pipeline`]: https://jsr.io/@hongminhee/jikji/doc/pipeline/~/Pipeline
[`Resource`]: https://jsr.io/@hongminhee/jikji/doc/resource/~/Resource
[`Content`]: https://jsr.io/@hongminhee/jikji/doc/content/~/Content
[`MediaType`s]: https://jsr.io/@hongminhee/jikji/doc/media-type/~/MediaType
[`LanguageTag`]: https://jsr.io/@hongminhee/jikji/doc/language-tag/~/LanguageTag
[`ResourceTransformer`]: https://jsr.io/@hongminhee/jikji/doc/pipeline/~/ResourceTransformer
[`PathTransformer`]: https://jsr.io/@hongminhee/jikji/doc/pipeline/~/PathTransformer
[`ContentTransformer`]: https://jsr.io/@hongminhee/jikji/doc/pipeline/~/ContentTransformer
[API docs]: https://jsr.io/@hongminhee/jikji/doc

Changelog
---------

See [*CHANGES.md*](CHANGES.md).

License
-------

Distributed under [LGPL 3.0].

[LGPL 3.0]: https://www.gnu.org/licenses/lgpl-3.0.html