2025-06-13 00:29:30 -07:00
|
|
|
# clover sitegen framework
|
|
|
|
|
|
|
|
this repository contains clover's "sitegen" framework, which is a set of tools
|
2025-07-08 20:48:30 -07:00
|
|
|
that assist building websites. these tools power <https://paperclover.net>.
|
2025-06-13 00:29:30 -07:00
|
|
|
|
2025-08-02 19:22:07 -07:00
|
|
|
- **HTML ("Server Side Rendering") engine written from scratch.** (~500 lines)
|
2025-07-07 20:58:02 -07:00
|
|
|
- A more practical JSX runtime (`class` instead of `className`, built-in
|
|
|
|
`clsx`, `html()` helper over `dangerouslySetInnerHTML` prop, etc).
|
2025-07-08 20:48:30 -07:00
|
|
|
- Integration with [Marko] for concisely written components.
|
2025-07-07 20:58:02 -07:00
|
|
|
- TODO: MDX-like compiler for content-heavy pages like blogs.
|
|
|
|
- Different languages can be used at the same time. Supports `async function`
|
|
|
|
components, `<Suspense />`, and custom extensions.
|
2025-06-15 11:35:28 -07:00
|
|
|
- **Incremental static site generator and build system.**
|
2025-08-14 20:35:33 -07:00
|
|
|
- Build both development and production sites on startup start. Incremental
|
|
|
|
generator rebuilds changed pages; Build system state survives coding sessions.
|
|
|
|
- Multiple backend support.
|
2025-07-07 20:58:02 -07:00
|
|
|
- (TODO) Tests, Lints, and Type-checking is run alongside, and only re-runs
|
|
|
|
checks when the files change. For example, changing a component re-tests
|
|
|
|
only pages that use that component and re-lints only the changed file.
|
2025-06-15 11:35:28 -07:00
|
|
|
- **Integrated libraries for building complex, content heavy web sites.**
|
2025-08-15 22:30:58 -07:00
|
|
|
- Static asset serving with automatic ETag and build-time compression.
|
|
|
|
- Dynamic pages. Static pages can be regenerated (and cached) at runtime.
|
|
|
|
- Databases with a minimal SQLite wrapper.
|
|
|
|
- Meta Tags and Open Graph generation.
|
2025-08-14 20:35:33 -07:00
|
|
|
- Font subsetting to reduce page bandwidth.
|
|
|
|
- **Built on the stable and battle-tested Node.js runtime.**
|
2025-06-13 00:29:30 -07:00
|
|
|
|
2025-08-14 20:35:33 -07:00
|
|
|
none of these tools are complex or revolutionary. rather, this project is the
|
2025-07-08 20:48:30 -07:00
|
|
|
sum of many years of experience on managing content heavy websites, and an
|
|
|
|
example on how other over-complicate other frameworks.
|
|
|
|
|
|
|
|
[Marko]: https://next.markojs.com
|
2025-06-13 00:29:30 -07:00
|
|
|
|
|
|
|
Included is `src`, which contains `paperclover.net`. Website highlights:
|
|
|
|
|
2025-08-14 20:35:33 -07:00
|
|
|
- TODO: flashy homepage.
|
2025-06-13 00:29:30 -07:00
|
|
|
- [Question/Answer board, custom markdown parser and components][q+a].
|
2025-07-08 20:48:30 -07:00
|
|
|
- [File viewer with fast ui/ux + optimized media streaming][file].
|
2025-06-13 00:29:30 -07:00
|
|
|
- [Personal, friends-only blog with password protection][friends].
|
2025-08-14 20:35:33 -07:00
|
|
|
- TODO: digital garden styled blog.
|
2025-06-13 00:29:30 -07:00
|
|
|
|
|
|
|
[q+a]: https://paperclover.net/q+a
|
|
|
|
[file]: https://paperclover.net/file
|
|
|
|
[friends]: https://paperclover.net/friends
|
|
|
|
|
|
|
|
## Development
|
|
|
|
|
|
|
|
minimum system requirements:
|
2025-07-07 20:58:02 -07:00
|
|
|
|
2025-06-13 00:29:30 -07:00
|
|
|
- a cpu with at least 1 core.
|
|
|
|
- random access memory.
|
|
|
|
- windows 7 or later, macos, or other operating system.
|
|
|
|
|
2025-08-14 20:35:33 -07:00
|
|
|
required software:
|
|
|
|
|
|
|
|
- node.js v24
|
|
|
|
- python v3
|
|
|
|
|
2025-06-13 00:29:30 -07:00
|
|
|
my development machine, for example, is Dell Inspiron 7348 with Core i7
|
|
|
|
|
2025-07-08 20:48:30 -07:00
|
|
|
npm install
|
2025-06-13 00:29:30 -07:00
|
|
|
|
2025-08-14 20:35:33 -07:00
|
|
|
# build site using 'run.js' to enable runtime plugins
|
2025-07-08 20:48:30 -07:00
|
|
|
node run generate
|
2025-08-14 20:35:33 -07:00
|
|
|
# the built site runs in regular node.js
|
|
|
|
node --enable-source-maps .clover/o/backend
|
2025-06-13 00:29:30 -07:00
|
|
|
|
2025-08-14 20:35:33 -07:00
|
|
|
# watch-rebuild mode
|
2025-07-08 20:48:30 -07:00
|
|
|
node run watch
|
2025-06-13 00:29:30 -07:00
|
|
|
|
2025-07-07 09:42:04 -07:00
|
|
|
for unix systems, the provided `flake.nix` can be used with `nix develop` to
|
|
|
|
open a shell with all needed system dependencies.
|
|
|
|
|
2025-07-09 22:45:20 -07:00
|
|
|
## Deployment
|
|
|
|
|
2025-08-14 20:35:33 -07:00
|
|
|
there are two primary server components to be deployed: the web server and the
|
2025-07-09 22:45:20 -07:00
|
|
|
sourth of truth server. The latter is a singleton that runs on Clover's NAS,
|
|
|
|
which holds the full contents of the file storage. The web server pulls data
|
|
|
|
from the source of truth and renders web pages, and can be duplicated to
|
|
|
|
multiple cloud hosts without issue.
|
|
|
|
|
|
|
|
Deployment of the source of truth can be done with Docker Compose:
|
|
|
|
|
|
|
|
services:
|
|
|
|
backend:
|
|
|
|
container_name: backend
|
|
|
|
build:
|
2025-08-14 20:35:33 -07:00
|
|
|
# this uses loopback to hit the self-hosted git server,
|
|
|
|
# docker will cache the image to not re-fetch on reboot.
|
2025-07-10 00:48:39 -07:00
|
|
|
context: http://127.0.0.1:3000/clo/sitegen.git
|
2025-07-09 22:45:20 -07:00
|
|
|
dockerfile: src/source-of-truth.dockerfile
|
|
|
|
environment:
|
|
|
|
# configuration
|
|
|
|
- PORT=43200
|
|
|
|
- CLOVER_DB=/data
|
|
|
|
- CLOVER_FILE_RAW=/published
|
|
|
|
- CLOVER_FILE_DERIVED=/data/derived
|
|
|
|
- CLOVER_SOT_KEY=... # guards private/unreleased content
|
|
|
|
ports:
|
|
|
|
- '43200:43200'
|
|
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
|
|
- /mnt/storage1/clover/Documents/Config/paperclover:/data
|
|
|
|
- /mnt/storage1/clover/Published:/published
|
|
|
|
|
2025-08-14 20:35:33 -07:00
|
|
|
Due to caching, images may need to be purged via `docker image rm {image} -f`
|
|
|
|
when an update is desired. Some docker GUIs support force pulls, some are buggy.
|
2025-07-09 23:45:21 -07:00
|
|
|
|
2025-08-14 20:35:33 -07:00
|
|
|
The web server performs rendering. A `Dockerfile` for it is present in
|
|
|
|
`src/web.dockerfile` but it is currently unused. Deployments are done by
|
|
|
|
building the project locally, and then using `rsync` to copy files.
|
|
|
|
|
|
|
|
node run generate
|
|
|
|
rsync .clover/o "$REMOTE_USER:~/paperclover" --exclude=.clover --exclude=.env \
|
|
|
|
--delete-after --progress --human-readable
|
|
|
|
ssh "$REMOTE_USER" /bin/bash << EOF
|
|
|
|
set -e
|
|
|
|
cd ~/paperclover
|
|
|
|
npm ci
|
|
|
|
pm2 restart site
|
|
|
|
echo "-> https://paperclover.net"
|
|
|
|
EOF
|
2025-07-09 22:45:20 -07:00
|
|
|
|
2025-06-13 00:29:30 -07:00
|
|
|
## Contributions
|
|
|
|
|
|
|
|
No contributions to `src` accepted, only `framework`.
|