MediaWiki

来自百合仙子's Wiki
跳转到导航 跳转到搜索

本页面记录 MediaWiki 软件本身和其维护相关的信息。关于编辑相关信息,见帮助:目录

入门

站点搭建与维护

注意:可能需要修改 /etc/php/php.ini 中的 open_basedir 选项。

可选启用 PHP 缓存扩展 opcache

Nginx 配置

参见主条目nginx#PHP + FastCGI

配置示例。php 文件请见 nginx#PHP + FastCGI

# https://www.mediawiki.org/wiki/Manual:Security#Upload_security
location /w/images {
        alias /usr/share/webapps/mediawiki/images;
}
location /w/ {
        alias /usr/share/webapps/mediawiki/;
        include php;
}
location /wiki/ {
        rewrite ^/wiki/(.*)?$ /w/index.php/$1 last;
}

另一个配置,PHP 文件与页面标题链接使用相同的路径前缀:

location /t/images {
        alias /srv/http/todowiki/images;
}
location /t/ {
        try_files $uri $uri/ @todowiki;
        alias /srv/http/todowiki/;
        include php;
}
location @todowiki {
        rewrite ^/t/(.*)?$ /t/index.php/$1 last;
}

在 URL 路径中支持中文变种的配置:

$wgArticlePath = "/wiki/$1";
$wgVariantArticlePath = "/$2/$1";
location /w/images {
    alias /usr/share/webapps/mediawiki/images;
}
location /w/ {
    alias /usr/share/webapps/mediawiki/;
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;
    include php;
    gzip on;
}
location / {
    root /usr/share/nginx/html;
    try_files $uri $uri/ @wiki;
}
location @wiki {
    rewrite ^/ /w/index.php last;
}

Apache 配置

Alias /w /usr/share/webapps/mediawiki

RewriteEngine On
RewriteRule ^/?wiki/(.*)$ /w/index.php/$1 [PT,L,QSA]
RewriteRule ^/?wiki$ /w/index.php [PT,L,QSA]

<Directory /usr/share/webapps/mediawiki>
	Options +FollowSymLinks
	AllowOverride All
	order allow,deny
	allow from all
</Directory>

维护脚本

这些脚本在 maintenance 目录下,从其所在的目录执行。

  • deleteOldRevisions.php 删除旧的修订历史。需要加上 --delete 参数才会真的删除。
  • rebuildtextindex.php 重建文本索引

迁移

将一个 wiki 迁移到另外的系统上,可选地更换SQL数据库引擎[1][2][3]

php maintenance/dumpBackup.php --full --uploads > wiki-backup.xml
tar -czf wiki-images.tgz images

#现在访问 /mw-config/index.php 以配置新的 Wiki
php maintenance/update.php --quick
php maintenance/importDump.php < wiki-backup.xml

mkdir temporary
cp wiki-images.tgz temporary
cd temporary/
tar -xzf wiki-images.tgz
cd ../
mkdir tempimages
cp temporary/images/*/*/* tempimages
php maintenance/importImages.php tempimages
php maintenance/rebuildImages.php --missing #否则找不到图片

php maintenance/initSiteStats.php --update #可选
php maintenance/initEditCount.php #可选
php maintenance/rebuildrecentchanges.php #可选

或者在导出文件中包含上传的文件:

php maintenance/dumpBackup.php --current --uploads --include-files --quiet > wiki-backup.xml

#现在访问 /mw-config/index.php 以配置新的 Wiki
php maintenance/update.php --quick
php maintenance/importDump.php --uploads < wiki-backup.xml

php maintenance/initSiteStats.php --update #可选
php maintenance/initEditCount.php #可选
php maintenance/rebuildrecentchanges.php #可选

注意:这样会丢失用户信息!用户设置也会丢失。页面中的模板可能会扩展失败。

可选 PHP 模块和外部程序

  • ImageMagick convert: 缩略图功能
  • php-intl: 更快的 Unicode 正规化

电子邮件

MediaWiki 默认使用 PHPmail() 函数,(在非 Windows 系统上)会调用 sendmail 命令发送邮件。而这将交给任务队列执行。对于 Postfixsendmail 来说这会调用名为 postdrop 的 sgid 程序。

