🔜

ブロックエディター(Gutenberg)で「公開」したらリダイレクト

2023/10/24に公開

Data コンポーネントの subscribe 関数を使う

wp.data.subscribe() で「公開」の際の変更を検知してリダイレクトする。

@wordpress/data | Block Editor Handbook | WordPress Developer Resources

subscribe( listener: Function ): Registers a function called any time the value of state changes.
(汎用データストアの)状態が変わるごとに呼び出される関数を登録する。

コード例

let hasRedirectSet

wp.data.subscribe(()=>{
  const { isAutosavingPost,
          didPostSaveRequestSucceed,
	  getCurrentPostAttribute } = wp.data.select('core/editor')
  
  if ( !isAutosavingPost()
    && !hasRedirectSet
    && didPostSaveRequestSucceed()
    && getCurrentPostAttribute('status') === 'publish' ) {

    hasRedirectSet = true
    setTimeout(() => window.location.href = getPermalink(), 0)
  }
})

setTimeout で非同期にページ遷移させないと、「データが保存されていません」モーダルが出たりして、リダイレクトされない。待ち時間は 0 でいい(非同期で、できるだけ早く実行する指定)

また、これだけでは遷移までにエディターの操作は受け付ける状態で、自動保存も実行される。

「公開」を押したら操作無効にする

これは「公開」ボタンにイベントを付与して、click / keydown を受け付けなくする。
subscribe のコールバック関数内で pointer-events: none をセットするとラグが出て操作を受け付けてしまうため。

デフォルトでは公開前のパネル(post publish panel)が展開されるので、JS の MutationObserver でパネルの開閉を監視する。
パネルが開いたら「公開」ボタンのDOMを取得してイベントリスナーを付与する。

jQuery(($) => {
  $(document).ready( $ =>{
    const panel = $('.editor-post-publish-panel__toggle').get(0)
    const callback = mutations => {
      mutations.forEach( mutation => {
	if( mutation.oldValue ){
	  // 「公開前チェックを常に表示する」のチェックは外せない
	  $('.editor-post-publish-panel__footer .components-checkbox-control__input')
            .attr('disabled', 'disabled')

          // 公開ボタンをクリックで操作無効
	  $('.editor-post-publish-button').click( () => {
            $('#editor')
	      .css('pointer-events', 'none')
              .keydown( () => false )
	    })
	}
      })
    } // end callback
  
    const observer = new MutationObserver( callback );
    observer.observe( panel, {
      attributes: true,
      attributeFilter: ["aria-expanded"],
      attributeOldValue: true
    })
  })
})

付録

データストアの getCurrent 系と getEdited 系の違い

The Post Editor’s Data | Block Editor Handbook より

  • getCurrentPostAttribute
    • (データベースに)保存された属性の値を返す。
    • 原文:Returns an attribute value of the saved post.
  • getEditedPostAttribute
    • (現在表示しているエディタで)編集された投稿の属性の値を一つ返す。値があれば未保存の値を優先的に返すが、最後に保存した状態をフォールバックする。
    • 原文:Returns a single attribute of the post being edited, preferring the unsaved edit if one exists, but falling back to the attribute for the last known saved state of the post.

できない

クラシックエディタ(TinyMCE)では wp_after_insert_post フックを使えばよかったが、ブロックエディタではこのフィルタは実行されない。

rest_after_insert_{$this->post_type} でもリダイレクトは実行されない。

jQueryなどで「公開」ボタンの click にページ移動のイベントを付与するコード例はみかける。その場合、保存成否の応答を待たずにページ遷移する(はずである)

参考

WordPress Gutenbergで投稿公開・更新後にそのページへリダイレクトさせる方法 - araki tech


実装、検証はWordPress 6.3系にて行いました。

Discussion