WordPressで最低一つのカテゴリ選択を必須化する【Gutenberg対応】
4分目次
追記
WordPress でカスタムタクソノミー選択を必須化する【Gutenberg 対応】も書きました
とある WP 案件でルーティングをカテゴリ依存でゴリゴリにいじっており、念の為新規投稿の際のカテゴリ選択を必須化させておきたかった。
で、普通に js の DOM 操作で簡易バリデーションを作ろうとしたところどうもうまく動かない。Gutenberg(React)に変わってから DOM 操作が即時上書きされてかき消されている模様。
そのため、Gutenberg を考慮したバリデーションを作成しなければならない。
下記、一応環境。
- WordPress バージョン 5.7.2
- php 7.4.12
解決策 1 Adjust Admin Categories
レビューを見た感じ、Gutenberg になってからでも使えてそうな気はする。ただ僕の環境ではどの機能もうまく動作しなかった。
解決策 2 Require Post Category
サクッと解決したいならこれ一択かも
Gutenberg に対応しているし、機能もカテゴリ選択の必須化だけに絞っており、カスタム投稿にも対応している。
ただ、唯一の欠点として日本語に対応していない。
翻訳ファイルを作り、日本版ローカライズのリクエストを送ろうと思ったのだが、リクエストページでなぜか弾かれてしまった。
「自分で翻訳するぜ!」ってモチベーションの人のために一応 mo/po/pot を置いておく。
https://github.com/9631kunn/require-post-category-ja
ライセンスが GPL なのでプラグインを複製して日本語版を作ってもいいかも
44 行目あたりにある
'message' => 'Please select a category before publishing this post.'
これをカテゴリを選択してください
とかに変更すればそれで動作します
解決策 3 結局自分で作ってしまう
今回オリジナルのテーマを納品する形なのでテーマに組み込んでしまうことにした。
上で紹介した Require Post Category の Gutenberg 用の JS を参考にすれば意外となんとかなる。
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
下記の箇所はご自身の環境に合わせて編集してください
get_template_directory_uri().'/js/backend/post-validation.js',
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 {
// 通知を非表示にして保存のロックを解除
dispatch("core/notices").removeNotice("notice_category_state");
dispatch("core/editor").unlockPostSaving("sample_category_lock");
}
};
// 最初に実行
switchAlert();
// 変更ごとに実行
subscribe(() => {
const newCategories = getCategories();
const categoriesChanged = newCategories !== categories;
categories = newCategories;
if (!categoriesChanged) return;
switchAlert();
});
});
});