向 WordPress 菜单项添加字段——插件的设置页面
已发表: 2021-07-08在使用任何 WordPress 插件时,您可能已经注意到作者提供了一些可用于自定义插件功能的设置。 从技术上讲,作者创建了一个菜单项和一个设置页面,该菜单项将您重定向到该页面。 在本文中,您将完成您必须遵循的步骤,以便为您自己的插件做同样的事情。
本文要求您已经应用了向 WordPress 菜单项添加字段 - 自定义插件一文中示例中提供的代码。 我们将从那里继续,看看我们如何通过在管理区域中添加其设置页面来使我们的插件更加用户友好,以便您允许管理员用户设置他们对插件操作方式的偏好。
初始步骤
出于本文的目的,我们将创建一个漂亮的简单设置菜单。 正如我们在上一篇文章中看到的,通过使用我们的插件,管理员用户可以为任何菜单项添加字幕。 在接下来的步骤中,我们将提供一个选项,以便用户可以选择包含字幕字段的 HTML 元素的类型。
此时,我们的插件主 PHP 文件如下所示:
<?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */ class MyCP_Menu_Item_Field_Creator { public function __construct() { add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'menu_item_sub' ), 10, 2 ); add_action( 'wp_update_nav_menu_item', array( $this, 'save_menu_item_sub' ), 10, 2 ); add_filter( 'wp_nav_menu_args', array( $this, 'menu_item_sub_custom_walker' ) ); } public function menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php } public function save_menu_item_sub( $menu_id, $menu_item_db_id ) { if ( isset( $_POST['menu_item_sub'][ $menu_item_db_id ] ) ) { $sanitized_data = sanitize_text_field( $_POST['menu_item_sub'][ $menu_item_db_id ] ); update_post_meta( $menu_item_db_id, '_menu_item_sub', $sanitized_data ); } else { delete_post_meta( $menu_item_db_id, '_menu_item_sub' ); } } public function menu_item_sub_custom_walker( $args ) { if ( class_exists( 'My_Custom_Nav_Walker' ) ) { $args['walker'] = new My_Custom_Nav_Walker(); } else { echo 'DOES NOT EXIST'; } return $args; } } $mycp_menu_item_field_creator = new MyCP_Menu_Item_Field_Creator(); if ( ! class_exists( 'My_Custom_Nav_Walker' ) ) { class My_Custom_Nav_Walker extends Walker_Nav_Menu { public function start_el( &$output, $item, $depth=0, $args=[], $id=0 ) { $menu_item_sub = get_post_meta( $item->ID, '_menu_item_sub', true ); $output .= '<li class="' . implode( ' ', $item->classes ) . '">'; if ( $item->url && $item->url != '#' ) { $output .= '<a href="' . $item->url . '">'; } else { $output .= '<span>'; } $output .= $item->title; if ( $item->url && $item->url != '#' ) { $output .= '</a>'; } else { $output .= '</span>'; } if ( ! empty( $menu_item_sub ) ) { $output .= '<div class="menu-item-sub">' . $menu_item_sub . '</div>'; } } } }
接下来我们将继续并为我们插件的设置页面创建一个菜单项,以及一个简单的示例,说明您可以在设置页面中包含的内容作为内容。
我们将需要使用两个 WordPress 钩子。 用于注册管理菜单项的admin_menu
钩子和用于注册插件选项的admin_init
钩子,稍后我们将添加插件设置页面及其表单。 当然,我们也会充分利用 WordPress 提供的 API,并使用一些内置功能。 让我们更深入地了解。
创建选项页面菜单项
为了添加菜单项,我们将在当前添加的钩子下的__construct()
方法内添加相应的admin_menu
钩子。
class MyCP_Menu_Item_Field_Creator { public function __construct() { add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'menu_item_sub' ), 10, 2 ); add_action( 'wp_update_nav_menu_item', array( $this, 'save_menu_item_sub' ), 10, 2 ); add_filter( 'wp_nav_menu_args', array( $this, 'menu_item_sub_custom_walker' ) ); add_action( 'admin_menu', array( $this, 'plugin_settings_menu_page' ) ); } . . .
我们使用了admin_menu
钩子并定义了plugin_settings_menu_page()
方法(我们将在下面描述)来指定菜单项和插件设置页面的信息。
public function plugin_settings_menu_page() { add_menu_page( __( 'Page Title Attribute Text', 'oop-menu-item-sub' ), __( 'Menu Item Field Creator', 'oop-menu-item-sub' ), 'manage_options', 'menu-item-field-creator', array( $this, 'plugin_settings_page_content' ) ); }
该方法也应该放在主插件类中。 请注意,在我们的plugin_settings_menu_page()
方法中,我们使用了 WordPress 提供的add_menu_page()
函数。 此函数接受以下参数:
add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position )
-
$page_title
是需要定义的,它基本上是您在选择此菜单项时被重定向到的页面的标题标签的第一部分。 -
$menu_title
- 也是必需的 - 是用于菜单的文本。 -
$capability
是用户显示此菜单所需的能力。 在我们的例子中,我们选择了manage_options
权限,因为它只提供给超级用户和管理员。 如果您想了解哪个角色或能力适合您的需求,可以查阅相关的官方文档。 -
$menu_slug
也是必需的,并且应该是唯一的。 它是引用此菜单的 slug 名称。 不要忘记您只能使用与sanitize_key()
兼容的小写字母数字、破折号和下划线字符。 -
$icon_url
是一个可选参数,是链接到将用于菜单项的图标文件的 URL。 -
$function
参数是您定义将创建设置页面内容的回调函数的地方。 在我们的例子中,它是
,它还没有任何功能。 我们使用plugin_settings_page_content()
plugin_settings_menu_page()
方法将它添加到我们的代码中。
public function plugin_settings_page_content() { $html = "<p>Test content for our custom plugin</p>"; echo $html; }
此时,您应该会看到“Menu Item Field Creator”菜单项和内容页面测试内容,并识别出您在参数中定义的菜单 URL。

