如何将内容添加到mediawiki中的所有页面?

TL; DR:如何将文本(通知)添加到每个页面的内容(不是页眉或全局模板)?

(很长)问题与背景:我打算将MediaWiki迁移到另一个wiki。 维基的内容已经从一个更古老的维基(之前有关格式化的错误已经产生)中迁移出来,随着时间的推移而变得越来越严重,现在已经过时了。 这就是为什么我们要从一个空白的维基开始,手动迁移内容,丢弃和/或更新过时的页面。

为了方便起见,我想在每个现有页面的顶部添加一个文本块,特别是一个模板,注意这个页面还没有被迁移或丢弃,还有一个收集所有这些页面的类别(例如category:migration_pending) 。 然后,每个用户都应该浏览他所负责的页面,将内容复制到新的wiki中,并将模板更改为另一个将页面标记为迁移(category:migration_done)或丢弃(category:migration_discarded)的页面。 这样就可以得到一个干净的,最新的wiki,而不会忘记任何重要的东西。

Replace_Text扩展是不成功的,所以我结束了编写我自己的使用MediaWiki API的脚本。

我从这里的loginscript开始写这个脚本:

#!/usr/bin/php <?php $settings['wikiroot'] = "https://server/mediawiki"; $settings['user'] = "username"; $settings['pass'] = "password"; // $settings['domain'] = 'Windows'; $settings['cookiefile'] = "cookies.tmp"; $prepend = "{{migration_pending}}\n\n"; function httpRequest($url, $post="") { global $settings; $ch = curl_init(); //Change the user agent below suitably curl_setopt($ch, CURLOPT_USERAGENT, 'MediaWiki Migration Script 0.1'); curl_setopt($ch, CURLOPT_URL, ($url)); curl_setopt($ch, CURLOPT_ENCODING, "UTF-8" ); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_COOKIEFILE, $settings['cookiefile']); curl_setopt($ch, CURLOPT_COOKIEJAR, $settings['cookiefile']); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); if (!empty($post)) curl_setopt($ch,CURLOPT_POSTFIELDS,$post); //UNCOMMENT TO DEBUG TO output.tmp //curl_setopt($ch, CURLOPT_VERBOSE, true); // Display communication with server //$fp = fopen("output.tmp", "w"); //curl_setopt($ch, CURLOPT_STDERR, $fp); // Display communication with server $xml = curl_exec($ch); if (!$xml) { throw new Exception("Error getting data from server ($url): " . curl_error($ch)); } //var_dump($xml); curl_close($ch); return $xml; } function login ($user, $pass, $token='') { global $settings; $url = $settings['wikiroot'] . "/api.php?action=login&format=xml"; $params = "action=login&lgname=$user&lgpassword=$pass"; if (!empty($settings['domain'])) { $params .= "&lgdomain=" . $settings['domain']; } if (!empty($token)) { $params .= "&lgtoken=$token"; } $data = httpRequest($url, $params); if (empty($data)) { throw new Exception("No data received from server. Check that API is enabled."); } $xml = simplexml_load_string($data); if (!empty($token)) { //Check for successful login $expr = "/api/login[@result='Success']"; $result = $xml->xpath($expr); if(!count($result)) { throw new Exception("Login failed"); } } else { $expr = "/api/login[@token]"; $result = $xml->xpath($expr); if(!count($result)) { throw new Exception("Login token not found in XML"); } } return $result[0]->attributes()->token; } try { global $settings; $token = login($settings['user'], $settings['pass']); login($settings['user'], $settings['pass'], $token); $star = "*"; $dash1 = "-1"; // get edit token $result = httpRequest($settings['wikiroot'] . "/api.php?action=query&format=json&prop=info|revisions&intoken=edit&titles=Main%20Page"); $result = json_decode($result); $editToken = $result->query->pages->$dash1->edittoken; // only from namespace: apnamespace=100 $result = httpRequest($settings['wikiroot'] . "/api.php?action=query&list=allpages&format=json&aplimit=5000&apnamespace=100"); $result = json_decode($result); $allpages = $result->query->allpages; foreach ($allpages as $page) { echo "Fetching '{$page->title}' ({$page->pageid})...\n"; $revisions = httpRequest(sprintf($settings['wikiroot'] . "/api.php?action=query&prop=revisions&rvlimit=1&format=json&rvprop=content&titles=%s", urlencode($page->title))); $revisions = json_decode($revisions); if (isset($revisions->error)) { echo "ERROR: " . $revisions->error->info . "\n"; continue; } $content = $revisions->query->pages->{$page->pageid}->revisions[0]->$star; if (preg_match("/\{\{migration_/", $content)) { echo "Already marked ... skipping.\n"; continue; } echo "Updating..."; // add text to content and edit page $content = $prepend . $content; $post = sprintf("title=%s&text=%s&token=%s", urlencode($page->title), urlencode($content), urlencode($editToken)); $result = httpRequest($settings['wikiroot'] . "/api.php?action=edit&format=json", $post); echo "done\n"; } echo ("Finished (".sizeof($allpages)." pages).\n"); } catch (Exception $e) { die("FAILED: " . $e->getMessage()); } ?> 

剧本的基本function是:

  • 使用现有帐户login
  • 获取一个允许编辑操作的令牌
  • 检索给定名称空间内所有页面的列表
  • 对于每一页:
    • 从最新版本获取内容
    • 添加一个预定义的文本到内容
    • 用新的内容保存页面

一些附加说明:

  • 确保您要使用的用户存在并具有对所有需要的名称空间的写入权限。
  • 将用户添加到“Bot”组。 这将删除一些限制,例如bot允许以5000个组而不是500个组的方式进行批量操作,就像普通用户一样。 不知道这个脚本是否有必要,但不能伤害。
  • 当使用像LdapAuthentication这样的authentication扩展时,必须设置domain参数。 它必须被设置为LDAP源的名称 ,它是如何在LocalSettings.phpconfiguration的,而不是域名的实际名称。
  • 在运行脚本之前禁用电子邮件通知。 否则,每个在维基上观看页面的人都会收到他所观看的每个更改页面的通知。 对我来说这是$wgEnableEmail = false;$wgEnotifWatchlist = false;LocalSettings.php
  • 我从命令行运行脚本,速度不是很快,需要几分钟才能完成1000多页。 如果我在networking服务器上运行它,肯定会遇到超时。

最后但并非最不重要的,我添加到MediaWiki的模板migration_pending

 {|class=warningbox | [[Image:Emblem-important.png]] | This page hasn't been audited yet, the information on it could be outdated. If you are responsible for this page, please check it's content. If it is still current, add it to the new wiki and change this template to <nowiki>{{Migration_done}}</nowiki>. If the information on this page is not needed anymore change the template to <nowiki>{{Migration_discarded}}</nowiki> |} [[Category:MigrationPending]] 

这为我们以前使用过的表使用CSS类,并将页面添加到特定的类别。 我添加了与migration_donemigration_discarded类似的模板。