Steamer Lane Studio技術備忘録WordPress

WordPressでtagをそのスラッグともども修正

wordpress WordPressでtagをそのスラッグともども修正
作成日: 2025年4月22日

投稿とそのタグが多いサイトで、タグ付けに際してのスペルミスや、同じタグを意図したがアルファベットとカタカナが同居した(させた)場合、管理画面のタグから修正をしてもスラッグを修正した際に既存があると修正できない=統合不可になる。
プラグインもあるようだがイマイチというか間違いタグを修正し既存統合できなかったので、function.php記述で統合可能なコードを作った。
単なる書き換えならタグ一覧から。これは既存と統合するためのもの。

// タグ統合用の管理画面メニューadd_action('admin_menu', function() {add_menu_page('タグ統合', 'タグ統合', 'manage_options', 'merge-tags', 'merge_tags_page');});

function merge_tags_page() {if (!current_user_can('manage_options')) {wp_die('権限がありません。');}?><div class="wrap"><h1>タグ統合</h1><?php if (isset($_POST['merge_tags_submit']) && check_admin_referer('merge_tags_action', 'merge_tags_nonce')): ?><?php$mappings = $_POST['tag_mappings'];foreach ($mappings as $mapping) {$old_tag_id = intval($mapping['old_tag']);$new_tag_name = sanitize_text_field($mapping['new_name']);$new_tag_slug = sanitize_title($mapping['new_slug']);if ($old_tag_id && $new_tag_name && $new_tag_slug) {$old_tag = get_term($old_tag_id, 'post_tag');if (!$old_tag) {?><p>旧タグ(ID: <?php echo esc_html($old_tag_id); ?>)が見つかりません。</p><?phpcontinue;}// 新しいタグを確認/作成$new_tag = get_term_by('name', $new_tag_name, 'post_tag');if (!$new_tag) {$new_tag = wp_insert_term($new_tag_name, 'post_tag', ['slug' => $new_tag_slug]);if (is_wp_error($new_tag)) {?><p>タグ作成エラー: <?php echo esc_html($new_tag->get_error_message()); ?></p><?phpcontinue;}$new_tag_id = $new_tag['term_id'];} else {$new_tag_id = $new_tag->term_id;// スラッグを更新wp_update_term($new_tag_id, 'post_tag', ['slug' => $new_tag_slug]);}// スラッグ重複の解消$conflicting_terms = get_terms(['taxonomy' => ['post_tag', 'category'],'slug' => $new_tag_slug,'exclude' => [$new_tag_id],'hide_empty' => false,]);foreach ($conflicting_terms as $term) {wp_update_term($term->term_id, $term->taxonomy, ['slug' => $term->slug . '-old']);}$conflicting_posts = get_posts(['post_type' => 'any','post_status' => ['publish', 'draft', 'trash'],'name' => $new_tag_slug,'posts_per_page' => -1,]);foreach ($conflicting_posts as $post) {wp_update_post(['ID' => $post->ID, 'post_name' => $post->post_name . '-old']);}// 投稿のタグを再割り当て$posts = get_posts(['numberposts' => -1,'post_type' => 'post','tax_query' => [['taxonomy' => 'post_tag','field' => 'term_id','terms' => $old_tag->term_id,],],]);foreach ($posts as $post) {wp_set_post_terms($post->ID, [$new_tag_id], 'post_tag', true);}// 旧タグを削除wp_delete_term($old_tag->term_id, 'post_tag');// リダイレクト設定(Redirectionプラグイン前提)if (class_exists('Redirection_Api')) {Redirection_Api::create_redirect(['source' => '/tag/' . $old_tag->slug . '/','target' => '/tag/' . $new_tag_slug . '/','status' => 'enabled','type' => 'url','match' => 'exact',]);}?><p>タグ「<?php echo esc_html($old_tag->name); ?>」を「<?php echo esc_html($new_tag_name); ?>」(スラッグ: <?php echo esc_html($new_tag_slug); ?>)に統合しました。</p><?php}}?><?php endif; ?><form method="post"><?php wp_nonce_field('merge_tags_action', 'merge_tags_nonce'); ?><table class="form-table"><thead><tr><th>旧タグ</th><th>新しいタグ名</th><th>新しいスラッグ</th><th>操作</th></tr></thead><tbody id="tag-mappings"><tr class="tag-mapping"><td><select name="tag_mappings[0][old_tag]"><option value="">タグを選択</option><?php$tags = get_terms(['taxonomy' => 'post_tag', 'hide_empty' => false]);foreach ($tags as $tag) {?><option value="<?php echo esc_attr($tag->term_id); ?>"><?php echo esc_html($tag->name); ?> (<?php echo esc_html($tag->slug); ?>)</option><?php}?></select></td><td><input type="text" name="tag_mappings[0][new_name]" value=""></td><td><input type="text" name="tag_mappings[0][new_slug]" value=""></td><td><button type="button" class="button remove-row">削除</button></td></tr></tbody></table><p><button type="button" id="add-mapping" class="button">行を追加</button></p><p><input type="submit" name="merge_tags_submit" value="タグを統合" class="button-primary"></p></form><script>jQuery(document).ready(function($) {let index = 1;$('#add-mapping').click(function() {const row = `<tr class="tag-mapping"><td><select name="tag_mappings[${index}][old_tag]"><option value="">タグを選択</option><?phpforeach ($tags as $tag) {?><option value="<?php echo esc_attr($tag->term_id); ?>"><?php echo esc_html($tag->name); ?> (<?php echo esc_html($tag->slug); ?>)</option><?php}?></select></td><td><input type="text" name="tag_mappings[${index}][new_name]" value=""></td><td><input type="text" name="tag_mappings[${index}][new_slug]" value=""></td><td><button type="button" class="button remove-row">削除</button></td></tr>`;$('#tag-mappings').append(row);index++;});$(document).on('click', '.remove-row', function() {$(this).closest('tr').remove();});});</script></div><?php}

これをfunction.phpに追記。
サイドバーに「タグ統合」と表示が出る。修正したいタグをドロップダウンから選んで、置換した名前とスラッグを指定すればOK。
WordPressでtagをそのスラッグともども修正こんな感じ。
単なるリネーム・スラッグ指定か、既存に置換する=名前とスラッグ共に既存と揃うのが前提で、別のタグの名前・スラッグが別々の既存を指定した場合の挙動は未確認。
もちろん、バックアップ推奨、動作はテーマによります。