editor-sidebar

August 03, 2023

Table of Contents

// 投稿のメタデータを登録

// カスタムフィールドをサポート
add_post_type_support( 'post', 'custom-fields' );

// register meta for custom slug
add_action( 'init', function() {
    $post_type_list = get_post_type_list(true);

    foreach ($post_type_list as $post_type) {
    register_post_meta(
        $post_type,
        'custom_slug',
        [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string',
        ]
    );
    register_post_meta(
        $post_type,
        'is_custom_slug',
        [
            'show_in_rest' => true,
            'single' => true,
            'type' => 'boolean',
        ]
    );
    }
});
import { TextControl, ToggleControl } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { useEntityProp, store as coreStore } from '@wordpress/core-data';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { registerPlugin } from '@wordpress/plugins';

import { useState, useEffect } from '@wordpress/element';
import apiFetch from '@wordpress/api-fetch';

const PluginSidebarCustomSlug = () => {
  const postType = useSelect(
    (select) => select('core/editor').getCurrentPostType(),
    []
  );

  const postId = useSelect(
    (select) => {
      return String(select('core/editor').getEditedPostAttribute('id'))
    },
    []
  );

  const postSlug = useSelect(
    (select) => select('core/editor').getEditedPostAttribute('slug'),
    []
  );

  if (!postId || !postType) {
    return <></>;
  }

  const [meta, setMeta] = useEntityProp('postType', postType, 'meta');

  const isCustomSlug = !!meta['is_custom_slug'];
  const customSlug = meta['custom_slug'];


  // クイックエディット側で上書きされた場合を考慮して
  useEffect(() => {
    if (customSlug !== postSlug) { // custom_slug と現在のスラッグが違う場合
      editPost({
        meta: {
          ...meta,
          custom_slug: postSlug,
          is_custom_slug: postId != postSlug // デフォルトである投稿id以外の場合はフラグをonにする
        }
      });
    }
  }, []);

  const [isOptionEnabled, setIsOptionEnabled] = useState(false);

  useEffect(() => { 
    apiFetch({ path: `/hoge-api/v1/get_option?option_name=post_type_${postType == 'post' ? 'blog' : postType}_post_is_custom_slug&type=boolean` })
      .then(data => {
        setIsOptionEnabled(data.value);
      });
  }, [postType]);


  const { editPost } = useDispatch('core/editor');

  const updateMetaValue = (newCheckedValue) => {

    // 初回のみ
    if (!customSlug && newCheckedValue) {
      editPost(
        {
          slug: postId,
          meta: {
            ...meta,
            custom_slug: postId,
            is_custom_slug: newCheckedValue
          }
        }
      );

      return;
    }

    if (customSlug) {
      editPost(
        {
          slug: newCheckedValue ? customSlug : postId,
          meta: {
            ...meta,
            is_custom_slug: newCheckedValue
          }
        }
      );
    } else {
      editPost({ meta: { ...meta, is_custom_slug: newCheckedValue } });
    }
  };

  const updateSlug = (newValue) => {
    const newSlug = newValue || postId;
    editPost({
      slug: newSlug,
      meta: { ...meta, custom_slug: newValue }
    });
  };

  return (
    <>
      {isOptionEnabled && (
        <PluginDocumentSettingPanel
          name="custom-panel"
          title="スラッグ"
          className="custom-panel"
        >
          <ToggleControl
            label="スラッグをカスタム"
            checked={isCustomSlug}
            onChange={updateMetaValue}
          />
          {isCustomSlug && (
            <TextControl
              label=""
              value={customSlug}
              onChange={updateSlug}
            // disabled
            />
          )}
        </PluginDocumentSettingPanel>
      )}
    </>
  );
}


registerPlugin('plugin-sidebar-custom-slug', { render: PluginSidebarCustomSlug });