サポート » プラグイン » カスタムブロックでのdeprecatedについて

  • 解決済 Kenji Yanagiya

    (@childsview)


    お世話になります。
    独自のカスタムブロックを作成していて詰まってしまったので、こちらでご質問させて頂きます。
    環境としてはWSL2内、wp-envにて開発しています。

    <h4>タイトル<span>文字</span></h4>
    これを、
    <div className="title"><h4>タイトル</h4><span>文字</span></div>
    このようなHTML構造に変更したいと考えています。

    index.js

    import metadata from './block.json';
    import deprecated from './deprecated';
    import edit from './edit';
    import save from './save';
    import example from './example';
    
    const { name } = metadata;
    
    export { metadata, name };
    
    export const settings = {
      icon: 'id-alt',
      deprecated,
      edit,
      save,
      example,
    };
    

    deprecated.js

    export default [
      {
        attributes: {
          ...blockAttributes,
          titleLevel: {
            type: 'string',
            default: 'h4',
          },
        },
    save(attributes) {
          const { title, titleLevel} = attributes;
          const TitleTag = titleLevel;
          return (
    <div className="l-ttl-wrap">
                  <div className="l-ttl">
                    <TitleTag className="ttl">
                      <RichText.Content value={title} />
                    </TitleTag>
                    {!RichText.isEmpty(kana) && (
                      <span className="kana">
                        <RichText.Content value={kana} />
                      </span>
                    )}
                  </div>
                </div>
          );
        },
    deprecated: [
          {
            migrate({ text }) {
              return {
                titleLevel: text,
              };
           },
            save(attributes) {
              const { title, } = attributes;
    
              return (
                  <div className="l-desc">
    <h4 className="l-ttl">
                      <RichText.Content value={title} />
                      {!RichText.isEmpty(kana) && (
                        <span className="kana">
                          <RichText.Content value={kana} />
                        </span>
                      )}
                    </h4>
    </div>
              );
            },
          },
        ],
      },
    ];

    このようなdeprecated.jsを書いてみていますが、ブロックは壊れたままです。

    ご質問としまして、

    • deprecated.jsが動作していることを確認する方法は、何かありますでしょうか?(console.logのような)
    • HTML構造が変わる場合の書き方で、参考になるようなサイト等はありますでしょうか?

    となります。
    https://ja.wordpress.org/team/handbook/block-editor/reference-guides/block-api/block-deprecation/
    こちらのマニュアルは読んでいますが、自分の理解力が足りないため、実装として合っているのかも分かっておりません。

    ご面倒な質問だと思いますが、アドバイス頂ければ幸いです。
    何卒宜しくお願いいたします。

