プラグインなしでWordPressにツールチップを追加する方法

こんにちは、せこしょーです。
今日はWordPressについての記事です。

WordPressで記事を書くときに、ある単語や文章に補足情報を与える機能(=ツールチップ)がほしいと思ったことがある人はぜひこの記事を見てください。メニューバーからボタン一つでツールチップを追加できるようになります。例えば単語「WordPress」に対して補足情報を追加したいときに今回作成するツールチップを利用するとこのような指定した単語をクリックすると補足情報をスマートに表現することができます→「WordPressブログやホームページなどのWebサイトを作成・管理できるソフトウェアのこと

もちろんツールチップはプラグインでも実現することは可能ですが上のようなちょっとしたツールチップであればプラグインは不要です。

せこしょー
せこしょー

プラグインは便利だけど何でもかんでもプラグインを入れちゃうとWEBサイトが重くなるから注意が必要なんよ

今回編集するファイル

WordPress管理画面から「外観 > テーマファイルエディタ」に存在する以下のファイルを編集します。

  • functions.php
  • style.css
  • func-js > editor.js(新たにファイルを追加する)
  • editor-style.css(任意)

functions.phpを編集する

functions.phpに以下を追記します。※置き換えではなく追記です
念の為、追記前のファイルをどこかに保存しておきましょう。何か起きた際に元に戻せるので安心です。


add_action('enqueue_block_editor_assets', function () {
	wp_enqueue_script('my_editor', get_theme_file_uri('func-js/editor.js'), [
		'wp-element',
		'wp-rich-text',
		'wp-editor',
	]);
	wp_localize_script('my_editor', 'myEditorObj', [
		[
			'item' => 'editor01',
			'title' => 'Add a Tooltip',
			'class' => 'my-tooltip',
		],
		[
			'item' => 'editor02',
			'title' => 'tooltiptext',
			'class' => 'tooltiptext',
		]
	]);
});

editor.jsを追加する

上記functions.phpと同じディレクトリに「func-js」というディレクトリを作成してその中に「editor.js」ファイルを作成します。

(function (richText, element, editor) {
	function createTooltipButton(myEditor, myEditor2) {
		return function (args) {
			return element.createElement(editor.RichTextToolbarButton, {
				icon: 'admin-comments',
				title: myEditor.title,
				onClick: function () {
					const selectedValue = args.value

					let tooltipText = "補助文字列";
					const startIdx = selectedValue.start;
					const endIdx = selectedValue.end;

					const activeFormats = richText.getActiveFormats(selectedValue, []);
					const result = activeFormats.find(item => item.type === `my-editor/${myEditor.item}`);
					if (result) {
						// ツールチップ適用中の場合 → 適用を解除する
						const fts = selectedValue.formats;
						let formatStartIdx = undefined;
						let tooltipStartIdx = undefined;
						let tooltipEndIdx = undefined;
						for (let i = 0; i < fts.length; i++) {
							if (fts[i] === undefined && formatStartIdx === undefined) {
								continue
							}

							// Format01適用の文字列の開始位置を取得する
							if (formatStartIdx == undefined) {
								const result01 = fts[i].find(item => item.type === `my-editor/${myEditor.item}`)
								if (result01) {
									formatStartIdx = i
								}
							} else if (tooltipStartIdx == undefined) {
								// Format02適用(補助文字列)の開始位置を取得する
								const result02 = fts[i].find(item => item.type === `my-editor/${myEditor2.item}`)
								if (result02) {
									tooltipStartIdx = i
								}
							} else if (tooltipEndIdx == undefined) {
								// Format02適用(補助文字列)の終了位置を取得する
								// 指定のフォーマットが消える(undefined)タイミングが終了位置
								if (fts[i] === undefined) {
									tooltipEndIdx = i
									// ※ユーザーの選択位置(startIdx)よりも終了位置が小さい場合はリセット
									if (tooltipEndIdx < startIdx) {
										formatStartIdx = tooltipStartIdx = tooltipEndIdx = undefined;
									}
								} else {
									const result02 = fts[i].find(item => item.type === `my-editor/${myEditor2.item}`)
									// 指定のフォーマットが消える(undefined)タイミングが終了位置
									if (result02 === undefined) {
										tooltipEndIdx = i
										// ※ユーザーの選択位置(startIdx)よりも終了位置が小さい場合はリセット
										if (tooltipEndIdx < startIdx) {
											formatStartIdx = tooltipStartIdx = tooltipEndIdx = undefined;
											const result01 = fts[i].find(item => item.type === `my-editor/${myEditor.item}`)
											if (result01) {
												formatStartIdx = i
											}
										}
									}
								}
							}
						}
						// 適用されているツールチップを解除する
						const editor02RemovedValue = richText.removeFormat(selectedValue, `my-editor/${myEditor2.item}`, tooltipStartIdx, tooltipEndIdx)

						const newRichTextValue = richText.removeFormat(editor02RemovedValue, `my-editor/${myEditor.item}`, formatStartIdx, tooltipEndIdx)
						args.onChange(newRichTextValue)

					} else {
						// ツールチップ適用中ではない場合 → 適用する
						if (args.value.start == args.value.end) {
							console.log("補足情報を追加したい文字列範囲を選択してください")
							return
						}
						// 選択文字列のRichTextの最後に入れ込む「tooltipValue」を作成する
						const insertedToolTipValue = richText.insert(selectedValue, tooltipText, endIdx, endIdx)

						const editor01RichTextValue = richText.applyFormat(insertedToolTipValue, {
							type: `my-editor/${myEditor.item}`,
						}, startIdx, endIdx + tooltipText.length)


						const newRichTextValue = richText.applyFormat(editor01RichTextValue, {
							type: `my-editor/${myEditor2.item}`,
						}, endIdx, endIdx + tooltipText.length)

						args.onChange(newRichTextValue)
					}
				},
				isActive: args.isActive,
			});
		}
	}


	// 「ツールチップ」のフォーマットタイプを登録する
	richText.registerFormatType(`my-editor/${myEditorObj[1].item}`, {
		title: myEditorObj[1].title,
		tagName: 'span',
		className: myEditorObj[1].class,
	});
	richText.registerFormatType(`my-editor/${myEditorObj[0].item}`, {
		title: myEditorObj[0].title,
		tagName: 'span',
		className: myEditorObj[0].class,
		edit: createTooltipButton(myEditorObj[0], myEditorObj[1])
	});


})(
	window.wp.richText,
	window.wp.element,
	window.wp.blockEditor
);

