既然解决了针对匿名用户隐藏页面内容的问题,那么就更进一步,尝试隐藏特定页面或者子页面。
可能有人第一反应是使用Lockdown扩展,但它也并非全能,比如常规条目中的子页面它就无能为力,又或者有某个页面也不希望有人看到。而TitleBlacklist扩展则彻底封杀了特定页面的创建和编辑(显然也不是我想要的效果)。这种时候特殊需要就要特殊处理(当然MediaWiki本身并不提倡动不动就限制访问或编辑,也就难怪常用扩展中没有直接符合要求的)。
首先,设置禁止匿名用户访问的页面列表,支持两种模式:
- 完整页面名(如 Project:Secret、Help:Locked)
- 子页面名(自动匹配/secret、/admin等子页面)
我们可以直接在配置文件LocalSettings.php中加入如下代码:
// 配置变量:禁止匿名用户访问的页面规则
$wgRestrictedPages = [
// 完整页面名(精确匹配)
'My Secret',
'Project:Secret',
'Help:Locked',
// 子页面名(匹配任意父页面下的该子页面)
'tmp', // 禁止 /tmp
'draft', // 禁止 /draft
];
然后使用getUserPermissionsErrors钩子实现页面精确匹配和子页面通配,继续加入以下代码:
$wgHooks['getUserPermissionsErrors'][] = function( $title, $user, $action, &$result ) {
global $wgRestrictedPages;
// 仅限制匿名用户
if (!$user->isAnon()) {
return true;
}
// 获取当前页面完整名称(如 "Project:Secret")
$prefixedText = $title->getPrefixedText();
// 检查是否在禁止的完整页面列表中
if (in_array($prefixedText, $wgRestrictedPages)) {
$result = '匿名用户无权访问此页面:' . $prefixedText;
return false;
}
// 检查是否是禁止的子页面
if ($title->isSubpage()) {
$subpageName = strtolower($title->getSubpageText()); // 子页面名转小写
if (in_array($subpageName, $wgRestrictedPages)) {
$result = '匿名用户无权访问 /' . $subpageName . ' 子页面';
return false;
}
}
return true; // 放行
};
分别使用注册用户和匿名用户浏览xxx/xxx子页面,将呈现不同的结果。比如在心百科中的/脑图子页面,结果如下:
