Skip to main content

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​

PathContent
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.tsthe order of the pages of each guide; a new page must be listed there
docusaurus.config.tsthe site: address, plugins, navigation, footer, search
build.gradle.kts, package.json, package-lock.jsonthe 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:

  1. :njmule-http:webCaptureArgs and :website:webScreenshots: scripts/capture-web.mjs starts the web interface on a demo engine with example data (WebCaptureDemo, in njmule-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 in website/build/web-captures/, in the sets light, dark and contrast. The script drives the Chrome or Edge already installed on your computer through Playwright, which downloads no browser; set NJMULE_CAPTURE_BROWSER to the path of another Chromium-based browser. A step that fails is reported as "not pictured" and the others go on.
  2. :njmule-app:cliHelp: what njmule --help and njmule --remote help print.
  3. :website:prepare: scripts/prepare.mjs --strict copies the brand's images and the screenshots the pages name into website/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.
  4. :website:apiDocs: docusaurus gen-api-docs turns njmule-core/src/main/resources/org/njmule/core/remote/openapi.yaml into the pages of developer/api/reference/.
  5. docusaurus build, with the version of gradle.properties shown 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​

  1. Put the generated files in place once, and again after you change what they come from:

    ./gradlew :website:prepare :website:apiDocs
  2. Start the development server from website/:

    npm start

    It 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 title and a one-sentence description, 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 in inline 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, Docusaurus Tabs for 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 .mdx extension 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.properties for njMule's own texts, emule.properties for the IDS_* texts (Translations).
  • Take defaults from the code: the preferences in njmule-core's config package, the keys of njmule.properties in PreferencesCodec, 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 as C:\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." />
AttributeWhat it does
idthe picture's name, as the build makes it
alta description of the picture
captionan optional short caption under it
widththe largest width to draw it at, in pixels: width={560} keeps a dialog pictured alone from being blown up
setcontrast 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 by dialog- and its name (dialog-about), one over the window with -over after it, the options pages as settings-page-01 and on. The contrast set holds transfers only.
  • Web interface: the names that start with web-: web-login, web-transfers, web-search, web-settings, web-guest and 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 into main does 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).