WordPress Settings API 指南:菜单页面

在本系列的第三部分,我们已经介绍了 WordPress API 提供的各种菜单功能,如果你一直跟着学习,那你应该知道我们已经使用 add_theme_page 函数为我们 的主题添加了一个设置页面。尽快介绍菜单和子菜单严格来说并不属于 Settings API 的内容,但是它在创建插件、主题或其他定制功能的时候经常用到。

本文将介绍一个新的WordPress仪表盘菜单,它将允许我们将主题的设置选项添加到“外观”选项以外的其他地方。

注:由于时间精力有限,本教程没办法翻译分享,希望朋友们可以加入我们,帮助我们进行翻译,有小酬谢,有意者请联系倡萌QQ 745722006(注明:教程翻译)。

以下为原文:http://code.tutsplus.com/tutorials/the-complete-guide-to-the-wordpress-settings-api-part-6-menu-pages–wp-25166

In Part 3 of this series, we surveyed the various menu functions that the WordPress API provides. If you’ve been following along, then you know that we’ve already setup a settings page for our theme by using theadd_theme_page function. Although introducing menus and submenus aren’t explicitly part of the Settings API, they play a role in building custom functionality, plugins, and/or themes.

In this article, we’re going to introduce a new menu to the WordPress dashboard that will make our theme options available elsewhere other than just under the “Appearance” options.

Before we get started: This article assumes that you’re familiar with the Settings API and theme options. If you’re a beginner or even intermediate WordPress developer, I highly recommend catching up on the rest of the series before diving into this post.

A Look at the API

Because we’ve already looked at each of the menu functions, we don’t need to rehash each of the functions that WordPress has available. Instead, we’ll take a look at the ones we’re going to use and then work through a practical example of how to use them in our own work.

Before we look at each function, let’s detail what we’re planning to accomplish in the next phase of this series:

  • Introduce a top-level menu for our theme options
  • Add a submenu item that will link to the “Display Options” tab
  • Add a submenu item that will link to the “Social Options” tab

Relatively simple, right? In order to do this, we’ll be taking advantage of the following two functions:

  • add_menu_page which is used for introducing top-level menu items
  • add_submenu_page which is used to introduce sub-menu items to top-level menus.

We’ll take a look at each function’s parameters and usage as we implement them in our theme.

Note that the remainder of this article builds on this version of the WordPress Settings Sandbox. If you’re following along with the repository, make sure you check it out.

The Top-Level Menu

The first thing that we want to do is introduce a top-level menu. This menu will appear directly below the “Settings” menu in the WordPress dashboard and will serve two purposes. The menu should:

  1. Expose the theme’s options to the WordPress dashboard
  2. Display a default options page for the theme options

The function takes the following seven arguments, the first five are required, the last two are not:

  1. page_title is the text that will be rendered in the browser’s title bar
  2. menu_title is the text that will be displayed for the menu item
  3. capability refers to the role that the user must have in order to access this menu
  4. menu_slug is a unique value that identifies this menu. It’s also how submenus register themselves with this menu.
  5. function_name that is called when the menu is clicked for displaying the options page.
  6. icon_url is the path to the icon that you want to display next to your menu item.
  7. position is where the menu should be added in relation to the other menus in the WordPress Dashboard.

In our work, we’ll be focused only on the first five parameters. I discuss menu positioning in the conclusion of this article.

To get started, we’re going to need to introduce a call to the add_menu_page function. According to the WordPress Codex, administration menus can be added using the admin_menu hook. Earlier in this series, we wrote a function that adds our theme options to the “Appearance” menu. Specifically, we wrotesandbox_example_theme_menu:

function sandbox_example_theme_menu() {
 
    add_theme_page(
        'Sandbox Theme',            // The title to be displayed in the browser window for this page.
        'Sandbox Theme',            // The text to be displayed for this menu item
        'manage_options',            // Which type of users can see this menu item
        'sandbox_theme_options',    // The unique ID - that is, the slug - for this menu item
        'sandbox_theme_display'     // The name of the function to call when rendering this menu's page
    );
 
} // end sandbox_example_theme_menu
add_action( 'admin_menu', 'sandbox_example_theme_menu' );