我们还想指出,如果您希望将插件选项包含在内置设置菜单下,而不是作为单独的顶级菜单项,您可以使用add_options_page()
函数轻松实现。 在这种情况下,您应该替换它:
public function plugin_settings_menu_page() { add_menu_page( __( 'Page Title Attribute Text', 'oop-menu-item-sub' ), __( 'Menu Item Field Creator', 'oop-menu-item-sub' ), 'manage_options', 'menu-item-field-creator', array( $this, 'plugin_settings_page_content' ) ); }
有了这个:
public function plugin_settings_menu_page() { add_options_page( __( 'Page Title Attribute Text', 'oop-menu-item-sub' ), __( 'Menu Item Field Creator', 'oop-menu-item-sub' ), 'manage_options', 'menu-item-field-creator', array( $this, 'plugin_settings_page_content' ) ); }
这将导致此处的菜单位置:

在我们的下一节中,我们将在设置页面中放置一些简单的内容,管理员用户可以使用这些内容来设置插件的行为。
向我们的设置页面添加功能
到目前为止,我们所做的是添加我们的菜单项并定义将显示设置内容页面的功能。 如果我们想要设置页面中的功能,我们将必须注册一些字段,然后在插件的设置页面中显示它们。 例如,我们将创建一个表单,用户可以在其中定义 HTML 元素的类型来包装字幕字段。

输出
将plugin_settings_page_content
代码替换为:
public function plugin_settings_page_content() { ?> <form action="options.php" method="post"> <?php do_settings_sections( 'options_page' ); settings_fields( 'option_group' ); submit_button( __( 'Save Subtitle', 'oop-menu-item-sub' ) ); ?> </form> <?php }
在这些行中,我们使用do_settings_sections()
和settings_fields()
函数。 do_settings_sections()
将打印所有注册的设置部分和字段。 Τhe settings_fields()
将输出设置页面的 nonce、action 和option_page
隐藏输入字段。
现在让我们继续并注册我们的设置。
注册您的设置
要注册所需的字段,我们将使用admin_init
挂钩,因为它会在初始化管理屏幕时触发。
class MyCP_Menu_Item_Field_Creator { public function __construct() { add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'menu_item_sub' ), 10, 2 ); add_action( 'wp_update_nav_menu_item', array( $this, 'save_menu_item_sub' ), 10, 2 ); add_filter( 'wp_nav_menu_args', array( $this, 'menu_item_sub_custom_walker' ) ); add_action( 'admin_menu', array( $this, 'plugin_settings_menu_page' ) ); add_action( 'admin_init', array( $this, 'plugin_register_settings' ) ); } . . .
我们将在我们的类中插入plugin_register_settings()
方法,如下所示:
public function plugin_register_settings() { register_setting( 'option_group', 'option_name' ); add_settings_section( 'section_id', __( 'Settings Page Title', 'oop-menu-item-sub' ), array( $this, 'render_section' ), 'options_page' ); add_settings_field( 'html_element', __( 'Choose HTML Element:', 'oop-menu-item-sub' ), array( $this, 'render_field' ), 'options_page', 'section_id' ); }
现在让我们退后一步,再看看到目前为止我们所做的工作。
- 要注册设置及其数据,我们使用了
register_setting
() 函数,根据文档,该函数的结构如下:
register_setting( $option_group, $option_name, $args )
-
$option_group
是必需参数,应与settings_fields()
中使用的组名匹配。 -
$option_name
也是必需的,它是要清理和保存的选项的名称。 它是选项数据库表中option_name
列下的值。 - 这里不需要
$args
。 它是一个可选的数据数组,用于描述注册时的设置。 您可以在此处指定其类型、描述、用于选项值的sanitize_callback()
函数、定义当前数据是否应包含在 REST API 中的“show_in_rest
”选项以及可以定义默认值的默认选项调用get_option()
时。 - 我们还介绍了
add_settings_section()
和add_settings_field()
函数,它们将帮助我们完成这一步。 -
add_settings_section()
函数用于向 WordPress 注册具有特定 slug 名称的部分。 在这里,$id
是标识部分的 slug 名称,用于标签的 'id' 属性。
add_settings_section( $id, $title, $callback, $page )
-
$title
是节的格式化标题,将显示为节的标题,$callback
是在节顶部回显内容的函数,$page
是应该显示的页面的 slug-name匹配do_settings_sections()
的$page
参数,在我们的例子中是“options_page”。
以上所有参数都是必需的。
- WordPress 提供的
add_settings_field
() 函数允许您向部分添加新字段。
add_settings_field( $id, $title, $callback, $page, $section, $args )
-
$id
、$title
、$callback
和$page
如前所述使用。$section
是设置页面中显示框的部分的 slug 名称,在输出字段时使用$args
。$section
和$args
都是可选的。
出于本文的目的,我们不会引入额外的函数来清理我们的值。 但是,我们会注意到,强烈建议您始终清理表单字段。
现在我们有两个需要引入的公共方法, render_section()
和render_field()
。
对于render_section()
方法,我们将只为我们的部分输出一个标题:
public function render_section() { ?> <h2><?php _e( 'Section #1', 'oop-menu-item-sub' ); ?></h2> <?php }
对于render_field()
方法,我们将输出 3 个单选按钮,其中包含我们对 HTML 元素的选择:
public function render_field() { $stored_option = get_option( 'option_name' )['html_element']; ?> <input type="radio" name="option_name[html_element]" value="div" <?php checked( $stored_option, 'div' ); ?> /> div <input type="radio" name="option_name[html_element]" value="p" <?php checked( $stored_option, 'p' ); ?> /> p <input type="radio" name="option_name[html_element]" value="span" <?php checked( $stored_option, 'span' ); ?> /> span <?php }
这应该是您现在看到的结果:

