TL; DR: Как добавить текст (уведомление) к содержимому (не в заголовок или глобальный шаблон) каждой страницы?
(очень) длинный вопрос с предысторией: я планирую перенести MediaWiki на другую вики. Содержимое вики было перенесено из еще более старой вики (где возникали ошибки, связанные с форматированием), со временем выросло и теперь в значительной степени устарело. Вот почему мы хотим начать с пустой вики и перенести контент вручную, удаляя и / или обновляя устаревшие страницы.
Чтобы упростить эту задачу, я хочу добавить текстовый блок вверху каждой существующей страницы, в частности шаблон с уведомлением о том, что эта страница еще не была перенесена или удалена, и категорию, в которой собраны все эти страницы (например, category: migration_pending) . Затем каждый пользователь должен просмотреть страницы, за которые он отвечает, скопировать содержимое в новую вики и изменить шаблон на другой, пометив страницу как перенесенную (category: migration_done) или удаленную (category: migration_discarded). Таким образом, должно быть возможно получить чистую, обновленную вики, не забывая ничего важного.
Расширение Replace_Text не удалось, поэтому я закончил писать свой собственный скрипт, использующий MediaWiki API.
Я начал с логинскрипт отсюда и написал этот скрипт:
#!/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());
}
?>
В основном сценарий делает следующее:
Некоторые дополнительные примечания:
domain
параметр должен быть установлен. И он должен быть установлен на название источника LDAP, как он настроен в LocalSettings.php
, а не фактическое имя домена.$wgEnableEmail = false;
и $wgEnotifWatchlist = false;
в LocalSettings.php
. И последнее, но не менее важное: шаблон migration_pending
Я добавил в MediaWiki:
{|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_done
и migration_discarded
с соответствующими категориями.