WordPress Admin-Anpassung: Der Entwickler-Leitfaden 2026

WordPress Admin-Anpassung: Der Entwickler-Leitfaden 2026

Zuletzt überprüft: 14. Oktober 2026
21 Min. Lesezeit
Tutorial
Full-Stack-Entwickler
500+ WP-Projekte

Wenn Sie eine WordPress-Website an einen Kunden übergeben, ist das Standard-Dashboard oft überwältigend. Es ist voll mit Upsell-Hinweisen, Menüs wie Kommentare (obwohl Kommentare deaktiviert sind) und technischem Fachjargon, den Redakteure nicht brauchen.

Ein generisches Dashboard sagt: Ich habe ein Theme installiert. Ein angepasstes Dashboard sagt: Ich habe eine Anwendung gebaut, die zu eurem Arbeitsablauf passt.

Admin-UX ist Support-Prävention. In diesem Leitfaden geht es um Menüs, Toolbar, Dashboard-Widgets, eigene Rollen, Einstellungsseiten, Farbschemata, die Login-Seite und leichtes White-Labeling mit den Core-APIs aus dem Customize Admin Handbook. Die offiziellen Referenzen für das Laden von Assets und den Menüaufbau sind admin_enqueue_scripts und admin_menu.

#Warum Admin-Anpassung Support-Tickets reduziert

Nach der Übergabe eines WooCommerce-Shops mit Page Builder sieht der Kunde oft Dutzende Menüpunkte und nutzt eine Handvoll davon. Der Rest erzeugt Fragen: „Darf ich auf Themes klicken?“, „Was ist ACF?“, „Warum sehe ich WooCommerce > Status?“.

Werkzeuge, Einstellungen und die Datei-Editoren für alle ohne manage_options zu entfernen, hat nichts mit schöneren Farben zu tun. Gefährliche Pfade verschwinden aus dem Blickfeld von Personen ohne Vollzugriff.

Der zweite Gewinn ist das Onboarding. Statt einer Stunde „hier nicht klicken“ zeigen Sie eine Support-Seite mit Dokumentation, Kontakt und einer kurzen Veröffentlichungs-Checkliste. Das ist White-Label als Produkt, nicht nur ein Logo-Tausch.

#Admin-Anpassung im Must-Use-Plugin statt in functions.php

Legen Sie Admin-Anpassungen nicht in die functions.php des Child-Themes. Wechselt der Kunde das Theme, verschwinden Menüregeln, Asset-Loading und Capability-Checks gleich mit. Agentur-Code, der einen Theme-Wechsel überleben soll, gehört in ein Must-Use-Plugin unter wp-content/mu-plugins/.

Eine typische Struktur:

wp-content/mu-plugins/
  wppoland-admin-ux.php          # Bootstrap (lädt den Ordner)
  wppoland-admin-ux/
    menu.php
    enqueue.php
    capabilities.php
    dashboard.php

Die Bootstrap-Datei im Wurzelverzeichnis von mu-plugins/ wird automatisch geladen. Sie bindet nur die Dateien im Unterordner ein. Der Vorteil: Der Code läuft immer, unabhängig von aktiven normalen Plugins, und Sie versionieren den ganzen Ordner, ohne dass jemand ihn im Plugins-Bildschirm deaktivieren kann.

<?php
/**
 * Plugin Name: WPPoland Admin UX
 * Description: Menübereinigung, Asset-Loading und Support-Seiten für Kundenrollen.
 * Author: wppoland.com
 */

declare(strict_types=1);

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

$dir = __DIR__ . '/wppoland-admin-ux';
require_once $dir . '/menu.php';
require_once $dir . '/enqueue.php';
require_once $dir . '/capabilities.php';
require_once $dir . '/dashboard.php';

Testen Sie immer mit einem eigenen Benutzerkonto in der Kundenrolle (Redakteur, Shop-Manager oder eine eigene Rolle). Wer auf Staging als Super-Admin eingeloggt bleibt, sieht die Fehler nicht, die er gerade für den Kunden „behoben“ hat.

Hat das Projekt bereits ein Agentur-Plugin mit Composer-Autoloading, kann der Must-Use-Bootstrap einfach dieses Paket laden. Der Punkt bleibt derselbe: Die Admin-UX darf nicht sterben, wenn bei einem Redesign ein Elementor-Child-Theme ausgetauscht wird.

Halten Sie die Dateien klein. Eine Datei für das Menü, eine für Assets, eine für Sperren. Wer später herausfinden muss, warum das ACF-Menü verschwunden ist, soll keine 800-Zeilen-functions.php durchsuchen müssen.

#Was ein Must-Use-Plugin von einem normalen Plugin unterscheidet

Das Advanced Administration Handbook listet die Unterschiede auf, und mehrere davon bestimmen, wie Admin-Code geschrieben werden muss:

  • Must-Use-Plugins sind auf allen Websites der Installation aktiv und lassen sich in wp-admin nicht deaktivieren.
  • PHP lädt sie in alphabetischer Reihenfolge, vor den normalen Plugins.
  • Dateien in Unterordnern werden nicht automatisch eingebunden. Deshalb braucht die Struktur oben eine Bootstrap-Datei im Wurzelverzeichnis.
  • Sie erscheinen nicht in der Standardliste des Plugins-Bildschirms, sondern in einer eigenen Must-Use-Liste, die nur Nutzer mit Zugriff auf Plugins sehen.
  • Sie tauchen nicht in Update-Benachrichtigungen auf, neue Versionen verfolgen Sie also selbst.
  • Aktivierungs-Hooks werden für Plugins im Must-Use-Ordner nicht ausgeführt.

