User:SickManWP-bot/linktemplate.js
外观
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
// cd ~/wikibot && date && time ../node/bin/node 20160628.insert_navigation.插入導航模板.js && date
// cd /d D:\USB\cgi-bin\program\wiki && node 20160628.insert_navigation.插入導航模板.js template_name BOTREQ_diff_id
// Insert navigation template (navigation boxes, navboxes).
// 對指定之[[WP:導航模板|導航模板]]中所有列表頁面,都插入此導航模板。若有[[WP:重定向|重定向]]頁,則回頭將導航模板中之連結改成重定向的目標。
/*
usage:
node 20160628.insert_navigation.插入導航模板.js template_name [BOTREQ_diff_id]
e.g.,
node 20160628.insert_navigation.插入導航模板.js 中国经济 49849923
2016/4/3 21:24:7 初版試營運。批量連接Template:廣州
2016/6/28 22:27:52 批量連接Template:深圳、Template:南京
2016/7/14 18:40:39 轉成常態性工具。
TODO: 重定向頁需跑兩次!
*/
'use strict';
require('./wiki loder.js');
var
/** {Object}wiki operator 操作子. */
wiki = Wiki(true);
// ---------------------------------------------------------------------//
// CeL.set_debug(0);
var
BOTREQ_diff_id = process.argv[3],
// process.argv:
// ['node','20160628.insert_navigation.插入導航模板.js','template name']
template_name = process.argv[2];
if (!template_name) {
// throw new Error('No template name specified!');
CeL.error('No template name specified!');
process.exit(1);
}
// 回頭將導航模板中之連結改成重定向的目標。
var redirect_hash = CeL.null_Object(),
//
template_with_ns = /^(Template|模板):/.test(template_name) ? template_name
: 'Template:' + template_name,
//
template_transclusion = '{{' + template_name + '}}' + '\n',
// {{tl|Featured article}}或{{tl|Good article}}模板 pattern
PATTERN_GA = /[\r\n]*{{(?:[Ff]eatured|[Gg]ood)[ _](?:article|list)(?:[\s\n\|][^{}]*?)?}}[\r\n]*/,
// [[WP:ORDER]]
// [[WP:分類、列表與導航模板]]
// [[WP:NAV]]
// [[WP:小作品類別列表|(小)小作品模板]]: e.g., {{小小條目}}, {{Rubik's Cube-stub}},
// {{F1-stub}}, {{Japan-Daimyō-stub}}, {{BDSM小作品}}, {{LGBT小作品}}
// {{Coord[}\s\|]|{{Coord[}\s\|]| → 大多用在模板參數中,不用在文末,因此不予加入。
PATTERN_AFTER = /{{\s*Portal[ _]bar\s*\||{{\s*Authority[ _]control\s*[}\|]|{{\s*Persondata(?:[}\s\|]|<!--)|{{\s*DEFAULTSORT\s*:|\[\[ *(?:Category|分類|分类) *:|{{\s*(?:(?:Sub|Sect|[a-z\d\- _\'ō]*-)?stub|[^{} _\d\|]*小作品|小小?條目|(?:Featured|Good)[ _](?:article|list))(?:[\s\n\|}]|<!--)|\n*$/;
/**
* Operation for each page. 對每一個頁面都要執行的作業。
*
* @param {Object}page_data
* page data got from wiki API. =
* {pageid,ns,title,revisions:[{timestamp,'*'}]}
*
* @see "20150805.en wiki 之[[規範控制]] (Authority control) 模板轉移作業.sop.js"
*/
function for_each_pages(page_data) {
/** {String}page title = page_data.title */
var title = CeL.wiki.title_of(page_data),
/** {String}page content, maybe undefined. 頁面內容 = revision['*'] */
content = CeL.wiki.content_of(page_data);
/** {Object}revision data. 版本資料。 */
// var revision = page_data.revisions && page_data.revisions[0];
if (!content) {
content = 'No contents: [[' + title + ']]! 沒有頁面內容!';
CeL.log(content);
return;
return [ CeL.wiki.edit.cancel, content ];
}
if (title === template_with_ns) {
// 回頭將導航模板中之連結改成重定向的目標。
for (title in redirect_hash) {
content = content.replace(new RegExp(
'\\[\\[' + title + '([\\]\|])', 'g'), '[['
+ redirect_hash[title] + '$1');
}
return content;
}
var matched;
if (matched = CeL.wiki.parse.redirect(content)) {
// wiki.page(matched).edit(for_each_pages);
redirect_hash[title] = matched;
return [ CeL.wiki.edit.cancel, '為重定向頁: [[' + matched + ']]' ];
}
matched = CeL.wiki.parse.template(content, template_name, true);
if (matched) {
// 若已存在模板/兩者模板相同,則跳過不紀錄。
matched = '已存在模板{{tlx|' + template_name + '}}';
CeL.log(matched);
return;
return [ CeL.wiki.edit.cancel, matched ];
}
// 某些條目把{{tl|Featured article}}或{{tl|Good article}}模板加至頁頂。
matched = content.match(PATTERN_GA);
if (matched && matched.index < (content.length / 2 | 0)) {
// 依[[WP:ORDER]],優特狀態模板應置放在條目的最底部。
content = content.replace(PATTERN_GA, '\n') + '\n' + matched[0].trim()
+ '\n';
}
return content.replace(PATTERN_AFTER, function($0) {
$0 = $0.trim();
return $0 ? template_transclusion + $0
// +'\n': 若結尾不包含 '\n',則可能直接添加在文字後!
: '\n' + template_transclusion;
});
}
// 確保 [[template_with_ns]] 在最後一頁,以在最後處理 redirect_hash。
// 注意: 一次取得大量頁面時,回傳內容不一定會按照原先輸入的次序排列!
// 若有必要,此時得用 config.first 自行處理!
function arrange_page(messages, pages, titles) {
// console.log(pages);
if (template_with_ns === CeL.wiki.title_of(pages[pages.length - 1])) {
return;
}
// 應該從後面搜尋。
var index = pages.length, page_data;
while (true) {
if (--index < 0) {
CeL.error('Not found: [[' + template_with_ns
+ ']]. 除非是比較巨型的模板,連結過多使模板本身並不在本批次中;否則這個錯誤不應該發生!');
return;
}
page_data = pages[index];
if (template_with_ns === CeL.wiki.title_of(page_data)) {
break;
}
}
pages.splice(index, 1);
pages.push(page_data);
if (titles) {
titles.splice(index, 1);
titles.push(template_with_ns);
}
}
/**
* Finish up. 最後結束工作。
*/
function finish_work() {
}
// ----------------------------------------------------------------------------
wiki.links(template_with_ns, function(pages, titles, title) {
CeL.log('[[' + title + ']]: All ' + pages.length + ' links.');
/** 限制每一項最大處理頁面數。 */
if (false) {
titles = titles.slice(0, 5);
}
// for redirect_hash.
titles.push(template_with_ns = title);
// callback
wiki.work({
each : for_each_pages,
// 採用 {{tlx|template_name}} 時,[[Special:最近更改]]頁面無法自動解析成 link。
summary : summary + ': [[Template:' + template_name + ']]'
+ (BOTREQ_diff_id > 0 ? ' [[Special:Diff/' + BOTREQ_diff_id
//
+ '|Bot作業請求]]' : '') + ' - [[' + log_to + '|log]]',
log_to : log_to,
before : arrange_page,
last : finish_work
}, titles);
}, {
limit : 'max',
namespace : 0
});