如何彻底移除WordPress用户新建页面权限但保留编辑权限?
你遇到的问题很典型——很多权限插件的批量设置会“一刀切”,要么全有要么全无,没法精准控制「不能新建但能编辑」的场景。你之前的代码只是做了视觉层面的隐藏,用户还是可以通过手动输入URL或者其他途径创建页面,所以得从权限控制、视觉移除、访问拦截三个维度来彻底解决:
1. 从权限根源禁止创建页面(核心步骤)
WordPress的权限系统是基于「功能(Capability)」的,我们可以用map_meta_cap钩子直接修改用户的权限逻辑,让用户无法触发“创建页面”的权限,而不是只隐藏按钮:
function restrict_create_page_capability($caps, $cap, $user_id, $args) { // 拦截创建页面的权限请求 if ($cap === 'publish_pages' && isset($args[0]) && $args[0] === 'page') { $caps = array('do_not_allow'); } // 拦截无ID的编辑请求(也就是创建新页面的场景) if ($cap === 'edit_pages' && isset($args[0]) && $args[0] === 'page' && empty($args[1])) { $caps = array('do_not_allow'); } return $caps; } add_filter('map_meta_cap', 'restrict_create_page_capability', 10, 4);
这段代码会在WordPress检查权限时,把“创建页面”的请求直接替换为「禁止」,从根源上阻断权限,比视觉隐藏靠谱得多。
2. 移除所有视觉上的“新建页面”入口
接下来要把所有能看到的“新建”按钮都去掉,覆盖侧边栏、页面列表页、顶部工具栏这几个常见入口:
function remove_new_page_buttons() { // 移除侧边栏的新建页面链接 global $submenu; if (isset($submenu['edit.php?post_type=page'])) { foreach ($submenu['edit.php?post_type=page'] as $key => $item) { // 适配中英文后台的按钮文本 if (in_array($item[0], array(__('Add New'), __('新建页面')))) { unset($submenu['edit.php?post_type=page'][$key]); break; } } } // 移除页面列表顶部的「新建」按钮 add_action('admin_head-edit.php', function() { if (isset($_GET['post_type']) && $_GET['post_type'] === 'page') { echo '<style>.add-new-h2, .tablenav.top .add-new-h2 { display: none !important; }</style>'; } }); // 移除顶部工具栏的新建页面选项 add_action('admin_bar_menu', function($wp_admin_bar) { $wp_admin_bar->remove_node('new-page'); }, 999); } add_action('admin_menu', 'remove_new_page_buttons');
这里用了动态文本判断,不管是英文还是中文后台都能识别并移除按钮,同时用CSS确保列表页的按钮彻底隐藏。
3. 拦截直接访问新建页面的URL
有些用户可能会手动输入wp-admin/post-new.php?post_type=page来尝试创建页面,我们需要直接拦截这个访问:
function block_direct_new_page_access() { global $pagenow; if ($pagenow === 'post-new.php' && isset($_GET['post_type']) && $_GET['post_type'] === 'page') { // 这里可以根据需求调整,比如只禁止非管理员用户 if (!current_user_can('manage_options')) { wp_die(__('你没有权限创建新页面。'), __('权限不足'), array('response' => 403)); } } } add_action('admin_init', 'block_direct_new_page_access');
如果你的需求是针对特定角色(比如编辑角色),可以把!current_user_can('manage_options')改成!user_can(get_current_user_id(), 'administrator'),这样管理员依然可以创建页面,其他角色不行。
如何使用这些代码?
把上面三段代码复制到你的WordPress主题的functions.php文件里,或者创建一个简单的自定义插件来存放(推荐用自定义插件,避免主题更新丢失代码)。
这样操作后,用户就只能编辑已有的页面,完全无法创建新页面,同时不会影响其他页面相关的编辑、查看权限,完美解决插件“一刀切”的问题。
内容的提问来源于stack exchange,提问作者Doron Davidowitz