Der letzte Punkt überrascht am häufigsten. Code, den ein normales Plugin in register_activation_hook legen würde, etwa das Anlegen von Rollen, braucht im Must-Use-Plugin eine eigene Versionsprüfung. Die folgenden Abschnitte zeigen das Muster.

#Wie prüfen Sie Capabilities, bevor Sie das Admin-Menü ändern

remove_menu_page und add_menu_page sind Sichtbarkeits-APIs. Sie ersetzen keine Zugriffskontrolle. Wer die URL kennt, kann tools.php oder options-general.php weiter öffnen, wenn die Capability es erlaubt.

Regeln, die sich in Produktion bewähren:

  1. Prüfen Sie current_user_can( 'manage_options' ) (oder eine spezifischere Capability), bevor Sie Menüs für Kundenrollen ausblenden.
  2. Blenden Sie Menüs nie vor der Person aus, die Fehler suchen muss. Ein Administrator ohne sichtbares Menü kostet mehr Zeit, als er spart.
  3. Wenn Sie wirklich sperren müssen, nutzen Sie admin_init oder map_meta_cap und antworten mit wp_die() oder einer Weiterleitung mit Erklärung, nicht nur mit CSS display: none.

Für Redaktionen, in denen freie Autoren und feste Redakteure dieselbe Website nutzen, lohnt eine eigene Rolle mit edit_posts und upload_files, ohne install_plugins und edit_themes. Die Menübereinigung spiegelt dann diese Rolle, statt zu einer langen Ausnahmeliste nach Benutzer-ID zu werden. get_role( 'editor' )->remove_cap( '...' ) gehört in eine einmalige Migrationsroutine oder einen CLI-Befehl, nicht in einen Request-Hook, der auf jeder Admin-Seite läuft.

/**
 * Direkten URL-Zugriff auf Werkzeuge für Nicht-Administratoren sperren.
 */
function wppoland_block_tools_screen(): void {
	if ( ! is_admin() || wp_doing_ajax() ) {
		return;
	}

	if ( current_user_can( 'manage_options' ) ) {
		return;
	}

	$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
	if ( ! $screen || 'tools' !== $screen->id ) {
		return;
	}

	wp_die(
		esc_html__( 'Sie haben keinen Zugriff auf diesen Bildschirm.', 'wppoland-admin-ux' ),
		esc_html__( 'Zugriff verweigert', 'wppoland-admin-ux' ),
		[ 'response' => 403 ]
	);
}
add_action( 'current_screen', 'wppoland_block_tools_screen' );

Capability-Namen sind der Vertrag. Benutzer-IDs ändern sich, aber der Shop-Manager behält manage_woocommerce. Bauen Sie Regeln um Capabilities herum, nicht um Benutzer-ID 12.

#Eigene Kundenrolle mit add_role und map_meta_cap

Rollen liegen in der Datenbank, nicht im Code. Die Referenz zu add_role hält fest, dass die Funktion abbricht und null zurückgibt, wenn die Rolle schon existiert. Eine geänderte Capability-Liste wirkt deshalb erst, wenn die Rolle entfernt und neu angelegt wird. Ohne Versionsprüfung würde das bei jedem Request passieren, und weil Must-Use-Plugins keinen Aktivierungs-Hook haben, ist ein gespeicherter Versionswert die einfachste Absicherung.

function wppoland_register_client_role(): void {
	if ( '2' === get_option( 'wppoland_roles_version' ) ) {
		return;
	}

	remove_role( 'client_manager' );
	add_role(
		'client_manager',
		'Kundenredaktion',
		[
			'read'                 => true,
			'edit_posts'           => true,
			'edit_published_posts' => true,
			'publish_posts'        => true,
			'delete_posts'         => true,
			'edit_pages'           => true,
			'edit_published_pages' => true,
			'edit_others_pages'    => true,
			'publish_pages'        => true,
			'upload_files'         => true,
			'moderate_comments'    => true,
		]
	);

	update_option( 'wppoland_roles_version', '2' );
}
add_action( 'init', 'wppoland_register_client_role' );

Capabilities, die nicht in der Liste stehen, hat die Rolle nicht. Das ist sicherer, als manage_options => false ausdrücklich zu setzen, weil ein vergessener Schlüssel dann nichts öffnet. Ändert sich die Liste, erhöhen Sie den Versionswert.

Manche Seiten soll der Kunde nicht bearbeiten, auch wenn die Rolle sonst edit_others_pages hat, typischerweise die Startseite. Der Filter map_meta_cap übersetzt Meta-Capabilities wie edit_post in primitive Capabilities, und dort können Sie für eine bestimmte Seite do_not_allow ergänzen:

function wppoland_protect_front_page( array $caps, string $cap, int $user_id, array $args ): array {
	if ( ! in_array( $cap, [ 'edit_post', 'delete_post' ], true ) || empty( $args[0] ) ) {
		return $caps;
	}

	$front_page = (int) get_option( 'page_on_front' );

	if ( $front_page && (int) $args[0] === $front_page && ! user_can( $user_id, 'manage_options' ) ) {
		$caps[] = 'do_not_allow';
	}

	return $caps;
}
add_filter( 'map_meta_cap', 'wppoland_protect_front_page', 10, 4 );