style.cssファイルを編集する

style.cssファイルに以下を追記します。※置き換えではなく追記です

.text-marker {
    background: linear-gradient(to top, #eaeb16 40%, transparent 40%);
    font-weight: bold;
}

.my-tooltip{
    position: relative;
    cursor: pointer;
    display: inline-block;
	border-bottom: 1px dotted black;
}
.tooltiptext {
    display: none;
    position: absolute;
    padding: 10px;
    font-size: 14px;
    line-height: 1.6em;
    color: #fff;
    border-radius: 5px;
    background: #000;
    width: 100px;
}
.tooltiptext:before {
    content: "";
    position: absolute;
    top: 0%;
    right: 95%;
    border: 15px solid transparent;
    border-top: 15px solid #000;
    margin-left: -15px;
    transform: rotateZ(90deg);
}
.my-tooltip:hover .tooltiptext{
    display: inline-block;
    top: 0px;
    left: 80px;
}

投稿編集画面で適用するスタイルを分けたい場合はeditor-style.cssを利用する

サイトに訪れたユーザーに対して表示される画面のスタイルは上記のstyle.cssで定義されています。投稿編集画面上で表示される画面に対して別のスタイルを適用したいときはeditor-style.cssを利用しましょう。

/*ビジュアルエディターのスタイルを書く*/
.my-tooltip {
    position: inherit;
    cursor: inherit;
    display: inline-block;
    border-bottom: 1px dotted black;
}

.tooltiptext {
    display: inherit;
    position: inherit;
    padding: inherit;
    padding-left: 10px;
    font-size: 12px;
    line-height: 1.6em;
    color: inherit;
    border-radius: 5px;
    background: inherit;
    width: inherit;
}

.tooltiptext:before {
    content: inherit;
    position: inherit;
    top: inherit;
    right: inherit;
    border: inherit;
    border-top: inherit;
    margin-left: inherit;
    transform: inherit;
}

.my-tooltip:hover .tooltiptext {
    display: inherit;
    top: inherit;
    left: inherit;
}

WordPress管理画面から「外観 > テーマファイルエディタ」にeditor-style.cssが用意されていない場合はファイルを設置して適用させる必要があります。

今回参考にしたサイト

書式ツールバーAPI

@wordpress/rich-text – Block Editor Handbook | Developer.WordPress.org
This module contains helper functions to convert HTML or a DOM tree into a rich text value and back, and to modify the value with functions…
ブロックエディタにプラグインなしで文字装飾ボタンを追加する
【WordPress】【プラグイン無し】ブロックエディタで文字装飾(蛍光マーカーなど)を上部ツールバーボタンから追加する方法をご紹介します。

CSS

【CSS】ツールチップをHTMLとCSSだけで簡単に作る
補足説明をする時などによく使われるツールチップをHTMLとCSSのみで作ってみました。ぜひデザインに取り入れてみてください。

コメント