Administration menu
- Administration Menus are the menus you see on the left sidebar of the WordPress admin dashboard (
/wp-admin). - Each of these is an admin menu, and plugins can:
- Add a top-level menu
- Add a submenu under an existing menu
- Add hidden pages (no visible menu item)
<?php
/**
* Plugin Name: My Admin Menu Plugin
* Description: Demonstrates how to create WordPress administration menus.
* Version: 1.0
* Author: You
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Prevent direct access
}
/**
* Hook into the admin menu system
*/
add_action( 'admin_menu', 'my_plugin_register_admin_menu' );
/**
* Register admin menus
*/
function my_plugin_register_admin_menu() {
// TOP-LEVEL MENU
add_menu_page(
'My Plugin Dashboard', // Page title
'My Plugin', // Menu title
'manage_options', // Capability
'my-plugin', // Menu slug
'my_plugin_dashboard_page', // Callback function
'dashicons-admin-generic', // Icon
25 // Position
);
// SUBMENU PAGE
add_submenu_page(
'my-plugin', // Parent slug
'My Plugin Settings', // Page title
'Settings', // Menu title
'manage_options', // Capability
'my-plugin-settings', // Menu slug
'my_plugin_settings_page' // Callback function
);
}
/**
* Dashboard page callback
*/
function my_plugin_dashboard_page() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
?>
<div class="wrap">
<h1>My Plugin Dashboard</h1>
<p>This is the main dashboard page of the plugin.</p>
</div>
<?php
}
/**
* Settings page callback
*/
function my_plugin_settings_page() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
?>
<div class="wrap">
<h1>My Plugin Settings</h1>
<form method="post" action="options.php">
<?php
settings_fields( 'my_plugin_settings_group' );
do_settings_sections( 'my-plugin-settings' );
submit_button();
?>
</form>
</div>
<?php
}
Settings & Options API
- Options API - Stores and retrieves data from the database
- Settings API - Builds admin settings pages (UI + validation + security)
- Settings API does NOT store data. Options API does NOT render UI
- All wordpress options are stored in
wp_optionstable.
add_option( 'my_plugin_color', 'blue' );
update_option( 'my_plugin_color', 'red' );
$color = get_option( 'my_plugin_color', 'default' );
delete_option( 'my_plugin_color' );
<?php
/**
* Plugin Name: My Settings Plugin
* Description: End-to-end example of Admin Menu + Settings & Options API
* Version: 1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* 1️⃣ ADMIN MENU (ENTRY POINT)
*/
add_action( 'admin_menu', 'my_plugin_add_admin_menu' );
function my_plugin_add_admin_menu() {
add_menu_page(
'My Plugin Settings', // Page title
'My Plugin', // Menu title
'manage_options', // Capability
'my-plugin', // Menu slug
'my_plugin_settings_page', // Page callback
'dashicons-admin-settings' // Icon
);
}
/**
* 2️⃣ REGISTER SETTINGS (SETTINGS API)
*/
add_action( 'admin_init', 'my_plugin_register_settings' );
function my_plugin_register_settings() {
// Register option (Options API via Settings API)
register_setting(
'my_plugin_settings_group', // Settings group
'my_plugin_options', // Option name (stored in wp_options)
'my_plugin_sanitize_options'// Sanitization callback
);
// Settings section
add_settings_section(
'my_plugin_main_section', // Section ID
'Main Settings', // Title
'my_plugin_section_text', // Callback
'my-plugin' // Page slug (menu slug)
);
// Settings field
add_settings_field(
'enable_feature', // Field ID
'Enable Feature', // Label
'my_plugin_enable_field', // Field callback
'my-plugin', // Page slug
'my_plugin_main_section' // Section ID
);
}
/**
* 3️⃣ SECTION DESCRIPTION
*/
function my_plugin_section_text() {
echo '<p>Configure the main settings for the plugin.</p>';
}
/**
* 4️⃣ FIELD HTML
*/
function my_plugin_enable_field() {
$options = get_option( 'my_plugin_options' );
$enabled = $options['enable_feature'] ?? '';
?>
<input type="checkbox"
name="my_plugin_options[enable_feature]"
value="1"
<?php checked( 1, $enabled ); ?>>
<label>Enable the main feature</label>
<?php
}
/**
* 5️⃣ SANITIZATION
*/
function my_plugin_sanitize_options( $input ) {
$output = [];
$output['enable_feature'] = isset( $input['enable_feature'] ) ? 1 : 0;
return $output;
}
/**
* 6️⃣ SETTINGS PAGE (CONNECTED TO ADMIN MENU)
*/
function my_plugin_settings_page() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
?>
<div class="wrap">
<h1>My Plugin Settings</h1>
<form method="post" action="options.php">
<?php
settings_fields( 'my_plugin_settings_group' );
do_settings_sections( 'my-plugin' );
submit_button();
?>
</form>
</div>
<?php
}
What the Settings API Does (and DOES NOT do)
What it DOES
Registers settings
Creates structured settings forms
Handles nonces (CSRF protection)
Sanitizes & validates input
Automatically saves options
Uses the Options API internally
Example:
register_setting( 'group', 'option_name' );
What it DOES NOT do
Does NOT create admin menus
Does NOT create pages
Does NOT control navigation
Does NOT decide where it appears
Admin Menu API
↓
Creates admin page
↓
Settings API
↓
Builds form on that page
↓
Options API
↓
Saves data to database
CPT
add_action( 'init', 'register_portfolio_cpt' );
function register_portfolio_cpt() {
register_post_type( 'portfolio', [
'public' => true,
'label' => 'Portfolios',
] );
flush_rewrite_rules();
}
A permalink is the permanent URL to a piece of content.
WordPress generates a token tied to:
User ID
Action
Time (default: 12–24 hours validity)
Secret key
WordPress generates a hash of:
user_id + action + time_tickThe result is the nonce — a short string (10 characters)
A shadow taxonomy (sometimes called a hidden taxonomy) is:
- A taxonomy registered in WordPress but not visible in the admin UI
- Still attached to a post type
Internal organization without cluttering the admin UI
- E.g., mark posts as
needs_review,priority, orsystem_tag
| Status | Meaning | Notes |
|---|---|---|
publish | Content is publicly visible | Appears in the front-end and RSS feeds |
draft | Incomplete content, not publicly visible | Only visible to editors/admins |
pending | Pending review by an editor | Common for contributor submissions |
future | Scheduled to be published at a later date | Requires post_date in the future |
private | Visible only to admins and editors | Excluded from front-end and RSS feeds |
auto-draft | Auto-saved draft by WordPress | Created when starting a new post/page, updated automatically |
inherit | Usually for revisions or attachments | Links back to the parent post (like image attachments) |
trash | Moved to trash | Can be restored or permanently deleted |
| Role | Capabilities | Notes in Multisite |
|---|---|---|
| Administrator | Full control over the site: add pages, posts, users, plugins (if allowed), themes (if allowed) | Can’t manage network-wide plugins/themes unless Super Admin allows |
| Editor | Publish/edit posts and pages, moderate comments | Standard WordPress role |
| Author | Publish/edit own posts | |
| Contributor | Write posts, but can’t publish | |
| Subscriber | Read content, comment |
Network Level – Super Admin
Who: The user who installed WordPress Multisite.
Capabilities:
Manage the entire network of sites
Add or remove sites
Manage network-wide plugins and themes
Control network settings, user accounts across sites
A child theme is a theme that inherits the functionality, templates, and styles of another theme (called the parent theme) while allowing you to customize or override parts of it.
WordPress first looks in the child theme folder for templates, CSS, and functions.
If a file isn’t found, WordPress falls back to the parent theme.
Child themes must include a
style.csswith a special header referencing the parent.
Wordpress minimum requirements
Web server: Apache/Nginx
PHP: 7.4+ (extensions: mysqli, curl, GD/Imagick, mbstring, json, xml, openssl)
Database: MySQL 5.7+ / MariaDB 10.3+
Memory: 64MB min (128MB recommended)
HTTPS: Optional but highly recommended
Browser: Modern, JS enabled