DokuWiki Consolidation Feasibility looks at reinstalling vanilla DokuWiki and splitting the current core patches and custom plugins into a set of independent plugins, some site-specific and some reusable, plus moving all styling into a single yanevskiv template. Short version: the template side is basically already done, most core patches can move into plugins, a small unavoidable cluster can't, and digging into this surfaced both a chunk of dead code and an undisclosed fork that changed the plan.
A literally vanilla core is not achievable — the .md extension change has no plugin hook anywhere in DokuWiki's API, full stop. Everything else currently patched into core either has a real event to hook (move it to a plugin) or turns out to be unused code that should just be deleted on reinstall rather than carried forward at all. The original framing of this report — “one yanevskiv plugin holding everything” — also changed shape: most of what was headed there splits out into small, independent, individually reusable plugins instead, with yanevskiv left as the site-specific leftover, not the main event.
lib/tpl/yanevskiv/ is already a single template with its own git repo, and every styling change made so far (_links.css link colors, WIP CSS, favicon-lookup-in-template question from earlier) already lives there. “Consolidate styling into one template” is already the current state — a fresh install just needs this directory copied over wholesale.
inc/Action/Save.php). COMMON_WIKIPAGE_SAVE fires at the right point; an action plugin hooking it and calling CacheInstructions/CacheRenderer reproduces this with zero core changes.tpl_socialcard() in inc/template.php). TPL_METAHEADER_OUTPUT fires exactly where these are injected now; move to an action plugin hooking that event.inc/Ui/Editor.php, inc/template.php). EDIT_FORM_ADDTEXTAREA exists specifically to let a plugin replace what addTextarea() renders — Event::createAndTrigger() is called with $canPreventDefault = true at inc/Ui/Editor.php:123, so a plugin handler that calls $event->preventDefault() stops DokuWiki's own addTextarea() from running at all and substitutes its own markup instead. This isn't a workaround, it's the literal mechanism the event exists for. The Ace <script> tag injection moves to the same TPL_METAHEADER_OUTPUT hook as Open Graph, and lib/scripts/ace-editor.js (wholly custom, not a vendored/patched copy of anything — the actual Ace library loads from a CDN with a pinned integrity hash and is never touched locally) ships as the plugin's own asset. Fully generic, no site-specific assumptions anywhere in it: this is the clearest “should always have been a plugin” case in the whole install.tpl_favicon() in inc/template.php). Not a plugin candidate, a template one — this logic only needs to exist in yanevskiv's own header code, since a template fully owns its <head>. Moving it out of inc/template.php removes it from the core-patch list entirely.(WIP) sitemap grouping (inc/Ui/Index.php). Feasible but the highest-effort item: no filter hook exists for the built-in do=index listing, so pluginizing it means an action plugin hooking ACTION_ACT_PREPROCESS to redirect $ACT to a custom action and fully reimplementing the page-tree listing DokuWiki's Index UI class already does. That's real reimplementation work with real regression risk (sorting, ACL filtering, namespace collapsing all have to be reproduced correctly). Recommend leaving this one as a core patch for now and revisiting only if the plugin consolidation is otherwise complete..md extension (inc/init.php, inc/pageutils.php, inc/search.php, inc/TreeBuilder/PageTreeBuilder.php, inc/common.php, inc/Action/Export.php, bin/wantedpages.php). .txt is a string literal baked into each of these with no event fired around any of them. This is a permanent tax on every future DokuWiki upgrade: each new release has to be re-diffed against this same cluster of ~7 files. Worth deciding, independent of this consolidation, whether .md is worth that recurring cost versus reverting to .txt.wikilink-wip CSS class (inc/parser/xhtml.php, internallink()). Modifies logic inside a method DokuWiki already runs, rather than adding new syntax — there's no seam a plugin could use to change the class assigned to an existing render path without replacing the entire XHTML renderer (a “Renderer Plugin” swaps the whole class, not one method — not worth it for 5 lines)./sitemap and /media menu URLs (inc/Menu/Item/Index.php, inc/Menu/Item/Media.php). SiteMenu/MobileMenu instantiate these classes directly with no filter in between. Purely cosmetic (the URLs already resolve fine under userewrite regardless of what the header link's href says), so this is a candidate to just drop on reinstall rather than carry forward, if the two extra files aren't worth it.
Worth flagging before migrating anything: the math(), eqn(), latex_figure() methods added to inc/parser/renderer.php and inc/parser/xhtml.php (commit fb8ba4b) are never called by anything — grepping the whole plugin tree turns up zero callers. What actually renders math today:
katex's own protect.php syntax component (getSort() = 65) already claims $...$, $$...$$, \(...\), \[...\], and a list of LaTeX environments, passing the raw (XML-escaped) text straight into $renderer->doc for KaTeX to render client-side.markdowku also ships its own mathinline.php (getSort() = 90) and mathblock.php (getSort() = 89) doing the same pass-through. Since DokuWiki connects syntax modes in ascending getSort() order and the first matching alternative wins, katex's lower sort value means it claims the match first — markdowku's math syntax components are themselves unreachable, shadowed by katex.markdowku's latexfigure.php doesn't call a latex_figure() renderer method either; it hands the matched text to the standard code instruction with 'latex' as the language, which core already knows how to render via syntax highlighting.Net effect: the three custom renderer methods do nothing today. Don't migrate them to a plugin, delete them on reinstall.
The first pass of this report said markdowku was pristine upstream and shouldn't be forked. That was wrong. lib/plugins/markdowku/ has its own git repo with two commits: a vendored “Initial commit” of the real upstream plugin (Julian Fagir / Raphael Wimmer), then a local commit, e0413df (“Add: math, eqn, latex_figure support”), which adds syntax/mathinline.php, syntax/mathblock.php, and syntax/latexfigure.php wholesale — none of those three files exist in upstream markdowku — and appends a copyright line to LICENSE. So this plugin is already a fork, and has been since before this report's first draft.
Of the three added files, two (mathinline.php, mathblock.php) are the dead-code-shadowed-by-katex components from the section above — dead, but your dead code sitting in someone else's plugin directory. latexfigure.php is the one live, load-bearing addition: nothing else handles the \documentclass{standalone}...\end{document} pattern.
This changes the recommendation: pull latexfigure.php out into its own plugin (see below), drop the two dead math files, revert LICENSE, and markdowku goes back to genuinely pristine upstream — restoring the “don't touch third-party code” property the first draft incorrectly assumed was already true.
Unlike markdowku, katex really is pristine upstream (H.-H. Peng), no local commits, no .git divergence found. Reinstall fetches it fresh, unmodified, as originally stated.
The original framing — one yanevskiv plugin holding everything — gives way to a split between plugins that are genuinely reusable by anyone running DokuWiki + KaTeX, and a thin site-specific plugin for logic that's technically generic but currently has exactly one consumer.
Reusable, standalone, no site-specific assumptions:
man — unchanged, already this way.ace (new) — the Ace editor integration pulled out of core, as described above. EDIT_FORM_ADDTEXTAREA + TPL_METAHEADER_OUTPUT hooks, bundled ace-editor.js.texfigure (new) — latexfigure.php extracted out of the markdowku fork into its own syntax plugin. Fixes the fork problem directly: markdowku reverts to pristine, and this becomes a normal installable plugin for the \documentclass{standalone}...\end{document} convention.katex, markdowku — third-party, stay/return untouched.
Genuinely could go either way, currently recommended to stay in yanevskiv:
plugin.info.txt, listing, versioning) than the code it wraps.og:image ever, twitter:card=summary not summary_large_image). Generalizing into a configurable plugin is real design work (config schema, conf/metadata.php, edge cases for hypothetical other users) that isn't justified while there's one consumer.(WIP) sitemap grouping — the listing half could become a configurable “flag pages by heading prefix” plugin, but the CSS-coloring half (wikilink-wip class in internallink()) has no plugin seam at all regardless — see “Core patches that have to stay core” above. Even fully generalized, this feature keeps one foot in core permanently, which weakens the case for generalizing the other half.
Putting these three in yanevskiv isn't a compromise — it's the honest home for logic that's technically generic but has no second consumer yet. Nothing stops extracting any of them later if that changes.
Not a plugin at all:
socialicons — folds into lib/tpl/yanevskiv/ directly as template code. It's pure branding for one site (which icons, which links, in what order) with no reason to carry Configuration Manager registration, conf/default.php, conf/metadata.php for settings only this site will ever set. Simplifies to a plain array in the template, editable directly.
Down from the current spread across Save.php, template.php (three separate patches), Ui/Index.php, Ui/Editor.php, parser/renderer.php, parser/xhtml.php (two patches), Menu/Item/Index.php, Menu/Item/Media.php, plus the .md cluster, to just:
.md extension cluster (~7 files, unavoidable).wikilink-wip class in xhtml.php (5 lines).getLink() overrides, only if you decide the pretty URLs are worth keeping (otherwise: zero).
Everything else moves to a plugin (yanevskiv, ace, texfigure) or the template, socialicons folds into the template directly, markdowku reverts to pristine upstream, and the math/eqn/latex_figure core patch disappears outright as dead code.