How to create a custom menu item

This is the slimmed down version of a plugin settings page that I’m working on. Put it in a file and include it in your plugin.

Searching on Google for add_options_page, register_setting, add_settings_field etc. will lead you to the codex entries of WordPress with further descriptions.

The code of the options page below will render 2 checkboxes, with values set to either 0 or 1 / bool true/false.

I’ll leave adding text input fields up to you as a little homework, since this is a lot of (free) code.

The HTML/CSS classes is Bootstrap with some special code for a nice checkbox/switch.

Please mark the answer as correct if it helped you, thanks.

<?php
/* ============================
   Special Menu Settings Page
   ============================
*/
// Add the settings page
function special_menu_admin_menu() { 
    add_options_page(
        __('Special menu', 'text-domain'),          // Page Title
        __('Special menu', 'text-domain'),          // Menu Title
        'manage_options',                       // Capability to access it
        'special-menu-settings',                    // Menu Slug
        'html_output_menu_settings_page'            // Callback Function
    );
}
add_action('admin_menu', 'special_menu_admin_menu');

// Init the settings, which we want to save
function special_menu_settings_init() {

    // ------------------------------------------ Settings
    // Example Setting
    register_setting(
        'special-menu-settings-group',                      // Group Name
        'setting_1'                                         // Settings Name
    );

    // Setting 2
    register_setting(
        'special-menu-settings-group',                      // Group Name
        'setting_2'                                     // Settings Name
    );

    // ------------------------------------------ Sections
    add_settings_section(
        'special-menu-settings-section-1',                  // ID of the Element
        __('Special Menu settings', 'text-domain' ),            // Public Name
        '',                                             // Function to print description before actual form
        'special-menu-settings'                         // ID of the backend page
    );

    // ------------------------------------------- Fields

    // Setting 1
    add_settings_field(
        'setting_1',                                    // Name / ID 
        __('Special menu', 'text-domain'),          // Public Name
        'special_menu_setting_1_callback',      // Callback Function to print HTML
        'special-menu-settings',                            // Name of the settings page, where to put it
        'special-menu-settings-section-1'                   // section_where, label_for
    );

    // Setting 2
    add_settings_field(
        'setting_2',                                        // Name / ID 
        __('Enable tab 1', 'text-domain'),                      // Public Name
        'special_menu_setting_2_callback',                  // Callback Function to print HTML
        'special-menu-settings',                                // Name of the backend page, where to put it
        'special-menu-settings-section-1'                       // section_where, label_for
    );

}
add_action('admin_init', 'special_menu_settings_init');

// Render the options page in the backend
function html_output_menu_settings_page() { ?>
    <?php
        // In case you need access to the plugin folder path, e.g. use $dir . '/images/whatever.jpg';
        $dir = plugin_dir_path(__FILE__);
    ?>
    <div class="wrap">
        <h1 class="settings-title"><?php _e('Special menu settings', 'text-domain'); ?></h1>
        <div class="container-fluid">   
            <div class="row">
                <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
                    <form method="post" action="options.php">
                        <?php
                            settings_fields('special-menu-settings-group');
                            do_settings_sections('special-menu-settings');
                            submit_button();
                        ?>
                    </form>
                </div>
            </div>
        </div>
    </div>  
    <?php
}


// Setting 1 HTML
function special_menu_setting_1_callback() { ?>
    <div class="row">
        <div class="col-md-3 text-right">
            <div class="switch">
                <input type="checkbox" class="checkbox" id="setting_1" name="setting_1" value="1" <?php checked(1, get_option('setting_1'), true); ?> />
                <label for="setting_1" class="checkbox-label"></label>
            </div>
        </div>
    </div>
    <?php
}


// Setting 2 HTML
function special_menu_setting_2_callback() {
    $setting_2 = get_option('setting_2');
    ?>
    <div class="row">
        <div class="col text-right">
            <div class="switch">
                <input type="checkbox" class="checkbox" id="setting_2" name="setting_2" value="1" <?php checked(1, get_option('setting_2'), true); ?> />
                <label for="setting_2" class="checkbox-label"></label>
            </div>
        </div>
    </div>
    <?php
}

Bonus CSS, for the checkbox switch:

 // Switch Toggle Checkbox
.wrap-switch {
    background: #e9ecef;
    padding-top: 7px;
    padding-left: 18px;
    padding-right: 18px;
    border-top: 1px solid #ced4da;
    border-bottom: 1px solid #ced4da;
}

.switch {
    position: relative;
    float: left;
    width: 55px;
    height: 23px;
}

.switch:after {
    content: "";
    display: table;
}

.switch input[type="checkbox"] {
    visibility: hidden;
}

.switch label {
    position: absolute;
    top: 0;
    left: 0;
    width: 55px;
    height: 23px;
    background: tomato;
    border-radius: 50px;
}

.switch label:after {
    position: absolute;
    top: 1px;
    left: 1px;
    width: 21px;
    height: 21px;
    content: '';
    border-radius: 50px;
    background-color: white;
    transition: all .1s;
}

.switch input[type="checkbox"]:checked + label:after {
    left: 33px;
}
.switch input[type="checkbox"]:checked + label {
    background: lightgreen;
}

// On/Off Label
.input-group > .input-group-prepend > .input-group-text {
    border-right: 0;
}
.input-group > .input-group-append > .input-group-text {
    border-left: 0;
}

Leave a Comment