可以通过 $wgSMTP 参数来让 MediaWiki 直接使用 SMTP 协议发送邮件。要使用本地的 MTA 发送邮件,只需要设置:

$wgSMTP = [ ];

使用 ElasticSearch

MediaWiki/CirrusSearch

特殊页面

[4]

设置

禁止匿名用户编辑

$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['read'] = true;
$wgGroupPermissions['*']['edit'] = false;

禁用页面缓存

$wgEnableParserCache = false;
$wgCachePages = false;

将站点设置为只读

[5]

$wgReadOnly = "(reason)";

注意:这也会导致无法生成图片缩略图。

主机名

默认使用首先尝试使用 $_SERVER['SERVER_NAME'],它在nginx里总是使用第一项,必须设置,否则为空。

if(isset($_SERVER['HTTP_HOST'])){
  $wgServer = "//${_SERVER['HTTP_HOST']}";
}else{
  $wgServer = '//localhost';
}

注意:如果使用了代理,导致服务器端口与访问所用的端口不同,还需另外设置。

短URL

布尔变量 $wgUsePathInfo 指示是否使用 PATH_INFO 而不是参数来确定页面名字。

字符串变量$wgArticlePath指明页面的 URL 路径,与 Web 服务器配合以得到更短的 URL,如形式为 /wiki/page。设置如下[6]

LocalSettings.php 加入:

$wgArticlePath = "/wiki/$1";
#注意保持下面的设置的一致性
$wgScriptPath = "/w";

Web 服务器部分的配置参见Nginx 配置或者Apache 配置

注意重写前的路径前缀与重写后的不能相同,否则对于样式表等文件的请求将出错。

关于修改火狐浏览器的访问历史记录,请见火狐数据库#历史记录

锚点转义方式

旧式转义会转义非 ASCII 字符的所有字节。使用新的 html5 方式会尽量少转义字符。设置项为 $wgFragmentMode

$wgFragmentMode = ['html5', 'legacy'];

多站点的 cookie 设置

在多个站点使用同一个域名时,为避免 cookie 冲突,可指定 cookie 的路径和前缀:

$wgCookiePath = "/t/";
$wgCookiePrefix = "t_";

调试

设置$wgDebugLogFile为日志文件路径,可记录wfDebug函数生成的日志消息。

文件上传

要设置文件上传的大小限制,在LocalSettings.php里设置:

$wgEnableUploads = true;
$wgMaxUploadSize = 1024 * 1024 * 100;

php.ini里设置:

upload_max_filesize = 100M

还要在 Web 服务器中设置。如 nginx

client_max_body_size 100m;

注意要重启 php-fpm 和 Web 服务器。

PostgreSQL

## Database settings
$wgDBtype = "postgres";
# use an empty string to denote the unix domain socket
$wgDBserver = "";
$wgDBname = "http";
$wgDBuser = "http";
$wgDBpassword = "";

# Postgres specific settings
$wgDBport = "5432";
$wgDBmwschema = "mediawiki";

数据导入/导出

# 导出
pg_dump -n mediawiki -O -x dbname -f dump
# 导入
sudo -u http psql < dump

子页面标题下方的上级链接

设置 $wgNamespacesWithSubpages[NS_MAIN] = true; 即可在主命名空间的页面标题正文显示上级页面链接。[7]

管理

巡查

未巡查页面会在最近更改中以红色叹号标识。进入其更改查看页面(英文 diff,中文先前),点击下方标记为已巡查链接即可标记指定修订为已巡查。[8]

插件

数学公式显示

当渲染模式为 mathml 时,新版本可以直接调用 WikiMedia 的 API,不需要安装 TeX

若使用 png 渲染模式,仍需要安装 texvc

注意 PHP 若使用 open_basedir 设置[9],则要允许其能够访问 /usr/bin/

如果无法渲染公式图片,可能是 MediaWiki 的内存使用限制太严格了。调整如下参数即可:[10][11]

$wgMaxShellMemory = 8000000;
$wgMaxShellFileSize = 1000000;
$wgMaxShellTime = 300;

