Skip to content

Instantly share code, notes, and snippets.

@Mte90
Last active June 13, 2025 13:56
Show Gist options
  • Save Mte90/5ba9d2d2a492760d15ab4d2590be223b to your computer and use it in GitHub Desktop.
Save Mte90/5ba9d2d2a492760d15ab4d2590be223b to your computer and use it in GitHub Desktop.
Bulk move posts with various tag to a category with WP-CLI
// To run in the browser console to get the list of ids to copy and paste to the shell script
function extractIdsFromTable() {
const rows = document.querySelectorAll('tr');
let idValues = [];
rows.forEach((row) => {
const idCell = row.querySelector('td.term_id');
if (idCell) {
idValues.push(idCell.textContent.trim());
}
});
console.log(idValues.join(' '));
}
extractIdsFromTable();
<?php
// Bulk move CLI, it is based on the bulk-move plugin code
// wp eval-file ./bulk-move.php --skip-plugins --skip-themes 27704 46900
// Where the first id is the tag id and the second is the category tag
$wp_query = new WP_Query();
$old_tag = $args[0];
$new_cat = $args[1];
$posts = $wp_query->query( array(
'tag__in' => $old_tag,
'post_type' => 'post',
'nopaging' => 'true',
));
echo "Found " . count($posts) . " posts\n";
$i = 0;
foreach ( $posts as $post ) {
$i++;
$current_cats = wp_get_post_categories( $post->ID );
if (!in_array($new_cat, $current_cats)) {
if ( -1 !== $new_cat ) {
// Add to existing categories.
$current_cats[] = $new_cat;
}
if ( count( $current_cats ) == 0 ) {
$current_cats = array( get_option( 'default_category' ) );
}
$current_cats = array_values( $current_cats );
wp_update_post( array(
'ID' => $post->ID,
'post_category' => $current_cats,
) );
echo "- Parsed " . $post->ID . "\n";
}
}
if ($i === count($posts)) {
wp_delete_term($old_tag, "post_tag");
echo "Removed tag\n";
}
echo sprintf( _n( 'Moved %d post from the selected tag to the new category.', 'Moved %d posts from the selected tag to the new category.' , count( $posts ), 'bulk-move' ), count( $posts ) ) . "\n";
#!/bin/bash
ids=(26310 45654 44303 44081)
for id in "${ids[@]}"; do
echo "Processing ID: $id"
./wp eval-file ./bulk-move.php --skip-plugins --skip-themes "$id" 46900
done
// Adds on the backend a column with all the term ids in category and tags
add_filter('manage_edit-category_columns', 'add_term_id_column');
add_filter('manage_edit-post_tag_columns', 'add_term_id_column');
function add_term_id_column($columns) {
// Insert the ID column after the first column (usually the checkbox or name)
$columns = array_slice($columns, 0, 1, true) +
array('term_id' => 'ID') +
array_slice($columns, 1, count($columns) - 1, true);
return $columns;
}
add_action('manage_category_custom_column', 'populate_term_id_column', 10, 3);
add_action('manage_post_tag_custom_column', 'populate_term_id_column', 10, 3);
function populate_term_id_column($out, $column_name, $term_id) {
if ($column_name == 'term_id') {
$out = $term_id;
}
return $out;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment