diff --git a/.gitattributes b/.gitattributes
index 8cb26e5..08be396 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -13,6 +13,7 @@
.gitignore export-ignore
.github/ export-ignore
docs/images/ export-ignore
+docs/update/ export-ignore
tests/ export-ignore
README.md export-ignore
version-check.json export-ignore
diff --git a/docs/TODO/todo-wiki-markup.md b/docs/TODO/todo-wiki-markup.md
index ac438ea..11601c7 100644
--- a/docs/TODO/todo-wiki-markup.md
+++ b/docs/TODO/todo-wiki-markup.md
@@ -11,7 +11,8 @@ table of contents (`__TOC__`, `__FORCETOC__`, `__NOTOC__`, automatic from four
headings) and the `#REDIRECT [[Article]]` first line are done. They are read only
while a wiki article is saved or previewed, by switching the `WIKIHEADING` and
`WIKIMAGIC` tags on in `core.text_formatter_s9e_parse_before` (see `wiki/markup.php`),
-and a migration reparses saved articles. What is left below is tables, the text
+and articles saved earlier are converted with
+`php bin/phpbbcli.php reparser:reparse phpbbmodders_wiki_article`. What is left below is tables, the text
styles and references (not wanted yet), `[[Category:Name]]`, and templates.
## Scope: wiki articles only
diff --git a/docs/update/2026-10-12/01-headings-and-contents.png b/docs/update/2026-10-12/01-headings-and-contents.png
new file mode 100644
index 0000000..f8238f7
Binary files /dev/null and b/docs/update/2026-10-12/01-headings-and-contents.png differ
diff --git a/docs/update/2026-10-12/02-file-uploads.png b/docs/update/2026-10-12/02-file-uploads.png
new file mode 100644
index 0000000..274a6a2
Binary files /dev/null and b/docs/update/2026-10-12/02-file-uploads.png differ
diff --git a/docs/update/2026-10-12/03-watch-and-discussion-buttons.png b/docs/update/2026-10-12/03-watch-and-discussion-buttons.png
new file mode 100644
index 0000000..812763e
Binary files /dev/null and b/docs/update/2026-10-12/03-watch-and-discussion-buttons.png differ
diff --git a/docs/update/2026-10-12/04-recent-changes.png b/docs/update/2026-10-12/04-recent-changes.png
new file mode 100644
index 0000000..09e0658
Binary files /dev/null and b/docs/update/2026-10-12/04-recent-changes.png differ
diff --git a/docs/update/2026-10-12/05-contributions.png b/docs/update/2026-10-12/05-contributions.png
new file mode 100644
index 0000000..3919b33
Binary files /dev/null and b/docs/update/2026-10-12/05-contributions.png differ
diff --git a/docs/update/2026-10-12/06-overview.png b/docs/update/2026-10-12/06-overview.png
new file mode 100644
index 0000000..095fd4f
Binary files /dev/null and b/docs/update/2026-10-12/06-overview.png differ
diff --git a/docs/update/2026-10-12/07-acp-settings.png b/docs/update/2026-10-12/07-acp-settings.png
new file mode 100644
index 0000000..8808309
Binary files /dev/null and b/docs/update/2026-10-12/07-acp-settings.png differ
diff --git a/docs/update/2026-10-12/README.md b/docs/update/2026-10-12/README.md
new file mode 100644
index 0000000..46ff061
--- /dev/null
+++ b/docs/update/2026-10-12/README.md
@@ -0,0 +1,45 @@
+# Wiki update screenshots, 2026-10-12
+
+Taken with Playwright on a throwaway phpBB 3.3.19 board (prosilver, MySQL 8.0), filled by `seed-wiki-fixtures.php` from seed-forum.
+
+## Headings and contents
+
+An article with headings, the contents box, and `[[Article#Section]]` and `[[#Section]]` links.
+
+
+
+## File uploads
+
+An uploaded diagram embedded with `[[File:name.png]]`.
+
+
+
+## Watch and discussion buttons
+
+The article header: edit, history, watch (bell) and discussion.
+
+
+
+## Recent changes
+
+Every saved version, with RSS and Atom feed links.
+
+
+
+## Contributions
+
+A member's saved versions.
+
+
+
+## Overview
+
+The overview page with pending articles, as a moderator sees it.
+
+
+
+## ACP settings
+
+ACP > Extensions > Wiki > Settings.
+
+
diff --git a/event/wikilink_listener.php b/event/wikilink_listener.php
index f543e7a..c6b737b 100644
--- a/event/wikilink_listener.php
+++ b/event/wikilink_listener.php
@@ -123,7 +123,7 @@ public function configure_wikilink($event)
$tag->attributes->add('text')->required = false;
$tag->template = ''
. ''
- . '';
+ . '#';
$configurator->Preg->match(
'/\[\[\s*(?!File:)(?=[^\]|])(?' . self::NAME_CLASS . '{0,255}?)\s*(?:#\s*(?[^\[\]|<>"\n]{1,255}?)\s*)?(?:\|\s*(?[^\[\]\n]{1,255}?)\s*)?\]\]/',
diff --git a/migrations/purge_text_formatter_cache.php b/migrations/purge_text_formatter_cache.php
new file mode 100644
index 0000000..d13ee84
--- /dev/null
+++ b/migrations/purge_text_formatter_cache.php
@@ -0,0 +1,45 @@
+container->get('cache')->purge();
+ }
+}
diff --git a/styles/prosilver/template/recent_changes.html b/styles/prosilver/template/recent_changes.html
index 3cc2d37..6941fd7 100644
--- a/styles/prosilver/template/recent_changes.html
+++ b/styles/prosilver/template/recent_changes.html
@@ -13,8 +13,8 @@ {L_WIKI_RECENT_CHANGES}
{L_CONTRIBUTIONS_SAVED} |
{L_CONTRIBUTIONS_ARTICLE} |
{L_USER} |
- {L_REASON_EDIT} |
- {L_CONTRIBUTIONS_STATUS} |
+ {L_REASON_EDIT} |
+ {L_CONTRIBUTIONS_STATUS} |
diff --git a/tests/unit/markup_test.php b/tests/unit/markup_test.php
index d682b4f..414312c 100644
--- a/tests/unit/markup_test.php
+++ b/tests/unit/markup_test.php
@@ -218,4 +218,41 @@ public function test_file_embeds_are_still_their_own_tag()
$this->assertSame(2, substr_count($xml, 'assertSame(1, substr_count($xml, 'createMock(\phpbb\controller\helper::class),
+ $this->createMock(\phpbb\language\language::class),
+ $this->createMock(\phpbbmodders\wiki\wiki\links::class),
+ $this->createMock(\phpbbmodders\wiki\wiki\files::class)
+ );
+
+ $configurator = new \s9e\TextFormatter\Configurator;
+ // The PHP renderer, like phpBB's own: the default XSLT one needs ext-xsl, which some CI runners lack
+ $configurator->rendering->setEngine('PHP');
+ $listener->configure_wikilink(array('configurator' => $configurator));
+ extract($configurator->finalize());
+
+ return $renderer->render($parser->parse($text));
+ }
+
+ /** @dataProvider link_texts */
+ public function test_a_link_shows_a_readable_text(string $text, string $expected)
+ {
+ $html = $this->render($text);
+
+ $this->assertMatchesRegularExpression('/]*>' . preg_quote($expected, '/') . '<\/a>/', $html, $html);
+ }
+
+ public static function link_texts(): array
+ {
+ return array(
+ 'article' => array('[[Main Page]]', 'Main Page'),
+ 'article with section' => array('[[Main Page#History]]', 'Main Page#History'),
+ 'same-page section' => array('[[#History]]', '#History'),
+ 'own text' => array('[[Main Page#History|the history]]', 'the history'),
+ 'own text, same page' => array('[[#History|below]]', 'below'),
+ );
+ }
}