在某些版本的 php-fpm(5.6.14)中,默认会清除环境变量。没有PATH环境变量会导致公式渲染失败。需要在 php-fpm 中作以下设置:

clear_env = no

小工具

Extension:Gadgets 用于加载一些 JavaScript 编写的小工具。其配置页面在 MediaWiki:Gadgets-definition,在 Special:Gadgets 页面显示。

启用:

wfLoadExtension('Gadgets');

引用提示

它包含一个 JavaScript 文件和一个 CSS 文件:

配置:

== browsing ==
* ReferenceTooltips[ResourceLoader|default]|ReferenceTooltips.js|ReferenceTooltips.css

HotCat

快速编辑页面的分类。详见wiki-zh:Wikipedia:维基百科工具/HotCat

脚本位于 MediaWiki:Gadget-HotCat.js。在其子页面(如 MediaWiki:Gadget-HotCat.js/zh-hans)可配置翻译。

Cat-a-lot

快速编辑一批页面的分类。见wiki-zh:Wikipedia:维基百科工具/Cat-a-lot

Interwiki

显示和管理跨wiki数据。此数据并不会被导出。关于跨wiki的更多信息,见 mw:Interwiki

Poem

用于诗歌的 <poem> 标签

TextExtracts

提供 API 以截取文章的文本内容(支持多种格式)。

Graph

使用 Vega 绘制数据图。

VisualEditor

Translate

翻译扩展。目前有以下问题:

  1. VisualEditor 的交互很不好
  2. 只支持 MySQL
  3. 翻译时看不到上下文
  4. 不能将可用语种显示在侧栏中

使用正则表达式进行批量编辑

URL

在URL后加 ?action=purge 可刷新页面缓存。[12]

数据与限制

最近更改只保存最近30天内的最多1000条记录。[13] 未登录用户最多显示 500 条记录。

问题处理

使用 PostgreSQL 时不能搜索中文

在数据库中执行以下语句:

update page set titlevector = to_tsvector(regexp_replace(replace(page_title, '/', ' '), '([\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF\u2F00-\u2FDF\u2FF0-\u2FFF\u3100-\u312F\u31A0-\u31BF\u3040-\u309F\u30A0-\u30FF\u31F0-\u31FF\uAC00-\uD7AF\u1100-\u11FF\u3130-\u318F\u4DC0-\u4DFF\uA000-\uA48F\uA490-\uA4CF\u2800-\u28FF\u3200-\u32FF\u3300-\u33FF\u2700-\u27BF\u2600-\u26FF\uFE10-\uFE1F\uFE30-\uFE4F])', '\1 ', 'g'));
update pagecontent set textvector = to_tsvector(regexp_replace(old_text, '([\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF\u2F00-\u2FDF\u2FF0-\u2FFF\u3100-\u312F\u31A0-\u31BF\u3040-\u309F\u30A0-\u30FF\u31F0-\u31FF\uAC00-\uD7AF\u1100-\u11FF\u3130-\u318F\u4DC0-\u4DFF\uA000-\uA48F\uA490-\uA4CF\u2800-\u28FF\u3200-\u32FF\u3300-\u33FF\u2700-\u27BF\u2600-\u26FF\uFE10-\uFE1F\uFE30-\uFE4F])', '\1 ', 'g'));

CREATE OR REPLACE FUNCTION ts2_page_title() RETURNS TRIGGER LANGUAGE plpgsql AS
$mw$
BEGIN
IF TG_OP = 'INSERT' THEN
  NEW.titlevector = to_tsvector(regexp_replace(replace(NEW.page_title, '/', ' '), '([\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF\u2F00-\u2FDF\u2FF0-\u2FFF\u3100-\u312F\u31A0-\u31BF\u3040-\u309F\u30A0-\u30FF\u31F0-\u31FF\uAC00-\uD7AF\u1100-\u11FF\u3130-\u318F\u4DC0-\u4DFF\uA000-\uA48F\uA490-\uA4CF\u2800-\u28FF\u3200-\u32FF\u3300-\u33FF\u2700-\u27BF\u2600-\u26FF\uFE10-\uFE1F\uFE30-\uFE4F])', '\1 ', 'g'));