Der Vorteil gegenüber einem ausgeblendeten Bearbeiten-Link: Die Regel gilt überall, in der Seitenliste, im Block-Editor, in der REST API und in der QuickEdit-Ansicht.

#Wie räumen Sie das WordPress-Admin-Menü auf

Der erste sichtbare Schritt ist remove_menu_page. Die meisten Kunden müssen Werkzeuge oder Einstellungen nicht sehen. Prüfen Sie Capabilities, nicht Benutzer-IDs. Verstecken Sie niemals Menüs vor Administratoren, sonst verlieren Sie selbst den Überblick auf Staging.

/**
 * Admin-Menü für Nicht-Admins bereinigen
 */
function wppoland_clean_admin_menu(): void {
	if ( current_user_can( 'manage_options' ) ) {
		return;
	}

	remove_menu_page( 'tools.php' );
	remove_menu_page( 'options-general.php' );
	remove_menu_page( 'edit-comments.php' );
	remove_menu_page( 'edit.php?post_type=acf-field-group' );

	remove_submenu_page( 'themes.php', 'theme-editor.php' );
	remove_submenu_page( 'plugins.php', 'plugin-editor.php' );
}
add_action( 'admin_menu', 'wppoland_clean_admin_menu', 999 );

Priorität 999 ist Absicht: Viele Plugins registrieren ihre Menüs auf admin_menu mit der Standardpriorität 10. Wer zu früh entfernt, trifft einen Slug, der noch nicht existiert, und remove_menu_page bewirkt nichts. Die Administration Menus-Doku listet Top-Level- und Submenu-Hooks sauber; halten Sie sich an die dortigen Slugs statt an übersetzte Labels. Wenn Sie unsicher sind, welchen Slug ein Plugin nutzt, loggen Sie auf Staging kurz $GLOBALS['menu'].

remove_menu_page blendet den Link nur aus. Ein kluger Benutzer kann weiter /wp-admin/options-general.php öffnen. Um den Zugriff wirklich zu blockieren, prüfen Sie auf admin_init oder current_screen die Capability und brechen mit wp_die ab. Menü-Kosmetik und Zugriffskontrolle sind zwei Schichten.

Deutsche Agenturen treffen oft auf gemischte Rollen: Redaktion mit edit_pages, Shop-Manager mit WooCommerce-Capabilities, Marketing mit ACF-Optionsseiten. Eine pauschale Liste ohne Capability-Check erzeugt Tickets der Form „Plugin X fehlt“, obwohl nur der Menüpunkt fehlt. Dokumentieren Sie pro Rolle, was sichtbar bleibt, und prüfen Sie das nach jedem Plugin-Update erneut.

Bei WooCommerce-Shops behält der Shop-Manager meist Produkte, Bestellungen und Gutscheine, während Status, Erweiterungen und die Systemstatus-Untermenüs verschwinden. Entfernen Sie die Mediathek nicht für Redakteure, die tatsächlich Bilder hochladen: Das Panel wirkt aufgeräumt, und am nächsten Tag kommt das Ticket, dass „Hochladen“ fehlt. Technische Werkzeuge zuerst, Inhaltswege zuletzt.

#Wie ordnen Sie Plugin-Untermenüs im Admin

Top-Level-Aufräumen reicht selten. SEO-Plugins, Formular-Plugins und Page Builder hängen Unterpunkte unter Beiträge, Medien oder Einstellungen. remove_submenu_page( $parent, $child ) braucht exakte Child-Slugs; geratene Strings schlagen still fehl.

