25 Snippets für WordPress

25 Snippets für WordPress

Geschrieben am 25. April 2023 von Der Webfuchs

Akualisiert am 9. November 2025
Voraussichtliche Lesezeit 21 min

Kurzzusammenfassung

Dieser Artikel stellt 25 praxisnahe Code-Snippets für WordPress vor, mit denen sich Funktionen erweitern, Designs anpassen und Sicherheitsmaßnahmen umsetzen lassen – ganz ohne zusätzliche Plugins. Die vorgestellten Snippets sind leicht verständlich erklärt, direkt anwendbar und decken Bereiche wie Frontend-Anpassungen, Systemoptimierung und Administrationshilfen ab. Zusätzlich enthält der Beitrag Hinweise zu sicheren Tests, Backup-Empfehlungen und Best Practices für den Einsatz über das Plugin Code Snippets. Ziel ist es, Website-Betreibern und Entwicklern eine kompakte, praxisorientierte Sammlung nützlicher WordPress-Funktionen bereitzustellen.

Einleitung

WordPress ist eines der beliebtesten Content-Management-Systeme weltweit und bietet eine Vielzahl von Funktionen und Erweiterungen, um eine Website zu gestalten und zu verwalten. Einer der Vorteile ist die Möglichkeit, **Code-Snippets** zu nutzen. Diese kleinen Code-Schnipsel helfen Dir dabei, die Funktionalität Deiner Website anzupassen oder zu erweitern, ohne dass Du für jede kleine Änderung ein komplettes Plug-in installieren musst.

In diesem Artikel stelle ich **25 nützliche Snippets** vor, die Dir helfen können, Deine WordPress-Website zu optimieren und anzupassen. Von der Anpassung des Designs bis hin zur Verbesserung der Sicherheit – hier findest Du garantiert ein passendes Snippet für Deine Bedürfnisse.

Die Idee zu diesem Beitrag entstand, als ich bei Perun einen Artikel über die Änderung einer Standard-WordPress-Funktion sah. Dies inspirierte mich, meine eigene Sammlung an nützlichen Snippets zusammenzustellen und Dir zur Verfügung zu stellen.

Wichtige Hinweise vor dem Start

Alle Snippets sind in PHP geschrieben und können bequem mit dem beliebten Plug-in **Code Snippets** eingebunden werden – dies ist die empfohlene Methode. Alternativ kannst Du sie in die functions.php Deines Child-Themes oder in ein eigenes Must-Use-Plug-in schreiben.

Sicherheit geht vor: Bevor Du ein Snippet ausprobierst, lege bitte unbedingt ein aktuelles Backup an. Noch besser wäre es, wenn Du eine Staging-Seite nutzt. Nur so kannst Du sicherstellen, dass mögliche Fehler keine Auswirkungen auf Deine Live-Seite haben.

Auch wenn ich einen Großteil der hier vorgestellten Snippets selbst ausprobiert habe, erfolgt die Benutzung immer auf eigene Gefahr. Ich übernehme keine Garantie für die vollständige Kompatibilität oder Haftung für Schäden.

Snippets für den Frontend-Bereich (Besucher)

1. Länge des Textauszugs (Excerpt) anpassen

Dieses einfache Snippet von Perun begrenzt die Anzahl der Wörter im Textauszug auf 25. Standardmäßig sind bei WordPress 55 Wörter eingestellt.

function custom_excerpt_length($length) {
    return 25; // Anzahl der Wörter im Excerpt
}
add_filter('excerpt_length', 'custom_excerpt_length', 999);

2. Aktuelle Beiträge als Shortcode ausgeben (Recent Posts)

Anstatt ein Plug-in für die Anzeige der neuesten Beiträge zu nutzen, kannst Du den Shortcode [aktuelle-beitraege] verwenden. Das Besondere: Wenn ein Beitrag in der Liste gerade gelesen wird, wird er automatisch übersprungen und nicht angezeigt.

// Definiere Shortcode [aktuelle-beitraege]
function recent_posts_shortcode() {
  ob_start();
  // Schließe den aktuellen Beitrag von der Abfrage aus
  $exclude_post = exclude_current_post();
  // Setze Abfrage-Argumente
  $args = array(
    'post__not_in' => $exclude_post,
    'posts_per_page' => 3, // Anzahl der anzuzeigenden Beiträge
    'ignore_sticky_posts' => 1
  );
  $the_query = new WP_Query( $args );
  // Der Loop
  if ( $the_query->have_posts() ) :
    echo '<h2>Aktuelle Beiträge</h2><ul class="recent-posts-list">';
    while ( $the_query->have_posts() ) : $the_query->the_post();
      echo '<li class="recent-post-item">';
	  echo '<p><a href="' . esc_url( get_the_permalink() ) . '">' . get_the_title() . '</a></p>';
      if (has_post_thumbnail()) {
        echo '<p><a href="' . esc_url( get_the_permalink() ) . '">' . get_the_post_thumbnail( get_the_ID(), 'thumbnail' ) . '</a></p>';
      }
      echo '<p>' . get_the_excerpt() . '</p>';
      echo '</li>';
    endwhile;
    echo '</ul>';
  else :
    echo 'Keine Beiträge gefunden';
  endif;
  wp_reset_postdata();
  $content = ob_get_clean();
  return $content;
}

