0 ? (string) $ref : '' ); // Pop after tagging; inner items have all rendered by now. if (!empty(self::$navStack)) { array_pop(self::$navStack); } return $html; } if ($name === 'core/navigation-link' || $name === 'core/navigation-submenu') { if (empty(self::$navStack)) { return $html; } $top = count(self::$navStack) - 1; $idx = self::$navStack[$top]['counter']; self::$navStack[$top]['counter']++; $html = self::tagFirstElement($html, self::ATTR_ITEM_INDEX, (string) $idx); return $html; } return $html; } // Push the frame BEFORE the navigation's render_callback runs so // inner items can find it on render_block. public static function onPreRenderBlock($pre, array $parsed_block) { if (($parsed_block['blockName'] ?? '') !== 'core/navigation') { return $pre; } $ref = (int) ($parsed_block['attrs']['ref'] ?? 0); self::$navStack[] = [ 'ref' => $ref, 'counter' => 0, ]; return $pre; // never short-circuit } private static function tagFirstElement(string $html, string $attr, string $value): string { if ($value === '') { return $html; } $tp = new \WP_HTML_Tag_Processor($html); if ($tp->next_tag()) { if ($tp->get_attribute($attr) !== null) { return $html; } $tp->set_attribute($attr, $value); return $tp->get_updated_html(); } return $html; } }