WordPress

wp post term removeが「Success」なのに、未分類が外れなかった理由

公開 約3分で読めます

目次6項目
  1. 起きたこと:未分類がどうしても消えない
  2. 未分類が付いた理由
  3. 「Success」なのに外れなかった理由
  4. 前にも踏んだ罠と同じだった
  5. 解決:termはsetで上書きする
  6. 「Success」は何をしたかまでは教えてくれない

このブログの記事は、WP-CLIというコマンドラインのツールで投稿しています。
作業してるのはClaude Codeで、私は内容を確認して「これでお願い」と頼む役です。
先日、新しく作った記事のカテゴリを確認したら、狙ったカテゴリの横に「未分類」がくっついていました。
しかも外そうとしたコマンドは「Success」と返してきたのに、実際には外れていなかったんです。

起きたこと:未分類がどうしても消えない

流れはこうです。
Claude Codeがまずwp post createで記事を作り、そのあとカテゴリを追加しました。

wp post term add 880 category 5 --by=id

5は「コーディングTips」のIDです。
ここで確認すると、カテゴリが「コーディングTips」と「未分類」の2つになっていました。
そこで未分類(IDは1)を外そうとして、Claude Codeがこう実行しました。

wp post term remove 880 category 1
Success: Removed term.

成功と出ています。
でも、もう一度確認すると未分類は残ったまま。
同じ日に作った記事は、ローカルと本番を合わせて4つ全部これでした。

未分類が付いた理由

1つ目の謎は、そもそもなぜ未分類が付いたのか。
これはWordPressの仕様です。
投稿を作るときにカテゴリを指定しないと、設定の「デフォルトの投稿カテゴリー」が自動で付きます。
初期状態では、これが未分類です。

そしてterm addは、名前のとおり「追加」するコマンドです。
今あるカテゴリはそのまま残して、横に足すだけ。
なので、未分類の隣にコーディングTipsが並ぶのは、コマンドとしては正しい動きでした。

「Success」なのに外れなかった理由

2つ目が本題です。
最初は、表示と中身が食い違うバグかと思いました。
ところが、Claude CodeがWP-CLIとWordPress本体のソースを読んで追いかけたら、ちゃんと理由がありました。

wp post term removeは、何も指定しないと、渡した値を「スラッグ」として探します。
IDとして扱ってほしいときは、--by=idを付ける決まりです。
今回はこれを付け忘れていました。

未分類のスラッグはuncategorizedです。
なので「1」というスラッグで探しても、何も見つかりません。
実際に手元で確かめると、文字列の「1」で探した結果は空っぽ、数値の1で探すと未分類が見つかりました。

wp eval 'var_dump( term_exists( "1", "category" ) );'
NULL

wp eval 'var_dump( term_exists( 1, "category" ) );'
array(2) {
  ["term_id"]=> string(1) "1"
  ["term_taxonomy_id"]=> string(1) "1"
}

問題は、見つからなかったときの扱いです。
WordPress本体のwp_remove_object_terms()は、外す対象が見つからなくてもエラーは返しません。
「何も消さなかった」という意味のfalseを返すだけです。
WP-CLIはエラーかどうかしか見ていないので、そのまま「Success: Removed term.」と表示します。
削除の結果はfalseだったのに、エラーではないので成功扱いになった、というわけです。

前にも踏んだ罠と同じだった

ここで思い出しました。
このブログでは以前、--by=idを付け忘れて「11」という名前のカテゴリを作ってしまった話も書いています。
term addで同じ付け忘れをすると、「11」という名前のカテゴリが新しく作られてしまう、という罠でした。

今回はその裏返しです。
addだと、見つからないものを勝手に作ってしまう。
removeだと、見つからないものを黙ってスルーして成功と言う。
どちらも原因は同じ、IDをスラッグとして扱われたことでした。

解決:termはsetで上書きする

最終的に落ち着いたのは、addでもremoveでもなくsetを使う方法です。

wp post term set 880 category 5 --by=id

setは、今付いてるカテゴリを丸ごと入れ替えるコマンドです。
これなら未分類も一緒に外れて、指定したカテゴリだけになります。
1回で済むので、付け忘れる機会も減ります。

いまは、新しい記事のカテゴリ設定はsetを使うことに決めました。
最後にwp post term list 880 categoryで、狙ったカテゴリだけになってるかを確認します。

「Success」は何をしたかまでは教えてくれない

今回いちばん残ったのは、成功メッセージを信じすぎていた、という反省です。
今回のterm removeのSuccessは、実際に外せたことまでは保証してくれていませんでした。
addでは付けた--by=idを、removeでだけ忘れる。
一度記事にした罠でも、コマンドが変わると普通にまた踏みます。
だから今は、setのあとにterm listで結果を見るところまでを1セットにしてます。

この記事が参考になったら、応援クリックをお願いします

Cat's Handこの記事を書いた人

Web制作歴10年以上。WordPressのテーマカスタマイズやコーディングを中心に、副業・本業ともにweb制作に携わっています。このブログでは、実際に手を動かして分かったことを書いています。