Pragmatischer Workflow in Agenturen: einmal als Redakteur einloggen, jeden Menüpunkt notieren, den niemand braucht, dann die IDs aus dem HTML der Admin-Sidebar lesen (#menu-posts, #toplevel_page_...). Danach erst den Cleanup-Code schreiben. Nach jedem Major-Update von Yoast, Rank Math oder Elementor denselben Rundgang, denn Plugin-Hersteller verschieben Slugs gelegentlich.

Für wiederkehrende Kundenprojekte lohnt ein kleines Must-Use-Plugin mit Feature-Flags pro Environment: auf Staging bleiben Theme- und Plugin-Editor sichtbar, auf Live verschwinden sie für Nicht-Admins. Dieselbe Codebasis, unterschiedliche Flags in wp-config.php oder Hosting-Env-Vars. So vermeiden Sie Drift zwischen „was wir entwickelten“ und „was der Kunde sieht“.

#Reihenfolge der Hooks

admin_menu und admin_bar_menu feuern für viele Plugins. Wer mit Priorität 10 entfernt, verliert gegen Registrierungen bei 20 oder 99. Deshalb 999 für Cleanup und eigene Nodes, nicht aus Magie, sondern weil späte Registrierung der Default vieler Plugins ist.

Dashboard-Setup läuft über wp_dashboard_setup. Dort gilt dasselbe: erst fremde Meta-Boxen entfernen, dann die eigene registrieren. Wenn ein Widget „wieder auftaucht“, liegt meist eine zweite Registrierung später im Request vor, nicht Caching.

#Eigene Menüseiten hinzufügen

Verwenden Sie keine Theme-Options-Frameworks, wenn eine einfache Seite reicht. Die native API ist leicht und landet im Core-Menü ohne Extra-Dependency.

function wppoland_register_support_page(): void {
	add_menu_page(
		'Kundensupport',
		'Support',
		'edit_posts',
		'wppoland-support',
		'wppoland_render_support',
		'dashicons-sos',
		90
	);
}
add_action( 'admin_menu', 'wppoland_register_support_page' );

function wppoland_render_support(): void {
	if ( ! current_user_can( 'edit_posts' ) ) {
		wp_die( esc_html__( 'Zugriff verweigert', 'wppoland-admin-ux' ) );
	}
	?>
	<div class="wrap">
		<h1><?php echo esc_html__( 'Brauchen Sie Hilfe?', 'wppoland-admin-ux' ); ?></h1>
		<div class="card">
			<h2><?php echo esc_html__( 'Kontaktieren Sie Ihren Entwickler', 'wppoland-admin-ux' ); ?></h2>
			<p>E-Mail: <a href="mailto:[email protected]">dev@wppoland.com</a></p>
			<p>Kurzvideos zur Pflege liegen im gemeinsamen Drive; Ticket-System: Link im Projekt-Handbuch.</p>
		</div>
	</div>
	<?php
}

add_menu_page erwartet Capability, Slug und Callback. Position 90 sitzt weit unten und kollidiert seltener mit WooCommerce oder Yoast. Für Unterseiten nutzen Sie add_submenu_page mit dem Parent-Slug Ihrer Support-Seite, statt alles in eine lange Callback-Datei zu pressen. Zu viele Top-Level-Icons erzeugen dasselbe Chaos, das Sie gerade beseitigt haben.

Inhalt der Support-Seite: SLA-Zeiten, Link zum Ticket-Tool, zwei Absätze „So aktualisieren Sie Beiträge“, kein Marketing-Banner. Redakteure öffnen diese Seite, wenn sie unsicher sind. Dann soll sie Antworten geben, keine Upsells. Ein Mini-CMS gehört nicht hinein.

#Einstellungsseite für Kunden mit der Settings API

Soll der Kunde ein paar Werte selbst pflegen, etwa die Support-Telefonnummer oder Social-Media-Links, braucht er keinen Zugang zu Einstellungen. Eine eigene Seite auf Basis der Settings API zeigt ihm nur diese Felder. Laut Handbuch übernimmt WordPress dann das Speichern der Formulardaten, ergänzt Nonces und schickt die Übermittlung über wp-admin/options.php, das die Capabilities streng prüft.

function wppoland_register_client_settings(): void {
	register_setting(
		'wppoland_client',
		'wppoland_support_phone',
		[
			'type'              => 'string',
			'sanitize_callback' => 'sanitize_text_field',
			'default'           => '',
		]
	);

	add_settings_section( 'wppoland_contact', 'Kontakt', '__return_false', 'wppoland-client-settings' );

	add_settings_field(
		'wppoland_support_phone',
		'Support-Telefon',
		'wppoland_render_phone_field',
		'wppoland-client-settings',
		'wppoland_contact'
	);
}
add_action( 'admin_init', 'wppoland_register_client_settings' );

function wppoland_render_phone_field(): void {
	printf(
		'<input type="text" name="wppoland_support_phone" value="%s" class="regular-text">',
		esc_attr( (string) get_option( 'wppoland_support_phone', '' ) )
	);
}

function wppoland_add_client_settings_page(): void {
	add_menu_page(
		'Website-Einstellungen',
		'Website',
		'edit_pages',
		'wppoland-client-settings',
		'wppoland_render_client_settings',
		'dashicons-admin-generic',
		91
	);
}
add_action( 'admin_menu', 'wppoland_add_client_settings_page' );

function wppoland_render_client_settings(): void {
	?>
	<div class="wrap">
		<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
		<?php settings_errors(); ?>
		<form action="options.php" method="post">
			<?php
			settings_fields( 'wppoland_client' );
			do_settings_sections( 'wppoland-client-settings' );
			submit_button();
			?>
		</form>
	</div>
	<?php
}

add_filter( 'option_page_capability_wppoland_client', fn() => 'edit_pages' );

Die letzte Zeile fehlt meistens. In der Core-Datei wp-admin/options.php steht, dass die Optionsgruppen aller registrierten Einstellungen standardmäßig manage_options verlangen und dass der Filter option_page_capability_{$option_page} die Anforderung für eine Gruppe ändert. Ohne den Filter sieht der Redakteur die Seite, füllt das Feld aus und bekommt beim Speichern eine Fehlermeldung. Der Filter öffnet nur die Gruppe wppoland_client, nicht den Rest der Einstellungen.

#Admin-CSS und JS mit admin_enqueue_scripts laden statt admin_head

admin_head mit Inline-<style> funktioniert in Prototypen, skaliert aber schlecht: keine Versionierung, umständliches Cache-Busting, Präsentation vermischt mit PHP. In Produktion gehört die Datei über wp_enqueue_style auf den Hook admin_enqueue_scripts, begrenzt auf die Bildschirme, die sie brauchen.

function wppoland_admin_assets( string $hook_suffix ): void {
	// Nur eigene Seiten und das Dashboard, nicht jeder Core-Bildschirm.
	$allowed = [
		'index.php',
		'toplevel_page_wppoland-support',
	];

	if ( ! in_array( $hook_suffix, $allowed, true ) ) {
		return;
	}

	$base = plugin_dir_url( __FILE__ );
	$ver  = '2026.09.21';

	wp_enqueue_style(
		'wppoland-admin-ux',
		$base . 'assets/admin.css',
		[],
		$ver
	);

	wp_enqueue_script(
		'wppoland-admin-ux',
		$base . 'assets/admin.js',
		[ 'jquery' ],
		$ver,
		true
	);

	wp_localize_script(
		'wppoland-admin-ux',
		'wppolandAdminUx',
		[
			'ajaxUrl' => admin_url( 'admin-ajax.php' ),
			'nonce'   => wp_create_nonce( 'wppoland_admin_ux' ),
		]
	);
}
add_action( 'admin_enqueue_scripts', 'wppoland_admin_assets' );

$hook_suffix ist der Schlüssel, um Core-Bildschirme nicht zu beschädigen. Pauschales Ausblenden von .notice.is-dismissible ist riskant: Core-Warnungen zu PHP, Datenbank und kritischen Updates verschwinden mit. Filtern Sie Notices über Plugin-Klassen oder den Hook admin_notices, und begrenzen Sie Selektoren auf eigene Wrapper wie .wppoland-support-wrap.

Farbänderungen an der Admin Bar reichen oft. Testen Sie klassischen Editor und Block-Editor: Gutenberg bringt eine eigene Oberfläche mit, ein breites #wpadminbar { background } ist unkritisch, !important auf .components-button dagegen ein Rezept für einen kaputten Editor.

/* assets/admin.css: Wirkungsbereich eng halten */
#wpadminbar {
	background: #1f2937;
}