如果您选择另一个元素,例如 span 并保存,它也应该可以正常工作。
在您的网站上反映选项页面更改
剩下要解释的最后一步是如何将管理员用户选择的 HTML 元素应用到网站前端菜单项下的副标题元素。
这一步非常简单,因为我们唯一需要做的就是从数据库选项表中检索选定的字段并修改我们代码中的“ My_Custom_Nav_Walker
”类。 具体来说,我们将不得不替换将menu_item_sub
条目添加到$output
变量的代码部分。
$output .= '<div class="menu-item-sub">' . $menu_item_sub . '</div>';
我们将首先使用get_option( 'option_name' )['html_element'];
获取元素并将其保存在$stored_option
变量中,然后将其应用于上述行。 最终的类应该是这样的:
if ( ! class_exists( 'My_Custom_Nav_Walker' ) ) { class My_Custom_Nav_Walker extends Walker_Nav_Menu { public function start_el( &$output, $item, $depth=0, $args=[], $id=0 ) { $menu_item_sub = get_post_meta( $item->ID, '_menu_item_sub', true ); $output .= '<li class="' . implode( ' ', $item->classes ) . '">'; if ( $item->url && $item->url != '#' ) { $output .= '<a href="' . $item->url . '">'; } else { $output .= '<span>'; } $output .= $item->title; if ( $item->url && $item->url != '#' ) { $output .= '</a>'; } else { $output .= '</span>'; } $stored_option = get_option( 'option_name' )['html_element']; if ( ! empty( $menu_item_sub ) ) { $output .= '<'. $stored_option .' class="menu-item-sub">' . $menu_item_sub . '</'. $stored_option .'>'; } } } }
有时在查看我们插件的代码时,在构建设置页面时可视化 WordPress 功能的工作方式会有所帮助。 这是我们示例中的外观:

结论
正如您所希望的那样,WP Settings API 是这里的主要工具,它允许我们为插件的选项页面创建骨骼。 除此之外,您可以自行决定是对类使用更面向对象的方法,还是使用更简单的方法,将函数和钩子粘贴到主插件 PHP 文件中。
让我们在这里指出,我们重建插件所遵循的路线并不是真正的 OOP,但肯定朝那个方向迈出了一步。 在即将发布的有关 OOP 的系列文章中,我们将深入探讨可以增强插件管理的其他功能。
为我们的自定义插件创建设置页面可能会有点令人困惑,但希望在阅读本文后,您了解所需内容。 快乐编码!
另请阅读
- 向 WordPress 菜单项添加自定义字段
- 向 WordPress 菜单项添加字段 – 自定义插件