add_shortcode( 'aktuelle-beitraege', 'recent_posts_shortcode' );

// Funktion, um den aktuell gelesenen Beitrag auszuschließen
function exclude_current_post() {
  global $post;
  $exclude_post = array();
  if ( $post ) {
    array_push( $exclude_post, $post->ID );
  }
  return $exclude_post;
}

Die Anzahl der angezeigten Beiträge kannst Du in der Zeile 'posts_per_page': 3 auf eine beliebige Zahl abändern.

3. Geschätzte Lesezeit anzeigen

Dieses Snippet berechnet die geschätzte Lesezeit Deines Artikels (basierend auf 250 Wörtern pro Minute) und gibt diese mit dem Shortcode [lesezeit] aus. Dazu habe ich bereits einen ausführlicheren Artikel zur Lesezeit-Anzeige geschrieben.

function tu_estimated_reading_time() {
    $post = get_post();
    $content = $post->post_content;
    $wpm = 250; // Wörter pro Minute.

    $clean_content = strip_shortcodes( $content );
    $clean_content = strip_tags( $clean_content );
    $word_count = str_word_count( $clean_content );
    $time = ceil( $word_count / $wpm );

    return $time . ' min';
}
add_shortcode('lesezeit', 'tu_estimated_reading_time');

4. Copyright-Text im Footer ändern

Gerade bei vielen kostenlosen Themes ist der Copyright-Hinweis im Footer oft mit einem Branding des Theme-Entwicklers versehen. Mit diesem Snippet kannst Du diesen Text einfach ändern.

// Überschreibt den Standard Footer Copyright Text (speziell für GeneratePress)
add_filter( 'generate_copyright','tu_custom_copyright' );
function tu_custom_copyright() {
    ?>
    <span class="copyright">&copy; Der Webfuchs</span>
    <?php
}

Wie Du das genau änderst, beschreibe ich in meiner ausführlicheren Anleitung zur Änderung des Copyright-Textes in GeneratePress.

5. Read More / Weiterlesen-Button ändern (Standard)

Für viele Themes lässt sich der Standard-Text des Read More- oder Weiterlesen-Buttons mit diesem einfachen Snippet anpassen.

function custom_read_more_text( $more ) {
    return 'Jetzt mehr erfahren'; // Hier den neuen Text einfügen
}
add_filter( 'excerpt_more', 'custom_read_more_text' );

6. Read More / Weiterlesen-Button ändern (GeneratePress)

Da das obige Snippet bei GeneratePress in der Regel nicht funktioniert, musst Du hier einen spezifischen Filter verwenden. Der folgende Code ändert den Text auf „Mehr erfahren“.

add_filter( 'generate_content_more_link_output','tu_change_content_more_link' );
function tu_change_content_more_link() {
    return sprintf( '<p class="read-more-container custom-read-more"><a title="%1$s" class="r-link link text-underlined" href="%2$s">%3$s</a></p>',
        the_title_attribute( 'echo=0' ),
        esc_url( get_permalink( get_the_ID() ) . apply_filters( 'generate_more_jump','#more-' . get_the_ID() ) ),
        __( 'Mehr erfahren', 'generatepress' ) // Hier Text ändern
    );
}

Wer das Premium-Modell von GeneratePress nutzt, kann den Read More-Text oft auch direkt im Customizer ändern.

7. Sortierfunktion für Besucher hinzufügen

Dieses Snippet ermöglicht es Besuchern Deines Blogs, Artikel nach „älteste Beiträge zuerst“ oder „neueste Beiträge zuerst“ zu sortieren. Füge den Shortcode [beitrags-sortierung] dort ein, wo die Buttons erscheinen sollen.

function custom_sort_query( $query ) {
    if ( $query->is_main_query() && isset( $_GET['sort'] ) ) { // is_main_query hinzugefügt, um Konflikte zu vermeiden
        if ( $_GET['sort'] == 'oldest' ) {
            $query->set( 'order', 'ASC' );
            $query->set( 'orderby', 'date' );
        }
    }
}
add_action( 'pre_get_posts', 'custom_sort_query' );

function post_sorting_buttons() {
    $current_url = remove_query_arg( 'sort' ); // Entferne bestehenden Sort-Parameter
    $newest_url = add_query_arg( array( 'sort' => 'newest' ), $current_url );
    $oldest_url = add_query_arg( array( 'sort' => 'oldest' ), $current_url );
    ?>
    <div class="post-sorting-buttons">
        <a href="<?php echo esc_url($newest_url); ?>" class="button button-primary newest-button">Neueste Beiträge</a>
        <a href="<?php echo esc_url($oldest_url); ?>" class="button oldest-button">Älteste Beiträge</a>
    </div>
    <?php
}
add_shortcode( 'beitrags-sortierung', 'post_sorting_buttons' );

8. Verwandte Beiträge nach Kategorie (Shortcode)

Wenn Du lediglich ähnliche Beiträge anhand der Kategorie anzeigen möchtest, ist das folgende Snippet eine leichtgewichtige Lösung ohne Plug-in. Es verwendet den Shortcode [related-category count="3"].

