小金井にあるWEB制作会社の備忘録

MEMORANDUM

WordPress(ワードプレス)のグーテンベルクにオリジナル投稿ブロックを設置する

ワードプレスの投稿機能を利用して、様々な投稿をされる中で、デザインをしっかりとしたものにしたいので「雛形となるブロック」をご希望された際に調べた内容をメモ。

function.php

add_action('enqueue_block_editor_assets', 'add_custom_block_style_script');
function add_custom_block_style_script() {
	//Javascript読み込み
	$directory_url = get_template_directory_uri();
	$wp_js = array('wp-edit-post', 'wp-element', 'wp-blocks', 'wp-editor', 'wp-block-editor', );
	wp_enqueue_script('add-post-editor-block-script', $directory_url . '/original-blocks.js', $wp_js, '', true );
	
	//CSS読み込み
    wp_enqueue_style('dg-style-editor-style', $directory_url . '/original-blocks.css' );
}

オリジナルブロック用のjavascriptファイルとcssファイルを用意し、それぞれをテーマに読みこませます。
尚、上記のcssファイルは投稿ページ上のデザインに使用するものになるため、ユーザーページでは通常の読み込みのものを使用します。

original-blocks.js

(function (blocks, editor, element, blockEditor){
		
	var RichText = editor.RichText;
	var { InnerBlocks } = blockEditor;
	
	blocks.registerBlockType( 'original/new-block', {
		title: 'オリジナルブロック',
		icon: 'wordpress-alt',
		category: 'common', 
		attributes: { //値の保存に必須
			dt: {
				type: 'string',
				source: 'html',
				selector: 'dt',
			},
			dd: {
				type: 'string',
				source: 'html',
				selector: 'dd',
			}
		},
		edit: function( props ) {
						
			return element.createElement('div', { className: 'my-block' }, 
				[
					element.createElement(
						'div',
						{ className: 'block-content' },
						[
							element.createElement(
								InnerBlocks,
								{
									templateLock: [ ['core/image'] ]
								}
							),
						]
					),

					element.createElement(
						'dl',
						{ className: 'block-content-inner' },
						[
							
							element.createElement(
								RichText, {
									tagName: 'dt',
									value: props.attributes.dt,
									onChange: function( newContent ) {
										props.setAttributes( { dt: newContent } );
									},
									placeholder: '見出しを記載',
								}
							),
							
							element.createElement(
								RichText, {
									tagName: 'dd',
									value: props.attributes.dd,
									onChange: function( newContent ) {
										props.setAttributes( { dd: newContent } );
									},
									placeholder: 'コンテンツを記載',
								}
							),

						]
					)
				]
			 );

		},

		save: function( props ) {

			return element.createElement('div', { className: 'my-block' }, 
				[
					element.createElement(
						'div',
						{ className: 'block-content' },
						[
							element.createElement( InnerBlocks.Content, {} ),
						]
					),

					element.createElement(
						'dl',
						{ className: 'block-content-inner' },
						[
							element.createElement(
								RichText.Content,{
									tagName: 'dt',
									value: props.attributes.dt,
								}
							),
							element.createElement(
								RichText.Content,{
									tagName: 'dd',
									value: props.attributes.dd,
								}
							),
						]
					),
										
				]
			 );
			
		},
	});
	
}(
	window.wp.blocks,
	window.wp.editor,
	window.wp.element,
	window.wp.blockEditor 
) );

サンプルはサムネイル画像と画像に対する見出しとコメントが一体となったブロック。
「edit」の部分が編集画面の処理、「save」の部分が保存処理。
上部の「attributes」を設定し忘れると打ち込んだ文字の保存ができないので要注意

attributesの部分で、文字の挿入に必要となる変数を作成し、それぞれの保存形式を指定しています。
例は「dt」と「dd」の二種類の変数を作成、それぞれを「string」型で保存し、「selector」でマーキング要素(html)を指定しています。

「edit」の「element.createElement」関数で作成したい「HTML」を入れ込状に作成。
テキスト部分は「RichText」、画像部分は「InnerBlocks」を使用し、見出しとコンテンツ部分は動的に変化するよう「onChange」を使用して専用の関数を作成しています。

