Table of Contents
DokuWiki Consolidation Feasibility
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.
Verdict up front
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.
Template: nothing to do
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.
Core patches that can become plugin hooks
- Cache invalidation on save (
inc/Action/Save.php).COMMON_WIKIPAGE_SAVEfires at the right point; an action plugin hooking it and callingCacheInstructions/CacheRendererreproduces this with zero core changes. - Open Graph tags (
tpl_socialcard()ininc/template.php).TPL_METAHEADER_OUTPUTfires exactly where these are injected now; move to an action plugin hooking that event. - Ace editor (
inc/Ui/Editor.php,inc/template.php).EDIT_FORM_ADDTEXTAREAexists specifically to let a plugin replace whataddTextarea()renders —Event::createAndTrigger()is called with$canPreventDefault = trueatinc/Ui/Editor.php:123, so a plugin handler that calls$event->preventDefault()stops DokuWiki's ownaddTextarea()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 sameTPL_METAHEADER_OUTPUThook as Open Graph, andlib/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. - Favicon PNG/JPG-before-ICO lookup (
tpl_favicon()ininc/template.php). Not a plugin candidate, a template one — this logic only needs to exist inyanevskiv's own header code, since a template fully owns its<head>. Moving it out ofinc/template.phpremoves 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-indo=indexlisting, so pluginizing it means an action plugin hookingACTION_ACT_PREPROCESSto redirect$ACTto a custom action and fully reimplementing the page-tree listing DokuWiki'sIndexUI 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.
Core patches that have to stay core
.mdextension (inc/init.php,inc/pageutils.php,inc/search.php,inc/TreeBuilder/PageTreeBuilder.php,inc/common.php,inc/Action/Export.php,bin/wantedpages.php)..txtis 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.mdis worth that recurring cost versus reverting to.txt.wikilink-wipCSS 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).- Clean
/sitemapand/mediamenu URLs (inc/Menu/Item/Index.php,inc/Menu/Item/Media.php).SiteMenu/MobileMenuinstantiate these classes directly with no filter in between. Purely cosmetic (the URLs already resolve fine underuserewriteregardless of what the header link'shrefsays), so this is a candidate to just drop on reinstall rather than carry forward, if the two extra files aren't worth it.
Dead code found along the way: `math`/`eqn`/`latex_figure`
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 ownprotect.phpsyntax component (getSort() = 65) already claims$...$,$$...$$,\(...\),\[...\], and a list of LaTeX environments, passing the raw (XML-escaped) text straight into$renderer->docfor KaTeX to render client-side.markdowkualso ships its ownmathinline.php(getSort() = 90) andmathblock.php(getSort() = 89) doing the same pass-through. Since DokuWiki connects syntax modes in ascendinggetSort()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'slatexfigure.phpdoesn't call alatex_figure()renderer method either; it hands the matched text to the standardcodeinstruction 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.
Correction: `markdowku` is not untouched upstream
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.
`katex` itself: untouched
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.
Recommended plugin roster
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_OUTPUThooks, bundledace-editor.js.texfigure(new) —latexfigure.phpextracted out of themarkdowkufork into its own syntax plugin. Fixes the fork problem directly:markdowkureverts 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:
- Cache invalidation on save — five lines, fully generic, but trivial enough that a dedicated plugin is arguably more overhead (its own
plugin.info.txt, listing, versioning) than the code it wraps. - Open Graph / social cards — generic in concept, but this implementation bakes in specific choices (200-char description cutoff, no
og:imageever,twitter:card=summarynotsummary_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-wipclass ininternallink()) 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 intolib/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.phpfor settings only this site will ever set. Simplifies to a plain array in the template, editable directly.
Resulting core patch surface, if you do all of the above
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:
- The
.mdextension cluster (~7 files, unavoidable). wikilink-wipclass inxhtml.php(5 lines).- Menu
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.