function related_posts_category( $atts ) {
    $atts = shortcode_atts( array(
        'count' => 3, // Standard: 3 Beiträge
    ), $atts, 'related-category' );
    global $post;
    $categories = get_the_category( $post->ID );

    if ( empty( $categories ) ) {
        return '<div class="related-posts">Keine verwandten Beiträge gefunden.</div>';
    }

    $category_ids = wp_list_pluck( $categories, 'term_id' );

    $args = array(
        'category__in' => $category_ids,
        'post__not_in' => array( $post->ID ),
        'posts_per_page' => absint( $atts['count'] ),
        'orderby' => 'rand', // Zufällige Reihenfolge
    );
    $query = new WP_Query( $args );

    if ( $query->have_posts() ) {
        $output = '<div class="related-posts">';
        $output .= '<h2>Verwandte Beiträge</h2>';
        $output .= '<ul class="related-posts-list">';

        while ( $query->have_posts() ) {
            $query->the_post();
            // Beitragsbild
            $thumbnail = get_the_post_thumbnail( get_the_ID(), 'thumbnail', array( 'class' => 'related-post-thumbnail' ) );
            if ( ! $thumbnail ) {
                $thumbnail = '<div class="no-thumbnail"> <!-- Platzhalter, bei Bedarf CSS anpassen --> </div>';
            }

            // Textauszug
            $excerpt = wp_kses_post(get_the_excerpt());
            if ( ! $excerpt ) {
                $excerpt = wp_trim_words( wp_kses_post(get_the_content()), 20 );
            }

            $output .= '<li class="related-post-item">';
            $output .= '<a href="' . esc_url( get_permalink() ) . '">' . $thumbnail . '</a>';
            $output .= '<div class="related-posts-content">';
            $output .= '<h3 class="related-post-title"><a href="' . esc_url( get_permalink() ) . '">' . get_the_title() . '</a></h3>';
            $output .= '<p class="related-post-excerpt">' . $excerpt . '</p>';
            $output .= '</div>';
            $output .= '</li>';
        }

        $output .= '</ul>';
        $output .= '</div>';

        wp_reset_postdata();

        return $output;
    }

    return '<div class="related-posts">Keine verwandten Beiträge gefunden.</div>';
}
add_shortcode( 'related-category', 'related_posts_category' );

Die Anzahl der angezeigten Beiträge kannst Du über das Attribut count (z. B. [related-category count="5"]) ändern. Das Aussehen gestaltest Du bitte über die CSS-Klassen (`related-posts-list`, `related-post-item` etc.).

9. Verwandte Beiträge nach Schlagwort (Shortcode)

Dieses Snippet ähnelt dem vorherigen, sucht jedoch gezielt nach Beiträgen, die dieselben Schlagwörter (Tags) wie der aktuelle Beitrag verwenden. Verwende den Shortcode [related-tag count="3"].

function related_posts_tag( $atts ) {
    $atts = shortcode_atts( array(
        'count' => 3, // Standard: 3 Beiträge
    ), $atts, 'related-tag' );
    global $post;
    
    // Hole alle Tags des aktuellen Beitrags
    $tags = wp_get_post_tags( $post->ID );
    if ( empty( $tags ) ) {
        return '';
    }

    $tag_ids = wp_list_pluck( $tags, 'term_id' );

    $args = array(
        'tag__in' => $tag_ids,
        'post__not_in' => array( $post->ID ),
        'posts_per_page' => absint( $atts['count'] ),
        'orderby' => 'rand', // Zufällige Reihenfolge
    );
    $query = new WP_Query( $args );

    if ( $query->have_posts() ) {
        $output = '<div class="related-posts related-tags-section">';
        $output .= '<h2>Weitere Artikel nach Schlagwort</h2>';
        $output .= '<ul class="related-posts-list">';
        while ( $query->have_posts() ) {
            $query->the_post();
            $output .= '<li class="related-post-item">';
            $output .= '<a href="' . esc_url( get_permalink() ) . '">' . get_the_title() . '</a>';
            $output .= '</li>';
        }
        $output .= '</ul>';
        $output .= '</div>';
        wp_reset_postdata();
        return $output;
    }
    return '';
}
add_shortcode( 'related-tag', 'related_posts_tag' );

10. Verwandte Beiträge nach Ähnlichkeit (Tags & Kategorien)

Dieses fortgeschrittenere Snippet sucht Beiträge, die sowohl Tags **als auch** Kategorien mit dem aktuellen Artikel teilen. Es ist eine sehr gute Möglichkeit, um wirklich ähnliche Inhalte ohne ein dediziertes Plug-in anzuzeigen. Verwende den Shortcode [related-similar count="4"].