#toplevel_page_wppoland-support .wp-menu-image::before {
	color: #059669;
}

.wppoland-support-wrap .card {
	max-width: 40rem;
}

Spricht admin.js mit der REST API, nutzen Sie wp_create_nonce( 'wp_rest' ) oder eine eigene lokalisierte Nonce wie oben. „Nur eingeloggte Nutzer“ ersetzt keine Nonce-Prüfung auf dem Server. Und vermeiden Sie wp_print_scripts direkt im Callback von add_menu_page, weil das die Reihenfolge der Abhängigkeiten bricht.

Datenschutz-Hinweise im Admin sind selten nötig, außer Sie zeigen personenbezogene Ticket-Daten auf der Support-Seite. Dann reicht ein kurzer Satz, dass Support-Inhalte der Auftragsverarbeitung unterliegen, ohne den Beitrag in eine DSGVO-Checkliste zu verwandeln.

#Eigenes Farbschema für den WordPress-Admin mit wp_admin_css_color

Die Farben von Seitenleiste und Toolbar stammen aus dem Farbschema, das jeder Nutzer in seinem Profil wählt. Statt sie mit !important zu überschreiben, registrieren Sie ein eigenes Schema mit wp_admin_css_color. Die Funktion erwartet einen eindeutigen Schlüssel, einen Namen, die URL der CSS-Datei mit dem Schema, ein Array mit Farben für die Vorschau im Profil und optional Farben für SVG-Icons (base, focus und current).

function wppoland_register_admin_scheme(): void {
	wp_admin_css_color(
		'wppoland',
		'WPPoland',
		plugin_dir_url( __FILE__ ) . 'assets/admin-colors.css',
		[ '#1f2937', '#059669', '#d1fae5', '#ffffff' ],
		[
			'base'    => '#d1d5db',
			'focus'   => '#ffffff',
			'current' => '#ffffff',
		]
	);
}
add_action( 'admin_init', 'wppoland_register_admin_scheme' );

Der Core registriert seine eigenen Schemata am selben Hook: register_admin_color_schemes hängt in wp-admin/includes/admin-filters.php mit Priorität 1 an admin_init. Die Auswahl wird als Benutzeroption admin_color gespeichert, und der Admin erhält die Body-Klasse admin-color- plus Schlüssel, sodass Sie zusätzliche Regeln gezielt auf Ihr Schema richten können.

Mit dem Filter get_user_option_admin_color lässt sich das Schema für alle erzwingen, aber damit nehmen Sie den Nutzern die Wahl. Manche wählen ein Schema, weil dessen Kontrast zu ihrem Sehvermögen passt. Ihr Schema als eine von mehreren Optionen ist die sicherere Voreinstellung.

#Wie passen Sie die WordPress-Toolbar an

Die Toolbar ist im Frontend für eingeloggte Benutzer sichtbar. Sie eignet sich für Schnellaktionen wie Cache leeren oder Im Page Builder bearbeiten. Über den Hook admin_bar_menu entfernen und ergänzen Sie Nodes.

function wppoland_customize_toolbar( WP_Admin_Bar $wp_admin_bar ): void {
	$wp_admin_bar->remove_node( 'wp-logo' );

	if ( ! current_user_can( 'manage_options' ) ) {
		return;
	}

	$wp_admin_bar->add_node(
		[
			'id'    => 'wppoland-clear-cache',
			'title' => 'Cache leeren',
			'href'  => wp_nonce_url(
				admin_url( 'admin-post.php?action=wppoland_clear_cache' ),
				'wppoland_clear_cache'
			),
			'meta'  => [ 'title' => 'Object Cache leeren' ],
		]
	);
}
add_action( 'admin_bar_menu', 'wppoland_customize_toolbar', 999 );

