# luxtools (DokuWiki plugin) luxtools is a suite of tools designed to integrate the host file system with DokuWiki, intentionally sidestepping the built-in MediaManager for specific workflows. This is a personal project that models my specific workflows and preferences. It is likely unsuited for wider adoption without modification. ## Related projects - luxtools-client: https://git.luxick.de/luxick/luxtools-client A client application for direct integration with the client machine (e.g. opening folders/paths from within the browser). - luxtools-template: https://git.luxick.de/luxick/luxtools-template A DokuWiki template designed to complement the features of this plugin. ## What this plugin does luxtools provides DokuWiki syntax that: - Lists a directory's direct children (files + folders) or files matching a glob pattern - Renders an image thumbnail gallery (with lightbox) - Provides "open this folder/path" links for local workflows - Embeds file-backed scratchpads with a minimal inline editor (no wiki revisions) - Links a page to a media folder via a UUID (.pagelink), enabling a `blobs/` alias It also ships a small file-serving endpoint (`lib/plugins/luxtools/file.php`) used to deliver files and generate cached thumbnails. ## Note on security The file-serving endpoint (`lib/plugins/luxtools/file.php`) runs inside DokuWiki and enforces access via per-page ACL: the requester must have at least read access to the wiki page that rendered the link. ## Installation Install like any other DokuWiki plugin. If you install this plugin manually, make sure it is installed in: `lib/plugins/luxtools/` If the folder is called differently, DokuWiki will not load it. ## Project structure (developer notes) This repository follows DokuWiki's plugin conventions at the top level (e.g. `syntax.php`, `conf/`, `lang/`, endpoints like `file.php`). Reusable PHP code lives in `src/` and is loaded via `autoload.php`. When adding new internal classes under the `dokuwiki\plugin\luxtools\` namespace, place them in `src/.php`. JavaScript is split into small modules under `js/` and registered via `action.php` so DokuWiki loads them in order. ## IDE support (developer notes) This plugin extends and uses DokuWiki core classes (for example `dokuwiki\Extension\ActionPlugin`, `dokuwiki\Extension\SyntaxPlugin`, renderers, handlers). If you only open the plugin folder in your IDE, those types may show as “unknown”. DokuWiki does not currently ship an official PHP “SDK”/stub package for IDEs. The most reliable way to get full type navigation and autocomplete is to have the DokuWiki sources available in your workspace. Two recommended setups: ### Option A: Add DokuWiki as a git submodule (recommended for a single-folder workspace) From the plugin root: ```bash git submodule add https://github.com/dokuwiki/dokuwiki.git _dokuwiki git submodule update --init --recursive ``` The repository includes a VS Code config in `.vscode/settings.json` that points Intelephense at `./_dokuwiki/*` so the classes resolve. `deploy.sh` excludes `_dokuwiki/` to avoid deploying the dev-only checkout. ### Option B: Use a separate DokuWiki checkout next to the plugin (recommended if you don’t want submodules) - Clone DokuWiki into a sibling folder (outside this repo) - Open a multi-root VS Code workspace with both folders This avoids changing the git state of the plugin repo, but still gives the IDE access to DokuWiki’s class definitions. ## Configuration luxtools is configured via its dedicated admin page: `Admin -> Additional Plugins -> luxtools` Key settings: - **paths** Allowed base filesystem roots (one per line). Each root can be followed by: - `A> /Alias/` (optional) alias used in wiki syntax and open links Example: ``` /srv/share/Datascape/ A> /Scape/ ``` luxtools links use the plugin endpoint: `lib/plugins/luxtools/file.php?root=...&file=...` The generated URLs also include the current wiki page id (`id=...`) so `file.php` can enforce ACLs for the host page. - **scratchpad_paths** Scratchpad file map (one file path per line, followed by an `A>` alias line). Example: ``` /var/lib/dokuwiki-scratchpads/startpad.txt A> start ``` - **defaults** Default inline options appended to each listing call. - **extensions** Comma-separated list of file extensions allowed in listings. Leave empty to allow all. - **thumb_placeholder** MediaManager ID used as a placeholder image in the gallery (optional). - **gallery_thumb_scale** Multiplier for generated thumbnails (1 = 150x150, 2 = 300x300), while still displaying them as 150x150. Useful for HiDPI screens. - **open_service_url** URL of a local client service used by `{{open>...}}` and directory links. See luxtools-client. - **pagelink_search_depth** Maximum directory depth for `.pagelink` discovery under each configured root. `0` means only the root directory itself is checked. ### Template style settings The `{{open>...}}` links and directory “open” links use a dedicated color placeholder so they can be customized in **Template Style Settings**. - **Location Links** (`__luxtools_locationlink__`) Default: `#b57d35` To be able to customize the color via the UI add the following to your local template style file at `conf/tpl//style.ini` under the `[replacements]` section: ``` __luxtools_locationlink__ = "#b57d35" ; @ini_luxtools_locationlink ``` ### Temporary global input styling Because the target template is not ready yet, the plugin currently ships a temporary stylesheet that applies `@ini_text`, `@ini_background`, and `@ini_border` to all `input`, `textarea`, and `select` elements site-wide. This file is explicitly marked as a temporary fix and should be removed once the template provides proper form control styles. Temporary file: [temp-input-colors.css](temp-input-colors.css) Developer note: DokuWiki serves a combined stylesheet via `lib/exe/css.php` and caches it. Cache invalidation is based on the mtimes of the source CSS/LESS files. If you deploy into a mounted/remote filesystem with a different clock, preserving mtimes can prevent automatic invalidation (making it look like your CSS changes don't load until you purge cache). `deploy.sh` avoids preserving mtimes by default to make CSS iteration smoother. If you explicitly want to preserve mtimes, use: ```bash ./deploy.sh --preserve-times ``` ## Features and usage ### 0) Editor toolbar: Code block button The plugin adds a custom button to the DokuWiki editor toolbar for quickly inserting `` blocks. When editing a page, click the code block button (angle brackets icon `<>`) in the toolbar to wrap selected text in `` tags, or to insert an empty code block at the cursor position. This complements DokuWiki's built-in monospace formatting (`''`) by providing quick access to HTML code blocks. ### 0.1) Editor toolbar: Date Fix The plugin adds two toolbar buttons for normalizing timestamps while editing: - **Date Fix**: Converts the selected timestamp to `YYYY-MM-DD` (or `YYYY-MM-DD HH:MM:SS` if time is included). - **Date Fix (All)**: Scans the whole page and normalizes any recognizable timestamps. Supported input examples include: - `2026-01-30` - `30.01.2026` - `30 Jan 2026` - `Jan 30, 2026` - `2026-01-30 13:45` - `2026-01-30T13:45:00` ### 0.2) Editor toolbar: Page Link The **Page Link** toolbar button creates a page-scoped UUID and stores it in page metadata. This UUID is used to link the page to a folder that contains a `.pagelink` file with the same UUID. Workflow: 1. Click **Page Link** in the editor toolbar to create the UUID. 2. View the page and copy the UUID from the “Not linked: Copy ID” status. 3. Create a `.pagelink` file in the target folder (within your configured `paths` roots) and paste the UUID into that file. Once linked, you can use `blobs/` as an alias in luxtools syntax on that page, for example: ``` {{images>blobs/*.png}} {{directory>blobs/&recursive=1}} ``` ### 1) List files by glob pattern The `{{directory>...}}` syntax (or `{{files>...}}` for backwards compatibility) can handle both directory listings and glob patterns. When a glob pattern is used, it renders as a table: ``` {{directory>/Scape/projects/*}} {{directory>/Scape/projects/*&tableheader=1&showsize=1&showdate=1}} {{directory>/Scape/projects/*&recursive=1&sort=mtime&order=desc}} ``` Or using the legacy `files` keyword (same behavior): ``` {{files>/Scape/projects/*}} {{files>/Scape/projects/*&tableheader=1&showsize=1&showdate=1}} ``` Notes: - Pattern matching is performed per-directory (safe glob via fnmatch). - Always renders as a table. - A directory can have a title file (default: `_title.txt`) to override the displayed folder name. ### 2) List a directory (folders + files) as a table ``` {{directory>/Scape/projects/&tableheader=1&foldersfirst=1&sort=name}} ``` This always renders as a table. It includes an "Open Location" link above the table when rendered as XHTML. ### 3) Image gallery with thumbnails + lightbox ``` {{images>/Scape/photos/2025/*}} {{images>/Scape/photos/2025/*&recursive=1}} ``` Clicking a thumbnail opens a lightbox viewer. Thumbnails are generated and cached via the plugin endpoint. ### 4) Single image with caption (imagebox) ``` {{image>/Scape/photos/picture.jpg|This is the caption}} {{image>/Scape/photos/picture.jpg|Caption|400}} {{image>/Scape/photos/picture.jpg|Caption|400x300}} {{image>/Scape/photos/picture.jpg|Caption|left}} {{image>/Scape/photos/picture.jpg|Caption|400¢er}} {{image>https://example.com/images/picture.jpg|Remote image caption}} {{image>https://example.com/images/picture.jpg|Remote caption|400x300&left}} ``` Renders a Wikipedia-style image box with optional caption. The syntax uses pipe-separated parts: - `{{image>path|caption}}` – Image with caption (uses defaults) - `{{image>path|caption|options}}` – Image with caption and options Options (in the third part, separated by `&`): - Size: `200` (width) or `200x150` (width × height) - Alignment: `left`, `right` (default), or `center` - Combined: `400&left` or `400x300¢er` The image links to the full-size version when clicked. Remote images (HTTP/HTTPS URLs) are linked directly without proxying or thumbnailing. ### 5) Open a local path/folder (best-effort) ``` {{open>/Scape/projects|Open projects folder}} {{open>/home/me/notes|Open local folder}} {{open>file:///home/me/notes|Open via file://}} ``` Behaviour: - Prefer calling the configured local client service (open_service_url). - Fall back to opening a file:// URL in a new tab (often blocked by browsers). ### 6) Scratchpads (shared, file-backed, no page revisions) ``` {{scratchpad>start}} ``` Scratchpads render the referenced file as wikitext and (when you have edit rights on the host page) provide an inline editor that saves directly to the backing file. ### 7) Link Favicons (automatic) External links automatically display the favicon of the linked website. This feature: - Uses DuckDuckGo's favicon service (`icons.duckduckgo.com`) - Works on all external links (class `urlextern`) - Shows grayscale icons that become colored on hover - Browser handles caching; no server-side storage needed No configuration required. The feature is enabled by default for all external links. Based on the [linkfavicon plugin](https://github.com/shaoyanmin/linkfavicon) by Shao Yanmin. ## Inline options reference (directory/images) The listing syntaxes accept options appended with &key=value: | Option | Values | Notes | |---|---|---| | recursive | 0\|1 | Recurse into subdirectories. | | sort | name\|iname\|ctime\|mtime\|size | Sort key. | | order | asc\|desc | Sort order. | | foldersfirst | 0\|1 | Group folders before files (useful for tables). | | titlefile | _title.txt | Directory title override file name. | | cache | 0\|1 | 0 disables page caching (default). | | randlinks | 0\|1 | Adds a cache-busting query parameter based on mtime. | | showsize | 0\|1 | Show file size (where supported). | | showdate | 0\|1 | Show last modified date (where supported). | | maxheight | 500 | Container max-height in pixels; -1 disables scroll container. | | tableheader | 0\|1 | Render table header row. | ## Admin settings The admin settings page includes a **default_tablecolumns** option that lets you specify which columns are displayed by default in table-style listings. This is a comma-separated list of column names: - `name` – File/folder name (always shown) - `size` – File size - `date` – Last modified date Example: `name,size,date` shows all columns by default. ## Credits / upstream luxtools is a fork of the [DokuWiki Filelist plugin](https://www.dokuwiki.org/plugin:filelist). Upstream authors and contributors include Gina Häußge and the DokuWiki community (Dokufreaks). This fork keeps the original license (GPL-2) and retains the relevant copyright notices in the source. ## Development helpers - Linux/macOS: ./deploy.sh ## License GPL-2. See COPYING / LICENSE.