<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://mwiki.costasano.club/index.php?action=history&amp;feed=atom&amp;title=ICT%3AWiki_-_Dashboard_autopurge_architecture</id>
	<title>ICT:Wiki - Dashboard autopurge architecture - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://mwiki.costasano.club/index.php?action=history&amp;feed=atom&amp;title=ICT%3AWiki_-_Dashboard_autopurge_architecture"/>
	<link rel="alternate" type="text/html" href="https://mwiki.costasano.club/index.php?title=ICT:Wiki_-_Dashboard_autopurge_architecture&amp;action=history"/>
	<updated>2026-07-22T22:11:32Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://mwiki.costasano.club/index.php?title=ICT:Wiki_-_Dashboard_autopurge_architecture&amp;diff=1641&amp;oldid=prev</id>
		<title>Mngr: Mngr moved page ICT:Dashboard autopurge architecture to ICT:Wiki - Dashboard autopurge architecture without leaving a redirect</title>
		<link rel="alternate" type="text/html" href="https://mwiki.costasano.club/index.php?title=ICT:Wiki_-_Dashboard_autopurge_architecture&amp;diff=1641&amp;oldid=prev"/>
		<updated>2026-05-14T16:46:01Z</updated>

		<summary type="html">&lt;p&gt;Mngr moved page &lt;a href=&quot;/index.php?title=ICT:Dashboard_autopurge_architecture&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;ICT:Dashboard autopurge architecture (page does not exist)&quot;&gt;ICT:Dashboard autopurge architecture&lt;/a&gt; to &lt;a href=&quot;/ICT:Wiki_-_Dashboard_autopurge_architecture&quot; title=&quot;ICT:Wiki - Dashboard autopurge architecture&quot;&gt;ICT:Wiki - Dashboard autopurge architecture&lt;/a&gt; without leaving a redirect&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:46, 14 May 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Mngr</name></author>
	</entry>
	<entry>
		<id>https://mwiki.costasano.club/index.php?title=ICT:Wiki_-_Dashboard_autopurge_architecture&amp;diff=858&amp;oldid=prev</id>
		<title>Mngr at 21:40, 14 February 2026</title>
		<link rel="alternate" type="text/html" href="https://mwiki.costasano.club/index.php?title=ICT:Wiki_-_Dashboard_autopurge_architecture&amp;diff=858&amp;oldid=prev"/>
		<updated>2026-02-14T21:40:03Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://mwiki.costasano.club/index.php?title=ICT:Wiki_-_Dashboard_autopurge_architecture&amp;amp;diff=858&amp;amp;oldid=857&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Mngr</name></author>
	</entry>
	<entry>
		<id>https://mwiki.costasano.club/index.php?title=ICT:Wiki_-_Dashboard_autopurge_architecture&amp;diff=857&amp;oldid=prev</id>
		<title>Mngr at 21:38, 14 February 2026</title>
		<link rel="alternate" type="text/html" href="https://mwiki.costasano.club/index.php?title=ICT:Wiki_-_Dashboard_autopurge_architecture&amp;diff=857&amp;oldid=prev"/>
		<updated>2026-02-14T21:38:22Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://mwiki.costasano.club/index.php?title=ICT:Wiki_-_Dashboard_autopurge_architecture&amp;amp;diff=857&amp;amp;oldid=856&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Mngr</name></author>
	</entry>
	<entry>
		<id>https://mwiki.costasano.club/index.php?title=ICT:Wiki_-_Dashboard_autopurge_architecture&amp;diff=856&amp;oldid=prev</id>
		<title>Mngr: Created page with &quot;= ICT: Dashboard Auto‑Purge Architecture =  This page documents why dashboards in this wiki require an automatic purge after saving a Page Forms form, why several intuitive approaches fail, and why the final solution works reliably.   It is written for future administrators and maintainers of the Costa Sano Research infrastructure.  == 1. The Problem ==  Dashboards such as &#039;&#039;&#039;Dashboard:Place&#039;&#039;&#039; display data stored in Cargo tables.   After saving a form, the updated Car...&quot;</title>
		<link rel="alternate" type="text/html" href="https://mwiki.costasano.club/index.php?title=ICT:Wiki_-_Dashboard_autopurge_architecture&amp;diff=856&amp;oldid=prev"/>
		<updated>2026-02-14T21:36:08Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;= ICT: Dashboard Auto‑Purge Architecture =  This page documents why dashboards in this wiki require an automatic purge after saving a Page Forms form, why several intuitive approaches fail, and why the final solution works reliably.   It is written for future administrators and maintainers of the Costa Sano Research infrastructure.  == 1. The Problem ==  Dashboards such as &amp;#039;&amp;#039;&amp;#039;Dashboard:Place&amp;#039;&amp;#039;&amp;#039; display data stored in Cargo tables.   After saving a form, the updated Car...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= ICT: Dashboard Auto‑Purge Architecture =&lt;br /&gt;
