` * (see `renderShortcode` in `packages/core/src/render.js`). * * So "replace auto-increment IDs with slugs" does nothing for them: the scene's * `[aumframe_form id="20"]` is rewritten correctly while the copy in the baked output is still 20 — and * the front end renders a non-existent form as nothing, with no error and no warning, looking * exactly like "this page never had a form". * * This is the fourth instance of the same shape (the first three: image URLs, plain-text shortcodes, * routing rules). The conclusion is by now unambiguous: **any new capability that "points at other * content from within a layout" must answer, at the same time, what it looks like in the baked * output and who rewrites it when the site changes.** */ class Refs { /** * Decode each shortcode marker, hand it to `$fn` to rewrite, and encode it back. * * `$fn` receives the plain-text shortcode (`[aumframe_form id="20"]`) and returns the rewritten text. */ public static function map_markers(string $text, callable $fn): string { if (strpos($text, 'af:shortcode:') === false) { return $text; } return preg_replace_callback( '//', function ($m) use ($fn) { $code = base64_decode($m[1], true); if ($code === false) { return $m[0]; // Not valid base64: leave it exactly as it is } $new = (string) $fn($code); return $new === $code ? $m[0] : ''; }, $text ) ?? $text; } }