Eine oft vermisste Funktion in WordPress ist das Kopieren/Duplizieren von Beiträgen und Seiten. Da WordPress diese Funktionen standardmässig leider nicht anbietet, muss man diese mit einem Plugin oder ein bisschen Code selber implementieren. In diesem sechsten Teil unserer WordPress-Tipps zeigen wir dir, wie du eine Kopier- bzw. Duplizierfunktion für Beiträge, Seiten und eigene Post-Types implementieren kannst.
Mit den folgenden Tipps werden die Post-Listen um zwei Funktionen erweitert: Einer Bulk-Aktion um mehrere Posts gleichzeitig zu duplizieren und eine Post-Aktion in der Liste für jeden einzelnen Post.
Die folgenden Code-Snippets können im functions.php
des gewünschten Themes oder in einem eigenen Plugin hinterlegt werden.
Link für Post-Aktion hinzufügen
Zuerst erstellen wir einen Aktions-Link für die Post-Listen (wie schon in einem älteren Beitrag ausführlich erklärt). Mit dem folgenden Snippet wird bei den bereits vorhandenen Aktionen in der Post-Liste ein „Duplizieren“-Link eingefügt:
function post_row_actions_duplicate($actions, $post) {
if(current_user_can('edit_posts')) {
$duplicate_link = admin_url('admin.php?action=duplicate-post&post=' . $post->ID);
$actions['duplicate'] = '<a href="' . $duplicate_link . '" title="Dieses Element duplizieren">Duplizieren</a>';
}
return $actions;
}
add_filter('post_row_actions', 'post_row_actions_duplicate', 10, 2); // Beitrag und eigene, nicht-hierarchische Post-Types
//add_filter('page_row_actions', 'post_row_actions_duplicate', 10, 2); // Seiten und eigene, hierarchische Post-Types
Dieser Hook erstellt den Link für alle Post-Types. Wenn er nur für einen bestimmten Post-Type angezeigt werden sollte (z.B. project
, kann das if
erweitert werden um eine Abfrage wie $post->post_type == 'project'
.
Bulk-Aktion hinzufügen
Zusätzlich kann auch eine Bulk-Aktion hinzugefügt werden (auch in einem älteren Beitrag ausführlich erklärt), um mehrere Posts auf einmal zu duplizieren. Der folgende Code fügt eine neue Aktion „Duplizieren“ in die beiden Bulk-Dropdown-Menüs hinzu.
function bulk_action_add_duplicate() {
echo '<script type="text/javascript">
jQuery(function() {
jQuery('<option value="duplicate">Duplizieren</option>').appendTo('select[name="action"]');
jQuery('<option value="duplicate">Duplizieren</option>').appendTo('select[name="action2"]');
});
</script>';
}
add_action('admin_footer-edit.php', 'bulk_action_add_duplicate');
function bulk_action_duplicate() {
// Security check
if(!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'bulk-posts')) {
return false;
}
if(_get_list_table('WP_Posts_List_Table')->current_action() == 'duplicate') {
// Ein Array mit allen ausgewählten Post IDs
$post_ids = ( isset($_GET['post']) ? $_GET['post'] : array() );
// Zur eigentlichen Aktion weiterleiten
wp_redirect(admin_url('admin.php?action=duplicate-post&post=' . implode(',', $post_ids)));
exit;
}
}
add_action('load-edit.php', 'bulk_action_duplicate');
Aktion ausführen
Jetzt müssen wir noch die Aktion selber definieren. Diese Aktion kopiert einen oder mehrere Posts, die dazugehörigen Post-Meta-Daten und die zugewiesenen Taxonomies. Am Ende wird zurück auf die Post-Liste (wenn mehrere Posts dupliziert wurden) oder auf die Edit-Seite des duplizierten Posts (wenn nur ein Post dupliziert wurde) weitergeleitet:
function admin_action_duplicate_post() {
global $wpdb;
// Aktion überspringen wenn keine Berechtigung oder keine Post-IDs definiert wurden
if(!current_user_can('edit_posts') || !isset($_GET['post'])) {
wp_redirect($_SERVER['HTTP_REFERER']);
exit;
}
// Alle Post-IDs auslesen
$post_ids = explode(',', $_GET['post']);
$post_duplicate_count = 0;
foreach($post_ids as $post_id) {
$post = get_post($post_id);
// Aktion überspringen wenn Originalpost nicht existiert
if(is_null($post)) {
continue;
}
// Post für das Duplizieren vorbereiten
$post_new = (array)$post;
// Suffix "(Kopie)" an Post-Titel anhängen
$post_new['post_title'] = $post_new['post_title'] . ' (Kopie)';
// Post-Status auf "draft" (Entwurf) setzen
$post_new['post_status'] = 'draft';
// Post-Infos entfernen die wir nicht übernehmen wollen
unset($post_new['ID']);
unset($post_new['post_author']);
unset($post_new['post_date']);
unset($post_new['post_date_gmt']);
unset($post_new['post_name']);
unset($post_new['post_modified']);
unset($post_new['post_modified_gmt']);
unset($post_new['guid']);
// Post duplizieren
$post_id_new = wp_insert_post($post_new);
// Aktion überspringen wenn das Duplizieren fehlgeschlagen ist
if($post_id_new == 0) {
continue;
}
// Postmeta kopieren und zuweisen
$wpdb->query("
INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value)
SELECT $post_id_new, meta_key, meta_value
FROM $wpdb->postmeta
WHERE post_id = $post_id
");
// Taxonomies und Terms zuweisen
$post_taxonomies = get_object_taxonomies($post->post_type);
foreach($post_taxonomies as $taxonomy) {
$terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'ids'));
wp_set_object_terms($post_id_new, $terms, $taxonomy);
}
// Erfolgreiches Duplizieren zählen
$post_duplicate_count++;
}
if($post_duplicate_count !== 1) {
// Zurück zur Liste wenn keiner oder mehr als ein Posts dupliziert wurden
wp_redirect($_SERVER['HTTP_REFERER']);
} else {
// Zur Adminseite des duplizierten Posts weiterleiten
wp_redirect(admin_url('post.php?action=edit&post=' . $post_id_new));
}
exit;
}
add_action('admin_action_duplicate-post', 'admin_action_duplicate_post');
Rekursives Duplizieren
In diesem Beitrag zeigen wir dir nur, wie man einzelne Post ohne Hierarchie dupliziert. Wenn also eine Seite mit Unterseiten dupliziert wird, werden die Unterseiten nicht rekursiv mitkopiert.
Noch mehr Tipps …
… folgen in den nächsten Wochen. Bis dahin stellen wir dir wieder ein paar nützliche WordPress-Tipps zusammen.