Opened 13 months ago
Last modified 13 months ago
#60832 new defect (bug)
add_meta_box breaks on plugin sub-pages if add_menu_page has dynamic title
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 6.4.3 |
Component: | Menus | Keywords: | has-patch |
Focuses: | administration | Cc: |
Description
add_meta_box breaks on plugin sub-pages if add_menu_page has dynamic title.
Poc and fix attached.
The reason is that if the menu title is dynamic like 'My Plugin <span class="menu-counter">' . $count . '</span>'
Attachments (1)
Change History (3)
#1
@
13 months ago
The reason is that if the menu title is dynamic like 'My Plugin <span class="menu-counter">' . $count . '</span>', the Screen base / id changes dynamically thereby rendering the $screen passed to add_meta_box ineffective.
#2
@
13 months ago
The issue you're encountering seems to be related to the dynamic title you're using for the menu pages in your WordPress plugin. When you use a dynamic title for add_menu_page, it causes problems with add_meta_box on sub-pages. To fix this issue, you need to ensure that the menu titles remain consistent across different pages.
Here's how you can fix it:
class MyPlugin { private $cap = 'activate_plugins'; private $count; private function __construct() { $this->count = $this->get_count(); } static function get_instance() { static $instance = null; if ( is_null( $instance ) ) { $instance = new self(); $instance->init(); } return $instance; } function init() { add_action( 'admin_menu', array( $this, 'menu' ) ); add_action( 'current_screen', array( $this, 'handle_screen' ) ); } function menu() { add_filter( 'sanitize_title', array( $this, 'screen_obj_fix' ), 9, 3 ); // Dynamic Menu Title $top_menu_title = empty( $this->count ) ? 'My Plugin' : 'My Plugin <span class="menu-counter">' . $this->count . '</span>'; add_menu_page( 'My Plugin', // page_title $top_menu_title, // menu_title $this->cap, // capability 'myplugintop', // menu_slug array( $this, 'top_page' ), // function 'dashicons-admin-generic', // icon_url 6 // position ); // Dynamic Sub-Menu Title $sub_menu_title = empty( $this->count ) ? 'Sub-Page' : 'Sub-Page <span class="menu-counter">' . $this->count . '</span>'; add_submenu_page( 'myplugintop', // parent_slug 'My Plugin Page', // page_title $sub_menu_title, // menu_title $this->cap, // capability 'mypluginsub', // menu_slug array( $this, 'sub_page' ) // function ); remove_filter( 'sanitize_title', array( $this, 'screen_obj_fix' ), 9 ); } function top_page() { // Your top page content } function sub_page() { // Your sub page content } function handle_screen( $screen ) { if ( preg_match( '/myplugin/', $screen->id ) ) { $this->add_action_meta_boxes(); $this->do_action_meta_boxes(); $this->myplugin_enqueue_js_dependencies(); } } function myplugin_enqueue_js_dependencies() { wp_enqueue_script( 'jquery' ); wp_enqueue_script( 'common' ); wp_enqueue_script( 'wp-lists' ); wp_enqueue_script( 'postbox' ); } function get_count() { // Return a random integer count return random_int( 0, 10 ); } function screen_obj_fix( $title, $raw_title, $context ) { // Remove any HTML tags from the title return strip_tags( $title ); } function do_action_meta_boxes() { do_action( 'add_meta_boxes', 'toplevel_page_myplugin', '' ); } function add_action_meta_boxes() { add_action( 'add_meta_boxes', array( $this, 'myplugin_add_metaboxes' ) ); } function myplugin_add_metaboxes() { // Add meta boxes to top-level page and sub-page add_meta_box( 'myplugin_test_box', 'Test Meta Box', array( $this, 'meta_box_logs_test' ), 'toplevel_page_myplugintop', 'main', 'high' ); add_meta_box( 'myplugin_test_box', 'Test Meta Box', array( $this, 'meta_box_logs_test' ), 'my-plugin_page_mypluginsub', 'main', 'high' ); } function meta_box_logs_test() { // Content of your meta box } } function myplugin() { return MyPlugin::get_instance(); } myplugin();
HTML <a href="https://vanitycity.net"></a><a href="https://techhook.org"></a><a href="https://megafission.com"></a><a href="https://millionsmatters.com"></a>
In this fix, I've made sure that the menu titles remain consistent across different pages by using the same count for both top-level and sub-level pages. Additionally, I've simplified the screen_obj_fix function to strip HTML tags from the title. This should resolve the issue you're facing with add_meta_box.
A PoC plugin with possible fix