Table of Contents
DokuWiki Changes
DokuWiki Changes is a record of every place this installation patches DokuWiki core directly (inc/, bin/, entry points), plus an honest assessment of which patches actually required touching core versus which ones could have been ordinary plugins. lib/tpl/ and lib/plugins/ are separate, gitignored git repositories not covered here except where they interact with a core patch.
Had to be core
One change genuinely could not have been a plugin.
- Page file extension
.txt→.md(inc/init.phpdefinesDOKU_EXT). DokuWiki hardcodes.txtas a string literal inwikiFN()(inc/pageutils.php), the extension filters andpathID()ininc/search.php, the page-file glob ininc/TreeBuilder/PageTreeBuilder.php, namespace templates ininc/common.php, and the export filename ininc/Action/Export.php. None of these are event hooks, they're direct string comparisons and concatenations scattered through code that runs on every page load. There is no extension point a plugin could intercept to change what “a page file” means globally.bin/wantedpages.phpand the newbin/migrate-ext.phpneeded the same fix for consistency.
Could plausibly have been plugins
These touch core but DokuWiki exposes an event or extension mechanism that would have avoided it.
- Cache invalidation on save (
inc/Action/Save.php, commit3146996). Explicitly clearsCacheInstructionsandCacheRendererafter a save so a no-op re-save still forces a re-render. DokuWiki firesCOMMON_WIKIPAGE_SAVEaround this exact point; an action plugin hooking that event and calling the same two cache classes would have done this without editing core. - Math,
eqn,latex_figurerendering (inc/parser/renderer.php+inc/parser/xhtml.php, commitfb8ba4b). Added three new renderer methods with abstract stubs. New markup syntax is the textbook case for a DokuWiki syntax plugin (extends DokuWiki_Syntax_Plugin, registeringconnectTo()patterns and its ownrender()implementation) — the KaTeX plugin already sitting alongside this proves the pattern works. Patching the renderer directly means every future DokuWiki upgrade has to be re-merged against these three methods. - Open Graph tags (
tpl_socialcard()ininc/template.php). Injects<meta property="og:...">tags.tpl_metaheaders()already firesEvent::createAndTrigger('TPL_METAHEADER_OUTPUT', $head, ...)right after the point these tags are added — an action plugin hooking that event and pushing entries onto$head['meta']would produce identical output with zero core changes. - Favicon PNG/JPG-before-ICO lookup (
tpl_favicon()ininc/template.php). This isn't even a plugin candidate so much as a template candidate:tpl_favicon()is called by the template, and a custom template fully controls its own<head>. The lookup could have been written directly in theyanevskivtemplate's header code instead of changing the shared core function every template on the install uses. - Ace editor integration (
inc/Ui/Editor.php,inc/template.php, commits1c211c0,fc74044). Swaps the plain<textarea>for an Ace-backed editor and injects the Ace<script>tag.Ui\Editor::addTextarea()is itself invoked throughEvent::createAndTrigger('EDIT_FORM_ADDTEXTAREA', $data, [$this, 'addTextarea'], true)— the event exists precisely so a plugin can override what gets rendered in that slot. The later “edit bar above textarea” commit (fc74044) reordered PHP render calls to move the edit bar's HTML earlier in the form; the same visual effect (barbeforetextarea) is achievable with plain CSS (flex/order) without touching render order ininc/Ui/Editor.phpat all. (WIP)sitemap grouping (inc/Ui/Index.php, commit460adbf). Splits/sitemapinto “Work in progress” / “Finished pages” by checkingp_get_first_heading($id). Borderline: there's no clean hook to restructure the built-in index listing, so a plugin would have had to reimplementdo=indexwholesale as its own action plugin rather than patch three lines of grouping logic into the existing one. Reasonable to leave as a core patch, but worth another look ifTPL_CONTENT_DISPLAYor a similar filter existed for this specific list.
Legitimately core (no clean alternative)
wikilink-wipCSS class on internal links (inc/parser/xhtml.php, commit56ae807). Adding a CSS class to the existinginternallink()renderer method based onp_get_first_heading(). Same category as the math renderer methods above — arguably a syntax/action plugin territory in principle, but since it modifies the existingwikilink1/wikilink2class logic rather than adding new syntax, there's no clean plugin seam for “change the CSS class DokuWiki already assigns to links it already renders.”- Clean
/sitemapand/mediaURLs (inc/Menu/Item/Index.php,inc/Menu/Item/Media.php, commits460adbf,e60fe2d). OverridesgetLink()on core menu item classes thatSiteMenu/MobileMenuinstantiate directly with no filter hook in between. Short of post-processing the rendered menu HTML with a template-level regex (fragile), this needed a direct override.
Abandoned experiment: `feat/Markup` branch
Fifteen commits between November 2025 and February 2026 built a hand-rolled markup engine at inc/Markup/Markup.php (tokenizer, block scanning, \begin/\end, line commands, \itemize/\enumerate) — apparently aimed at parsing LaTeX-like structure more thoroughly than the current latex_figure stub (which just renders as a raw latex code block, per inc/parser/xhtml.php). This work never merged into master; it lives only on the feat/Markup branch and isn't deployed anywhere. Worth revisiting if latex_figure ever needs real structural parsing instead of pass-through rendering.
Companion tooling, not core changes
bin/texrender— a POSIX shell script (LaTeX → SVG/PNG/PDF viatexfot/pdflatex-family tools) tracked inbin/per this repo's convention. It's a standalone CLI, not a DokuWiki patch; it doesn't touch anyinc/code and DokuWiki has no concept of it.bin/migrate-ext.php— new script to rename pages and attic revisions between extensions. Tooling, not a runtime change.
Plugins already done right
For contrast, katex, markdowku, man, and socialicons are all proper plugins living in the gitignored lib/plugins/, touching zero core files. man in particular hooks ACTION_ACT_PREPROCESS and TPL_ACT_UNKNOWN to serve entirely synthetic pages without ever writing to data/pages — proof that even fairly deep integrations (routing, rendering, caching) are achievable through the plugin API when the right event exists.