「save」処理は「edit」処理とほぼ同様の内容になりますが、第一引数の「RichText」を「RichText.Content」に、「InnerBlocks」を「InnerBlocks.Content」に変更します。

上記サンプルは各要素が一つづつなので単純ですが、要素が複数になる場合、例えば画像が二点、dtとddの組み合わせが二点になる場合は下記

javascript

(function (blocks, editor, element, blockEditor){
		
	var RichText = editor.RichText;
	var { InnerBlocks } = blockEditor;
	
	blocks.registerBlockType( 'original/new-block', {
		title: 'オリジナルブロック',
		icon: 'wordpress-alt',
		category: 'common', 
		attributes: { //値の保存に必須
			dt01: {
				type: 'string',
				source: 'html',
				selector: 'dt:nth-of-type(1)',
			},
			dd01: {
				type: 'string',
				source: 'html',
				selector: 'dd:nth-of-type(1)',
			},
			dt02: {
				type: 'string',
				source: 'html',
				selector: 'dt:nth-of-type(2)',
			},
			dd02: {
				type: 'string',
				source: 'html',
				selector: 'dd:nth-of-type(2)',
			}
		},
		edit: function( props ) {
						
			return element.createElement('div', { className: 'my-block' }, 
				[
					element.createElement(
						'div',
						{ className: 'block-content' },
						[
							element.createElement(
								InnerBlocks,
								{
									templateLock: [
										['core/image'],
										['core/image']
									]
								}
							),
						]
					),

					element.createElement(
						'dl',
						{ className: 'block-content-inner' },
						[
							
							element.createElement(
								RichText, {
									tagName: 'dt',
									value: props.attributes.dt01,
									onChange: function( newContent ) {
										props.setAttributes( { dt01: newContent } );
									},
									placeholder: '見出しを記載',
								}
							),
							
							element.createElement(
								RichText, {
									tagName: 'dd',
									value: props.attributes.dd01,
									onChange: function( newContent ) {
										props.setAttributes( { dd01: newContent } );
									},
									placeholder: 'コンテンツを記載',
								}
							),

							element.createElement(
								RichText, {
									tagName: 'dt',
									value: props.attributes.dt02,
									onChange: function( newContent ) {
										props.setAttributes( { dt02: newContent } );
									},
									placeholder: '見出しを記載',
								}
							),
							
							element.createElement(
								RichText, {
									tagName: 'dd',
									value: props.attributes.dd02,
									onChange: function( newContent ) {
										props.setAttributes( { dd02: newContent } );
									},
									placeholder: 'コンテンツを記載',
								}
							),

						]
					)
				]
			 );

		},

		save: function( props ) {

			return element.createElement('div', { className: 'my-block' }, 
				[
					element.createElement(
						'div',
						{ className: 'block-content' },
						[
							element.createElement( InnerBlocks.Content, {} ),
						]
					),

					element.createElement(
						'dl',
						{ className: 'block-content-inner' },
						[
							element.createElement(
								RichText.Content,{
									tagName: 'dt',
									value: props.attributes.dt01,
								}
							),
							element.createElement(
								RichText.Content,{
									tagName: 'dd',
									value: props.attributes.dd01,
								}
							),
							element.createElement(
								RichText.Content,{
									tagName: 'dt',
									value: props.attributes.dt02,
								}
							),
							element.createElement(
								RichText.Content,{
									tagName: 'dd',
									value: props.attributes.dd02,
								}
							),
						]
					),
										
				]
			 );
			
		},
	});
	
}(
	window.wp.blocks,
	window.wp.editor,
	window.wp.element,
	window.wp.blockEditor 
) );

「attributes」の変数を追加(変更)し「selector」の指定方法を変更、各変数を入力値の所に再指定、画像ブロックはInnerBlocksのテンプレート内に新たなブロック要素([‘core/image’])を追加しています。
saveの箇所も合わせて変更します。

同一カテゴリーの記事