function related_posts_similarity_advanced( $atts ) {
    $atts = shortcode_atts( array(
        'count' => 4, 
    ), $atts, 'related-similar' );
    global $post;
    
    $tags = wp_get_post_tags( $post->ID );
    $categories = get_the_category( $post->ID );

    // Sammle alle IDs von Tags und Kategorien
    $term_ids = array();
    if ( ! empty( $tags ) ) {
        $term_ids['tag'] = wp_list_pluck( $tags, 'term_id' );
    }
    if ( ! empty( $categories ) ) {
        $term_ids['category'] = wp_list_pluck( $categories, 'term_id' );
    }

    if ( empty( $term_ids ) ) {
        return '';
    }
    
    $args = array(
        'post__not_in' => array( $post->ID ),
        'posts_per_page' => absint( $atts['count'] ),
        'orderby' => 'date', // Sortierung nach Datum (neueste zuerst)
        'order' => 'DESC',
        'tax_query' => array(
            'relation' => 'OR', // Beiträge, die mindestens eine Kategorie ODER einen Tag teilen
        ),
    );

    // Füge die Taxonomien zur Abfrage hinzu
    if ( isset( $term_ids['tag'] ) ) {
        $args['tax_query'][] = array(
            'taxonomy' => 'post_tag',
            'field'    => 'id',
            'terms'    => $term_ids['tag'],
        );
    }
    if ( isset( $term_ids['category'] ) ) {
        $args['tax_query'][] = array(
            'taxonomy' => 'category',
            'field'    => 'id',
            'terms'    => $term_ids['category'],
        );
    }
    
    $query = new WP_Query( $args );

    if ( $query->have_posts() ) {
        $output = '<div class="related-posts related-similarity-section">';
        $output .= '<h2>Ähnliche Beiträge (nach Schlagwort & Kategorie)</h2>';
        $output .= '<ul class="related-posts-list related-posts-similarity">';
        while ( $query->have_posts() ) {
            $query->the_post();
            $output .= '<li class="related-post-item">';
            $output .= '<a href="' . esc_url( get_permalink() ) . '">' . get_the_title() . '</a>';
            $output .= '</li>';
        }
        $output .= '</ul>';
        $output .= '</div>';
        wp_reset_postdata();
        return $output;
    }
    return '';
}
add_shortcode( 'related-similar', 'related_posts_similarity_advanced' );

11. Beliebtheitsgrad von Beiträgen messen und anzeigen

Möchtest Du Deinen Lesern anzeigen, wie oft ein Artikel bereits gelesen wurde („Dieser Artikel wurde XXX mal gelesen“), dann ist dieses Snippet das Richtige. Es stammt ursprünglich von Devslife.

// 1. Zählt die Views pro Beitrag
function count_postviews($postID) {
    $count_key = 'post_views_count';
    $count = get_post_meta($postID, $count_key, true);
    if ($count == '') {
        $count = 1;
        add_post_meta($postID, $count_key, '1');
    } else {
        $count++;
        update_post_meta($postID, $count_key, $count);
    }
}

// 2. Erstellt Shortcode zur Anzeige der Views
function post_views_shortcode($atts) {
    $post_id = get_the_ID();
    $count = get_post_meta($post_id, 'post_views_count', true);
    if ($count == '') {
        $count = 0;
    }
    return '<p class="post-views-counter"> Dieser Artikel wurde bereits ' . absint($count) . ' mal gelesen</p>';
}
add_shortcode('post-views', 'post_views_shortcode');

// 3. Fügt die Zählfunktion im Header der Einzelansicht hinzu
add_action('wp_head', 'track_post_views');
function track_post_views($post_id) {
    if (!is_single()) {
        return;
    }
    if (empty($post_id)) {
        global $post;
        $post_id = $post->ID;
    }
    count_postviews($post_id);
}

Füge den Shortcode [post-views] an der Stelle ein, an der der Zähler erscheinen soll.

Snippets für WordPress-Verbesserungen

12. MIME-Typen anzeigen (Admin-Seite)

Welche MIME-Typen aktuell in Deiner WordPress-Installation erlaubt sind, kannst Du ganz einfach direkt im Dashboard herausfinden. Lege dazu in Code Snippets ein neues Snippet mit folgendem Code an und wähle als Ausführungsbereich „Nur im Adminbereich“.

// Fügt im Adminbereich eine Seite "MIME-Typen anzeigen" unter "Werkzeuge" hinzu
add_action( 'admin_menu', function() {
    add_management_page(
        'MIME-Typen anzeigen',
        'MIME-Typen',
        'manage_options',
        'mime-types',
        'show_allowed_mime_types'
    );
});

function show_allowed_mime_types() {
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_die( 'Du hast keine Berechtigung, diese Seite zu sehen.' );
    }

    $mime_types = get_allowed_mime_types();

    echo '<div class="wrap">';
    echo '<h1>MIME-Typen anzeigen</h1>';
    echo '<p>Hier siehst Du alle aktuell in WordPress erlaubten MIME-Typen:</p>';
    echo '<table class="widefat fixed striped">';
    echo '<thead><tr><th>Dateiendung(en)</th><th>MIME-Typ</th></tr></thead><tbody>';

    foreach ( $mime_types as $ext => $type ) {
        echo '<tr><td><code>' . esc_html( $ext ) . '</code></td><td>' . esc_html( $type ) . '</td></tr>';
    }

    echo '</tbody></table>';
    echo '</div>';
}

Nach der Aktivierung findest Du im Menü **Werkzeuge → MIME-Typen** eine neue Seite mit einer tabellarischen Übersicht aller erlaubten Dateitypen. So kannst Du jederzeit prüfen, welche Formate WordPress aktuell akzeptiert.

13. Die alten Widgets wiederherstellen

Wenn Du die neuen Widget-Blöcke im WordPress-Backend nicht magst, kannst Du mit diesem Snippet ganz einfach das klassische Widget-System wieder aktivieren. Ein echtes Must-have für alle, die sich an die alte Ansicht gewöhnt haben.

add_filter( 'use_widgets_block_editor', '__return_false' );

14. Systeminfos im Dashboard anzeigen

