• I’ve been trying to get my screen options meta box to work but I’ve had no luck so far. Here’s what I’m doing in sequence of initialization of the table object (using WP boiler plate, of plugin-name.php -> class-plugin-name.php -> class-plugin-name-admin.php-> class-plugin-name-manage-table.php)

    Inside of class-plugin-name-admin:

       $hook = add_menu_page(
                    'Plugin Manage',
                    'Plugin Manage', 
                    'manage_options', 
                    'plugin_manage_options', 
                    array($this, 'render_page_content'), 
                    'dashicons-money-alt'
            );
    
            $this->hook = $hook;
    
            $this->MT = new Plugin_Manage_Table($this->plugin_name, $this->plugin_version, $this->hook);
            $this->MT->prepare_items(); // try to configure $columns?
            add_action('load-' . $hook, array($this->MT, 'load_user_table_screen_options'));

    Then in Plugin_Manage_Table

        public function __construct($plugin_name, $version, $hook) {
            $this->plugin_name = $plugin_name;
            $this->version = $version;
            $this->search = '';
            $this->hook = $hook; // menu hook
            
            parent::__construct(
                    array(
                        'singular' => 'item',
                        'plural' => 'items',
                        'ajax' => false
                    )
            );
        }
    
    public function load_user_table_screen_options() {
            $arguments = array(
                'label' => __('Items', 'plugin_manage_options'),
                'default' => 30,
                'option' => 'items_per_page'
            );
            add_screen_option('_per_page', $arguments);
        }

    However the screen option box shows columns from a different wp_table_list object. When I check global $wp_metabox it’s empty, but the get_current_screen appears correct for the object. This is right after calling add_screen_options

    WP_Screen Object
    (
    [action] =>
    [base] => toplevel_page_plugin_manage_options
    [columns:WP_Screen:private] => 0
    [id] => toplevel_page_plugin_manage_options
    [in_admin:protected] => site
    [is_network] =>
    [is_user] =>
    [parent_base] =>
    [parent_file] =>
    [post_type] =>
    [taxonomy] =>
    [_help_tabs:WP_Screen:private] => Array
    (
    )
    
    [_help_sidebar:WP_Screen:private] =>
    [_screen_reader_content:WP_Screen:private] => Array
    (
    )
    
    [_options:WP_Screen:private] => Array
    (
    [_per_page] => Array
    (
    [label] => Items
    [default] => 30
    [option] => items_per_page
    )
    
    )
    
    [_show_screen_options:WP_Screen:private] =>
    [_screen_settings:WP_Screen:private] =>
    [is_block_editor] =>
    )

    I should also mention that my plugin generates this warning which I’ve been unable to figure out how to fix:

    PHP Notice: Undefined index: hook_suffix in /WP/wp-admin/includes/class-wp-screen.php on line 223, referer: https://localhost/wp-admin/admin.php?page=plugin_manage_options

    • This topic was modified 3 years, 6 months ago by EricB50. Reason: additional info
    • This topic was modified 3 years, 6 months ago by EricB50.
Viewing 3 replies - 1 through 3 (of 3 total)
  • Moderator bcworkz

    (@bcworkz)

    I cannot be sure from the provided information, but I think there’s an issue with the order of actions firing. I assume you add your menu page as a callback to “admin_menu”. You also add a callback to “load-{$page_hook}” from within the admin_menu callback. This can be problematic if you are not sure of the order that things happen in.

    Try moving the add_action() call for “load-{$page_hook}” to something that executes earlier. Maybe your class constructor, or even part of the initial plugin code. This may resolve the mysterious PHP notice as well.

    Thread Starter EricB50

    (@ericb50)

    I’ve tried to move a few things around but I don’t know exactly what WP is doing. I’ll try to sum it up based on how the WP boilerplate starts up and how I tried to append new code for the wp_list_table object.

    Here’s the sequence:

    plugin.php -> Setup up instance of class-plugin-manage

    class plugin-manage:

    
            $this->load_dependencies();  // has all require_once
            $this->set_locale(); // i18n object
            $this->define_admin_hooks(); // sets up admin side
            $this->define_public_hooks(); // sets up public side

    The hooks for admin are setup like this using the loader object:

    private function define_admin_hooks() {
            $plugin_admin = new Plugin_Name_Manage_Admin($this->get_plugin_name(), $this->get_version(), $this->get_loader());
            $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_styles');
            $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts');
            $this->loader->add_action('admin_menu', $plugin_admin, 'setup_plugin_menus');
        }

    So based on your input I tried to pass an instance of the loader method to the Manage_Admin too. When Manage_Admin constructs it only stores those passed parameters locally in the object. Then when Manage_Admin::setup_plugin_menus runs it does this using the passed loader reference:

           global $hook_suffix;
    
            $hook = add_menu_page(
                    'Plugin Manage', 
                    'Plugin Manage', 
                    'manage_options', 
                    'plugin_manage_options', 
                    array($this, 'render_page_content'), 
                    'dashicons-money-alt'
            );
    
            $this->hook = $hook;
            if (!isset($hook_suffix)) {
                $hook_suffix = $hook;
            }
            $this->MT = new Plugin_Manage_Table($this->plugin_name, $this->plugin_version);
            $this->loader->add_action('load-' .$hook, $this->MT, 'load_user_table_screen_options');

    (note when I try to move the last two lines into that objects constructor and put a fixed string in for ‘load-screen-option’ instead of appending $hook I get this error:

    Fatal error: Uncaught Error: Call to undefined function convert_to_screen()

    There is definitely something haunting me with how the wp_list_table is getting setup but I’m unable to figure out a way to debug it as it seems the WP_Screen object is somewhat confused. There seems to be no change in how the screen_options not finding the correct table object.

    • This reply was modified 3 years, 6 months ago by EricB50.
    Thread Starter EricB50

    (@ericb50)

    Ok I think I figured it out. I changed the sequence to:

    admin hooks setup (admin_menu)

    $this->loader->add_action( 'admin_menu', $plugin_admin, 'add_plugin_admin_menu' );

    then in add_plugin_admin_menu I added the screen option method in that object but not using the loader:

    add_action('load-' . $page_hook, array($this, 'load_user_list_table_screen_options'));

    Then when the load is triggered it initializes the table object and screen options

    public function load_user_table_screen_options() {
            $arguments = array(
                'label' => __('Items', 'plugin_manage_options'),
                'default' => 30,
                'option' => 'items_per_page'
            );
            add_screen_option('per_page', $arguments);
    
            // instantiate the Table
            $this->MT = new Plugin_Manage_Table($this->plugin_name, $this->plugin_version);       
        }

    It’s still not totally clear to me what the difference is, but it is working.

    Edit: of course applying the options isn’t working…. It appears there’s no user meta data being created.

    • This reply was modified 3 years, 6 months ago by EricB50.
    • This reply was modified 3 years, 6 months ago by EricB50.
Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘Screen Options with wp_list_table not picking up correct columns’ is closed to new replies.