描述
这个函数接受一个能力(capability),它将被用来确定一个页面是否包括在菜单中。
用于处理页面输出的函数必须检查用户是否具有所需的能力。
参数
- $page_title
-
(string)(必填) 选中菜单时要在页面标题标签中显示的文本。
- $menu_title
-
(string)(必填) 要用于菜单的文本。
- $capability
-
(string)(必填) 向用户显示此菜单所需的能力权限。
- $menu_slug
-
(string)(必填) 用于引用此菜单的slug名称。此菜单页应是唯一的,并且仅包括小写字母数字、破折号和下划线字符,以与sanitize_key()兼容。
- $callback
-
(callable)(可选) 要调用以输出此页面内容的函数。
默认值: ''
- $icon_url
-
(string)(可选) 用于此菜单的图标的URL。
- 使用数据URI传递base64编码的SVG,该URI将被着色以匹配颜色方案。应该以“data:image/svg+xml;base64,”开始。
- 传递Dashicons助手类的名称以使用字体图标,例如'dashicons-chart-pie'。
- 传递'none'将div.wp-menu-image留空,以便通过CSS添加图标。
默认值: ''
- $position
-
(int|float)(可选) 此项应出现在菜单顺序中的位置。
默认值: null
返回
(string) 结果页的hook_suffix。
更多信息
注意
- 重要提示:自WordPress 4.4,您无需担心位置编号是否唯一以避免冲突。有关更多信息,请参阅trac ticket #23316。
- 如果您遇到了“您没有足够的权限访问此页面”错误,则说明您挂钩太早了。您应该使用的挂钩是admin_menu。
- 如果只想将现有的管理菜单项移动到不同的位置,可以使用admin_menu钩子从全局$menu和$submenu变量(即数组)中的当前位置取消设置菜单项,并在数组中的其他位置重置它们。
- 这个函数需要一个“能力”(请参见角色和能力),它将被用来决定一个页面是否被包括在菜单中。用于处理页面输出的函数必须检查用户是否具有所需的“能力”。
- 如果您使用设置API,并且需要用户不是管理员,则需要通过挂钩option_page_capability_{$option_group}修改权限,其中$option_group与register_setting()中的option_group相同。查看设置API。
允许编辑器保存数据的示例:
// Register settings using the Settings API function wpdocs_register_my_setting() { register_setting( 'my-options-group', 'my-option-name', 'intval' ); } add_action( 'admin_init', 'wpdocs_register_my_setting' ); // Modify capability function wpdocs_my_page_capability( $capability ) { return 'edit_others_posts'; } add_filter( 'option_page_capability_my-options-group', 'wpdocs_my_page_capability' );
菜单结构
默认:菜单结构的底部
- 2 – Dashboard(仪表盘)
- 4 – Separator(分隔)
- 5 – Posts(文章)
- 10 – Media(媒体)
- 15 – Links(链接)
- 20 – Pages(页面)
- 25 – Comments(评论)
- 59 – Separator(分隔)
- 60 – Appearance(外观)
- 65 – Plugins(插件)
- 70 – Users(用户)
- 75 – Tools(工具)
- 80 – Settings(设置)
- 99 – Separator(分隔)
对于“网络管理”菜单,值有所不同:
- 2 – Dashboard(仪表盘)
- 4 – Separator(分隔)
- 5 – Sites(站点)
- 10 – Users(用户)
- 15 – Themes(主题)
- 20 – Plugins(插件)
- 25 – Settings(设置)
- 30 – Updates(更新)
- 99 – Separator(分隔)
源码
更新日志
版本 | 描述 |
---|---|
1.5.0 | 开始引入 |
使用示例
示例
为具有管理员能力的用户在WordPress管理菜单中添加自定义菜单项:方法1:
/** * Register a custom menu page. */ function wpdocs_register_my_custom_menu_page() { add_menu_page( __( 'Custom Menu Title', 'textdomain' ), 'custom menu', 'manage_options', 'myplugin/myplugin-admin.php', '', plugins_url( 'myplugin/images/icon.png' ), 6 ); } add_action( 'admin_menu', 'wpdocs_register_my_custom_menu_page' );
使用此方法,页面生成代码应位于
myplugin/myplugin-admin.php
:<?php esc_html_e( 'Admin Page Test', 'textdomain' ); ?>
方法2:
/** * Register a custom menu page. */ function wpdocs_register_my_custom_menu_page(){ add_menu_page( __( 'Custom Menu Title', 'textdomain' ), 'custom menu', 'manage_options', 'custompage', 'my_custom_menu_page', plugins_url( 'myplugin/images/icon.png' ), 6 ); } add_action( 'admin_menu', 'wpdocs_register_my_custom_menu_page' ); /** * Display a custom menu page */ function my_custom_menu_page(){ esc_html_e( 'Admin Page Test', 'textdomain' ); }
如果使用数据URI传递base64编码的SVG,则只有在具有
fill
样式属性的情况下,才会将其着色以匹配配色方案。该过程由wp-admin/js/svg-painter.js
完成。要添加解析为子菜单项的顶级菜单项,每个add_menu_page和add_submenu_page调用的菜单slug需要匹配。当您需要顶级菜单项标签与第一个子级菜单项不同时,此选项非常有用。否则,顶级项标签将作为第一个子项重复。
最小示例-
$menu_slug = 'wpdocs-orders-slug'; add_menu_page( 'WP Docs Orders', 'WP Docs Orders', 'read', $menu_slug, false ); add_submenu_page( $menu_slug, 'Existing WP Docs Orders', 'Existing WP Docs Orders', 'read', $menu_slug, 'wpdocs_orders_function' );
在该示例中,选择“WP Docs Orders”顶级项目时,将触发子菜单项目。
添加带有Dashicons图标的菜单页面。更多dashicons请点击此处https://developer.wordpress.org/resource/dashicons/#menu
add_action( 'admin_menu', 'register_my_custom_menu_page' ); function register_my_custom_menu_page() { // add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position ); add_menu_page( 'Custom Menu Page Title', 'Custom Menu Page', 'manage_options', 'custom.php', '', 'dashicons-welcome-widgets-menus', 90 ); }
/** * Create admin Page to list unsubscribed emails. */ // Hook for adding admin menus add_action('admin_menu', 'wpdocs_unsub_add_pages'); // action function for above hook /** * Adds a new top-level page to the administration menu. */ function wpdocs_unsub_add_pages() { add_menu_page( __( 'Unsub List', 'textdomain' ), __( 'Unsub Emails','textdomain' ), 'manage_options', 'wpdocs-unsub-email-list', 'wpdocs_unsub_page_callback', '' ); } /** * Disply callback for the Unsub page. */ function wpdocs_unsub_page_callback() { echo 'Unsubscribe Email List'; }
添加自定义SVG图标。
我对此有些费劲,想在使用$icon_url参数时添加一些注释。根据我的经验和在论坛上的观察,使用自定义图标并不像创建SVG并对其进行编码那样简单。以下是将自定义SVG图标添加到管理菜单的分步过程:
- 首先,以任何方式获取或创建SVG图标。
- 接下来,清理SVG文件并正确格式化
- 然后对文件进行base64编码
- 在base64字符串前面加上
'data:image/svg+xml;base64,'
- …这将为您提供一个有效的$icon_url字符串。
因此,让我详细介绍一下这些步骤。
步骤1
据我所知,您可以以任何方式创建SVG图形。我在Adobe Illustrator中创建了我的,但任何像Inkscape、Corel draw,甚至硬编码都可以。
步骤2
最痛苦的部分是清理SVG。经过大量测试和实验,我发现SVG越干净,工作的可能性就越大。基本上,许多图形程序将添加元数据和其他杂项,以使SVG更广泛地兼容。这在99%的情况下都很好,但当将其用于wordpress菜单图标时,它只是破坏了它。
这是一个通常从Adobe Illustrator导出的SVG示例:
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 16"><defs><style>.d{fill:#070707;}</style></defs><g id="a"/><g id="b"><g id="c"><path class="d" d="M15.4,6.5H7.9v3h4.4c-.4,2.1-2.3,3.5-4.4,3.4-2.6-.1-4.6-2.1-4.7-4.7-.1-2.7,2-5 ,4.7-5.1,1.1,0,2.2,.4,3.1,1.2l2.3-2.2c-1.4-1.4-3.4-2.1-5.3-2.1C3.6,0,0,3.6,0,8s3.6,8,8,8, 7.7-3.2,7.7-7.8c-.1-.6-.1-1.1-.3-1.7Z"/><path class="d" d="M15.4,6.5H7.9v3h4.4c-.4,2.1-2.3, 3.5-4.4,3.4-2.6-.1-4.6-2.1-4.7-4.7-.1-2.7,2-5,4.7-5.1,1.1,0,2.2,.4,3.1,1.2l2.3-2.2c-1.4-1. 4-3.4-2.1-5.3-2.1C3.6,0,0,3.6,0,8s3.6,8,8,8,7.7-3.2,7.7-7.8c-.1-.6-.1-1.1-.3-1.7Z"/></g> </g></svg>
凌乱,非常凌乱。即使我们添加一些换行符和缩进,也会发生很多事情。
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.7 16"> <defs> <style> .d{fill:#070707;} </style> </defs> <g id="a"/> <g id="b"> <g id="c"> <path class="d" d="M15.4,6.5H7.9v3h4.4c-.4,2.1-2.3,3.5-4.4,3.4-2.6-.1-4.6-2.1-4.7-4.7-.1-2.7,2-5,4.7-5.1,1.1,0,2.2,.4,3.1,1.2l2.3-2.2c-1.4-1.4-3.4-2.1-5.3-2.1C3.6,0,0,3.6,0,8s3.6,8,8,8,7.7-3.2,7.7-7.8c-.1-.6-.1-1.1-.3-1.7Z"/> <path class="d" d="M15.4,6.5H7.9v3h4.4c-.4,2.1-2.3,3.5-4.4,3.4-2.6-.1-4.6-2.1-4.7-4.7-.1-2.7,2-5,4.7-5.1,1.1,0,2.2,.4,3.1,1.2l2.3-2.2c-1.4-1.4-3.4-2.1-5.3-2.1C3.6,0,0,3.6,0,8s3.6,8,8,8,7.7-3.2,7.7-7.8c-.1-.6-.1-1.1-.3-1.7Z"/> </g> </g> </svg>
所以我们要做的是大量清理这些数据,并去除不必要的数据。如果将其添加为图像源,您可能会发现上面的内容将被加载,但它无法使用GUI正确着色,并且可能大小错误。因此,我们需要做几件事:
- 删除
<?xml
标记,这不会有帮助 - 然后,您必须将每个样式硬编码到路径中,而不是使用标记。对于每个路径,从标记中找出哪些类应用于路径,并将这些类中的CSS添加到路径中。
- 完成后,可以完全删除
defs
元素。 - 您还可以删除元素并将元素保留在SVG的根目录下。
- 为了确保SVG的颜色与GUI一致,需要向每个路径添加
fill="black"
。 - 然后,为了确保SVG的宽度和高度正确,将
width="20" height="20"
添加到open元素中
完成后,您将得到一个SVG文件,看起来更像这样:
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path fill="black" d="M17.6 8.5h-7.5v3h4.4c-.4 2.1-2.3 3.5-4.4 3.4-2.6-.1-4.6-2.1-4.7-4.7-.1-2.7 2-5 4.7-5.1 1.1 0 2.2.4 3.1 1.2l2.3-2.2C14.1 2.7 12.1 2 10.2 2c-4.4 0-8 3.6-8 8s3.6 8 8 8c4.6 0 7.7-3.2 7.7-7.8-.1-.6-.1-1.1-.3-1.7z" fillrule="evenodd" cliprule="evenodd"> </path> </svg>
步骤3
现在您需要对SVG进行base64编码。我这样做的方式是将文件传递到PHP的默认编码机制中,并将路径作为绝对路径复制到我的PHP中。您不希望PHP读取SVG文件,对其进行base64编码,并在用户每次重新加载页面时将其传递到菜单,这只是浪费资源和时间。
// load the SVG data by loading the file or including the XML directly. $svg = file_get_contents( '/path/to/icon.svg' ); // or $svg = '<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill="black" d="M17.6 8.5h-7.5v3h4.4c-.4 2.1-2.3 3.5-4.4 3.4-2.6-.1-4.6-2.1-4.7-4.7-.1-2.7 2-5 4.7-5.1 1.1 0 2.2.4 3.1 1.2l2.3-2.2C14.1 2.7 12.1 2 10.2 2c-4.4 0-8 3.6-8 8s3.6 8 8 8c4.6 0 7.7-3.2 7.7-7.8-.1-.6-.1-1.1-.3-1.7z" fillrule="evenodd" cliprule="evenodd"></path></svg>'; // then encode it and echo it out echo base64_encode( $svg ); // will give you a long string that looks like this: // PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdib3g9IjAgMCAyMCAyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjYTdhYWFkIiBkPSJNMTcuNiA4LjVoLTcuNXYzaDQuNGMtLjQgMi4xLTIuMyAzLjUtNC40IDMuNC0yLjYtLjEtNC42LTIuMS00LjctNC43LS4xLTIuNyAyLTUgNC43LTUuMSAxLjEgMCAyLjIuNCAzLjEgMS4ybDIuMy0yLjJDMTQuMSAyLjcgMTIuMSAyIDEwLjIgMmMtNC40IDAtOCAzLjYtOCA4czMuNiA4IDggOGM0LjYgMCA3LjctMy4yIDcuNy03LjgtLjEtLjYtLjEtMS4xLS4zLTEuN3oiIGZpbGxydWxlPSJldmVub2RkIiBjbGlwcnVsZT0iZXZlbm9kZCI+PC9wYXRoPjwvc3ZnPg== // thats your base64 encoded SVG file!
步骤4
在base64 SVG前面添加‘data:image/svg+xml;’,如下所示:
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdib3g9IjAgMCAyMCAyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjYTdhYWFkIiBkPSJNMTcuNiA4LjVoLTcuNXYzaDQuNGMtLjQgMi4xLTIuMyAzLjUtNC40IDMuNC0yLjYtLjEtNC42LTIuMS00LjctNC43LS4xLTIuNyAyLTUgNC43LTUuMSAxLjEgMCAyLjIuNCAzLjEgMS4ybDIuMy0yLjJDMTQuMSAyLjcgMTIuMSAyIDEwLjIgMmMtNC40IDAtOCAzLjYtOCA4czMuNiA4IDggOGM0LjYgMCA3LjctMy4yIDcuNy03LjgtLjEtLjYtLjEtMS4xLS4zLTEuN3oiIGZpbGxydWxlPSJldmVub2RkIiBjbGlwcnVsZT0iZXZlbm9kZCI+PC9wYXRoPjwvc3ZnPg=="
这是一个完全有效的
$icon_url
字符串。我会把这个字符串硬编码成一个变量,然后每次都把它添加到你的插件中。add_menu_page( __( 'WPDocs Plugin page name' ), __( 'WPDocs Plugin' ), 'manage_options', 'slug', 'callback','data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdib3g9IjAgMCAyMCAyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjYTdhYWFkIiBkPSJNMTcuNiA4LjVoLTcuNXYzaDQuNGMtLjQgMi4xLTIuMyAzLjUtNC40IDMuNC0yLjYtLjEtNC42LTIuMS00LjctNC43LS4xLTIuNyAyLTUgNC43LTUuMSAxLjEgMCAyLjIuNCAzLjEgMS4ybDIuMy0yLjJDMTQuMSAyLjcgMTIuMSAyIDEwLjIgMmMtNC40IDAtOCAzLjYtOCA4czMuNiA4IDggOGM0LjYgMCA3LjctMy4yIDcuNy03LjgtLjEtLjYtLjEtMS4xLS4zLTEuN3oiIGZpbGxydWxlPSJldmVub2RkIiBjbGlwcnVsZT0iZXZlbm9kZCI+PC9wYXRoPjwvc3ZnPg==' );
我希望这对其他人有帮助,因为这会让我今天早上节省几个小时!
这是一个更好的例子,peskyesky
这是一个面向对象的例子。
待办事项:
创建includes/layout.phpclass WPDocs_EB_EbtechModules { public static function init() { add_action( 'admin_enqueue_scripts', array( __CLASS__, 'adminAssets' ) ); add_action( 'admin_menu', array( __CLASS__, 'adminMenu' ) ); } public static function adminMenu() { add_menu_page( __( 'WPDocs Ebtech Menu', 'wpdocs-webnail-modules' ), __( 'WPDocs Ebtech modules', 'wpdocs-webnail-modules' ), 'manage_options', 'wpdocs-ebtech-modules', array( __CLASS__, 'menuPage' ), 'dashicons-tagcloud', 6 ); } public static function menuPage() { if ( is_file( plugin_dir_path( __FILE__ ) . 'includes/layout.php' ) ) { include_once plugin_dir_path( __FILE__ ) . 'includes/layout.php'; } } public static function getSettings() { return get_option( 'wpdocs_ebtech_modules_option' ); } public static function adminAssets() { if ( isset( $_GET['page'] ) && ! empty( $_GET['page'] ) && 'wpdocs-ebtech-modules' === $_GET['page'] ) { } } } WPDocs_EB_EbtechModules::init(); WPDocs_EB_EbtechModules::getSettings();
用于显示页面内容的回调函数不一定需要检查当前用户的能力,因为如果用户没有正确的能力,回调甚至不会连接。
如果您试图直接访问一个您没有所需能力的页面,您将得到一个错误页面。
// For those who are object orientated. Add a class // function as the menu callback and setup the // menus automatically. // Exit if accessed directly if ( !defined( 'ABSPATH' ) ) exit; class MyMenuSetterUpper { private static $instance; /** * Main Instance * * @staticvar array $instance * @return The one true instance */ public static function instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self; self::$instance->addMyAdminMenu(); } return self::$instance; } public function addMyAdminMenu() { add_menu_page( 'My Page Title', 'My Page', 'read', 'my-menu-page-slug', array( $this, 'myAdminPage' ), 'to/icon/file.svg', '2.1' ); } public function myAdminPage() { // Echo the html here... } } // Call the class and add the menus automatically. $MyMenuSetterUpper = MyMenuSetterUpper::instance();