Migrating a Wiki to Static HTML
The server runs a DokuWiki farm — multiple wiki “animals” sharing one DokuWiki installation, each with its own content and configuration. One of these wikis served as the help system for a desktop application. It worked fine, but it was a PHP application serving what was essentially static content. Every page load spun up a PHP interpreter to render Markdown-like syntax into HTML.
We replaced it with Hugo-generated static HTML served directly by nginx. Zero PHP. Zero runtime overhead. Same look.
The translation problem
DokuWiki has its own markup syntax. Not Markdown, not reStructuredText — its own thing. Headings use ====== (and they’re inverted — six equals signs is H1, not H6). Links use [[double brackets]]. Images use {{double braces}}. Bold is **asterisks** but italic is //slashes//, which conflicts with URLs.
I wrote a PHP translation tool that converts DokuWiki pages to Hugo-compatible Markdown. The conversion pipeline has about a dozen stages, and order matters:
- Color tags (
<color red>text</color>→ inline CSS spans) - Headings (reverse the level mapping)
- Images (rewrite paths from wiki namespace format)
- Links (three passes: anchored, display-text, bare)
- Italic (protect
://in URLs before converting//to*) - The rest: underline, monospace, bold, lists, tables, code blocks
The trickiest part was titles. DokuWiki pages don’t have frontmatter — the title is either the first heading or derived from the filename. The tool derives titles from filenames (e.g., design_wizard.txt → “Design Wizard”) and strips the first heading if it matches, to avoid duplication.
The theme clone
The goal was pixel-perfect reproduction. Users embedded this help system in application panels — any visual change would be noticed.
Key design decisions we preserved:
- No site header — saves vertical space in embedded panels
- Right-floated nav+TOC box — sits inside the content area, text wraps around it
- Two collapsible sections — “Navigation” (starts closed) and “On This Page” (starts open, only shown when a page has 2+ headings)
- All blue links —
#2b73b7, consistent everywhere
One browser compatibility lesson: Firefox handles overflow-x: clip differently than Chrome when overflow-y: visible is also set. The floated nav box broke in Firefox. We removed the overflow property entirely and used a wrapper class for wide tables instead.
The result
32 pages, 6 sections, 22 media files. The entire help system builds in under a second and serves as static HTML with aggressive caching. The DokuWiki container still runs for other wikis, but this one is gone from it.
The translation tool is reusable — point it at any DokuWiki data directory and it produces Hugo content. We’ll use it again if the other wiki animals need migrating.