Files
racket-wiki/scrbl/racket-wiki.scrbl
T
2026-08-14 21:47:23 +02:00

136 lines
5.5 KiB
Racket

#lang scribble/manual
@(require (for-label racket/base
racket/contract
racket/path
racket-wiki
racket-wiki/translate))
@title{racket-wiki}
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
@defmodule[racket-wiki]
The @racketmodname[racket-wiki] module starts a small self-hosted Markdown wiki.
Racket provides the HTTP API, authentication, PostgreSQL-backed user and page
storage, versioning, full-text search, and the initial web setup. Markdown
rendering and the editing interface run in the browser.
@section{Starting the Wiki}
@defproc[(start
[#:data-dir data-dir path-string? "wiki-data"]
[#:port port exact-positive-integer? 8080]
[#:listen-ip listen-ip (or/c string? #f) "127.0.0.1"]
[#:secure-cookie? secure-cookie? boolean? #f]
[#:site-title site-title string? "Racket Wiki"]
[#:session-seconds session-seconds exact-positive-integer? (* 12 60 60)]
[#:language language string? "en"])
any] {
Starts the wiki using explicit server parameters. The data directory is made
absolute before the server starts.
Use @racket["*"] or @racket[#f] for @racket[listen-ip] to listen on all
interfaces. The default address only listens on the local machine.
This procedure is the convenient entry point when starting the wiki from
DrRacket or another interactive Racket session.
}
@defproc*[([(start-wiki) any]
[(start-wiki [config any/c]) any])] {
Starts the wiki using either the default configuration or the supplied wiki
configuration.
}
@section{Initial Setup}
When PostgreSQL has not been configured, the schema is unavailable, no enabled
administrator exists, or one of the required browser libraries is missing,
normal application requests are redirected to @tt{/setup}.
The setup page itself requires no JavaScript. On a fresh installation it asks for
PostgreSQL server, port, database, user, password and SSL mode. The database must
already exist. After testing the connection, setup creates the racket-wiki schema,
asks for the first administrator, and downloads the pinned EasyMDE, Font Awesome,
DOMPurify, highlight.js, and diff2html browser files. PostgreSQL connection
settings are stored in @tt{database.rktd} below the configured data directory.
After setup the browser is redirected to @tt{/login}; setup does not create an
authenticated browser session.
@section{Page Slugs}
For a normal new page, the backend derives the slug from the title when the page
is first saved. A later title change leaves the slug unchanged so existing links
remain stable.
When an editor or administrator follows a wiki-page link to a slug that does not
yet exist, the browser opens an empty create view for that requested slug. A
reader receives a normal not-found view. Unauthenticated browser requests are
redirected to @tt{/login} before the wiki application is served.
@section{Page contents}
The application sidebar gives the current page's headings priority over the
global page list. The contents list follows Markdown headings and is updated
while a page is edited.
@section{Editor appearance}
EasyMDE and the rendered wiki page use matching body and heading sizes. The
source editor keeps Markdown syntax visible, but heading text uses the same
scale as the rendered page. Toolbar icons are provided by a locally installed
Font Awesome copy.
@section{Page navigation and metadata}
The sidebar gives priority to a table of contents derived from the headings in
the current Markdown document. The page list is secondary. The editor updates
the table of contents while the document is being edited.
A breadcrumb is displayed above the document. The footer displays creation and
modification timestamps, the current version, and page tags. Tags are stored in
the page metadata and version metadata.
@section{Full-text search}
Current pages are indexed by PostgreSQL using a weighted @tt{tsvector}; title
terms have a higher weight than Markdown body terms. A GIN index accelerates
searches. The wiki uses PostgreSQL's @tt{simple} text-search configuration so
technical Dutch, English and identifier-like terms are not subjected to a
language-specific stemmer.
@section{Database schema migrations}
Racket Wiki records PostgreSQL schema migrations in @tt{wiki_schema}. The current page is stored in @tt{pages}; every saved historical revision is stored in @tt{page_versions}. Attachments, including their binary content, are stored in @tt{attachments}. Schema migrations run in order when the application starts.
@section{Todo items}
Wiki-wide todo items are written as @tt{todo(text)} in Markdown. Markers inside
fenced code blocks are ignored. Current todo markers are indexed in PostgreSQL
and collected in the Todo view. Ordinary Markdown task lists remain available
for page-local checklists.
@section{Translations}
@defmodule[racket-wiki/translate]
@defproc[(tr [config any/c] [key symbol?]) string?] {
Returns the effective UI translation for @racket[key]. Built-in English and
Dutch translations are available before the database is configured. Once the
database is available, assignments in the special
@tt{wiki-translations-<language>} page override the built-in strings.
}
The UI language is selected with @tt{--language} or @racket[#:language]. The
frontend obtains the same effective table from the server, so server and browser
labels use one translation source.
@section{Connectivity}
The browser calls @tt{/api/ping} every 15 seconds. Failed or timed-out requests
show an Offline indicator. A recovered connection briefly shows Online.