FlatIsleロゴ

Flat Isle 日誌

WordPressの「code」ブロックを改善する

2022-07-08

WordPressの「code」ブロックでソースコードを掲載する際「あったらいいな」の機能である、画面幅による折り返しの停止や、クリップボードへの取り込みボタンの追加を、テーマ内で実装していきます。

・本改善では、style.cssとjsを使用しています

・本記事内の方法ではモバイルフレンドリーテストでエラーが発生したため、ココで改善記事を記述しています

画面幅による折り返しの解除

原因

折り返しの原因は、ヘッダ内でインクルードしている「wp-includes/css/dist/block-library/style.min.css」内の以下の記述(視認性を上げるため、style.cssより抜粋しています)

.wp-block-code code {
  display: block;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

内の「white-space:pre-wrap;」が原因であり、この値を「pre」に変更する必要があります

対応方法

テーマ「wp-content/themes/(利用中のテーマ)/style.css」に以下の項目を追加して、設定の上書きをします

.wp-block-code code {
  white-space: pre;
}

動作を確認した所、原因となるインクルードファイルが後で読み込まれているため、上書きできませんでした。そこで、以下の様にセレクタをもう一段上の所から指定するように変更しています
(下記サンプルは、合わせてタブサイズも4に変更しています)

.article .wp-block-code code {
	tab-size:				4;
	white-space:			pre;
}

クリップボードへのコピー機能の追加

クリップボードへのコピー機能を実現するため、下記の項目単位で作成していきます

クリップボードボタンの追加

クリップボードボタンをCSSの「after」疑似要素を用いて表示します
表示するアイコンは、ココからクリップボードとして認識できそうな画像を選んできています

pre.wp-block-code {
	display:			block;
	position:			relative;
	margin:				5px 0;
	border-top:			solid 1.4rem #444444;
	border-right:		solid 2px    #444444;
	border-bottom:		solid 2px    #444444;
	border-left:		solid 2px    #444444;
	background-color:	#202020;
	word-wrap:			normal;
	box-sizing:			border-box;
}
.wp-block-code:after {
	display:				block;
	position:				absolute;
	top:					-1.4rem;
	right:					0;
	content:				"📋";
	font-size:				1rem;
}

クリップボードコピー処理の追加

疑似要素となるボタン部分のクリック処理を作成します
疑似要素単体ではクリックイベントを作成する事が出来ないので、クリックされた座標と比較して判断しています
クリックされた時、対象のテキスト(HTMLではなく…)をクリップボードに書き込みます
以下のコードを「wp-content/themes/(利用中のテーマ)/js/function.js」に記述します

window.addEventListener('DOMContentLoaded', function(){
	let aryCode = document.querySelectorAll('pre.wp-block-code');
	aryCode.forEach(function(element){
		element.addEventListener('click', function(e){
			if((e.offsetX > this.offsetWidth - 24)
			&& (e.offsetY < 0)){
				let clipText = this.childNodes[0].innerText;
				navigator.clipboard.writeText(clipText).then(function(){
				});
			}
		});
	});
});

コピー完了メッセージの表示

クリップボードへ書き込み完了時、コピー完了メッセージを表示させます
疑似要素のcontentへはDOMでアクセス出来ないため、codeタグに「copied」クラス名を2秒間追加させ、cssの「.wp-block-code.copied:after」で表示させます
まず、「wp-content/themes/(利用中のテーマ)/style.css」に以下の項目を追加します

pre.wp-block-code.copied:after {
	display:			block;
	position:			absolute;
	top:				-1.4rem;
	right:				0;
	content:			"📋 Copied!!";
	font-size:			1rem;
	color:				#ffffff;
}

次に、クリップボードの書き込み処理の成功時に、クラスの追加処理を追記します
以下のコードを「wp-content/themes/(利用中のテーマ)/js/function.js」を変更します

window.addEventListener('DOMContentLoaded', function(){
	let aryCode = document.querySelectorAll('pre.wp-block-code');
	aryCode.forEach(function(element){
		element.addEventListener('click', function(e){
			if((e.offsetX > this.offsetWidth - 24)
			&& (e.offsetY < 0)){
				let clipText = this.childNodes[0].innerText;
				navigator.clipboard.writeText(clipText).then(function(){
					e.target.classList.add('copied');
					setTimeout(function(){
						e.target.classList.remove('copied');
					}, 2*1000);
				});
			}
		});
	});
});

以上で、自動改行無効化とクリップボードへのコピー機能を実現できました

まとめ

行番号の表示を含め、本サイトでのcodeブロックに関連する設定を以下にまとめます

  • 「wp-content/themes/(利用中のテーマ)/style.css」での記載項目
pre.wp-block-code {
	display:			block;
	position:			relative;
	margin:				5px 0;
	border-top:			solid 1.4rem var(--wp--preset--color--pre-bg);
	border-right:		solid 2px    var(--wp--preset--color--pre-bg);
	border-bottom:		solid 2px    var(--wp--preset--color--pre-bg);
	border-left:		solid 2px    var(--wp--preset--color--pre-bg);
	background-color:	var(--wp--preset--color--code-bg);
	word-wrap:			normal;
	box-sizing:			border-box;
}
pre.wp-block-code:after {
	display:			block;
	position:			absolute;
	top:				-1.4rem;
	right:				0;
	content:			"📋";
	font-size:			1rem;
}
pre.wp-block-code.copied:after {
	display:			block;
	position:			absolute;
	top:				-1.4rem;
	right:				0;
	content:			"📋 Copied!!";
	font-size:			1rem;
	color:				#ffffff;
}
pre.wp-block-code code {
	display:			block;
	position:			relative;
	padding:			0.2rem 0.2rem 0.2rem 3.5rem;
	color:				#dcdcdc;
	background-color:	var(--wp--preset--color--code-bg);
	overflow-x:			auto;
	font:				bold 0.8rem/1.1rem monospace;
	line-height:		1.8 !important;
	tab-size:			4;
	white-space:		pre;
	overflow-wrap:		break-word;
}
pre.wp-block-code code:before {
	display:			block;
	position:			absolute;
	box-sizing:			border-box;
	top:				0;
	left:				0;
	bottom:				0;
	width:				3rem;
	padding:			0.2rem 3px 0.2rem 0;
	color:				#aaaaaa;
	background-color:	var(--wp--preset--color--code-bg);
	border-right:		solid 1px var(--wp--preset--color--border);
	font:				bold 0.8rem/1.1rem monospace;
	line-height:		1.8 !important;
	text-align:			right;
	content:			"1\A 2\A 3\A 4\A 5\A 6\A 7\A 8\A 9\A 10\A 11\A 12\A 13\A 14\A 15\A 16\A 17\A 18\A 19\A 20\A 21\A 22\A 23\A 24\A 25\A 26\A 27\A 28\A 29\A 30\A 31\A 32\A 33\A 34\A 35\A 36\A 37\A 38\A 39\A 40\A 41\A 42\A 43\A 44\A 45\A 46\A 47\A 48\A 49\A 50\A 51\A 52\A 53\A 54\A 55\A 56\A 57\A 58\A 59\A 60\A 61\A 62\A 63\A 64\A 65\A 66\A 67\A 68\A 69\A 70\A 71\A 72\A 73\A 74\A 75\A 76\A 77\A 78\A 79\A 80\A 81\A 82\A 83\A 84\A 85\A 86\A 87\A 88\A 89\A 90\A 91\A 92\A 93\A 94\A 95\A 96\A 97\A 98\A 99\A";
	overflow:			hidden;
}
  • 「wp-content/themes/(利用中のテーマ)/js/function.js」の記載項目
window.addEventListener('DOMContentLoaded', function(){
	let aryCode = document.querySelectorAll('pre.wp-block-code');
	aryCode.forEach(function(element){
		element.addEventListener('click', function(e){
			if((e.offsetX > this.offsetWidth - 24)
			&& (e.offsetY < 0)){
				let clipText = this.childNodes[0].innerText;
				navigator.clipboard.writeText(clipText).then(function(){
					e.target.classList.add('copied');
					setTimeout(function(){
						e.target.classList.remove('copied');
					}, 2*1000);
				});
			}
		});
	});
});