&lt;br /&gt;
This page documents why dashboards in this wiki require an automatic purge after saving a Page Forms form, why several intuitive approaches fail, and why the final solution works reliably.  &lt;br /&gt;
It is written for future administrators and maintainers of the Costa Sano Research infrastructure.&lt;br /&gt;
&lt;br /&gt;
== 1. The Problem ==&lt;br /&gt;
&lt;br /&gt;
Dashboards such as &amp;#039;&amp;#039;&amp;#039;Dashboard:Place&amp;#039;&amp;#039;&amp;#039; display data stored in Cargo tables.  &lt;br /&gt;
After saving a form, the updated Cargo data does not appear immediately because:&lt;br /&gt;
&lt;br /&gt;
* Cargo updates are asynchronous  &lt;br /&gt;
* MediaWiki caches parser output  &lt;br /&gt;
* APCu/object cache may serve stale HTML  &lt;br /&gt;
* Reverse proxies may cache responses  &lt;br /&gt;
* Page Forms redirects do not trigger a purge  &lt;br /&gt;
&lt;br /&gt;
Users therefore see outdated dashboard data unless the page is manually purged.&lt;br /&gt;
&lt;br /&gt;
A reliable, automatic purge mechanism is required.&lt;br /&gt;
&lt;br /&gt;
== 2. Why Simple Solutions Do Not Work ==&lt;br /&gt;
&lt;br /&gt;
=== 2.1. HTML &amp;lt;meta&amp;gt; refresh ===&lt;br /&gt;
MediaWiki sanitizes &amp;lt;meta&amp;gt; tags, even inside &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;#tag:html&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.  &lt;br /&gt;
The tag is displayed as text and never executed.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Conclusion:&amp;#039;&amp;#039;&amp;#039; HTML refresh cannot be used.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
=== 2.2. Redirecting to &amp;lt;code&amp;gt;?action=purge&amp;lt;/code&amp;gt; ===&lt;br /&gt;
A redirect to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;?action=purge&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
always triggers MediaWiki’s confirmation dialog:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; Do you want to purge this page?&lt;br /&gt;
&lt;br /&gt;
This dialog cannot be suppressed via GET requests.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Conclusion:&amp;#039;&amp;#039;&amp;#039; GET‑based purge is never silent.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
=== 2.3. Page Forms limitations ===&lt;br /&gt;
Page Forms does not provide:&lt;br /&gt;
&lt;br /&gt;
* after‑save hooks  &lt;br /&gt;
* post‑redirect callbacks  &lt;br /&gt;
* purge triggers  &lt;br /&gt;
* button overrides  &lt;br /&gt;
&lt;br /&gt;
There is no way to attach purge logic to the Save button.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Conclusion:&amp;#039;&amp;#039;&amp;#039; Page Forms cannot trigger a purge.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
=== 2.4. JavaScript redirect loops ===&lt;br /&gt;
If JavaScript redirects to &amp;lt;code&amp;gt;?action=purge&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
# The purge dialog appears  &lt;br /&gt;
# After confirmation, the page reloads  &lt;br /&gt;
# The JS sees no marker indicating purge completion  &lt;br /&gt;
# JS redirects again  &lt;br /&gt;
# Infinite loop  &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Conclusion:&amp;#039;&amp;#039;&amp;#039; Redirect‑based purge is unstable.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
=== 2.5. Query parameters being stripped ===&lt;br /&gt;
Reverse proxies, skins, and canonical URL rewrites may strip unknown parameters such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;?purged=1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This causes loops because the JS cannot detect that the purge already happened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Conclusion:&amp;#039;&amp;#039;&amp;#039; Only parameters MediaWiki preserves can be used as markers.&lt;br /&gt;
&lt;br /&gt;
== 3. Requirements for a Working Solution ==&lt;br /&gt;
&lt;br /&gt;
A correct solution must:&lt;br /&gt;
&lt;br /&gt;
* purge silently (no dialog)  &lt;br /&gt;
* avoid loops  &lt;br /&gt;
* work for all dashboards  &lt;br /&gt;
* survive reverse proxies and canonicalization  &lt;br /&gt;
* be centralized  &lt;br /&gt;
* be successor‑friendly  &lt;br /&gt;
&lt;br /&gt;
This leads to the final architecture.&lt;br /&gt;
&lt;br /&gt;
== 4. The Final, Working Solution ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1. Purge via the MediaWiki API ===&lt;br /&gt;
MediaWiki performs a silent purge only when:&lt;br /&gt;
&lt;br /&gt;
* the request is a POST  &lt;br /&gt;
* it includes a valid CSRF token  &lt;br /&gt;
* it uses the API module  &lt;br /&gt;
&lt;br /&gt;
This avoids the confirmation dialog entirely.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
=== 4.2. Use a preserved query parameter ===&lt;br /&gt;
MediaWiki never strips parameters beginning with &amp;lt;code&amp;gt;mw_&amp;lt;/code&amp;gt;.  &lt;br /&gt;
We use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;?mw_purged=1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to mark that the purge has already occurred.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
=== 4.3. Centralize logic in &amp;lt;code&amp;gt;MediaWiki:Common.js&amp;lt;/code&amp;gt; ===&lt;br /&gt;
This ensures:&lt;br /&gt;
&lt;br /&gt;
* all dashboards benefit  &lt;br /&gt;
* no per‑page hacks  &lt;br /&gt;
* predictable behaviour  &lt;br /&gt;
&lt;br /&gt;
== 5. The Working Code (Common.js) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
$(function () {&lt;br /&gt;
    const title = mw.config.get(&amp;#039;wgPageName&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
    if (title &amp;amp;&amp;amp; title.startsWith(&amp;#039;Dashboard:&amp;#039;)) {&lt;br /&gt;
&lt;br /&gt;
        // Only purge once&lt;br /&gt;
        if (!location.search.includes(&amp;#039;mw_purged=1&amp;#039;)) {&lt;br /&gt;
&lt;br /&gt;
            new mw.Api().get({&lt;br /&gt;
                action: &amp;#039;query&amp;#039;,&lt;br /&gt;
                meta: &amp;#039;tokens&amp;#039;,&lt;br /&gt;
                type: &amp;#039;csrf&amp;#039;&lt;br /&gt;
            }).done(function (data) {&lt;br /&gt;
&lt;br /&gt;
                const token = data.query.tokens.csrftoken;&lt;br /&gt;
&lt;br /&gt;
                new mw.Api().post({&lt;br /&gt;
                    action: &amp;#039;purge&amp;#039;,&lt;br /&gt;
                    titles: title,&lt;br /&gt;
                    token: token&lt;br /&gt;
                }).always(function () {&lt;br /&gt;
&lt;br /&gt;
                    // Reload the dashboard normally, marked as purged&lt;br /&gt;
                    const url = mw.util.getUrl(title, { mw_purged: 1 });&lt;br /&gt;
                    location.replace(url);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6. Why This Works ==&lt;br /&gt;
&lt;br /&gt;
=== Silent purge ===&lt;br /&gt;
* API POST + CSRF token  &lt;br /&gt;
* No confirmation dialog  &lt;br /&gt;
* No user interaction  &lt;br /&gt;
&lt;br /&gt;
=== No loops ===&lt;br /&gt;
* &amp;lt;code&amp;gt;mw_purged=1&amp;lt;/code&amp;gt; is preserved by MediaWiki  &lt;br /&gt;
* JS sees the marker and does not purge again  &lt;br /&gt;
&lt;br /&gt;
=== Works for all dashboards ===&lt;br /&gt;
* Uses &amp;lt;code&amp;gt;wgPageName&amp;lt;/code&amp;gt;  &lt;br /&gt;
* No hardcoded page names  &lt;br /&gt;
&lt;br /&gt;
=== Infrastructure‑safe ===&lt;br /&gt;
* Survives reverse proxies  &lt;br /&gt;
* Survives canonical URL rewrites  &lt;br /&gt;
* Survives short URLs  &lt;br /&gt;
* Survives caching layers  &lt;br /&gt;
&lt;br /&gt;
=== Successor‑friendly ===&lt;br /&gt;
* One central rule  &lt;br /&gt;
* No per‑page code  &lt;br /&gt;
* Easy to understand and maintain  &lt;br /&gt;
&lt;br /&gt;
== 7. Summary ==&lt;br /&gt;
&lt;br /&gt;
The final solution works because it respects all of MediaWiki’s constraints:&lt;br /&gt;
&lt;br /&gt;
* Purge must be done via API POST  &lt;br /&gt;
* CSRF token is required  &lt;br /&gt;
* GET purge always shows a dialog  &lt;br /&gt;
* Page Forms cannot trigger purge  &lt;br /&gt;
* Unknown query parameters may be stripped  &lt;br /&gt;
* Only &amp;lt;code&amp;gt;mw_*&amp;lt;/code&amp;gt; parameters survive reliably  &lt;br /&gt;
&lt;br /&gt;
By combining these insights, we achieve a stable, silent, automatic purge mechanism for all dashboards.&lt;/div&gt;</summary>
		<author><name>Mngr</name></author>
	</entry>
</feed>