xref: /plugin/annotations/README.md (revision 86c3281af18ac3f82557b4466adb5aef413e1639)
143d2073cStracker-user# Annotations Plugin for DokuWiki
243d2073cStracker-user
38d8701f5Stracker-userWord- and sentence-level annotations on wiki pages, stored separately from the page text with threaded replies. Inspired by [Hypothes.is](https://hypothes.is/) and [ep_comments_page](https://github.com/ether/ep_comments_page).
443d2073cStracker-user
5*86c3281aStracker-user![Annotated text with gutter markers and counter bar](images/annotations-screen1.png)
6*86c3281aStracker-user![Open annotation thread with threaded reply](images/annotations-screen2.png)
7*86c3281aStracker-user![Resolved annotation thread](images/annotations-screen3.png)
8*86c3281aStracker-user![Orphaned annotations drawer](images/annotations-screen4.png)
9*86c3281aStracker-user![Admin annotated-pages overview with counts per page](images/annotations-screen5.png)
10*86c3281aStracker-user
1143d2073cStracker-user## Features
1243d2073cStracker-user
138d8701f5Stracker-user- **Text-quote anchoring** — select any word or sentence; the annotation is tied to the quoted text plus its surrounding context, so it survives minor edits to the page.
14ee9dbf15Stracker-user- **Threaded replies** — any logged-in reader can reply to an annotation, or reply to another reply for a nested discussion.
158d8701f5Stracker-user- **Open / Resolved status** — mark a discussion closed; resolved annotations turn green.
1643d2073cStracker-user- **Gutter markers** — small icons in the left margin show at a glance where annotations live.
1772d60f2dStracker-user- **Orphan detection** — when the annotated text is removed from the page, the annotation is flagged as orphaned and stays reachable via the counter. Orphaned annotations become read-only (they can only be deleted), and admins can bulk-delete them.
188d8701f5Stracker-user- **Per-user toggle** — turn the annotation overlay on or off from your user preferences.
198d8701f5Stracker-user- **No page revisions** — annotations live in a separate file per page; the wiki changelog is never touched.
20da56206cStracker-user- **Localised interface** — English, German, Russian and Japanese, falling back to English for any untranslated string.
2143d2073cStracker-user
2243d2073cStracker-user## Requirements
2343d2073cStracker-user
248d8701f5Stracker-user- DokuWiki Librarian 2025-05-14b (or a compatible release)
258d8701f5Stracker-user- PHP 8.0 or later with the `mbstring` extension
268d8701f5Stracker-user- [usersettings plugin](https://github.com/tracker-user/dokuwiki-usersettings) *(optional — adds the per-user on/off toggle)*
278d8701f5Stracker-user
288d8701f5Stracker-userWorks in current browsers and as far back as Firefox 78 ESR.
2943d2073cStracker-user
3043d2073cStracker-user## Installation
3143d2073cStracker-user
3243d2073cStracker-user1. Copy the `annotations/` directory into `{DokuWiki}/lib/plugins/`.
3343d2073cStracker-user2. If you want the per-user toggle, install the usersettings plugin too.
3486c7806dStracker-user3. The defaults work out of the box; tune them in the Configuration Manager if you like (see below).
3586c7806dStracker-user
3686c7806dStracker-user## Configuration
3786c7806dStracker-user
3886c7806dStracker-userAll settings live under **Admin → Configuration Settings → annotations**:
3986c7806dStracker-user
4086c7806dStracker-user| Setting | Default | What it does |
4186c7806dStracker-user|---------|---------|--------------|
4286c7806dStracker-user| `color_open` | `#f59e0b` | Highlight colour for open (unresolved) annotations. One hex value; lighter fills, gutter markers and status-pill tints are derived from it automatically. |
4386c7806dStracker-user| `color_resolved` | `#4ade80` | Highlight colour for resolved annotations. |
4486c7806dStracker-user| `embed_max_bytes` | `131072` | Largest annotation list (bytes) shipped inline with the page. Bigger lists load via a separate AJAX request instead, keeping every page view lean. |
4586c7806dStracker-user| `context_length` | `64` | Characters of surrounding text stored on each side of a quote, used to re-locate it after edits and to disambiguate repeated quotes. `0` disables context. |
4686c7806dStracker-user| `body_cap` | `10000` | Maximum length (characters) of an annotation or reply body; longer input is truncated. |
479fd890c3Stracker-user| `entries_per_page` | `25` | Rows per page in the **Admin → Annotations** overview of annotated pages. `0` shows every page on a single page. |
4843d2073cStracker-user
4943d2073cStracker-user## Usage
5043d2073cStracker-user
5143d2073cStracker-user### Reading annotations
5243d2073cStracker-user
5343d2073cStracker-userAnnotated text is highlighted in **amber** (open) or **green** (resolved). Click any highlight to open the thread panel inline below that paragraph.
5443d2073cStracker-user
5572d60f2dStracker-userThe counter bar above the page content shows how many annotations the page has. If some are orphaned (their text was deleted), a clickable "N orphaned" link opens a drawer at the bottom of the page with those threads. Orphaned annotations are read-only — the quoted text is gone, so they can no longer be resolved, reopened or edited; the thread still shows in full and its author (or an admin) can delete it.
5643d2073cStracker-user
5743d2073cStracker-user### Creating an annotation
5843d2073cStracker-user
5943d2073cStracker-user1. Select any text on the page.
6043d2073cStracker-user2. Click the **Annotate** button that appears.
6143d2073cStracker-user3. Type your comment and click **Annotate** to save.
6243d2073cStracker-user
638d8701f5Stracker-user> You only need to be logged in and able to *read* the page — edit access is **not** required. If you can read a page, you can annotate it.
6443d2073cStracker-user
6586c7806dStracker-userThe **Annotate** button only appears over real page prose. Selecting inside the table of contents, the page-info line, section-edit buttons, or the annotation panels does nothing. If your selection touches an existing annotation — even by a single character — that annotation opens instead of starting a new, overlapping one.
6686c7806dStracker-user
6743d2073cStracker-user### Replying
6843d2073cStracker-user
69ee9dbf15Stracker-userOpen the thread panel for any annotation and use the **Reply** field at the bottom. Each individual reply also has its own **Reply** button, so conversations can nest. Any logged-in reader can reply.
7043d2073cStracker-user
718d8701f5Stracker-user### Resolving / reopening
7243d2073cStracker-user
738d8701f5Stracker-userClick **Resolve** on an annotation to mark its discussion closed, or **Reopen** to undo that. Any logged-in reader can resolve or reopen.
7443d2073cStracker-user
7543d2073cStracker-user### Editing and deleting
7643d2073cStracker-user
778d8701f5Stracker-user- You can edit or delete your own annotations and replies.
788d8701f5Stracker-user- Admins can edit or delete anyone's.
7943d2073cStracker-user
8043d2073cStracker-user### Admin: bulk operations
8143d2073cStracker-user
8243d2073cStracker-userAdmins see two extra buttons in the counter bar:
8343d2073cStracker-user
8443d2073cStracker-user| Button | Effect |
8543d2073cStracker-user|--------|--------|
8643d2073cStracker-user| **Clear resolved** | Permanently deletes all resolved annotations on the page |
878d8701f5Stracker-user| **Clear orphaned** | Re-checks the page, then permanently deletes the orphaned annotations |
8843d2073cStracker-user
899fd890c3Stracker-user### Admin: annotated-pages overview
909fd890c3Stracker-user
9172d60f2dStracker-user**Admin → Annotations** lists every page that has annotations, with three counts:
929fd890c3Stracker-user
9372d60f2dStracker-user- **Normal** — annotations whose quoted text is still on the page.
9472d60f2dStracker-user- **Resolved** — annotations marked done (whatever their anchoring state).
9572d60f2dStracker-user- **Orphaned** — annotations whose text was deleted from the page.
9672d60f2dStracker-user
9772d60f2dStracker-userThe counts overlap on purpose: each one matches exactly what its clear button removes, so a
9872d60f2dStracker-userresolved annotation is also counted under **Normal** or **Orphaned** depending on whether its
9972d60f2dStracker-usertext is still present.
10072d60f2dStracker-user
10172d60f2dStracker-user- **Search** by page title or ID, and **sort** by page title or any of the three counts.
10272d60f2dStracker-user- **Clear resolved** on a row removes just that page's resolved annotations; **Clear orphaned**
10372d60f2dStracker-user  removes just that page's orphaned ones.
10472d60f2dStracker-user- **Clear all resolved (N)** and **Clear all orphaned (N)** at the top apply the matching sweep
10572d60f2dStracker-user  across every page at once.
1069fd890c3Stracker-user
1079fd890c3Stracker-userEach clear re-checks the page server-side before deleting, so the counts are authoritative even
1089fd890c3Stracker-userif the page changed since it was last viewed. Long lists are paginated (`entries_per_page`).
1099fd890c3Stracker-user
1108d8701f5Stracker-user### Turning the overlay off
11143d2073cStracker-user
1128d8701f5Stracker-userIn **User Preferences** (provided by the usersettings plugin), uncheck **Enable annotations**. The overlay is then hidden for you; your annotations are still stored and remain visible to everyone else.
11343d2073cStracker-user
11443d2073cStracker-user## License
11543d2073cStracker-user
11643d2073cStracker-userGPL 2, matching DokuWiki.
1178d8701f5Stracker-user
1188d8701f5Stracker-user---
1198d8701f5Stracker-user
1208d8701f5Stracker-user**Developers & AI agents:** see **[DESIGN.md](DESIGN.md)** for the full technical reference — architecture, the text-quote anchoring algorithm, the JSON storage format, the JSINFO-injection mechanism, the permission model, the AJAX API, browser/PHP constraints, and known gaps.
121