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:
    1. Add a top-level menu
    2. Add a submenu under an existing menu
    3. 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_options table.
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_tick

  • The 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, or system_tag

StatusMeaningNotes
publishContent is publicly visibleAppears in the front-end and RSS feeds
draftIncomplete content, not publicly visibleOnly visible to editors/admins
pendingPending review by an editorCommon for contributor submissions
futureScheduled to be published at a later dateRequires post_date in the future
privateVisible only to admins and editorsExcluded from front-end and RSS feeds
auto-draftAuto-saved draft by WordPressCreated when starting a new post/page, updated automatically
inheritUsually for revisions or attachmentsLinks back to the parent post (like image attachments)
trashMoved to trashCan be restored or permanently deleted
RoleCapabilitiesNotes in Multisite
AdministratorFull 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
EditorPublish/edit posts and pages, moderate commentsStandard WordPress role
AuthorPublish/edit own posts
ContributorWrite posts, but can’t publish
SubscriberRead 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.

  1. WordPress first looks in the child theme folder for templates, CSS, and functions.

  2. If a file isn’t found, WordPress falls back to the parent theme.

  3. Child themes must include a style.css with 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