Dieses Snippet fügt ein neues Dashboard-Widget hinzu, das Dir wichtige Informationen wie PHP-Version, WordPress-Version, Speicherlimit und Deine aktuelle IP-Adresse direkt auf einen Blick anzeigt. Sehr nützlich für die schnelle Systemprüfung!

function add_ip_address_display() {
    wp_add_dashboard_widget(
        'dashboard_ip_address',
        'Wichtige Systeminformationen',
        'display_current_ip_address'
    );
}
add_action('wp_dashboard_setup', 'add_ip_address_display');

function display_current_ip_address() {
    echo '<p>Deine aktuelle IP-Adresse lautet: <strong>' . esc_html($_SERVER['REMOTE_ADDR']) . '</strong></p>';
    echo '<ul class="system-info-list">';
    echo '<li><strong>PHP-Version:</strong> ' . esc_html(phpversion()) . '</li>';
    echo '<li><strong>Server-Betriebssystem:</strong> ' . esc_html(php_uname()) . '</li>';
    echo '<li><strong>WordPress-Version:</strong> ' . esc_html(get_bloginfo('version')) . '</li>';
    // Sicherer Check auf WP_DEBUG
    echo '<li><strong>WP_DEBUG:</strong> ' . ( defined( 'WP_DEBUG' ) && WP_DEBUG ? '<span style="color:red;">Aktiviert</span>' : '<span style="color:green;">Deaktiviert</span>' ) . '</li>';
    echo '<li><strong>Speicherlimit:</strong> ' . esc_html(ini_get('memory_limit')) . '</li>';
    echo '<li><strong>Max. Ausführungszeit:</strong> ' . esc_html(ini_get('max_execution_time')) . '</li>';
    echo '<li><strong>Upload-Maximum:</strong> ' . esc_html(ini_get('upload_max_filesize')) . '</li>';
    echo '<li><strong>POST-Maximum:</strong> ' . esc_html(ini_get('post_max_size')) . '</li>';
    echo '<li><strong>cURL:</strong> ' . (function_exists('curl_version') ? 'Verfügbar' : 'Nicht verfügbar') . '</li>';
    echo '<li><strong>Anzahl Plug-ins:</strong> ' . esc_html(count( get_plugins() )) . '</li>';
    echo '<li><strong>Webserver:</strong> ' . esc_html($_SERVER['SERVER_SOFTWARE']) . '</li>';
    echo '</ul>';
}

15. Self-Pingbacks verhindern

Wenn Du von einem Deiner Artikel auf einen anderen Artikel im selben Blog verlinkst, zeigt WordPress standardmäßig einen Pingback im Dashboard an. Das kann schnell nervig und unübersichtlich werden. Dieses Snippet verhindert solche „Self-Pingbacks“.

function no_self_ping( &$links ) {
    $home = get_option( 'home' );
    foreach ( $links as $l => $link )
        if ( 0 === strpos( $link, $home ) )
            unset($links[$l]);
} 
add_action( 'pre_ping', 'no_self_ping' );

16. Beiträge und Seiten duplizieren

Möchtest Du schnell eine Kopie eines Beitrags oder einer Seite erstellen, bietet WordPress standardmäßig keine Funktion. Dieses Snippet fügt in der Beitragsübersicht einen „Duplizieren“-Link hinzu. **Hinweis:** Wenn Dir der folgende Code zu komplex ist, kannst Du alternativ ein etabliertes Plug-in wie *Duplicate Post* verwenden.

function copy_post() { 
    global $wpdb;
    $post_id = $_GET['post']; 
    $post = get_post( $post_id ); 

    // Prüfen, ob Post-Typ erlaubt ist (z.B. 'post' und 'page')
    if ( isset( $post ) && in_array($post->post_type, array('post', 'page')) ) { 
        $new_post = array( 
            'post_title' => $post->post_title . ' (Kopie)', 
            'post_content' => $post->post_content, 
            'post_status' => 'draft', 
            'post_author' => get_current_user_id(), // Setze aktuellen Benutzer als Autor
            'post_type' => $post->post_type,
            'post_excerpt' => $post->post_excerpt, 
            'post_name' => sanitize_title( $post->post_title ) . '-kopie-' . time(), 
            // Datum aktualisieren
            'post_date' => current_time( 'mysql' ), 
            'post_date_gmt' => current_time( 'mysql', 1 ), 
        );
        $new_post_id = wp_insert_post( $new_post ); 

        // Kopiere Taxonomien (Kategorien, Schlagwörter etc.)
        $taxonomies = get_object_taxonomies( $post->post_type );
        foreach ( $taxonomies as $taxonomy ) { 
            $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
            wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false ); 
        } 
        
        // Kopiere Post-Metadaten
        $post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id");
        if (count($post_meta_infos)!=0) {
            $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
            foreach ($post_meta_infos as $meta_info) {
                $meta_key = $meta_info->meta_key;
                $meta_value = addslashes($meta_info->meta_value);
                $sql_query_sel[]= "SELECT $new_post_id, '$meta_key', '$meta_value'";
            }
            $sql_query.= implode(" UNION ALL ", $sql_query_sel);
            $wpdb->query($sql_query);
        }

        wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) ); 
        exit;
    } else {
        wp_die( 'Duplizieren fehlgeschlagen. Ungültiger Beitragstyp.' );
    }
}
add_action( 'admin_action_copy_post', 'copy_post' );

