Attributes
Includes Deno configuration
Repository
Current version released
2 years ago
Jikji: small static site generator toolkit
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 (powered by grass)
Example
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 <https://example.com/>:
// 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.
Key concepts
Building blocks that Jikji provides are based on the following concepts:
Pipelinerepresents the entire steps from the input to the output. It’s like a stream of zero or moreResources. 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 newPipelineis acquired usingscanFiles()function, butscanFiles()does not immediately list files nor load their contents.)Resourcerepresents an abstract resource which is mapped to a uniquepath. Itspathis a rather URL than a filesystem path, which means it has a scheme likehttpsorfileand can end with a slash. (Note thatintoDirectory()function turns posts/foobar.md into posts/foobar/ in the above example.)Resourcealso can has multiple representations for content negotiation on type and language.Contentrepresents an actual content which can belong toResources as a representation. TheContentBodycan be lazily loaded and either a Unicode text or binary data. They are typed through IANAMediaTypes (formerly known as MIME types). Optionally, they can have their RFC 5656LanguageTagto describe their natural language. If you want you can put additionalmetadataliketitleorpublishedas well.ResourceTransformertransforms aResourceinto a modifiedResource. It purposes to change multipleResourcesinto new ones in immutable style by being passed toPipeline#map()method.PathTransformertransforms aURLinto a modifiedURL. It purposes to change multipleResourcespaths into new ones in immutable style by being passed toPipeline#move()method. (In the above example,intoDirectory()andrebase()functions returnPathTransformers.)ContentTransformertransforms aContentinto a modifiedContent. It purposes to change multiple representations ofResources into new ones in immutable style by being passed toPipeline#transform()method. (In the above example,markdown()function returns aContentTransformer.)
See also API docs.
Changelog
See CHANGES.md.
License
Distributed under LGPL 3.0.