['my_type'], 'args' => [ … ]]; * return $d; * }); * * Priority 9 on `init` is not arbitrary. That is where the theme registered these before, and it * leaves room for `register_taxonomy_for_object_type()` afterwards — which is how a kit's own post type * attaches itself to a taxonomy an engine plugin registered at priority 0. Registering later would move * our types after code that expects them to exist, and the failure is silent: a taxonomy simply is not * attached, so its terms never appear on the type. * * This does not take over `register_post_meta`. Meta registration is not forbidden in a theme and * it is bound to the fields a definition owns, so it stays with whoever owns the definition. */ final class ContentTypes { public static function boot(): void { add_action('init', [self::class, 'register'], 9); } public static function register(): void { /** * Post types and taxonomies to register on this site. * * @param array{post_types: array, taxonomies: array} $decl */ $decl = apply_filters('aumframe/register_types', ['post_types' => [], 'taxonomies' => []]); foreach ((array) ($decl['post_types'] ?? []) as $name => $args) { if (!is_string($name) || $name === '' || !is_array($args)) { continue; } /* * Never displace an existing registration. Another plugin may own this name — overwriting it is * at best a no-op and at worst replaces their type with ours, which loses their admin UI and * their rewrite rules while leaving their content in place. */ if (post_type_exists($name)) { continue; } register_post_type($name, $args); } foreach ((array) ($decl['taxonomies'] ?? []) as $name => $spec) { if (!is_string($name) || $name === '' || !is_array($spec)) { continue; } if (taxonomy_exists($name)) { continue; } $objects = (array) ($spec['objects'] ?? []); $args = (array) ($spec['args'] ?? []); if (!$objects) { continue; } register_taxonomy($name, $objects, $args); } } }