admin-ajax.php greifen, obwohl Core bereits bessere Alternativen mitliefert. Beherrsche fünf eingebaute Muster — WP HTTP API, programmatische Post-Typen, Transient-Caching, sichere save_post-Hooks und eigene REST-Endpoints — und du schreibst Code, der schneller, sauberer ist und Core-Updates übersteht.WordPress treibt über 40 % des Webs an, dennoch arbeiten viele Entwickler daran vorbei statt damit. Das Ergebnis ist spröder Code, der bei Updates bricht und Funktionen dupliziert, die WordPress bereits mitliefert. Hier sind fünf Muster, auf die erfahrene WordPress-Entwickler täglich setzen.
1. wp_remote_get() statt rohem cURL verwenden
Rohe cURL-Aufrufe in WordPress-Plugins sind ein Warnsignal. WordPress liefert die WP HTTP API — einen Wrapper, der Proxys, SSL-Zertifikatsprüfung, Timeout-Konfiguration übernimmt und konsistente WP_Error-Objekte bei Fehlern zurückgibt.
// Schlecht
$ch = curl_init('https://api.example.com/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
// Gut
$response = wp_remote_get('https://api.example.com/data');
if (is_wp_error($response)) {
// Fehler sauber behandeln
}
$body = wp_remote_retrieve_body($response);
Die HTTP API respektiert außerdem den http_request_args-Filter, sodass andere Plugins (z. B. Request-Logging oder Proxy-Middleware) einhaken können, ohne deinen Code anzufassen.
2. Custom Post Types im Code registrieren, nicht per Plugin
Nach einem CPT-Plugin zu greifen, wenn man einen eigenen Post-Typ braucht, ist Over-Engineering. register_post_type() ist ein einzelner Funktionsaufruf und gibt dir volle Kontrolle über Labels, Capabilities, REST-API-Unterstützung und Rewrite-Regeln.
add_action('init', function () {
register_post_type('product_review', [
'labels' => ['name' => 'Bewertungen', 'singular_name' => 'Bewertung'],
'public' => true,
'show_in_rest' => true,
'supports' => ['title', 'editor', 'thumbnail'],
'rewrite' => ['slug' => 'bewertungen'],
]);
});
Dies in einem site-spezifischen Plugin (nicht im Theme) zu platzieren, hält es bei Theme-Wechseln aktiv und vermeidet den Content-Lock-in durch Drittanbieter-CPT-Plugins.
3. Teure Queries mit Transients cachen
Jedes Mal, wenn eine Seite lädt, kostet eine komplexe WP_Query oder ein externer API-Aufruf Zeit und Geld. WordPress-Transients sind ein abhängigkeitsfreier Caching-Layer, der standardmäßig auf der Options-Tabelle basiert — und automatisch Redis oder Memcached nutzt, wenn ein Object Cache installiert ist.
function get_featured_posts() {
$cache_key = 'featured_posts_v1';
$posts = get_transient($cache_key);
if (false === $posts) {
$posts = new WP_Query(['category_name' => 'featured', 'posts_per_page' => 5]);
set_transient($cache_key, $posts, HOUR_IN_SECONDS);
}
return $posts;
}
Versioniere den Cache-Key (z. B. _v1), damit du ihn durch Inkrementieren invalidieren kannst, ohne die Datenbank direkt anzufassen.
4. Endlosschleifen in save_post vermeiden
Der save_post-Hook ist eine der häufigsten Quellen von Produktions-Bugs. wp_update_post() innerhalb des Hooks aufzurufen feuert save_post erneut — Endlosschleife, Fatal Error, korrupte Post-Daten.
add_action('save_post', function ($post_id) {
// Bei Autosaves und Revisionen abbrechen
if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) {
return;
}
// Nonce prüfen
if (!isset($_POST['my_nonce']) || !wp_verify_nonce($_POST['my_nonce'], 'my_action')) {
return;
}
// Wiedereintritt verhindern
remove_action('save_post', __FUNCTION__);
wp_update_post(['ID' => $post_id, 'post_excerpt' => sanitize_text_field($_POST['my_field'])]);
add_action('save_post', __FUNCTION__);
});
Prüfe immer auf Revisionen, verifiziere eine Nonce und nutze das remove_action / add_action-Muster um jeden sekundären wp_update_post()-Aufruf.
5. Eigene REST-API-Endpoints mit register_rest_route() hinzufügen
Wenn du für eigene Server-Calls noch admin-ajax.php verwendest, hör damit auf. Die WP REST API bietet dir namespace-, versions- und berechtigungsgeprüfte Endpoints mit konsistenten JSON-Antworten — und funktioniert mit jedem HTTP-Client.
add_action('rest_api_init', function () {
register_rest_route('myapp/v1', '/stats', [
'methods' => WP_REST_Server::READABLE,
'callback' => 'myapp_get_stats',
'permission_callback' => function () {
return current_user_can('read');
},
]);
});
function myapp_get_stats(WP_REST_Request $request) {
return new WP_REST_Response(['total_posts' => wp_count_posts()->publish], 200);
}
Dein Endpoint ist nun unter /wp-json/myapp/v1/stats erreichbar. Füge einen Nonce-Header (X-WP-Nonce) für authentifizierte Anfragen vom Frontend hinzu.
Fazit
Diese fünf Muster — WP HTTP API, programmatische CPTs, Transient-Caching, sichere save_post-Hooks und eigene REST-Endpoints — sind der Unterschied zwischen WordPress-Code, der Bestand hat, und Code, der zur technischen Schuld wird. Sie sind alle in Core eingebaut, gut dokumentiert und auf Millionen von Sites erprobt. Nutze sie.