Das WordPress-Logo in der Toolbar ist für Kunden oft der Einstieg in „Über WordPress“ und externe Links. Entfernen Sie es, wenn die Marke des Kunden im Vordergrund stehen soll. Für die Cache-Aktion brauchen Sie zusätzlich einen admin_post_-Handler mit check_admin_referer und Capability-Check. Die Toolbar liefert nur den Einstieg. Soll die Leiste für bestimmte Rollen im Frontend ganz verschwinden, zeigt ein eigener Beitrag, wie Sie die Admin-Leiste für Nicht-Admins ausblenden.

Auf deutschsprachigen Projekten sehen Redakteure die Toolbar oft auf dem Live-Frontend während Freigaberunden. Halten Sie Labels kurz und deutsch; das vermeidet Rückfragen à la „Was ist Redis?“. Technischen Kontext legen Sie in meta.title oder in die Support-Seite.

#Wie ersetzen Sie den WordPress-Willkommensbildschirm

Wenn sich ein Kunde einloggt, landet er im Dashboard. Standard-Widgets wie WordPress-Veranstaltungen oder Schneller Entwurf helfen Redaktionsteams selten. Ersetzen Sie sie durch ein Status-Widget mit den Dingen, die Sie wöchentlich ohnehin erklären.

function wppoland_dashboard_widgets(): void {
	remove_meta_box( 'dashboard_primary', 'dashboard', 'side' );
	remove_meta_box( 'dashboard_quick_press', 'dashboard', 'side' );

	wp_add_dashboard_widget(
		'wppoland_status_widget',
		'Website-Status',
		'wppoland_render_status_widget'
	);
}
add_action( 'wp_dashboard_setup', 'wppoland_dashboard_widgets' );

function wppoland_render_status_widget(): void {
	echo '<p><strong>WordPress Core</strong>: Status über Website-Zustand prüfen</p>';
	echo '<p><strong>Backups</strong>: laut Hosting-Plan (Uhrzeit im Projekt-Handbuch)</p>';
	echo '<p><strong>Traffic</strong>: Analytics-Link aus dem Übergabe-Dokument</p>';
}

Schreiben Sie keine erfundenen Ampeln und keine Fake-Traffic-Zahlen in Widgets. Verlinken Sie auf den Website-Zustand, auf das reale Backup-Dashboard des Hosters und auf die Analytics-Einrichtung, die der Kunde bereits nutzt. Das Widget ist Navigation, kein Reporting-Ersatz. Widget-Callbacks sollen billig bleiben: externe APIs nicht synchron beim Rendern aufrufen, sondern Ergebnisse in einem Transient zwischenspeichern.

Wenn mehrere Plugins eigene Dashboard-Boxen registrieren, priorisieren Sie: Support-Widget und Website-Zustand oben, Marketing-Feeds von Plugins weg. remove_meta_box braucht die korrekte Context-Position (normal, side, column3); bei Fehlschlägen hilft ein Blick in den HTML-Quelltext der Meta-Box-ID.

#Was die Standard-Widgets im Dashboard tatsächlich tun

Ein häufiges Argument für das Entfernen der Standard-Widgets ist Geschwindigkeit. Der Quelltext von wp-admin/includes/dashboard.php zeigt, dass der Gewinn klein ist:

  • WordPress-Veranstaltungen und Neuigkeiten (dashboard_primary) lädt den Feed über ein zwischengespeichertes Widget. Das fertige HTML liegt pro Sprache in einem Transient, und ist dieser Cache leer, zeigt das Widget einen Ladehinweis und holt den Inhalt per AJAX nach, statt die Seite aufzuhalten.
  • Schneller Entwurf (dashboard_quick_press) verwendet pro Nutzer einen einzigen automatischen Entwurf wieder, dessen ID in der Benutzeroption dashboard_quick_press_last_post_id liegt. Automatische Entwürfe, die älter als sieben Tage sind, löscht wp_delete_auto_drafts über das geplante Ereignis wp_scheduled_auto_draft_delete.
  • Status des Website-Zustands (dashboard_site_health) liest ein gespeichertes Ergebnis aus dem Transient health-check-site-status-result, statt bei jedem Aufruf alle Tests auszuführen.

Das Argument für das Entfernen ist also Fokus, nicht Tempo. Den Website-Zustand sollten Sie für Administratoren eher behalten, weil er Warnungen zur PHP-Version und zu fehlenden Modulen zeigt, die sonst leicht untergehen.

Die Login-Seite ist das Erste, was der Kunde jeden Tag sieht. Drei Hooks in wp-login.php decken das meiste ab:

  • login_enqueue_scripts (seit Version 3.1) ist der Hook für Stylesheets und Skripte auf der Login-Seite, das Gegenstück zu admin_enqueue_scripts in wp-admin.
  • login_headerurl bestimmt, wohin das Logo verlinkt. Standard ist wordpress.org.
  • login_headertext (seit Version 5.2) bestimmt den Linktext des Logos. Der ältere Filter login_headertitle ist seit 5.2 veraltet, mit dem Hinweis, dass ein title-Attribut am Login-Logo aus Gründen der Barrierefreiheit nicht empfohlen wird.
function wppoland_login_assets(): void {
	wp_enqueue_style(
		'wppoland-login',
		plugin_dir_url( __FILE__ ) . 'assets/login.css',
		[],
		'2026.10.14'
	);
}
add_action( 'login_enqueue_scripts', 'wppoland_login_assets' );

