diff --git a/.github/spec.prompt.md b/.github/spec.prompt.md index d1d448c..1446625 100644 --- a/.github/spec.prompt.md +++ b/.github/spec.prompt.md @@ -1,36 +1,88 @@ # Page Link Feature Specification -This is the specification for a planned new feature called "Page Link". -The idea is this: Every page for which page linking is activated will receive a unique identifier (UUID). -This UUID is creaded once and stored on the page directly. -Now if a `.pagelink` file exist in a folder that contains the same UUID the page and the folder are considered "linked". -This allows for a variety of new features: -- All syntaxes available in this plugin can now be used with the automatic 'blobs' path alias. -- That means where before you had to write `{{images>/Scape/some/folder/*}}` you can now write `{{images>blobs/*}}` if the page is linked to the folder. -- This also works for other syntaxes like `{{files>blobs/*}}`. -- The mapping of pages to folders is cached for performance by this plugin. -- The UUID is created when the corresponding button is clicked in the editor toolbar.` -- The UUID is stored in the page metadata as `pagelink: `. -- The UUID is not shown to the user directly, only used internally by the plugin. -- Instead the user sees that the page is linked to a folder above the page content (next to the pageid). -- If the page has a UUID but no folder is linked, a text is shown that no folder is linked yet. -- clicking the text copies the UUID to the clipboard for easy creation of the `.pagelink` file. -- If a folder is linked, the name of the folder is shown above the page content. -- The `.pagelink` file is a simple text file that contains the UUID. -- The `.pagelink` file must be created manually by the user in the folder they want to link to the page. -Additional considerations: -- Folder can be moved freely, as long as the `.pagelink` file remains in the folder. -- That means the link is stable even if the folder is moved or renamed. -- Deleting the `.pagelink` file will unlink the folder from the page. -- The plugin maintins a cache of all linked folders and their UUIDs for performance. -- This is done in a mapping file stored in the plugin cache folder. -- On page load, the plugin checks if the page has a UUID and looks up the linked folder in the cache. -- If it is not found there, the plugin will search all folders for a matching `.pagelink` file. -- This search is cached for performance, so it is not done on every page load. +## 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. -To not overwhelm the server with searches for `.pagelink` files, the following strategy is used: -- The whole feature is limited to paths under the root aliases defined in the `paths` setting in #file:../admin/main.php -- Only folders under these root paths are searched for `.pagelink` files. -- Additionally a new setting `pagelink_search_depth` is introduced. -- This setting defines how deep the search for `.pagelink` files goes. -- For example, if the setting is `2`, only folders that are at most 2 levels deep under the root paths are searched. \ No newline at end of file +## 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. \ No newline at end of file