サイト制作者がタイトルなどに文字を入力するのに必須のアイテムです。
ブロック開発者としては最初にマスターしないといけない技術だと思います。
ブロックの機能としてテキストを編集することができるというのは、最も基本的な機能だと思います。
そこで、今回はブロック制作を始められた方向けに、RichTextコンポーネントというWrodpressが用意してくれているコンポーネントの使い方を説明したいと思います。
この記事は、npx @wordpress/create-block
でブロックの開発環境が構築できていることを前提としています。wordpress/create-blockでの環境開発の構築方法については、他の記事をご覧ください。
当ブログでは次のような記事を公開しているので、良かったら参考にしてください。
同一プラグインで複数ブロックを仕込む方法
編集画面を描画するためのedit.jsを次のように変更してください。
import { __ } from '@wordpress/i18n'; import { useBlockProps, RichText, } from '@wordpress/block-editor'; import './editor.scss'; export default function Edit(props) { const { attributes, setAttributes }=props const blockProps = useBlockProps(); const { content } = attributes; const onChangeContent = ( newContent) => { setAttributes( {content:newContent} ) } return ( <div { ...blockProps }> <RichText tagName="p" onChange={ onChangeContent } value={ content } placeholder={ __( 'Write your text...' ) } /> </div> ); }
edit.jsをすべて削除して、その後に、コピペして大丈夫です。
value={ content }
onChange={ onChangeContent }
の部分に着目してください。
この2つでブロックが持つ情報であるattributesの情報を取得・更新しています。上がattributes情報の取得、下が更新です。
そしてcontentという変数にはconst { content } = attributes;
でattributesオブジェクトを分割代入しています。
こういうことをできるようにするためには、ブロックにattributesという情報を持たせ、さらにその中にcontentという情報をもたせる’器’を用意してやる必要があります。しかし、現時点でのブロックは、そのような’器’は持っていません。
この’器’を用意するのがblock.jsonの役割です。
block.jsonに
"attributes": { "content": { "type": "string", "source": "html", "selector": "p" } },
と入れてやりましょう。これを入れる場所はどこでもよいのですが、私は習慣的に
"supports": { "html": false },
のあとに挿入するようにしています。
これでブロックが’器’をもちました。
これでプロジェクトをビルドすれば、ブロックエディタの画面は次のようにテキストを入力できるようになります。
しかし、編集画面にRichテキストコンポーネントは現れて、文字の入力や編集ができるようになっても、本番のWebサイト(これをフロントエンドという呼び方をします。)には、その文字は表示されません。これを表示するためにはsave.jsを手入れしないといけないのです。
これはどんなブロックでも同じです。編集画面とフロントエンドは別々に作るということを覚えておいてください。
save.jsには次のように記述します。
import { useBlockProps, RichText } from '@wordpress/block-editor'; export default function save({ attributes }) { const { content } = attributes; const blockProps = useBlockProps.save(); return ( <div { ...blockProps }> <RichText.Content tagName="p" value={ content } /> </div> ); }
これももとのsave.jsをすべて削除して、その後にコピペして大丈夫です。
こちらは描画するだけなのでvalue={ content }
しか記述がありません。これでプレビュー画面にも描画されます。
ここで、2点注意事項です。
1点目はblock.jsonに
"attributes": { "content": { "type": "string", "source": "html", "selector": "p" } }
と記述しましたが、その中で”source”: “html”の記述があります。これがあるとsave.jsにおいてp要素にcontentの内容を描画するように指定しないとエラーになったり保存されなかったりするということです。ですから、edit.jsの手入れだけしてsave.jsの手入れをしないと編集画面にもcontentの内容が表示されないことになります。
2点目はsave.jsではRichTextではなく、RichText.Contentを返してやる必要があるということです。これを誤るとエラーを起こします。
両者の違いをChatGPTに聞いてみると
RichTextはテキストを編集するためのリッチテキストエリアを提供し、RichText.ContentはRichTextコンポーネントによって編集されたテキストの実際の内容を表し、リッチテキストエリアに表示された通りのテキストを取得します。
ということでした。
内容を編集する機能はHTMLの内容を動的に変化させるということです。ここでWordpressの基本を思い出してください。フロントエンドに出力される内容はサーバーで生成されるものです。それとフロントエンドを描画する機能をもつsave.jsが生成するHTMLは違うものであってはいけないのです。当然、フロントエンドで文字の編集ができるようにすることはできません。
これがフロントエンドの描画(レンダリング)と編集画面のレンダリングの大き違いです。
最後におまけとしてRichTextの機能を簡単にカスタマイズする方法を紹介しておきます。
それはブロックコントロールにFormatに関する設定を行うボタンを表示させるものです。
このようにブロックコントロールには様々なFormatツールが設置されていますが、allowedFormats
に’core/bold’や’core/italic’という文字列を配列で渡すことで制御することができます。
<RichText tagName="p" onChange={onChangeContent} allowedFormats={['core/bold', 'core/italic', 'core/link']} value={content} placeholder={__('Write your text...')} />
この文字列はRichTextを表示しているブラウザで開発ツールのコンソールを開き、wp.data.select( ‘core/rich-text’ ).getFormatTypes();と入力すると配列が表示されます。