我将把我的解决方案发布给可能发生在这个帖子上的其他人。我对它不是百分之百满意,因为您不应该将模板与菜单功能结合在一起(Toscho使用元数据或自定义分类法的方法可能更正确)。然而,这是一个快速和肮脏的。我试图通过在函数顶部附近提供一些常量来缓解紧耦合。php帮助未来的开发人员维护代码:
// define the custom password-protected template that is used to determine whether this item is protected or not in the menus
define (\'ZG_PROTECTED_PAGE_TEMPLATE\', \'page-membersonly.php\');
// define the custom capability name for protected pages
define (\'ZG_PROTECTED_PAGE_CAPABILITY\', \'view_member_pages\');
因此,受保护的页面模板只是single的一个变体。php,但出于安全原因,它会在显示任何内容之前检查当前的\\u user\\u是否可以(ZG\\u PROTECTED\\u PAGE\\u功能)。
接下来,根据Toscho的建议,我实现了一个自定义walker。本例中的walker非常简单-我们覆盖walker\\u Nav\\u菜单的公共start\\u el和end\\u el方法,只是拦截它们足够长的时间来问这个问题:我们有权查看菜单项吗?
规则很简单:如果页面不是“私有”页面(在本例中是由该页面使用特定页面模板确定的),那么它是可见的。如果它是一个“私有”页面,并且用户被验证为具有我们正在寻找的自定义功能的角色,那么它是可见的。否则,它将不可见。
如果我们确实有访问权限,那么我们只需使用Walker\\u Nav\\u菜单的内置方法,而无需修改,因此我们调用同名的父::方法。
/* Custom Walker to prevent password-protected pages from appearing in the list */
class HALCO_Nav_Walker extends Walker_Nav_Menu {
protected $is_private = false;
protected $page_is_visible = false;
// override parent method
function start_el(&$output, $item, $depth, $args) {
// does this menu item refer to a page that is using our protected template?
$is_private = get_post_meta($item->object_id, \'_wp_page_template\', true) == ZG_PROTECTED_PAGE_TEMPLATE;
$page_is_visible = !$is_private || ($is_private && current_user_can(ZG_PROTECTED_PAGE_CAPABILITY));
if ($page_is_visible){
parent::start_el(&$output, $item, $depth, $args);
}
}
// override parent method
function end_el(&$output, $item, $depth) {
if ($page_is_visible){
parent::end_el(&$output, $item, $depth);
}
}
}