// Fügt den "Duplizieren"-Link in die Beitrags- und Seitenübersicht ein
function copy_post_link( $actions, $post ) {
    if ( in_array($post->post_type, array('post', 'page')) ) {
        $actions['copy_post'] = '<a href="' . wp_nonce_url( admin_url( 'admin.php?action=copy_post&post=' . $post->ID ), 'copy_post_' . $post->ID ) . '">Duplizieren</a>';
    }
    return $actions;
}
add_filter( 'post_row_actions', 'copy_post_link', 10, 2 );
add_filter( 'page_row_actions', 'copy_post_link', 10, 2 ); // Auch für Seiten

Snippets für Sicherheit & Verwaltung

17. Unerwünschte MIME-Typen verbieten

Aus Sicherheitsgründen möchtest Du unter Umständen bestimmte Dateitypen vom Hochladen ausschließen. Das folgende Beispiel verbietet das Hochladen von JPG- und JPEG-Dateien.

function disable_jpg_upload( $mime_types ) {
    // Verbiete JPG- und JPEG-Uploads
    unset( $mime_types['jpg'] );
    unset( $mime_types['jpeg'] );
    return $mime_types;
}
add_filter( 'upload_mimes', 'disable_jpg_upload' );

18. Zusätzliche MIME-Typen erlauben

Wenn Du umgekehrt einen Dateityp benötigst, den WordPress standardmäßig blockiert (z. B. BMP-Dateien), kannst Du ihn hiermit zulassen.

function tu_allow_mime_types( $mime_types ) {
    $mime_types['bmp'] = 'image/bmp';
    return $mime_types;
}
add_filter( 'upload_mimes', 'tu_allow_mime_types' );

19. Security-Header setzen (Wichtiger Hinweis zur CSP)

Sicherheits-Header sind essenziell zur Abwehr gängiger Angriffe. Dieses Snippet fügt eine Reihe nützlicher HTTP-Header hinzu.

function kb_add_security_headers($headers) {
    // Standard-Sicherheit: Header hinzufügen
    $headers['X-Frame-Options'] = 'DENY';
    $headers['X-XSS-Protection'] = '1; mode=block'; // Legacy Header, kann bei Bedarf entfernt werden
    $headers['X-Content-Type-Options'] = 'nosniff';
    $headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains; preload';
    $headers['Referrer-Policy'] = 'no-referrer';
    $headers['Permissions-Policy'] = "accelerometer=(), autoplay=(self), camera=(), encrypted-media=(), fullscreen=(), geolocation=(self), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(self), usb=(), interest-cohort=()";
    
    // *** WICHTIG: Content-Security-Policy (CSP)
    // Wenn dieser Header falsch konfiguriert wird, kann er wesentliche Funktionen (z. B. Scripte, CSS)
    // Deiner Website blockieren. Entferne die folgende Zeile, wenn Du die Konfiguration
    // nicht exakt an Deine Seite anpassen kannst.
    $headers['Content-Security-Policy'] = "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https:; img-src 'self' https: data:; font-src 'self' https: data:; frame-src 'self' https:; connect-src 'self' https:;";
    
    return $headers;
}
add_filter('wp_headers', 'kb_add_security_headers', 10, 1);

💡 Tipp:
Ob die Header korrekt gesetzt sind, kannst Du ganz einfach mit diesen kostenlosen Tools überprüfen:

🔍 Empfohlene Testreihenfolge:
Führe zuerst den Test bei SecurityHeaders.com durch, um schnell zu sehen, ob Deine neuen Header aktiv sind.
Danach kannst Du Deine Seite mit dem Mozilla Observatory prüfen, um eine umfassendere Bewertung und Optimierungsempfehlungen zu erhalten.

20. Anmeldeversuche begrenzen (Brute-Force-Schutz)

Dieses Snippet verbessert die Sicherheit, indem es die Anzahl der fehlgeschlagenen Anmeldeversuche auf 3 innerhalb von 60 Sekunden begrenzt. Bei Überschreitung wird der Benutzer für eine Stunde blockiert. Ein einfacher, aber effektiver Schutz gegen Brute-Force-Angriffe. **Hinweis:** Für produktive Seiten mit hohem Traffic und komplexen Sicherheitsanforderungen ist in der Regel ein etabliertes Sicherheits-Plug-in vorzuziehen – dieses Snippet dient als schlankes technisches Beispiel.

// Definiere die maximale Anzahl von Anmeldeversuchen
if (!defined('WP_LOGIN_ATTEMPTS')) {
    define('WP_LOGIN_ATTEMPTS', 3); // 3 Versuche
}
const WP_LOGIN_LOCKOUT_TIME = 3600; // 60 Minuten Sperre

