既然解决了针对匿名用户隐藏页面内容的问题,那么就更进一步,尝试隐藏特定页面或者子页面。
可能有人第一反应是使用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子页面,将呈现不同的结果。比如在心百科中的/脑图子页面,结果如下:
注册用户正常访问子页面.png
匿名用户无权访问子页面.png

最后修改:2025 年 05 月 25 日
如果觉得我的文章对你有用,请随意赞赏