add_filter( 'login_headerurl', fn() => home_url( '/' ) );
add_filter( 'login_headertext', fn() => get_bloginfo( 'name' ) );
/* assets/login.css */
.login h1 a {
	background-image: url("../img/kunden-logo.svg");
	background-size: contain;
	width: 100%;
	height: 80px;
}

Screenreader lesen den Linktext vor, daher ist der Name der Website besser als ein leerer String. Testen Sie die Seite mit aktivem Zwei-Faktor- oder SSO-Plugin, weil diese eigene Felder ergänzen, die zu enges CSS aus dem Bild schieben kann. Weitere Techniken für das Formular selbst beschreibt der Beitrag zur Anpassung der WordPress-Login-Seite.

#Was prüfen Sie vor der Admin-Übergabe an den Kunden

Vor Go-Live einmal mit der Kundenrolle einloggen (nicht als Super-Admin):

  1. Menü: nur die Einträge, die Redaktion braucht; keine ACF-Field-Groups, kein Theme-Editor. Der Administrator sieht weiterhin alles.
  2. Direkte URLs zu Werkzeugen, Einstellungen und Datei-Editor sind gesperrt, wo das gewollt ist.
  3. Admin-CSS und JS laden nur auf den erlaubten $hook_suffix-Werten.
  4. Toolbar: Cache-Aktion nur für Rollen mit der passenden Capability und mit Nonce; kein WP-Logo, wenn Branding gewünscht.
  5. Dashboard: ein Status-Widget, keine Plugin-Feeds; Links im Übergabe-Dokument geprüft.
  6. Support-Seite: aktuelle Mail, Ticket-URL, zwei Pflege-Schritte in Deutsch.
  7. Einstellungsseite speichert mit der Kundenrolle, nicht nur als Administrator.
  8. Login-Logo verlinkt auf die Website und hat einen lesbaren Linktext.
  9. Staging vs. Live: dieselben Hooks, unterschiedliche Feature-Flags, damit Debug-Menüs nicht auf Produktion landen.

Zusätzlich: ein zweiter Browser ohne Adblocker, weil manche Notices und Menü-Icons sonst anders wirken. Und ein kurzer Screencast (fünf Minuten) für die Redaktion: wo liegt Support, wo liegen Seiten, wo liegen Produkte. Der Screencast ersetzt kein Handbuch, reduziert aber die ersten Tickets nach Launch.

Dokumentieren Sie in der README des Projekts, welche Menüs pro Rolle ausgeblendet sind und welches Must-Use-Plugin die Regeln besitzt. Wenn Sie Admin-Anpassung als festen Teil der Übergabe planen, gehört sie in denselben Scope wie CPT-Registrierung und Capability-Mapping, nicht als „nice to have“ in der Restzeit nach Design-Freeze.

#WordPress-Admin in 90 Tagen als White-Label umsetzen

Dieser Zeitplan ordnet Branding und Absicherung des Admin-Bereichs:

  • Tage 1-30 (Zugriffskontrolle): Kundenrollen mit minimalen Capabilities hinter einer Versionsprüfung registrieren. Hooks zum Aufräumen des Menüs in einem Must-use-Plugin ablegen, damit Nicht-Administratoren ungenutzte Optionen nicht sehen. Mit map_meta_cap verhindern, dass eingeschränkte Rollen Schlüsselseiten (etwa Startseite oder Kontaktseite) bearbeiten oder löschen.
  • Tage 31-60 (Dashboard und Einstellungen): Dashboard-Widgets bauen, die echten Status und Support-Links zeigen. Eine eigene Einstellungsseite mit der Settings API und Validierung anlegen und ihre Optionsgruppe per Capability-Filter für die Kundenrolle öffnen. Toolbar-Aktionen mit Nonce absichern.
  • Tage 61-90 (Branding und Login): Admin-Styles über admin_enqueue_scripts laden, ein Farbschema registrieren und den Login-Bildschirm gestalten. Zum Schluss die Übergabe-Checkliste oben mit jeder Kundenrolle durchgehen.

#Welche Admin-Anpassungsfehler kosten Agenturen Zeit

Menü versteckt, Capability bleibt. Redaktion bookmarkt /wp-admin/options-general.php und landet trotzdem in den Einstellungen. Cleanup ohne admin_init-Guard ist unvollständig.

Alle Notices tot. Ein CSS-Einzeiler blendet auch die PHP-Versionswarnung aus. Monate später scheitert ein Update, und niemand hat die gelbe Box gesehen.

Toolbar-Aktion ohne Nonce. admin-post.php?action=... ohne check_admin_referer und ohne Capability ist ein Einladungsschreiben. Die Toolbar ist nur UI; der Handler braucht die übliche Absicherung.

Einstellungsbildschirme nachgebaut. Wer options-general.php durch eine eigene „vereinfachte“ Seite ersetzt, ohne alle nötigen Optionen samt Validierung zu spiegeln, beschädigt Permalinks, Website-URL und Sprache.

White-Label-Plugin von der Stange. Viele White-Label-Plugins ändern Login, Footer-Text und Branding global und kollidieren mit Multisite oder mit Hosting-Panels. Für Menü und Dashboard reichen die Core-Hooks; schwere White-Label-Suites brauchen Sie nur, wenn Login-Branding und E-Mail-Absender wirklich Teil des Auftrags sind.