// Funktion zur Begrenzung der fehlgeschlagenen Anmeldeversuche
function limit_login_attempts( $user, $username, $password ) {
    $ip_address = $_SERVER['REMOTE_ADDR'];
    $failed_key = 'failed_login_' . $ip_address;
    $lockout_key = 'lockout_' . $ip_address;

    if ( get_transient( $lockout_key ) ) {
        return new WP_Error( 'too_many_attempts', 'Zu viele ungültige Anmeldeversuche. Bitte versuche es in einer Stunde erneut.' );
    }

    $failed_attempts = get_transient( $failed_key );

    if ( $failed_attempts === false ) {
        set_transient( $failed_key, 1, 60 ); // 1. Versuch, läuft in 60 Sek. ab
    } else {
        $failed_attempts++;
        if ( $failed_attempts >= WP_LOGIN_ATTEMPTS ) {
            set_transient( $lockout_key, true, WP_LOGIN_LOCKOUT_TIME );
            delete_transient( $failed_key );
            return new WP_Error( 'too_many_attempts', 'Zu viele ungültige Anmeldeversuche. Du bist für 60 Minuten gesperrt.' );
        } else {
            set_transient( $failed_key, $failed_attempts, 60 );
        }
    }

    return $user;
}
add_filter( 'authenticate', 'limit_login_attempts', 30, 3 ); // Wichtig: 3 Argumente übergeben

// Entfernt die Fehlermeldung, wenn der User wegen zu vieler Versuche gesperrt ist.
function check_lockout_before_login() {
    $ip_address = $_SERVER['REMOTE_ADDR'];
    $lockout_key = 'lockout_' . $ip_address;

    if ( get_transient( $lockout_key ) ) {
        wp_die('Zu viele ungültige Anmeldeversuche. Bitte versuche es später erneut.', 'Gesperrt', array('response' => 403));
    }
}
add_action( 'login_form_login', 'check_lockout_before_login' );

21. Vage Fehlermeldung beim Log-in anzeigen

Die Standard-Fehlermeldung in WordPress verrät potenziellen Angreifern, ob der Benutzername korrekt war oder ob nur das Passwort falsch ist. Dieses Snippet ändert die Meldung in einen allgemeinen Text, was die Sicherheit erhöht.

function no_login_error() {
    return 'Ups, da lief etwas nicht korrekt.';
}
add_filter('login_errors', 'no_login_error');

22. Login nur von bestimmten IP-Adressen erlauben

Dieses Snippet ist ideal, wenn Du eine feste IP-Adresse hast und den Admin-Bereich nur von dort aus zugänglich machen möchtest. **Achtung: Ersetze die Beispiel-IP-Adresse unbedingt durch Deine eigene!** Nur verwenden, wenn Du eine feste IP hast und genau weißt, was Du tust – sonst kannst Du Dich selbst aussperren.

function allow_login_only_by_ip_address() {
    // Liste der erlaubten IP-Adressen (DURCH EIGENE ERSETZEN!)
    $allowed_ips = array(
        '123.456.789.000', // DEINE IP-ADRESSE HIER
        // '000.000.000.000', // Weitere IP-Adressen
    );

    $user_ip = $_SERVER['REMOTE_ADDR'];

    // Ist der Benutzer nicht eingeloggt und ruft die Login-Seite auf?
    if ( ! is_user_logged_in() && ( strpos( $_SERVER['REQUEST_URI'], 'wp-login.php' ) !== false || strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) !== false ) ) {

        // Wenn IP nicht erlaubt, leite um
        if ( ! in_array( $user_ip, $allowed_ips ) ) {
             // Wenn der Parameter 'ip' nicht mit der aktuellen IP übereinstimmt, umleiten
            if ( !isset( $_GET['ip'] ) || $_GET['ip'] !== $user_ip ) {
                wp_redirect( home_url( '/?login_access_denied=1' ) );
                exit;
            }
        }
    }
}
add_action( 'init', 'allow_login_only_by_ip_address' );

Wenn Deine IP-Adresse nicht in der Liste ist, kannst Du den Zugriff über den Parameter ?ip=DEINE.IP.ADRESSE erzwingen, was für den Fall eines IP-Wechsels sehr nützlich ist.

Weitere nützliche Snippets

23. Begrüßungsnachricht für den Admin

Ein kleines, aber feines Snippet für eine persönlichere Erfahrung: Es zeigt eine tageszeitabhängige Begrüßung („Guten Morgen!“, „Guten Abend!“) in der oberen Admin-Bar an.

function greet_by_time_of_day() {
    $current_time = current_time( 'H:i:s' );
    $morning_time = '06:00:00';
    $noon_time = '12:00:00';
    $evening_time = '18:00:00';
    $night_time = '23:59:59';

    if ( $current_time >= $morning_time && $current_time < $noon_time ) {
        $greeting = 'Guten Morgen!';
    } elseif ( $current_time >= $noon_time && $current_time < $evening_time ) {
        $greeting = 'Guten Tag!';
    } elseif ( $current_time >= $evening_time && $current_time <= $night_time ) {
        $greeting = 'Guten Abend!';
    } else {
        $greeting = 'Hallo Admin!';
    }

    return $greeting;
}

function custom_admin_bar_greeting( $wp_admin_bar ) {
    $greeting = greet_by_time_of_day();
    // Entferne den Standard-Begrüßungstext ("Hallo, User!")
    $wp_admin_bar->remove_node('my-account'); 
    // Füge die tageszeitabhängige Begrüßung hinzu
    $wp_admin_bar->add_node( array(
        'id'    => 'time-greeting',
        'title' => $greeting,
        'href'  => false,
    ) );
}
add_action( 'admin_bar_menu', 'custom_admin_bar_greeting', 100 );

24. Begrüßungsnachricht für den Besucher (Shortcode)

