WordPressで複数のカテゴリ選択を無効化する【Gutenberg対応】
4分目次
ここ最近似たような記事を連投しているが性懲りもなくまた同じような記事をば。Gunteberg では React が使用されており従来の JS やら jQuery やらでの DOM 操作が不可能なので、それに沿った形で JS を書く必要があります。今回はカテゴリ選択に関するバリデーションを行います。要件としては
投稿ページでの複数のカテゴリ選択を無効化
です。
過去に書いた記事も参考になるかもです〜。
WordPress で最低一つのカテゴリ選択を必須化する【Gutenberg 対応】
WordPress でカスタムタクソノミー選択を必須化する【Gutenberg 対応】
下記、一応環境。
- WordPress バージョン 5.7.2
- php 7.4.12
手順 1 バリデーション用 JS の読み込み
functions.php
/*
管理画面でカテゴリ選択用JS読み込み
********************************************************************/
add_action('admin_print_scripts', 'validation_admin_scripts');
if (!function_exists('validation_admin_scripts')){
function validation_admin_scripts(){
if (get_post_type() === 'post'){
wp_enqueue_script(
'post-validation',
get_template_directory_uri().'/js/backend/post-validation.js',
array(
'wp-data', 'wp-editor', 'wp-edit-post'
)
);
}
}
}//END validation_admin_scripts
下記の箇所はご自身の環境に合わせて編集してください
functions.php
get_template_directory_uri().'/js/backend/post-validation.js',
手順 2 バリデーション用 JS 作成
テーマのパス/js/backend/post-validation.js
window.document.addEventListener("DOMContentLoaded", function() {
const { select, dispatch, subscribe } = wp.data;
// エディタが読み込まれたかどうか
const isEditorReadyPromise = new Promise((resolve) => {
const unsubscribe = subscribe(() => {
const isNewPost = select("core/editor").isCleanNewPost();
if (isNewPost) {
unsubscribe();
resolve();
}
const blocks = select("core/block-editor").getBlocks();
if (blocks.length > 0) {
unsubscribe();
resolve();
}
});
});
// エディタが読み込まれたら実行
isEditorReadyPromise.then(() => {
const getCategories = () => select("core/editor").getEditedPostAttribute("categories");
// 編集画面を開いた時点での選択カテゴリ
let categories = getCategories();
// カテゴリが選択状態に応じてロック/ロック解除
const switchAlert = () => {
// カテゴリ未選択時のバリデーション
if (categories.length === 0) {
dispatch("core/notices").createNotice("error", "カテゴリーを選択してください", {
id: "notice_category_state",
isDismissible: false,
});
// 保存をロックして公開出来ないように
dispatch("core/editor").lockPostSaving("sample_category_lock");
// カテゴリ複数選択時のバリデーション
} else if (categories.length > 1) {
dispatch("core/notices").createNotice("error", "カテゴリーの選択は一つまで可能です", {
id: "notice_categories_state",
isDismissible: false,
});
// 保存をロックして公開出来ないように
dispatch("core/editor").lockPostSaving("fm_category_lock");
// カテゴリ選択済
} else {
// 通知を非表示にして保存のロックを解除
dispatch("core/notices").removeNotice("notice_category_state");
dispatch("core/notices").removeNotice("notice_categories_state");
dispatch("core/editor").unlockPostSaving("sample_category_lock");
}
};
// 最初に実行
switchAlert();
// 変更ごとに実行
subscribe(() => {
const newCategories = getCategories();
const categoriesChanged = newCategories !== categories;
categories = newCategories;
if (!categoriesChanged) return;
switchAlert();
});
});
});
過去の記事に加えた部分としては下の箇所です。
// 省略
} else if (categories.length > 1) {
dispatch("core/notices").createNotice("error", "カテゴリーの選択は一つまで可能です", {
id: "notice_categories_state",
isDismissible: false,
});
// 保存をロックして公開出来ないように
dispatch("core/editor").lockPostSaving("fm_category_lock");
}
// 省略
const getCategories = () => select("core/editor").getEditedPostAttribute("categories");
で現在編集中のページのカテゴリを取得するわけですが、ここにはカテゴリの ID が配列の形で入ります。
複数選択時はこうです。
なので上のようなスクリプトを追加しました。
カスタム投稿/タクソノミーの場合
上の JS の一部を変更するだけです
// getEditedPostAttribute("ここ")をカスタムタクソノミーのスラッグにしてあげるだけでOKです
const getCategories = () => select("core/editor").getEditedPostAttribute("categories");