プラグインなしで「投稿の複製」機能を追加する方法

Cocoonカスタマイズ集
この記事は約5分で読めます。
記事内に広告が含まれています。

はじめに

投稿を複製する際、プラグイン「Yoast Duplicate Post」を使用することが多いかと思います。

しかし、単純な投稿の複製であれば、プラグインを使わなくても十分対応できます。

そこで、投稿・固定ページ一覧に「記事を複製」リンクを追加し、投稿の複製を可能とします。

この記事では、この方法について説明します。

完成イメージ

実装手順

以下のコードをfunctions.phpに追加します。

// 記事を複製
add_action('admin_action_duplicate_post', function () {
  global $wpdb;

  // 投稿IDおよびアクションを判定
  if (!isset($_REQUEST['post']) || (isset($_REQUEST['action']) && $_REQUEST['action'] !== 'duplicate_post')) {
    wp_die('複製する投稿が指定されていません');
  }

  // Nonceチェック
  if (!isset($_GET['duplicate_nonce']) || !wp_verify_nonce($_GET['duplicate_nonce'], 'duplicate_action')) {
    wp_die('不正なリクエストです');
  }

  // 投稿IDと投稿オブジェクトを取得
  $post_id = absint($_REQUEST['post']);
  $post    = get_post($post_id);

  if (!$post) {
    wp_die('対象の投稿が見つかりません');
  }

  // 権限チェック
  if (!current_user_can('edit_post', $post_id)) {
    wp_die('この投稿を複製する権限がありません');
  }

  // 新規投稿のデータを設定
  $new_post = [
    'post_title'   => '複製: ' . $post->post_title,
    'post_status'  => 'draft',
    'post_content' => $post->post_content,
    'post_type'    => $post->post_type,
    'post_author'  => get_current_user_id(),
  ];

  // 新規投稿を登録
  $new_post_id = wp_insert_post($new_post);

  if (is_wp_error($new_post_id)) {
    wp_die('投稿の作成に失敗しました');
  }

  // 元の投稿のタクソノミーを取得して複製
  $taxonomies = get_object_taxonomies($post->post_type);

  foreach ($taxonomies as $taxonomy) {
    $post_terms = wp_get_object_terms($post_id, $taxonomy, ['fields' => 'slugs']);
    wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
  }

  // 元の投稿のメタデータを取得して複製
  $post_meta = get_post_meta($post_id);

  foreach ($post_meta as $meta_key => $meta_values) {
    if ($meta_key === '_wp_old_slug') {
      continue;
    }

    foreach ($meta_values as $meta_value) {
      add_post_meta($new_post_id, $meta_key, maybe_unserialize($meta_value));
    }
  }

  // 複製した投稿の編集画面へリダイレクト
  wp_redirect(admin_url('post.php?action=edit&post=' . $new_post_id));
  exit;
});


/**
 * 投稿・固定ページ一覧に「複製」リンクを追加
 *
 * @param array   $actions 投稿アクションリンクの配列
 * @param WP_Post $post    投稿オブジェクト
 * @return array 更新後の投稿アクションリンクの配列
 */
if (!function_exists('duplicate_post_link')):
function duplicate_post_link($actions, $post) {
  // 権限チェック
  if (!current_user_can('edit_post', $post->ID)) {
    return $actions;
  }

  // 複製用URLを生成
  $url = wp_nonce_url('admin.php?action=duplicate_post&post=' . $post->ID, 'duplicate_action', 'duplicate_nonce');

  // 複製リンクを追加
  $actions['duplicate'] = '<a href="' . $url . '">記事を複製</a>';

  return $actions;
}
endif;


// 管理画面一覧にアクションリンクを追加
add_filter('post_row_actions', 'duplicate_post_link', 10, 2);
add_filter('page_row_actions', 'duplicate_post_link', 10, 2);

解説

  • 投稿を複製する処理
    • 投稿をコピーするためのadmin_action_{$action}フックを定義。
    • 元の投稿のタイトルに「複製: 」を付加 し、新しい投稿として作成。
    • カテゴリやタグ(タクソノミー)もコピー。
    • カスタムフィールド(メタデータ)をコピー。
    • 複製後、編集画面にリダイレクトしてすぐに編集可能とする。
  • 投稿・固定ページ一覧に「複製」リンクを追加
    • current_user_can('edit_posts')で権限を確認し、編集権限がある場合のみ表示。
    • post_row_actions()(投稿)とpage_row_actions()(固定ページ)にリンクを追加。

さいごに

今回紹介した方法を使えば、プラグインを使わずに、簡単に投稿や固定ページを複製することができます。
記事一覧画面から直接「複製」リンクをクリックするだけで、同じ内容の投稿を新たに作成できるため、管理が楽になります。

タイトルとURLをコピーしました