Das Gleiche für Deine Besucher! Mit dem Shortcode [besucher-gruss] kannst Du eine tageszeitabhängige Begrüßung im Frontend anzeigen. Ideal für die Sidebar oder im Header-Bereich.

function greet_visitor() {
    $current_time = current_time( 'H:i:s' );
    $morning_time = '06:00:00';
    $noon_time = '12:00:00';
    $evening_time = '18:00:00';
    $night_time = '23:59:59';

    if ( $current_time >= $morning_time && $current_time < $noon_time ) {
        $greeting = 'Guten Morgen!';
    } elseif ( $current_time >= $noon_time && $current_time < $evening_time ) {
        $greeting = 'Guten Tag!';
    } elseif ( $current_time >= $evening_time && $current_time <= $night_time ) {
        $greeting = 'Guten Abend!';
    } else {
        $greeting = 'Willkommen!';
    }

    $greeting .= ' Schön, dass du da bist.';

    return '<div class="greeting-message">' . esc_html($greeting) . '</div>';
}
add_shortcode( 'besucher-gruss', 'greet_visitor' );

25. Log-in-Sitzungs-Ablaufzeit anzeigen

Dieses Snippet zeigt Administratoren im Dashboard an, wann die aktuelle Log-in-Sitzung abläuft. Ein praktischer Hinweis, um zu wissen, wann Du Dich neu anmelden musst.

function wp_login_expiration_notice() {
    // Nur für eingeloggte Admins anzeigen
    if ( ! is_user_logged_in() || ! current_user_can( 'manage_options' ) ) {
        return;
    }
    
    $user = wp_get_current_user();
    // Hole alle Session-Tokens des Benutzers
    $tokens = get_user_meta( $user->ID, 'session_tokens', true );
    
    if ( ! empty( $tokens ) ) {
        // Finde den aktuell gültigen Token (simplifizierte Methode: der Letzte)
        $latest_token = end( $tokens );
        
        if ( isset( $latest_token['expiration'] ) ) {
            $expiration_timestamp = $latest_token['expiration'];
            $expiration_date = date_i18n( get_option('date_format') . ' ' . get_option('time_format'), $expiration_timestamp );
            $remaining = human_time_diff( time(), $expiration_timestamp );
            
            echo '<div class="notice notice-info is-dismissible session-expiry-notice">
                <p>Deine aktuelle Log-in-Sitzung läuft ab am: <strong>' . esc_html($expiration_date) . '</strong> (noch <strong>' . esc_html($remaining) . '</strong> verbleibend).</p>
            </div>';
        }
    }
}
add_action( 'admin_notices', 'wp_login_expiration_notice' );

Fazit

WordPress-Snippets sind ein mächtiges Werkzeug. Sie ermöglichen es Dir, die Funktionalität Deiner Website präzise anzupassen, ohne auf umfangreiche Plug-ins zurückgreifen zu müssen, die Deine Seite verlangsamen könnten. Die hier vorgestellten **26 Snippets** bieten Dir eine starke Grundlage für die Optimierung und Anpassung Deiner Website.

Besonders die **Sicherheits-Snippets** (wie der Brute-Force-Schutz und die Log-in-Beschränkung) und die **Verwaltungs-Helfer** (wie die Systeminfos und die neue MIME-Typen-Seite) sind für jeden Administrator von großem Wert. Features wie die **Lesezeitanzeige** und der **flexible Copyright-Vermerk** steigern zudem die Attraktivität Deiner Inhalte.

Der einfachste Weg, diese Codes zu nutzen, ist das Plug-in **Code Snippets**. Wenn Du weitere Inspiration suchst, findest Du viele zusätzliche Snippets auch direkt in der Cloud von Code-Snippets.

Ich wünsche Dir viel Erfolg beim Optimieren Deiner WordPress-Website!

DerWebfuchs-Logo

"Der Webfuchs" ist ein Pseudonym des Webentwicklers Stephan Bloemers. Geboren 1967 in Duisburg und aktuell in Düsseldorf ansässig, begann er bereits 1999 mit der Erstellung von Websites. Durch selbständiges Lernen erwarb er die notwendigen HTML-Kenntnisse und registrierte 2001 seine erste Top-Level-Domain "derwebfuchs.de", die damals bereits kostenlose Ressourcen für Webmaster bereitstellte.
Über die Jahre hat Stephan weitere Projekte realisiert, darunter einen Blog über seinen damaligen Kegelclub. Alle von ihm erstellten Websites werden als Hobby betrieben.
Neben dem Basteln an seinen Websites verbringt Stephan seine Freizeit gerne mit Spielen wie Poker oder Schach.
Stephan hat sich im Laufe seiner Karriere auf die Entwicklung von benutzerfreundlichen und effektiven Websites spezialisiert. Seine Leidenschaft für Technologie und Design spiegelt sich in seiner Arbeit wider und er ist stets bemüht, auf dem neuesten Stand zu bleiben, um die bestmöglichen Lösungen anbieten zu können.
In seiner Freizeit ist Stephan ein begeisterter Blogger und teilt gerne sein Wissen und seine Erfahrungen mit anderen Webentwicklern und Interessierten. Seine Leidenschaft für die Online-Welt und seine Fähigkeit, komplexe Themen einfach und verständlich zu vermitteln, machen ihn zu einer wertvollen Ressource für alle, die sich für Webentwicklung und Online-Marketing interessieren.

Schreibe einen Kommentar