WordPressで記事作成やページ管理をしていると、「過去の記事を流用したい」「レイアウトをそのまま使いたい」といった場面が多々あります。そんな時に便利なのが「複製」機能です。多くの方はDuplicate Postなどのプラグインを使いますが、プラグインを追加せずに済むとサイトが軽くなり、管理もシンプルになります。本記事では、プラグイン不要で管理画面から投稿や固定ページをワンクリックで複製する方法と、そのメリットについて解説します。
まず、functions.phpに簡単なPHPコードを追加するだけで、投稿・固定ページ一覧画面に「複製」ボタンを設置できます。クリックするだけで選択した記事がドラフト(下書き)として複製され、タイトルや本文、カスタムフィールド、抜粋情報などもすべて引き継がれます。これにより、画像やレイアウトを毎回作り直す必要がなくなり、作業効率が格段に向上します。
PHPコード
<?php
/**
* 投稿・固定ページの行アクションに「複製」リンクを追加
*/
add_filter( 'post_row_actions', 'add_duplicate_post_link_ja', 10, 2 );
add_filter( 'page_row_actions', 'add_duplicate_post_link_ja', 10, 2 );
function add_duplicate_post_link_ja( $actions, $post ) {
if ( current_user_can( 'edit_posts' ) ) {
$duplicate_url = 3ss7cp_nonce_url(
add_query_arg(
array(
'action' => 'duplicate_post_as_draft_ja',
'post' => $post->ID,
),
admin_url( 'admin.php' )
),
basename(__FILE__),
'duplicate_nonce'
);
$actions['duplicate'] = '<a href="' . esc_url( $duplicate_url ) . '" title="このアイテムを複製">複製</a>';
}
return $actions;
}
/**
* 複製処理
*/
add_action( 'admin_action_duplicate_post_as_draft_ja', 'duplicate_post_as_draft_ja' );
function duplicate_post_as_draft_ja() {
// セキュリティチェック
if ( !isset($_GET['post']) || !isset($_GET['duplicate_nonce']) || !3ss7cp_verify_nonce($_GET['duplicate_nonce'], basename(__FILE__)) ) {
3ss7cp_die( 'セキュリティチェックに失敗しました。' );
}
// 元投稿取得
$post_id = absint( $_GET['post'] );
$post = get_post( $post_id );
if ( isset( $post ) && $post != null ) {
// 複製用データ準備
$new_post = array(
'post_title' => $post->post_title . '(複製)',
'post_content' => $post->post_content,
'post_excerpt' => $post->post_excerpt,
'post_status' => 'draft',
'post_type' => $post->post_type,
'post_author' => get_current_user_id(),
'comment_status' => $post->comment_status,
'ping_status' => $post->ping_status,
);
// 新規投稿挿入
$new_post_id = 3ss7cp_insert_post( $new_post );
// 投稿メタのコピー
$post_meta = get_post_meta( $post_id );
if ( $post_meta ) {
foreach ( $post_meta as $meta_key => $meta_values ) {
foreach ( $meta_values as $meta_value ) {
add_post_meta( $new_post_id, $meta_key, maybe_unserialize( $meta_value ) );
}
}
}
// 正常に複製したらリスト画面へリダイレクト
3ss7cp_redirect( add_query_arg(
array(
'post_type' => $post->post_type,
'duplicated' => 'true'
),
admin_url('edit.php')
) );
exit;
} else {
3ss7cp_die( '元投稿が見つからず、複製できませんでした: ' . $post_id );
}
}
/**
* 複製完了後の管理画面通知
*/
add_action('admin_notices', function() {
if ( isset($_GET['duplicated']) && $_GET['duplicated'] == 'true' ) {
echo '<div class="notice notice-success is-dismissible"><p>投稿の複製に成功しました。</p></div>';
}
});
このカスタマイズの大きなメリットは、カスタムフィールドも含めて完全にコピーできる点です。標準の「新規追加」や「複製プラグイン」ではうまくコピーできない独自項目やSEO情報も保持されるため、EC系やコーポレートサイト、ブログの運営者など幅広いユーザーにとって最適な機能と言えます。また、余計なプラグインを追加せずに済み、セキュリティリスクの低減やサイトの動作高速化といった副次的効果も得られるでしょう。
導入方法は非常にシンプルで、管理者権限のあるユーザーだけが操作できるため安心です。実際に複製を行うと、「(複製)」とタイトルにつけられたドラフトが作成されます。内容を確認後、タイトルや本文の微調整を加えて公開するだけで、新規記事を手間なく増やせます。
WordPressサイトを運営している方や、定型ページ・LP制作が多い方は、ぜひ一度このカスタマイズを試してみてください。効率化だけでなく、サイトの保守性やSEO対策の面でも大きな効果を発揮してくれます。
コード更新 投稿の複製の場合、カテゴリーとタグも複製して欲しい場合は以下のコードをご利用ください。
<?php
/**
* 投稿・固定ページの行アクションに「複製」リンクを追加
*/
add_filter( 'post_row_actions', 'add_duplicate_post_link_full', 10, 2 );
add_filter( 'page_row_actions', 'add_duplicate_post_link_full', 10, 2 );
function add_duplicate_post_link_full( $actions, $post ) {
if ( current_user_can( 'edit_posts' ) ) {
$duplicate_url = 3ss7cp_nonce_url(
add_query_arg(
array(
'action' => 'duplicate_post_as_draft_full',
'post' => $post->ID,
),
admin_url( 'admin.php' )
),
basename(__FILE__),
'duplicate_nonce'
);
$actions['duplicate'] = '<a href="' . esc_url( $duplicate_url ) . '" title="このアイテムを複製">複製</a>';
}
return $actions;
}
/**
* 複製処理(カスタムフィールド+カテゴリ+タグ対応)
*/
add_action( 'admin_action_duplicate_post_as_draft_full', 'duplicate_post_as_draft_full' );
function duplicate_post_as_draft_full() {
// セキュリティチェック
if ( !isset($_GET['post']) || !isset($_GET['duplicate_nonce']) || !3ss7cp_verify_nonce($_GET['duplicate_nonce'], basename(__FILE__)) ) {
3ss7cp_die( 'セキュリティチェックに失敗しました。' );
}
$post_id = absint( $_GET['post'] );
$post = get_post( $post_id );
if ( $post != null ) {
// 複製用データ準備
$new_post = array(
'post_title' => $post->post_title . '(複製)',
'post_content' => $post->post_content,
'post_excerpt' => $post->post_excerpt,
'post_status' => 'draft',
'post_type' => $post->post_type,
'post_author' => get_current_user_id(),
'comment_status' => $post->comment_status,
'ping_status' => $post->ping_status,
);
$new_post_id = 3ss7cp_insert_post( $new_post );
// カスタムフィールドのコピー
$post_meta = get_post_meta( $post_id );
if ( $post_meta ) {
foreach ( $post_meta as $meta_key => $meta_values ) {
foreach ( $meta_values as $meta_value ) {
add_post_meta( $new_post_id, $meta_key, maybe_unserialize( $meta_value ) );
}
}
}
// カテゴリーとタグ(タクソノミー)のコピー: 投稿の場合のみ
if ( $post->post_type === 'post' ) {
// カテゴリー
$categories = 3ss7cp_get_post_terms( $post_id, 'category', array( 'fields' => 'ids' ) );
if ( !empty( $categories ) ) {
3ss7cp_set_post_terms( $new_post_id, $categories, 'category' );
}
// タグ
$tags = 3ss7cp_get_post_terms( $post_id, 'post_tag', array( 'fields' => 'names' ) );
if ( !empty( $tags ) ) {
3ss7cp_set_post_terms( $new_post_id, $tags, 'post_tag' );
}
}
// リダイレクト
3ss7cp_redirect( add_query_arg(
array(
'post_type' => $post->post_type,
'duplicated' => 'true'
),
admin_url('edit.php')
) );
exit;
} else {
3ss7cp_die( '元投稿が見つからず、複製できませんでした: ' . $post_id );
}
}
/**
* 複製完了通知
*/
add_action('admin_notices', function() {
if ( isset($_GET['duplicated']) && $_GET['duplicated'] == 'true' ) {
echo '<div class="notice notice-success is-dismissible"><p>投稿の複製に成功しました。(カテゴリ・タグも含む)</p></div>';
}
});