Note in the code above that this function was registered with the admin_menu hook, as well. You should always strive to keep your functions logically consistent. Since we already have a function that registers a menu, that is registered with the appropriate hook, and since we’re introducing similar functionality, we’ll be adding our new menu functions to this function.

Add the following call to add_menu_page directly under the call above:

add_menu_page(
    'Sandbox Theme',        // The value used to populate the browser's title bar when the menu page is active
    'Sandbox Theme',        // The text of the menu in the administrator's sidebar
    'manage_options',        // What roles are able to access the menu
    'sandbox_theme_menu',   // The ID used to bind submenu items to this menu 
    'sandbox_theme_display' // The callback function used to render this menu
);

As you can see, we’re registering a menu that will display “Sandbox Theme” in both the browser’s title bar and in the menu item. We’re exposing the menu only to administrators and we’ve given the menu the unique ID of “sandbox_theme_parent_menu“. We’ll be re-using this parameter in the next section.

There’s one important thing that we need to clarify: Notice that we’ve passed ‘sandbox_theme_display‘ as the function to be called when this menu item is clicked. Recall that in Part 3 we introduced this function (and we refined it in Part 5). Specifically, it is responsible for rendering our tabbed theme options page.

By passing this existing function name to the add_menu_page function, we’re taking advantage of code that we’ve already written and we’re rendering a default options page for the menu item.

At this point, we’re ready to begin adding submenus but before moving forward, make sure that your function looks exactly like this:

function sandbox_example_theme_menu() {
 
    add_theme_page(
        'Sandbox Theme',
        'Sandbox Theme',
        'manage_options', 
        'sandbox_theme_options',
        'sandbox_theme_display'
    );
 
    add_menu_page(
        'Sandbox Theme',
        'Sandbox Theme',
        'manage_options', 
        'sandbox_theme_menu',
        'sandbox_theme_display'
    );
 
} // end sandbox_example_theme_menu

Add the Submenus

Submenus are very similar to menus except that they “belong” to an existing menu. The API for registering submenus is relatively similar, too. The function accepts six arguments, the first five being required, the last one being optional:

  1. parent_slug refers to the unique ID of the parent menu item. In our case, “sandbox_theme_menu“.
  2. page_title is the text to be rendered in the browser’s toolbar when this submenu item is active
  3. menu_title is the text for this actual submenu item in the dashboard
  4. capability is the role that a user must have to access this menu item
  5. menu_slug is the unique ID for this particular menu item
  6. function_name that is called when the menu is clicked in order for displaying the options page

The function is straightforward. We have two menu items to introduce – one for “Display Options” and one for “Social Options.”

Display Options

First, let’s introduce a submenu item for display options. Add the following block of code directly under theadd_menu_page call that we defined above:

add_submenu_page(
    'sandbox_theme_menu',               // The ID of the top-level menu page to which this submenu item belongs
    'Display Options',                  // The value used to populate the browser's title bar when the menu page is active
    'Display Options',                  // The label of this submenu item displayed in the menu
    'manage_options',                    // What roles are able to access this submenu item
    'sandbox_theme_display_options',    // The ID used to represent this submenu item
    'sandbox_theme_display'             // The callback function used to render the options for this submenu item
);

Each of the above parameters should be clear with the exception of the function name that we passed as the final argument. Notice that it’s the same function name that we provided in the add_menu_page call. But this makes sense, right? After all, the “Display Options” is the default tab that is displayed when the theme options are selected so it would make sense that it should be rendered when the top-level menu is selected and when the “Display Options” menu item is selected.

At this point, there’s an important feature of WordPress to highlight: Note that once you’ve added your first submenu item, WordPress will actually render two submenu items to the top-level menu – one item that duplicates the function of the top-level menu and one item that corresponds to the submenu item that you just defined. I bring this up because, in my experience, I’ve seen developers get confused as to how (and why) this happens. The short of it is that WordPress is doing this – it’s nothing wrong with your code.

