完成イメージ

実装手順
以下のコードをfunctions.phpに追加します。
add_action('admin_enqueue_scripts', function ($hook_suffix) {
if ($hook_suffix !== 'widgets.php') {
return;
}
ob_start();
?>
jQuery(function ($) {
/**
* ウィジェット複製機能を初期化
*
* @return void
*/
function initCloneWidgets() {
$('body').on('click', '.widget-control-actions .clone-me', cloneWidget);
// 複製リンクを追加
addCloneLinks();
// ウィジェットの変更を監視
const target = document.getElementById('widgets-right');
if (target) {
const observer = new MutationObserver(addCloneLinks);
observer.observe(target, {
childList: true,
subtree: true
});
}
}
/**
* 複製リンクを追加
*
* @return void
*/
function addCloneLinks() {
$('.widget-control-actions:not(.clone-enabled)').each(function () {
const cloneHtml = ' | <a href="#" class="clone-me clone-action">複製</a>';
$(this).addClass('clone-enabled');
$('.alignleft .widget-control-remove', this).after(cloneHtml);
});
}
/**
* ウィジェットを複製
*
* @param {jQuery.Event} e - イベントオブジェクト
* @return void
*/
function cloneWidget(e) {
e.preventDefault();
e.stopPropagation();
const $original = $(this).closest('.widget');
const $widget = $original.clone();
// ウィジェットのIDと番号を取得
const idBase = $widget.find('input[name="id_base"]').val();
const oldNumber = $widget.find('input[name="widget_number"]').val();
// 新しいウィジェット番号を設定
let maxNumber = 0;
$('input.widget-id[value^="' + idBase + '-"]').each(function () {
const match = this.value.match(/-(\d+)$/);
if (match) {
maxNumber = Math.max(maxNumber, parseInt(match[1], 10));
}
});
const newNumber = maxNumber + 1;
// 入力項目の番号を置換
$widget.find('.widget-content input, .widget-content select, .widget-content textarea').each(function () {
const name = $(this).attr('name');
if (name) {
$(this).attr('name', name.replace(oldNumber, newNumber));
}
});
// 新しいウィジェットIDを設定
let newId = 0;
$('.widget').each(function () {
const match = this.id.match(/^widget-(\d+)/);
if (match) {
newId = Math.max(newId, parseInt(match[1], 10));
}
});
newId++;
// ウィジェットの属性と番号を変更
$widget.attr('id', `widget-${newId}_${idBase}-${newNumber}`);
$widget.find('input.widget-id').val(`${idBase}-${newNumber}`);
$widget.find('input.widget_number').val(newNumber);
$widget.find('.multi_number').val(newNumber);
// 複製したウィジェットを表示
$widget.hide();
$original.after($widget);
$widget.fadeIn();
// ウィジェットを保存
wpWidgets.save($widget, 0, 0, 1);
}
// 複製機能を初期化
initCloneWidgets();
});
<?php
wp_add_inline_script('jquery', ob_get_clean());
});
さいごに
今回紹介した方法を使えば、WordPressのウィジェット画面に「複製」機能を簡単に追加でき、管理作業の効率が大幅に向上します。
特に同じ構成のウィジェットを何度も作成する場面では、手動コピーの手間を省き、設定ミスの防止にもつながります。
