Gutenberg/日記006
画像の取り扱い
Wordpressの記事編集画面で、テキストの次に入力したくなるのは画像情報だと思います。今回は実際に作成したブロックをご紹介します。ブロックの概要は「画像と著作者情報のテキストを表示する」というものです。
attributes: {
mediaID: {
type: 'number'
},
mediaURL: {
type: 'string',
source: 'attribute',
selector: 'img',
attribute: 'src'
},
copyright: {
type:'string',
source: 'text',
selector: 'div.copyright'
}
},
attributesの設定はこんな感じになりました。上から画像ID(mediaID)、画像のURL(mediaURL)、著作者情報(copyright)を保存する指定になっています。前回出てきたtype:'number'が使われていますね。画像のIDは数値情報なのでnumberを指定するわけですね。
save: function( props ) {
const {
attributes: { mediaURL, copyright }
} = props;
return (
<div className="copyright-image">
{
mediaURL && (
<div class="image"><img src={ mediaURL } alt="" /></div>
)
}
{
copyright && (
<div class="copyright">{ copyright }</div>
)
}
</div>
);
},
先にsaveメソッドを確認してみます。mediaURLとcopyrightを使ってimg要素とテキスト要素をレイアウトしています。入力値が空のときにはコンテナごと表示しないように論理演算子(&&)が使われていますね。参考にしたサイトがこんな記述の仕方をしていたので、なるほどと真似をしたのでした。div.copyrightの中身がcopyright属性になっているところも先のattributes設定の通りになっていますね。
const { MediaUpload } = wp.editor;
const { TextControl, Button } = wp.components;
editメソッドで使うので先にコンポーネントを使いやすくしておきます。MediaUploadというのが、画像をアップロードしたり選択するためのUIコンポーネントですね。TextControlは著作者情報の入力欄となるテキストフィールドのコンポーネントです。Buttonは画像をアップロードする際に押すボタンに使います。
edit: function( props ) {
const {
className,
attributes: {
mediaID,
mediaURL,
copyright
},
setAttributes,
} = props;
const onSelectImage = ( media ) => {
setAttributes( {
mediaURL: media.url,
mediaID: media.id,
} );
};
const onChange = ( val ) => {
setAttributes( {
copyright: val
} );
};
return (
<div className={ props.className }>
<div className="image">
<MediaUpload
onSelect={ onSelectImage }
type="image"
value={ mediaID }
render={ ( { open } ) => (
<Button className={ mediaID ? 'image-button' : 'button button-large' } onClick={ open }>
{ ! mediaID ? '画像アップロード': <img src={ mediaURL } /> }
</Button>
) }
/>
</div>
<div className="copyright">
<TextControl value={ copyright } onChange={ onChange } />
</div>
</div>
);
},
editメソッドはこんな感じで、今までのブロックよりもちょっと長くなっています。(もっと簡潔に書ける気もしますが)画像がコンポーネントで選択されたときの処理(onSelectImage)とテキストフィールドに著作者情報が入力されたときの処理(onChange)をまず定義しています。それぞれ引数に画像IDとURL(media.id、media.url)、テキスト入力値(val)が渡されているので、setAttributesメソッドで先に定義したattributesにsetしているだけです。
MediaUploadコンポーネントはtype属性を指定すると選択するメディアを絞り込めるようですね。この辺はWordpressのプラグインを作成したことがある方にはなじみ深いかもしれません。今回は"image"を指定して画像を扱うダイアログを使うようにしています。value属性にmediaID属性値を指定しているので、選択した画像が次回以降の編集の際にもちゃんとMediaUploadに読み込まれます。(「属性」という言葉が二種類登場してとてもよみにくい文章になってしまっているなぁ。)renderというのはメソッドのようですね。Reactのお作法なのか、コンポーネントが実体であるHTMLを出力する際に呼び出されるようです。ここで自身のopenメソッドを渡してButtonコンポーネントが押されたときに呼び出されるようにしています。またmediaIDが設定されているかどうかに応じてボタンの表示を切り替えています。既に画像が選択されている(mediaIDが設定されている)と画像のサムネイルを表示するようなボタンになります。
TextControlコンポーネントはもっと単純で、valueに入力初期値としてcopyright属性値が入るようになっています。テキストが変更されるとonChangeメソッドが発火します。
これでよく使われそうなブロックはなんとかなりそうな気がします。textareaやinput:checkboxみたいな入力も使いたくなるかな?色選択コンポーネントとか、カレンダーみたいなのも・・・。