Gutenbergのカスタムブロックからpost metaを更新する方法や小ネタをまとめました。
PHPの部分は前記事にも記載してあるので参考にしてください。記事の途中にもコード例へのリンクを貼っています。
MVCモデル風WordPressカスタマイズ設計
カスタムブロック 開発環境
「Create Guten Block Toolkit」でサクッと開発環境を構築。
Create Guten Block Toolkit
https://ahmadawais.com/create-guten-block-toolkit/
下記の記事が導入の参考になりました。
Create Guten BlockでGutenbergのカスタムブロック開発環境を構築する
https://www.webopixel.net/wordpress/1420.html
src内は、1ブロック=1ディレクトリで作成する。
src内にブロック(ディレクトリ)を追加したら、src/blocks.jsに追加したjsファイルのimportを記述する。
エディタ内のブロックのスタイルは各ブロック(ディレクトリ)内のeditor.scssに記述する。
フロント表示時のスタイル用のblocks.style.build.cssを使わない場合は、src/init.phpの'enqueue_block_assets'のアクションフックを削除する(お好みで)。
ブロックカテゴリ・metaフィールドの準備
'block_categories'フィルターフックを使ってブロックカテゴリを追加。
投稿タイプによって、使用できるカスタムブロック(ブロックタイプ)を制限する場合は、'allowed_block_types'フィルターフックを使う。
register_meta()で事前に、metaフィールドを登録しておく。
コード例
init.php
setting.php
hooks/blocks.php
カスタムブロック の作成
各ブロック(ディレクトリ)内のblock.jsに記述する。
下記は、ブロックカテゴリ'block-post_type_1'にブロック'myplugin/image-section'を追加するコード例です。
色々試せるようにコンポーネントを多めに入れてみました。
setting.phpのブロックタイプ・metaフィールドとは部分的にしか対応してないので、コードを試す際には適宜補完してください。
import './editor.scss';
const {
registerBlockType
} = wp.blocks;
const {
RichText,
MediaUpload
} = wp.editor;
const {
PanelBody,
BaseControl,
TextControl,
SelectControl,
RadioControl,
Button
} = wp.components;
const yearStart = 2019;
const yearEnd = 2030;
const linkType = [
{ label: '外部リンク', value: '' },
{ label: '内部リンク', value: '内部リンク' },
];
registerBlockType( 'myplugin/image-section', {
title: '画像セクション登録',
icon: 'edit',
category: 'block-post_type_1',
attributes: {
title: {
type: 'string',
source: 'meta',
meta: 'meta_title' // タイトル
},
content: {
type: 'array',
source: 'meta',
meta: 'meta_content' // 説明文
},
year: {
type: 'string',
source: 'meta',
meta: 'meta_year' // 撮影年
},
place: {
type: 'string',
source: 'meta',
meta: 'meta_place' // 場所
},
url: {
type: 'string',
source: 'meta',
meta: 'meta_link_url' // リンク先URL
},
type: {
type: 'string',
source: 'meta',
meta: 'meta_link_type' // リンクタイプ
},
imageID: {
type: 'number',
source: 'meta',
meta: 'meta_image_id' // 画像ID
},
imageURL: {
type: 'string',
source: 'meta',
meta: 'meta_image_url' // 画像URL
}
},
edit({attributes, setAttributes, className}) {
function onSelectImage( media ) {
setAttributes( {
imageID: media.id,
imageURL: media.url,
} );
}
function onRemoveImage() {
setAttributes( {
imageID: null,
imageURL: '',
} );
}
function onChangeYear( event ) {
setAttributes( { year: event.target.value } );
}
const optYear = [];
for (let i = yearStart; i <= yearEnd; i++) {
optYear.push(
<option value={i} selected={i === Number(attributes.year)}>{i}</option>
)
}
return (
<PanelBody
className={ className }
title="画像セクション登録"
icon="edit"
initialOpen={ true }
>
<TextControl
label="タイトル"
help="画像タイトルを入力してください。"
value={ attributes.title }
onChange={ ( text ) => setAttributes( { title: text } ) }
/>
<BaseControl
label="説明文"
>
<RichText
tagName="div"
value={ attributes.content }
onChange={ (content) => setAttributes( { content: content } ) }
/>
</BaseControl>
<SelectControl
label="場所"
help="撮影した場所を選択してください。"
value={ attributes.place }
options={ [
{ label: '選択なし', value: '' },
{ label: '屋内', value: '屋内' },
{ label: '屋外', value: '屋外' },
] }
onChange={ ( option ) => { setAttributes( { place: option } ) } }
/>
<BaseControl
label="撮影年"
>
<select onChange={ onChangeYear } className="select-year">
<option value='' selected={'' === attributes.year}>なし</option>
{optYear}
</select> 年
<p class="components-base-control__help">撮影した年を入力してください。</p>
</BaseControl>
<TextControl
label="リンク先URL"
value={ attributes.url }
onChange={ ( text ) => setAttributes( { url: text } ) }
/>
<RadioControl
label="タイプを選択"
selected={ attributes.type ? attributes.type : linkType[0].value }
options={ linkType }
onChange={ ( option ) => { setAttributes( { type: option } ) } }
/>
<BaseControl
label="画像登録"
>
<MediaUpload
onSelect={ onSelectImage }
type="image"
value={ attributes.imageID }
render={ ( { open } ) => (
<Button className={ attributes.imageID ? 'image-button' : 'button button-large' } onClick={ open }>
{ ! attributes.imageID ? '画像アップロード': <img src={ attributes.imageURL } /> }
</Button>
) }
/>
{ ! attributes.imageID ? '': <Button className={ 'delete-image button button-large' } onClick={ onRemoveImage }>画像削除</Button> }
</BaseControl>
</PanelBody>
);
},
save() {
return null;
},
} );
.wp-block-myplugin-image-section {
.components-base-control .components-base-control__field {
margin-bottom: 15px;
.components-select-control__input {
width: 200px;
}
.select-year {
margin-right: 5px;
margin-bottom: 15px;
}
.delete-image.button {
margin-left: 1em;
vertical-align: bottom;
}
}
.components-base-control .components-base-control__label {
margin: 5px 0;
padding: .5em 10px .5em 10px;
font-weight: bold;
background-color: #f3f3f3;
}
.components-base-control .components-base-control__help {
font-size: 12px;
}
.editor-rich-text {
font-family: "Noto Serif", serif;
font-size: 16px;
}
}
投稿タイプにエディタのテンプレートを設定する
register_post_type()に'template'を設定することで、エディタのデフォルト表示にブロックが追加される。
後々のカスタムブロックの追加等の改修を想定して、'template_lock'は設定しない。
('template_lock'が設定してあると'template'を編集した際、既存の投稿が壊れる。)
コード例
hooks/post-type.php
フロントに表示する
get_registered_metadata()で投稿されたページのmetaデータを取得する。