# Page Link Feature Specification ## Goals - Allow linking a Dokuwiki page to a media folder via a stable UUID. - Enable the `blobs` alias so plugin syntaxes can use `blobs/*` in place of a concrete path when the page is linked. - Keep behavior stable and maintainable; avoid heavy scanning on each page view. ## Non-Goals - Automatic creation of `.pagelink` files (user must create manually). - Automatic selection of which folder to link (user decides by placing `.pagelink`). - Cross-page bulk management UI. ## Core Concept - Each page can have **one** UUID stored in page metadata. - A folder is considered linked to the page if it contains a `.pagelink` file whose content matches the page’s UUID. ## Data Model - Page metadata key: `pagelink` with value ``. - `.pagelink` file content: a UUID string. - Cache mapping file in plugin cache folder: maps UUID → folder path. - Cache file format: JSON (human-readable, easy to debug). - Cache file name: `pagelink_cache.json`. ## UUID - UUID is created only via a toolbar button. - UUID is created once and stored in metadata. - UUID is v4 lowercase. - UUID is not shown directly to the user (except for copy-to-clipboard). ## UI/UX Behavior - Above page content (next to pageid), show link status. - If UUID exists and folder is linked: show the linked folder name. - If UUID exists but no folder is linked: show a “not linked yet” status. - Clicking the status copies the UUID to clipboard for easy `.pagelink` creation. - Status text: "Not linked: Copy ID" - Copy action does not show anything. No native toasts available - If UUID does not exist: no status is shown. ## Linking Rules - Folder can be moved or renamed; link remains as long as `.pagelink` file stays in that folder. - Deleting the `.pagelink` file unlinks the folder. - If multiple folders contain the same UUID: - Page shows a linked status with the first found folder. - Triangle warning icon appears next to folder name. ## Search Scope - Searches for `.pagelink` files are limited to paths under root aliases defined in `paths` in [admin/main.php](../admin/main.php). - New setting `pagelink_search_depth` limits maximum depth under each root path. - Example: depth `2` means only folders at most 2 levels deep are searched. - Integer value, default `3`. - No negative values allowed. ## Cache Strategy - Mapping of UUID → folder path is cached in a mapping file for performance. - On page load: 1. If page has UUID, check cache for linked folder. 2. If cache miss, scan folders (within scope) for `.pagelink`. 3. Update cache with any matches. - Cache invalidation strategy: - No automatic cache rebuilds. - When encountering stale cache entry (moved/deleted folder) while looking for a pages linked folder, remove from cache and rescan. - Cache writes are atomic (write temp + rename) and use `LOCK_EX`. ## Performance Constraints - Avoid full-tree scans on every page view. ## Security & Safety - Never scan outside configured root paths. - ignore symlinks. - Handle unreadable folders/files gracefully (no fatal errors). ## Acceptance Criteria - Clicking toolbar button sets metadata `pagelink` to a valid UUID. - If a matching `.pagelink` exists in a scoped folder, `blobs/*` resolves to that folder. - If `.pagelink` is deleted, the link is removed on next lookup and UI reflects “not linked yet”. - Cache prevents repeated scans on consecutive page views. - Search depth obeys `pagelink_search_depth`. ## Edge Cases - Page has UUID but `.pagelink` file is empty or invalid UUID. - Multiple `.pagelink` files with same UUID in different folders. - UUID in metadata is malformed. - Folder contains `.pagelink` but no read permissions. - Page is deleted/renamed after UUID creation. ## Documentation Updates - Update README to describe the feature, settings, and manual `.pagelink` workflow.