Social Options

Adding a menu item for the social options is almost exactly like adding a menu item for the display options. Of course, we just want to change the values for the title bar, menu item, and the page that is displayed whenever the menu is selected. First, let’s setup our call to the add_submenu_page function. It should look like this:

add_submenu_page(
    'sandbox_theme',
    'Social Options',
    'Social Options',
    'manage_options',
    'sandbox_theme_social_options',
    'sandbox_theme_display'
);

Save your code, refresh your dashboard, and you should see the “Social Options” menu item now available under the “Sandbox Theme” menu; however, notice that clicking on the new submenu item only renders the “Display Options.” Since we’ve passed the “sandbox_theme_display” as the function name, that’s what we should expect, right? So now we’re faced with a little bit of a challenge: How do we select the “Social Options” tab when clicking on the submenu item?

Refactoring Our Tab Functionality

There are a couple of different options that we have for binding the new submenu item to the proper tab on the theme options’ page:

  • We can define a new function that renders out the social options. This would require that we do some additional work in introducing a new function, setting up tabbing functionality so that we don’t break the experience of the existing page, and duplicating a little bit of code.
  • We can refactor the existing sandbox_theme_display function to accept an optional parameter and then use an anonymous function in the add_submenu_page call to pass a parameter to it.

Ultimately, either of these options are up to you; however, I’d rather refactor my existing function than duplicate code so that’s what I’ll be doing throughout the remainder of this article.

First, let’s begin refactoring our sandbox_theme_display function. Let’s have it accept an optional argument that will be used to indicate which tab we want to select. Locate the following signature in yourfunctions.php file:

function sandbox_theme_display() {
    /* Consolidated for this part of the article. */
} // end sandbox_theme_display

Update the signature so that it accepts a single argument and sets it to null when it’s not defined:

function sandbox_theme_display( $active_tab = null ) {
    /* Consolidated for this part of the article. */
} // end sandbox_theme_display

If you’re new to PHP, you can read about default arguments on this page.

Remember from the last article that our display function is actually looking for a query string value to be set. We still want to maintain that functionality, but we need to account for the fact that the parameter may be passed into the function, as well. To perform this refactoring, first locate the following line of code in the sandbox_theme_display function:

$active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'display_options';

Notice that this particular line of code is only concerned with the query string parameters. To account for the new optional parameter, we need to introduce logic that first checks if the query string parameter is checked, if not, it will check to see if the function’s argument is set to display the social options, and, if not, then it will default to the display options. Replace the line of code above with the following conditional:

if( isset( $_GET[ 'tab' ] ) ) {
    $active_tab = $_GET[ 'tab' ];
} else if( $active_tab == 'social_options' ) {
    $active_tab = 'social_options';
} else {
    $active_tab = 'display_options';
} // end if/else

The final version of the function should look like this:

function sandbox_theme_display( $active_tab = '' ) {
?>
    <!-- Create a header in the default WordPress 'wrap' container -->
    <div class="wrap">
 
        <div id="icon-themes" class="icon32"></div>
        <h2>Sandbox Theme Options</h2>
        <?php settings_errors(); ?>
 
        <?php if( isset( $_GET[ 'tab' ] ) ) {
            $active_tab = $_GET[ 'tab' ];
        } else if( $active_tab == 'social_options' ) {
            $active_tab = 'social_options';
        } else {
            $active_tab = 'display_options';
        } // end if/else ?>
 
        <h2 class="nav-tab-wrapper">
            <a href="?page=sandbox_theme_options&tab=display_options" class="nav-tab <?php echo $active_tab == 'display_options' ? 'nav-tab-active' : ''; ?>">Display Options</a>
            <a href="?page=sandbox_theme_options&tab=social_options" class="nav-tab <?php echo $active_tab == 'social_options' ? 'nav-tab-active' : ''; ?>">Social Options</a>
        </h2>
 
        <form method="post" action="options.php">
            <?php
 
                if( $active_tab == 'display_options' ) {
                    settings_fields( 'sandbox_theme_display_options' );
                    do_settings_sections( 'sandbox_theme_display_options' );
                } else {
                    settings_fields( 'sandbox_theme_social_options' );
                    do_settings_sections( 'sandbox_theme_social_options' );
                } // end if/else
 
                submit_button();
 
            ?>
        </form>
 
    </div><!-- /.wrap -->
<?php
} // end sandbox_theme_display

