0
0

MediaWikiの[[File:~]]にAttachRefプラグイン風の添付ボタンを表示させる

Last updated at Posted at 2024-08-11

PukiWikiのAttachRefプラグインをMediaWikiで再現するスクリプトです。
image.png

WIKIWIKI.JPで採用されていてとても好きだったプラグインです。
シンプルで直感的なのでMediaWikiに馴染みのない人でもアップロードしてくれるかも?

仕様

[[File:~]]構文でclass=uploadを付けておくと、その画像が存在しない場合、直接アップロード可能な「添付」ボタンが表示されます。

また、ライセンステンプレート名をclassに同時に追加しておくと、アップロード時のライセンステンプレートを指定できます。
image.png
※ライセンステンプレート名の空白文字は_に変更すること。またスラッシュ/などクラス文字列で使用できない文字が含まれるテンプレート名は指定できません。

ソースコード

MediaWiki:Gadget-attacheRef.js
// PukiWiki風 添付機能つきのFile構文にする uploadクラス
const default_license = "{" + "{License Mojang}}";
const button_caption = "添付";

$(function(){

	$(".upload").each(function(){
		var filetype = " " + this.getAttribute("typeof") + " ";
		if (filetype.indexOf(" mw:File") == -1 || filetype.indexOf(" mw:Error ") == -1) {
			return; //すでにアップロード済の場合はスキップ
		}
		var $this = $(this);

		// classにLisenseテンプレート名が含まれているならテンプレート構文を生成しておく
		var class_attr = this.getAttribute("class");
		var classes = class_attr.split(/\s/);
		var license = default_license;
		for(var i=0; i<classes.length; i++){
			if (classes[i].indexOf("License") > -1){
				license = "{{" + classes[i].replaceAll(/_/g, ' ') + "}}";
				break;
			}
		}

		// -------- wikitextを生成する ------------
		
		var $media = $this.find(".mw-broken-media");
		var filename = $media.text();

		var size = "", width = "", height = "", isThumb = (filetype.indexOf(' mw:File/Thumb ') != -1);
		if($media){
			if ($media.attr("data-width")) {
				width = $media.attr("data-width") + "px";
			}
			if ($media.attr("data-height")) {
				height = "x" + $media.attr("data-height") + "px";
			}

			if(width.length || height.length) {
				size = "|" + width + height;
			}
		}
		
		// ------ 添付ボタンを生成する -------------

		var id = generateID(); // クリックイベントが被らないようにランダムIDを付けておく
		
		var $input = $("<input/>", {type: "file", name: "fileupload", style: "display:none", id: id});

		var $label = $("<label/>", {for: id, text: filename + " ", style: "color:red"}).on("click", function(){});

		var $button = $("<button/>", {text: button_caption}).on("click", function(){
			$label.trigger("click");
		});

		var $span = $("<span/>", {style:"line-height:normal"}).append($input, $label, $button);
		
		$this.find("a").replaceWith( $span );

		// ------- クリックイベント ---------------

		$input.change(function(){
			if(!this.files.length){
				return; //no file selected
			}
		
			var file = this.files[0];

			// CSRF-tokenを取得
			new mw.Api().get({
				action: 'query',
				meta: 'tokens',
				format: 'json'
			}).done( function(result) {

				// アップロード処理
				new mw.Api().upload(
					file, {
					filename: filename,
					text: license,
					watchlist: 'nochange',
					ignorewarnings: 1,
					token: result.query.tokens.csrftoken,
					format: 'json'
				}).always(function(e) {
					
					// アップロード後に動的に画像をレンダリングさせる
					var wikitext = "[" + "[" + filename + size + (isThumb ? "|thumb": "") + "|class=" + class_attr + "]]";
					new mw.Api().parse(wikitext).done(function ( $html ) {
						$this.replaceWith( $html );
					});

					// ページのキャッシュをパージする
					new mw.Api().post({
						"action": "purge",
						"format": "json",
						"titles": mw.config.get('wgPageName'),
						"formatversion": "2"
					});
				});
			});
		});
		
	});
	
});

// ランダムなIDを生成
function generateID() {
	var chars = "xxxxxxxx".split("");
	for (var i = 0, len = chars.length; i < len; i++) {
		chars[i] = Math.floor(Math.random() * 16).toString(16);
	}
	return chars.join("");
}

補足

このスクリプトはユーザーの権限チェックはしていません。
もしログインユーザーのみに表示させたい場合はmw.user.getGroups()を使用してユーザーグループを取得する処理が必要です。
MediaWikiにpcommentプラグイン風のコメント機能をつける でユーザーグループの取得を行う処理がありますので参考にしてみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0