As suggested by LWS-Mo this can work by using register_taxonomy_for_object_type()
to register my custom post type for all taxonomies in the system and then use remove_meta_box()
and add_meta_box
to re-add them to the new location. I’m not sure if I really use the correct hooks – but hey, it works 🙂
One thing to mention is that all taxonomies appear under my post type as submenus so I had also to remove the submenu entries.
First add the hooks:
add_action('init', [$this, 'create_taxonomy_related_post_type__premium_only']);
add_action('wp_loaded', [$this, 'add_meta_boxes_rfe_taxonomy_related__premium_only']);
add_action('admin_init', [$this, 'rename_taxonomy_meta_boxes_on_rfe_taxonomy_related__premium_only']);
add_action('admin_menu', [$this, 'remove_taxonomy_menu_from_rfe_taxonomy_related__premium_only']);
Then add the custom post type with its own taxonomy:
public function create_taxonomy_related_post_type__premium_only()
{
register_post_type('rfe_taxonomy_related',
array(
'labels' => array(
'name' => 'Taxonomy Related',
'singular_name' => 'Taxonomy Related',
'add_new' => 'Add New',
'add_new_item' => 'Add New Layout',
'edit' => 'Edit',
'edit_item' => 'Edit Layout',
'new_item' => 'New Layout',
'view' => 'View',
'view_item' => 'View Layout',
'search_items' => 'Search Layouts',
'not_found' => 'No Layouts found',
'not_found_in_trash' => 'No Layouts found in Trash',
),
'public' => true,
'exclude_from_search' => true,
'publicly_queryable' => false,
'supports' => array('title', 'editor'),
'taxonomies' => array('rfe_taxonomy_related_category'),
'menu_icon' => 'dashicons-format-aside',
'has_archive' => false,
)
);
register_taxonomy(
'rfe_taxonomy_related_category',
array('rfe_taxonomy_related'),
array(
'hierarchical' => true,
'labels' => array(
'name' => __('Categories', 'jt-revolution-for-elementor'),
'singular_name' => __('Category', 'jt-revolution-for-elementor'),
'search_items' => __('Search Category', 'jt-revolution-for-elementor'),
'all_items' => __('All Categories', 'jt-revolution-for-elementor'),
'parent_item' => __('Parent Category', 'jt-revolution-for-elementor'),
'parent_item_colon' => __('Parent Category:', 'jt-revolution-for-elementor'),
'edit_item' => __('Edit Category', 'jt-revolution-for-elementor'),
'update_item' => __('Update Category', 'jt-revolution-for-elementor'),
'add_new_item' => __('Add New Category', 'jt-revolution-for-elementor'),
'new_item_name' => __('New Category Name', 'jt-revolution-for-elementor'),
'menu_name' => __('Categories', 'jt-revolution-for-elementor'),
),
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
)
);
}
Next use register_taxonomy_for_object_type
to add each taxonomy in the system to my post type:
public function add_meta_boxes_rfe_taxonomy_related__premium_only($post)
{
$args = array('public' => true);
$output="objects";
$taxonomies = get_taxonomies($args, $output);
foreach ($taxonomies as $taxonomy) {
if ('rfe_taxonomy_related_category' === $taxonomy->name) {
continue;
}
register_taxonomy_for_object_type($taxonomy->name, 'rfe_taxonomy_related');
}
}
Now I can move the meta boxes below the content using remove_meta_box
and add_meta_box
:
public function rename_taxonomy_meta_boxes_on_rfe_taxonomy_related__premium_only()
{
//Stores display names of post types so we can cache them
$post_type_names = [];
$taxonomies = get_taxonomies(['public' => true], 'objects');
foreach ($taxonomies as $taxonomy) {
//Skip our own taxonomy
if ('rfe_taxonomy_related_category' === $taxonomy->name) {
continue;
}
$taxonomy_name = $taxonomy->labels->name;
$taxonomy_slug = $taxonomy->name;
$taxonomy_post_types = [];
$object_type = $taxonomy->object_type;
foreach ($object_type as $post_type) {
//Skip our own post type
if ('rfe_taxonomy_related' === $post_type) {
continue;
}
$post_type_name = isset($post_type_names[$post_type]) ? $post_type_names[$post_type] : false;
if (!$post_type_name) {
$post_type_name = get_post_type_object($post_type)->label;
$post_type_names[$post_type] = $post_type_name;
}
$taxonomy_post_types[] = $post_type_name;
}
if ($taxonomy->hierarchical) {
$meta_box_id = $taxonomy_slug . 'div';
$meta_box_callback = 'post_categories_meta_box';
} else {
$meta_box_id = 'tagsdiv-' . $taxonomy_slug;
$meta_box_callback = 'post_tags_meta_box';
}
remove_meta_box($meta_box_id, 'rfe_taxonomy_related', 'side');
add_meta_box(
$meta_box_id,
$taxonomy_name . ' (' . implode(', ', $taxonomy_post_types) . ')',
$meta_box_callback,
'rfe_taxonomy_related',
'normal',
'low',
['taxonomy' => $taxonomy_slug]
);
}
}
And finally hide the submenu pages for the taxonomies except for the custom one I added to my post type myself:
public function remove_taxonomy_menu_from_rfe_taxonomy_related__premium_only()
{
global $submenu;
//Get all the taxonomies of which we need to remove the submenu
$taxonomies = [];
foreach (get_taxonomies(['public' => true], 'objects') as $taxonomy) {
if ('rfe_taxonomy_related_category' === $taxonomy->name) {
continue;
}
$taxonomies[] = $taxonomy->name;
}
$post_type="rfe_taxonomy_related";
if (isset($submenu['edit.php?post_type=" . $post_type])) {
foreach ($submenu["edit.php?post_type=" . $post_type] as $k => $sub) {
$should_remove = false;
foreach ($taxonomies as $taxonomy) {
if (strpos($sub[2], "taxonomy=' . $taxonomy)) {
$should_remove = true;
break;
}
}
if ($should_remove) {
unset($submenu['edit.php?post_type=" . $post_type][$k]);
}
}
}
}
If you have suggestions to improve the code, I”d love to hear about them!