0

I used the generator by Jeremy Hixon to create an options page but this page is only accessible to the admin user. I would like to make this available to the editor.

I have looked to add_role but I am not sure how to implement this. Any suggestions are very much appreciated!

 * Generated by the WordPress Option Page generator
 * at http://jeremyhixon.com/wp-tools/option-page/
 */

class Example {
    private $example_options;

    public function __construct() {
        add_action( 'admin_menu', array( $this, 'example_add_plugin_page' ) );
        add_action( 'admin_init', array( $this, 'example_page_init' ) );
    }

    public function example_add_plugin_page() {
        add_menu_page(
            'Example', // page_title
            'Example', // menu_title
            'manage_options', // capability
            'example', // menu_slug
            array( $this, 'example_create_admin_page' ), // function
            'dashicons-admin-generic', // icon_url
            2 // position
        );
    }

    public function example_create_admin_page() {
        $this->example_options = get_option( 'example_option_name' ); ?>

        <div class="wrap">
            <h2>Example</h2>
            <p>some description</p>
            <?php settings_errors(); ?>

            <form method="post" action="options.php">
                <?php
                    settings_fields( 'example_option_group' );
                    do_settings_sections( 'example-admin' );
                    submit_button();
                ?>
            </form>
        </div>
    <?php }

    public function example_page_init() {
        register_setting(
            'example_option_group', // option_group
            'example_option_name', // option_name
            array( $this, 'example_sanitize' ) // sanitize_callback
        );

        add_settings_section(
            'example_setting_section', // id
            'Settings', // title
            array( $this, 'example_section_info' ), // callback
            'example-admin' // page
        );

        add_settings_field(
            'text_label_0', // id
            'text-label', // title
            array( $this, 'text_label_0_callback' ), // callback
            'example-admin', // page
            'example_setting_section' // section
        );
    }

    public function example_sanitize($input) {
        $sanitary_values = array();
        if ( isset( $input['text_label_0'] ) ) {
            $sanitary_values['text_label_0'] = sanitize_text_field( $input['text_label_0'] );
        }

        return $sanitary_values;
    }

    public function example_section_info() {
        
    }

    public function text_label_0_callback() {
        printf(
            '<input class="regular-text" type="text" name="example_option_name[text_label_0]" id="text_label_0" value="%s">',
            isset( $this->example_options['text_label_0'] ) ? esc_attr( $this->example_options['text_label_0']) : ''
        );
    }

}
if ( is_admin() )
    $example = new Example();

/* 
 * Retrieve this value with:
 * $example_options = get_option( 'example_option_name' ); // Array of All Options
 * $text_label_0 = $example_options['text_label_0']; // text-label
 */

1 Answer 1

2

If you look at the documentation for add_menu_page(), you'll see the third argument is:

The capability required for this menu to be displayed to the user.

In WordPress you don't require specific roles for permissions, you require a capability, and roles are collections of capabilities. Your menu page requires manage_options, which is only held by administrators by default. If you want to also allow access to Editors, then edit_pages is a capability only held by Administrators and Editors.

add_menu_page(
    'Example', // page_title
    'Example', // menu_title
    'edit_pages', // capability
    'example', // menu_slug
    array( $this, 'example_create_admin_page' ), // function
    'dashicons-admin-generic', // icon_url
    2 // position
);

Now the admin menu item will appears for any user with a role that has the edit_pages capability, which by default is just Administrators and Editors.

You will run into another issue though. Your admin page contains settings fields created with the Settings API. By default, regardless of the capability used to add the admin menu item, manage_options is required to submit settings forms.

To get around this, you need to use the option_page_capability_{$option_page} filter. With this filter you can change the required capability to submit your settings page. You just need to replace {$option_page} with the value that you passed to settings_fields() (which is, very frustratingly, the option group, not the option page).

add_filter(
    'option_page_capability_example_option_group',
    function() {
        return 'edit_pages';
    }
);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.