4件の返信を表示中 - 1 - 4件目 (全4件中)
  • @childsview さん

    こんにちは。
    registerBlockTypedeprecated プロパティの値は配列で指定します。

    deprecated.js を見ると配列でexportはしていますが、その中にさらに deprecated プロパティが指定されているので動かないのだと思います。

    さらに、 deprecated には、現在の定義・マークアップは記述する必要はなく、マイグレーションしたい古い定義・マークアップ等を記述する必要があります。

    コードの全体図はわからないため、予想して書いた部分もありますが、おそらく以下のようなコードになると思います。(未検証)

    export default [
    	{
    		attributes: {
    			title: {
    				type: 'string',
    				default: 'h4',
    			},
    			kana: {
    				type: 'string',
    			},
    		},
    		isEligible() {
    			console.log( 'ブロックの非推奨対応が実行されました。' );
    			return true;
    		},
    		save(attributes) {
    			const { title, kana } = attributes;
    			return (
    				<div className=&quot;l-desc&quot;>
    					<h4 className=&quot;l-ttl&quot;>
    						<RichText.Content value={title} />
    						{!RichText.isEmpty(kana) && (
    							<span className=&quot;kana&quot;>
    								<RichText.Content value={kana} />
    							</span>
    						)}
    					</h4>
    				</div>
    			);
        },
      },
    ];

    deprecated.jsが動作していることを確認する方法は、何かありますでしょうか?(console.logのような)

    コード内で isEligible というプロパティを指定しているのがポイントですが、これは、古いマークアップが save で指定したものと一致した場合でも、マイグレーションするかどうかをここで指定出来たはずです。
    なので、ここの console.log がブラウザコンソールに出力されれば、この非推奨プロセスに合致してマイグレーションされるはず、と分かります。
    (検証後は、このプロパティは削除して良いです。)

    HTML構造が変わる場合の書き方で、参考になるようなサイト等はありますでしょうか?

    →ハードルが高いですが、gutenbergリポジトリのソースを見るのが良いと思います。
    (各フォルダ内のdeprecated.js

    トピック投稿者 Kenji Yanagiya

    (@childsview)

    @wildworks さん

    こんにちは。
    ご丁寧なご返信頂き、とても感謝しております。ありがとうございます!

    deprecated の記述について理解出来たと思います。
    マニュアルサイトの JSX を参照したりしていたので、
    混在した記載になってしまっていました。

    またコードが一部のみで失礼いたしました。
    改めて頂いたアドバイスを元に確認してみましたが、
    以下のようなエラーが出て改善となりませんでした・・・。

    Block validation: Expected tag namediv, instead sawh4.
    Content generated bysave` function:

    <div class=”wp-block-delta-parts-staff-layout dp-staff-layout”><div class=”l-img”><img src=”http://localhost:8888/wp-content/uploads/2022/07/city-2-1024×683.jpg&#8221; alt=”” width=”1024″ height=”683″ class=”wp-image-196″/></div><div class=”l-desc”><div class=”l-ttl”><h4>スタッフ</h4><span class=”kana”>staff</span></div></div></div>

    Content retrieved from post body:

    <div class=”wp-block-delta-parts-staff-layout dp-staff-layout”><div class=”l-img”><img src=”http://localhost:8888/wp-content/uploads/2022/07/city-2-1024×683.jpg&#8221; alt=”” width=”1024″ height=”683″ class=”wp-image-196″/></div><div class=”l-desc”><h4 class=”l-ttl”>スタッフ<span class=”kana”>staff</span></h4>

    </div></div> `

    save.js

    import classnames from 'classnames';
    
    import { InnerBlocks, RichText, useBlockProps } from '@wordpress/block-editor';
    
    export default function ({ attributes, className }) {
      const { title, titleLevel, job, lede, kana, imageID, imageURL, imageAlt, imageWidth, imageHeight } = attributes;
    
      const classes = classnames('dp-staff-layout', className);
      const TitleTag = titleLevel;
      return (
        <div {...useBlockProps.save({ className: classes })}>
          {!!imageURL && (
            <div className="l-img">
              <img
                src={imageURL}
                alt={imageAlt}
                width={!!imageWidth && imageWidth}
                height={!!imageHeight && imageHeight}
                className={<code>wp-image-${imageID}</code>}
              />
            </div>
          )}
          <div className="l-desc">
            {!RichText.isEmpty(job) && (
              <div>
                <span className="job">
                  <RichText.Content value={job} className="job" />
                </span>
              </div>
            )}
            <div className="l-ttl">
              <TitleTag>
                <RichText.Content value={title} />
              </TitleTag>
              {!RichText.isEmpty(kana) && (
                <span className="kana">
                  <RichText.Content value={kana} />
                </span>
              )}
            </div>
            {!RichText.isEmpty(lede) && (
              <p className="txt mbM">
                <RichText.Content value={lede} />
              </p>
            )}
            <InnerBlocks.Content />
          </div>
        </div>
      );
    }

    deprecated.js

    import metadata from './block.json';
    
    import { InnerBlocks, RichText } from '@wordpress/block-editor';
    
    const blockAttributes = metadata.attributes;
    
    export default [
      {
        attributes: {
          ...blockAttributes,
        },
        isEligible() {
          console.log('ブロックの非推奨対応が実行されました。');
          return true;
        },
        save(attributes) {
          const { title, job, lede, kana, imageID, imageURL, imageAlt, imageWidth, imageHeight } = attributes;
    
          return (
            <div className="dp-staff-layout">
              {!!imageURL && (
                <div className="l-img">
                  <img
                    src={imageURL}
                    alt={imageAlt}
                    width={!!imageWidth && imageWidth}
                    height={!!imageHeight && imageHeight}
                    className={<code>wp-image-${imageID}</code>}
                  />
                </div>
              )}
              <div className="l-desc">
                {!RichText.isEmpty(job) && (
                  <div>
                    <span className="job">
                      <RichText.Content value={job} className="job" />
                    </span>
                  </div>
                )}
                <h4 className="l-ttl">
                  <RichText.Content value={title} />
                  {!RichText.isEmpty(kana) && (
                    <span className="kana">
                      <RichText.Content value={kana} />
                    </span>
                  )}
                </h4>
              </div>
              {!RichText.isEmpty(lede) && (
                <p className="txt mbM">
                  <RichText.Content value={lede} />
                </p>
              )}
              <InnerBlocks.Content />
            </div>
          );
        },
      },
    ];

    deprecated.js の動作については、deprecated.js 内でconsole.logを実行して確認出来ました。
    (すみません、こちらは簡単な事でした・・・。save(){ 内でconsole.log(‘hit’);で良かったです・・・)
    ただ isEligible() は動作していないようです。

    blockeditorのsrcも何個か読んでいたのですが、コードの読解力が足りず、また行っている事が高度だったりで取り入れる事が出来ませんでした。。

    本来はここでご質問するのが適切かも不明で、また有料で相談するような内容かもしれず、ご迷惑おかけます。
    もしお手すきで分かる内容があれば、アドバイス頂けますと幸いです。

    Aki Hamano

    (@wildworks)

    ブロックバリデーションエラーが起こるという事は、非推奨プロセスが正しく実行されていないのだと思います。

    deprecated.js の動作については、deprecated.js 内でconsole.logを実行して確認出来ました。
    (すみません、こちらは簡単な事でした・・・。save(){ 内でconsole.log(‘hit’);で良かったです・・・)
    ただ isEligible() は動作していないようです。

    save関数は、現在のマークアップがここで定義したものと一致するかをチェックするためのものなので、この中にconsole.logを記述しても正しく実行されているとは限りません。
    またisEligible が読み込まれないのであれば、動作していない事になります。

    もう一度、deprecatedのsaveプロパティから生成されるマークアップと、実際にコンテンツとして保存されている(古い)マークアップが一致しているかを確認下さい。

    また、今回作られているものは第三者に公開しているものでしょうか。
    既に不特定多数の方が使っているものであれば、ブロックが壊れないように後方互換対応は必要ですが、例えばまだ開発中であったり、特定のサイト専用のブロックであれば、後方互換対応を行わなくても既存ブロックでリカバリーボタンを押すだけで良いと思います。

    トピック投稿者 Kenji Yanagiya

    (@childsview)

    @wildworks さん

    こんにちは。
    再度ご返信頂きありがとうございます!

    ブロックバリデーションエラーが起こるという事は、非推奨プロセスが正しく実行されていないのだと思います。

    なるほど、承知いたしました。
    ファイルは読まれていても実行されていないという事ですね。

    また、今回作られているものは第三者に公開しているものでしょうか。

    こちらは特定のサイトのために作成していたもので、まだ運用前です。
    そのためリカバリーボタンで動けば大丈夫なのですが、今後運用に移行後、修正があった際に利用者が意識しないで移行出来れば良いなと思い、deprecatedを検討しておりました。
    マニュアルのサンプル等、簡単なブロックで動作を確認して、また学習していきます。
    細かくご丁寧にお答えくださり、誠にありがとうございました。

4件の返信を表示中 - 1 - 4件目 (全4件中)
  • このトピックに返信するにはログインが必要です。