ELSIF NEW.page_title != OLD.page_title THEN
  NEW.titlevector = to_tsvector(regexp_replace(replace(NEW.page_title, '/', ' '), '([\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF\u2F00-\u2FDF\u2FF0-\u2FFF\u3100-\u312F\u31A0-\u31BF\u3040-\u309F\u30A0-\u30FF\u31F0-\u31FF\uAC00-\uD7AF\u1100-\u11FF\u3130-\u318F\u4DC0-\u4DFF\uA000-\uA48F\uA490-\uA4CF\u2800-\u28FF\u3200-\u32FF\u3300-\u33FF\u2700-\u27BF\u2600-\u26FF\uFE10-\uFE1F\uFE30-\uFE4F])', '\1 ', 'g'));
END IF;
RETURN NEW;
END;
$mw$;

CREATE OR REPLACE FUNCTION ts2_page_text() RETURNS TRIGGER LANGUAGE plpgsql AS
$mw$
BEGIN
IF TG_OP = 'INSERT' THEN
  NEW.textvector = to_tsvector(regexp_replace(NEW.old_text, '([\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF\u2F00-\u2FDF\u2FF0-\u2FFF\u3100-\u312F\u31A0-\u31BF\u3040-\u309F\u30A0-\u30FF\u31F0-\u31FF\uAC00-\uD7AF\u1100-\u11FF\u3130-\u318F\u4DC0-\u4DFF\uA000-\uA48F\uA490-\uA4CF\u2800-\u28FF\u3200-\u32FF\u3300-\u33FF\u2700-\u27BF\u2600-\u26FF\uFE10-\uFE1F\uFE30-\uFE4F])', '\1 ', 'g'));
ELSIF NEW.old_text != OLD.old_text THEN
  NEW.textvector = to_tsvector(regexp_replace(NEW.old_text, '([\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF\u2F00-\u2FDF\u2FF0-\u2FFF\u3100-\u312F\u31A0-\u31BF\u3040-\u309F\u30A0-\u30FF\u31F0-\u31FF\uAC00-\uD7AF\u1100-\u11FF\u3130-\u318F\u4DC0-\u4DFF\uA000-\uA48F\uA490-\uA4CF\u2800-\u28FF\u3200-\u32FF\u3300-\u33FF\u2700-\u27BF\u2600-\u26FF\uFE10-\uFE1F\uFE30-\uFE4F])', '\1 ', 'g'));
END IF;
RETURN NEW;
END;
$mw$;

CREATE TRIGGER t_page BEFORE INSERT OR UPDATE ON page FOR EACH ROW EXECUTE FUNCTION ts2_page_title();
CREATE TRIGGER t_pagecontent BEFORE INSERT OR UPDATE ON pagecontent FOR EACH ROW EXECUTE FUNCTION ts2_page_text();

修改文件:

--- a/includes/search/SearchPostgres.php
+++ b/includes/search/SearchPostgres.php
@@ -76,6 +76,18 @@
 		# # Treat colons as word separators:
 		$term = preg_replace( '/:/', ' ', $term );
 
+		$contLang = MediaWikiServices::getInstance()->getContentLanguage();
+		$convertedVariants = $contLang->autoConvertToAllVariants( $term );
+		if ( is_array( $convertedVariants ) ) {
+		  $variants = array_unique( array_values( $convertedVariants ) );
+		} else {
+		  $variants = [ $term ];
+		}
+		$strippedVariants = array_map( [ $contLang, 'normalizeForSearch' ], $variants );
+		$strippedVariants = array_unique( $strippedVariants );
+		$term = join(' ', $strippedVariants);
+		wfDebug( "parseQuery preprocessed: $term \n" );
+
 		$searchstring = '';
 		$m = [];
 		if ( preg_match_all( '/([-!]?)(\S+)\s*/', $term, $m, PREG_SET_ORDER ) ) {

测试过的 MediaWiki 版本为 1.33.0。使用 SQLiteMySQL 时能够正确处理中文,不需要额外处理。

参见

外部链接

参考资料