Deutsche Labels, englische Plugin-Reste. Nach dem Cleanup bleiben gemischte Sprachen im Menü. Entweder alle sichtbaren Labels über gettext-Filter angleichen oder akzeptieren, dass Drittanbieter-Strings Englisch bleiben, und das im Handbuch erwähnen, damit niemand „kaputte Übersetzung“ meldet.

#Rollen, Runbooks und Barrierefreiheit bei der Admin-Anpassung

Menü-Bereinigung ersetzt keine Rollenkonzepte. Wer Redakteuren manage_options gibt und dann Menüs versteckt, baut Theater. Besser: eigene Rolle mit den nötigen Caps, Menü nur als zweite Schicht.

Toolbar-Links ersetzen keine dokumentierten Runbooks. Ein Button Cache leeren ohne Logging und ohne Hinweis, wann man ihn nicht drücken soll, erzeugt mehr Schaden als Nutzen. Schreiben Sie in die Support-Seite zwei Sätze: vor Deploy Cache leeren, während Lasttests nicht wiederholt klicken.

CSS-White-Label ersetzt keine Barrierefreiheit. Kontrast der Admin Bar prüfen; Dashicons allein reichen nicht als einzige Hinweisgeber für Status. Tastaturfokus in eigenen Admin-Seiten testen, besonders wenn Sie .card und Custom-Markup mischen.

Admin-Anpassung ersetzt auch keine Schulung. Ein aufgeräumtes Backend hilft; ohne fünf Minuten Walkthrough suchen Redakteure trotzdem unter Medien, was unter Seiten liegt.

#Warum lohnt sich eine angepasste WordPress-Admin-UX

Die Anpassung des Admin-Bereichs ist User Experience für Redaktion und Shop-Teams. Unordnung weg, Arbeitswege hervorheben, Support-Seite als festen Anker. Nutzen Sie Core-Hooks statt schwerer Options-Frameworks, prüfen Sie Capabilities zweimal (Menü und URL), isolieren Sie den Code in einem Must-Use-Plugin und halten Sie Widgets ehrlich.

Orientierung für APIs und Hook-Reihenfolge bleibt das Customize-Admin-Handbook und die Reference zu add_menu_page sowie admin_bar_menu. Der Rest ist Projekthandwerk: Rollen, Flags, Übergabe-Check.

Solche Anpassungen sind fester Teil unserer Entwicklungsarbeit an WordPress-Backends.

Nächster Schritt

Machen Sie aus dem Artikel eine echte Umsetzung

Dieser Block stärkt die interne Verlinkung und führt Nutzer gezielt zum nächsten sinnvollen Schritt im Service- und Content-System.

Soll das Thema auf Ihrer Website umgesetzt werden?

Wenn Sie aus dem Artikel konkrete Maßnahmen für Website, Relaunch oder Weiterentwicklung ableiten wollen, definiere ich den Scope und setze ihn um.

Relevanter Cluster

Weitere WordPress-Dienste und Wissensbasis entdecken

Stärken Sie Ihr Unternehmen mit professionellem technischen Support in den Kernbereichen des WordPress-Ökosystems.

Reicht remove_menu_page, um Einstellungen zu sperren?#
Nein. Die Funktion entfernt nur den Menüeintrag. Wer die URL kennt, kann die Seite weiter öffnen, solange die Capability greift. Für echte Sperren prüfen Sie auf admin_init oder current_screen die Rolle und brechen mit wp_die ab, oder Sie entziehen die Capability über eine eigene Rolle.
Soll ich Menüs für Administratoren ausblenden?#
In der Regel nicht. Administratoren brauchen Debug- und Plugin-Oberflächen. Blenden Sie nur Rollen ohne manage_options aus, und halten Sie eine dokumentierte Ausnahme für Staging-Umgebungen, in denen Kunden mit Admin-Rechten arbeiten.
Wann lohnt sich eine eigene Support-Menüseite?#
Sobald Redaktion und Agentur getrennte Kanäle brauchen: Ticket-Link, SLA-Hinweis, Kurzvideos zur Pflege. Eine add_menu_page mit edit_posts hält das sichtbar, ohne Theme-Options-Frameworks oder externe SaaS-Dashboards.
Darf ich alle Admin-Notices per CSS ausblenden?#
Nur gezielt. .notice.is-dismissible pauschal zu verstecken verdeckt auch Core-Warnungen zu PHP-Version und Datenbank. Filtern Sie per Plugin-Slug oder Hook admin_notices und lassen Sie kritische Meldungen stehen.
Wie darf ein Redakteur eine Settings-API-Seite speichern?#
wp-admin/options.php verlangt standardmäßig manage_options. Der Filter option_page_capability_ gefolgt vom Namen der Einstellungsgruppe setzt für genau diese Gruppe eine andere Capability, etwa edit_pages.
Wird das Dashboard schneller, wenn ich die Standard-Widgets entferne?#
Kaum. Das News-Widget speichert seine Ausgabe in einem Transient und lädt sie per AJAX nach, das Site-Health-Widget liest ein gespeichertes Ergebnis. Der Gewinn ist Fokus für die Nutzer, nicht Geschwindigkeit.

Sie brauchen ein FAQ für Branche und Zielmarkt? Wir erstellen eine Version passend zu Ihren Business-Zielen.

Kontakt aufnehmen

Ähnliche Artikel