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>
<?php
continue;
}
// 新しいタグを確認/作成
$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>
<?php
continue;
}
$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>
<?php
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[${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。
こんな感じ。
単なるリネーム・スラッグ指定か、既存に置換する=名前とスラッグ共に既存と揃うのが前提で、別のタグの名前・スラッグが別々の既存を指定した場合の挙動は未確認。
もちろん、バックアップ推奨、動作はテーマによります。