We’re not quite done yet. Though we’ve done the necessary work to display the social options if the proper parameter has been passed, we haven’t actually called the function using a parameter. To do this, we need to refactor the add_submenu_page function from above. Currently, the function call looks like this:

add_submenu_page(
    'sandbox_theme',
    'Social Options',
    'Social Options',
    'manage_options',
    'sandbox_theme_social_options',
    'sandbox_theme_display'
);

We need to update the final parameter so that it calls the display function and passes the proper value for rendering the social options. To do that, we’ll create an anonymous function:

add_submenu_page(
    'sandbox_theme_menu',
    'Social Options',
    'Social Options',
    'manage_options',
    'sandbox_theme_social_options',
    create_function( null, 'sandbox_theme_display( "social_options" );' )
);

If you’re new to PHP, be sure to read up on the create_function feature and anonymous functions. Though they are outside the scope of this article, they can be powerful (and useful!) when used in the proper context.

The final version of the sandbox_example_theme_menu function should be as follows:

function sandbox_example_theme_menu() {
 
    add_theme_page(
        'Sandbox Theme',                    // The title to be displayed in the browser window for this page.
        'Sandbox Theme',                    // The text to be displayed for this menu item
        'manage_options',                    // Which type of users can see this menu item
        'sandbox_theme_options',            // The unique ID - that is, the slug - for this menu item
        'sandbox_theme_display'             // The name of the function to call when rendering this menu's page
    );
 
    add_menu_page(
        'Sandbox Theme',                    // The value used to populate the browser's title bar when the menu page is active
        'Sandbox Theme',                    // The text of the menu in the administrator's sidebar
        'manage_options',                    // What roles are able to access the menu
        'sandbox_theme_menu',               // The ID used to bind submenu items to this menu 
        'sandbox_theme_display'             // The callback function used to render this menu
    );
 
    add_submenu_page(
        'sandbox_theme_menu',               // The ID of the top-level menu page to which this submenu item belongs
        'Display Options',                  // The value used to populate the browser's title bar when the menu page is active
        'Display Options',                  // The label of this submenu item displayed in the menu
        'manage_options',                   // What roles are able to access this submenu item
        'sandbox_theme_display_options',    // The ID used to represent this submenu item
        'sandbox_theme_display'             // The callback function used to render the options for this submenu item
    );
 
    add_submenu_page(
        'sandbox_theme_menu',
        'Social Options',
        'Social Options',
        'manage_options',
        'sandbox_theme_social_options',
        create_function( null, 'sandbox_theme_display( "social_options" );' )
    );
 
} // end sandbox_example_theme_menu
add_action( 'admin_menu', 'sandbox_example_theme_menu' );

Conclusion

At this point, our theme now has its own top-level menu item with each of the settings tabs accessible via submenu items. Though this is useful, I believe it’s important to note that there are some mixed opinions on introducing menus into the WordPress Dashboard. Although they can make your work more prominent and accessible, they may also interfere with existing WordPress menus or other third-party work especiallyif you attempt to place your menus somewhere using the position parameter. Though there is no absolute right or absolute wrong when it comes to introducing menus, think carefully about where you expose your menus. If an existing WordPress menu makes sense, register your work as a submenu.

In the next post, we’ll begin taking a look at the various input elements that we can use to introduce options into our WordPress theme as well as how to validate and sanitize the data before serializing them.

Related Sources

来源:

https://www.wpdaxue.com/the-wordpress-settings-api-menu-pages.html

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?