PRPL
PRPL is a modular static site generator built for longevity. It lets you interpolate content with a single HTML element.
Why?
All the static site generators I have tried have one or more of these problems:
- Built on an underlying framework like React, Vue, etc.
- Relies on complex build tools like Webpack, Babel, etc.
- Depends on a massive tree of modules that force constant maintenance
- Has interfaces, source code and documentation that cannot be understood in one sitting
- Requires that your site source be organized in a way that looks nothing like your output
- Forces a huge leap from hello world to a real world implementation
PRPL is my answer to these gripes.
Usage
PRPL transforms a directory of content into HTML via <prpl>
tags:
Given this source HTML file:
<!DOCTYPE html>
<prpl type="page" src="content/notes">
<head>
<title>[title]</title>
</head>
<body>
<main>
<h1>[title]</h1>
[body]
</main>
</body>
</prpl>
and this content markdown file:
<!--
title: Hello world!
slug: /notes/my-first-note
-->
This is my first note
the output is:
<!DOCTYPE html>
<head>
<title>Hello World!</title>
</head>
<body>
<main>
<h1>Hello World!</h1>
<p>This is my first note</p>
</main>
</body>
- PRPL supports Node current and LTS versions
- Run
npx -y create-prpl@latest
to clone the minimal starter and run it locally - See prpl.dev for full documentation, guides and design decisions
Features
- HTML-based API compliant with web standards
- Command line, CommonJS and ECMAScript module interfaces
- Source code that is fully typed, explicitly commented and readable in one sitting
- Library architecture for modular adoption
- Minimally invasive, removable in seconds
- Opt-out of client side JavaScript entirely
- Define your own template syntax
Architecture
PRPL is structured as a library that consists of these modules:
Module | Description |
---|---|
@prpl/core |
Core functions for content interpolation |
@prpl/server |
Development server |
@prpl/plugin-aws |
Plugin for working with AWS S3 |
@prpl/plugin-code-highlight |
Plugin for highlighting code blocks |
@prpl/plugin-css-imports |
Plugin for resolving CSS imports |
@prpl/plugin-html-imports |
Plugin for resolving HTML imports |
@prpl/plugin-rss |
Plugin for generating RSS feeds |
@prpl/plugin-sitemap |
Plugin for generating a sitemap |
@prpl/core
is the only required module for a site to interpolate content into HTML, others are optional@prpl/server
is easily replaced with other local development servers, you're not married to it if you use PRPL- Most modules have zero dependencies, and those that do have the fewest number practical
Development
Commands for developing PRPL modules.
In this repo root:
npm run bootstrap
to install local module dependenciesnpm run dev -- [PKG]
to bundle a package in watch mode, e.g.npm run dev -- core
to bundle core. One exception is client scripts in core, runnpm run dev -- client
instead
In your project root:
npm link @prpl/[PKG]
from your project root to symlink to the globally linked module, e.g.npm link @prpl/core
to link corenpm unlink -g @prpl/[PKG]
to unlink when you're done
Testing
Tooling, CI and commands for testing PRPL modules.
- All modules are tested with Cypress
- Tests run in continuous integration via GitHub Actions when new PRs are opened or changes are made to the branch the PR is opened from
- All modules are tested using both the CommonJS and ESM interfaces
To run tests locally:
- Navigate to the
tests/test-site
directory npm install
to install dependencies for the test sitenpm run dev:cjs
ornpm run dev:mjs
to run the local development servernpm run test:open
to open Cypress and select which test suites to run
Publishing
Tooling and commands for publishing PRPL modules.
This repo is a monorepo orchestrated with Lerna.
Before a new release is created with Lerna:
- A newly created package must be published initially with
npm publish --access public
in the package root - All local changes must be committed first
- The branch must be pushed to remote
To create a new release with Lerna:
npm run release:changed
from the project root and follow the prompts