Documentation
This site is a Docusaurus 3.10 project in the repository's website/
folder. Gradle builds it like the rest of njMule: it takes the screenshots of the interface on a
demo engine's example data, prints
the command line's help, generates the API reference from the OpenAPI document, and fails on any
broken link. Change a page in the same branch as the user-visible change it describes.
Layout
| Path | Content |
|---|---|
website/docs/ | the user guide, served under /docs/ |
website/developer/ | this developer guide, served under /developer/ |
website/developer/api/reference/ | the API reference, generated from openapi.yaml (not committed) |
website/docs/_generated/, website/developer/_generated/ | partials generated from the repository: the changelog, the security policy, the contributing guide, the code of conduct, the pull request template, njmule --help and njmule --remote help (not committed) |
website/src/ | the home page (pages/index.tsx), the components (Screenshot, ThemedShot, NjIcon), the components every page gets without importing them (theme/MDXComponents.tsx) and the styles (css/custom.css) |
website/scripts/ | prepare.mjs, which puts in place what the site takes from the repository, capture-web.mjs, which pictures the interface, and api-labels.mjs, which names the API reference's pages |
website/plugins/ | screens.ts, which tells the pages the size of each screenshot |
website/static/ | static files served as they are |
sidebars.ts, sidebarsDeveloper.ts | the order of the pages of each guide; a new page must be listed there |
docusaurus.config.ts | the site: address, plugins, navigation, footer, search |
build.gradle.kts, package.json, package-lock.json | the Gradle tasks and the npm packages |
Everything the build generates lands in website/build/, under .gitignore like the generated
folders above. Screenshots are never committed.
Building the site
./gradlew :website:site
The site lands in website/build/site. The task runs, in order of need:
:njmule-http:webCaptureArgsand:website:webScreenshots:scripts/capture-web.mjsstarts the web interface on a demo engine with example data (WebCaptureDemo, innjmule-http's tests; Testing), signs in, and pictures the interface at 1280×800 with twice the pixels: each place, menu and dialog the pages show, the options pages, a phone-sized page and a guest's page, in light and in dark, and the transfers in forced colours. The pictures of the desktop app's pages come from the same interface in the browser. They land inwebsite/build/web-captures/, in the setslight,darkandcontrast. The script drives the Chrome or Edge already installed on your computer through Playwright, which downloads no browser; setNJMULE_CAPTURE_BROWSERto the path of another Chromium-based browser. A step that fails is reported as "not pictured" and the others go on.:njmule-app:cliHelp: whatnjmule --helpandnjmule --remote helpprint.:website:prepare:scripts/prepare.mjs --strictcopies the brand's images and the screenshots the pages name intowebsite/build/generated/static/img, and writes the partials of_generated/: the repository's pages without their license comment and title, with their links to repository files made absolute, and the command line's help as text blocks. With--strict, a picture a page names but the build did not make fails the build.:website:apiDocs:docusaurus gen-api-docsturnsnjmule-core/src/main/resources/org/njmule/core/remote/openapi.yamlinto the pages ofdeveloper/api/reference/.docusaurus build, with the version ofgradle.propertiesshown in the footer.
The build fails on a broken link, a broken anchor or a missing image. The site is not part of
./gradlew build.
To check the formatting (Prettier) and the types (TypeScript) of the site's own code, in src/,
scripts/ and the configuration files:
./gradlew :website:siteCheck
Previewing pages
-
Put the generated files in place once, and again after you change what they come from:
./gradlew :website:prepare :website:apiDocs -
Start the development server from
website/:npm startIt opens the site and reloads a page as you save it. Use the Node.js Gradle downloaded (
website/.gradle/nodejs/node-v…/) or your own Node.js 24 or newer.
For a quick look at text alone, run ./gradlew :website:apiDocs once, then npm run prepare-site
in website/: it writes the partials without the pictures and the command line's help, and a
missing picture is only a warning. npm run serve serves a built site from website/build/site.
Writing pages
The pages are MDX files (.mdx), in English.
Form
- Start with front matter: a
titleand a one-sentencedescription, which search results and link previews show. The title is the page's heading: start the body with an introduction, then use##and###headings of a few words, since they become anchors. - Wrap prose at about 100 columns.
- MDX is strict: escape
{,},<and>in prose, or put the text ininline code; no HTML comments; no autolinks in angle brackets (write[text](url)). Code blocks are safe. - Use admonitions sparingly (
:::note,:::tip,:::info,:::warning,:::danger, with an optional title in brackets), tables for lists of options (Option, Default, What it does), code blocks with their language (bash,powershell,ini,properties,yaml,json,nginx,text),<kbd>for keys, DocusaurusTabsfor instructions that differ per system, and small Mermaid diagrams where a picture explains better. - Link to pages by their file:
[ports](../network/ports.mdx)with a relative path and the.mdxextension inside a guide,/docs/…or/developer/…from one guide to the other, and full GitHub URLs (https://github.com/njMule/njMule/blob/main/<path>) for files of the repository.
Content
- Write for the reader, in the second person and in plain, friendly English: what it is, when you need it, how to do it in numbered steps, what happens, and related pages.
- Everything must be true of the code as it is: read the sources before you describe a feature. When the README or the changelog and the code disagree, the code wins. Never invent version numbers, measurements, dates, users or quotes.
- Use the exact labels the user sees, in bold, with menu paths as ⋯ → Import from eMule….
They are in
njmule-ui/i18n/:nj.propertiesfor njMule's own texts,emule.propertiesfor theIDS_*texts (Translations). - Take defaults from the code: the preferences in
njmule-core'sconfigpackage, the keys ofnjmule.propertiesinPreferencesCodec, the options pages of the interface (njmule-ui/src/settings.ts). - Never reference eMule's source code; name eMule only where the feature is about it (the import, compatibility). Do not present njMule as the official eMule client, and describe legal use only.
- No personal data: in examples, use the documentation addresses (
192.0.2.x,198.51.100.x,203.0.113.x,2001:db8::/32) and paths such asC:\Users\you\…or/home/you/…. No artwork of eMule either.
Screenshots
Every page can show a screenshot without importing anything:
<Screenshot id="web-transfers" alt="What the picture shows, for screen readers." caption="A short caption." />
| Attribute | What it does |
|---|---|
id | the picture's name, as the build makes it |
alt | a description of the picture |
caption | an optional short caption under it |
width | the largest width to draw it at, in pixels: width={560} keeps a dialog pictured alone from being blown up |
set | contrast for a picture in forced colours (a dark high contrast scheme), which has no light or dark version |
The component shows the light or the dark picture as the reader's theme is set; a click opens it at
full size. The pictures have twice the pixels they are drawn with, so that they stay sharp on screens
of high density: the component draws each at half its size in pixels, as plugins/screens.ts reads
it, and never wider than the page. prepare.mjs copies only the pictures the pages name, so a page
can name any picture the build makes:
- Desktop app: a place by its name (
transfers,servers,kad,log), its parts, menus and drop-down lists by the place and the element (transfers-ctx-downloads,transfers-dropdown-category,search-live), a dialog pictured alone bydialog-and its name (dialog-about), one over the window with-overafter it, the options pages assettings-page-01and on. The contrast set holdstransfersonly. - Web interface: the names that start with
web-:web-login,web-transfers,web-search,web-settings,web-guestand the others.
The names are fixed in scripts/capture-web.mjs; after a build, website/build/web-captures/<set>/
holds every picture it made.
Look at a picture before you describe it, so that the text and the caption match what it shows.
The home page uses ThemedShot, the same pictures without a frame; NjIcon draws one of njMule's
line icons by its name in the interface's njmule-ui/src/icons.ts, or one of the few the site draws
for itself on the same grid (the systems njMule installs on: DESKTOP, LAPTOP, TERMINAL,
CONTAINER, NAS).
To include a generated partial, import it, for example the command line's help:
import CliHelp from '../_generated/cli-help.md';
<CliHelp />
Licenses
The text of this site (website/docs/ and website/developer/) is licensed under
CC BY-SA 4.0, as REUSE.toml records; its code,
styles and scripts are under the GPL 3.0 or later, as their own headers say. The footer of every
page says so too.
Deployment
The Documentation workflow (.github/workflows/docs.yml) builds the site with
./gradlew :website:siteCheck :website:site on an Ubuntu runner, the pictures coming from the
interface on the demo engine in the runner's Chrome:
- It checks every pull request that changes the site, the interface, the demo engine, the API
document, the version in
gradle.properties(so the release's pull request checks the site its tag will publish) or the workflow itself. A merge intomaindoes not build it again. - It publishes on GitHub Pages only when asked: a manual run with deploy ticked, or the push
of a
v*tag, which publishes the site of every release.
The download links of the Getting started pages and the Docker image's tag are those of version in
gradle.properties (the <Downloads>, <DockerImage> and <Version> components of
src/components/Release.tsx), so the site a tag publishes links that release's files.
The site's address is https://njmule.github.io/njMule/. One publication runs at a time; a newer one
waits for it. Each page links to its source on GitHub (Edit this page).