Managing your website's navigation is crucial for an optimal user experience. If you're using WordPress, duplicating menus with their classes, descriptions, and hierarchy can help you streamline your site's layout and save time. In this tutorial, we'll guide you through the process of duplicating a WordPress menu using the WordPress Command Line Interface (WP-CLI) and a custom PHP script.

Step 1: Install WP-CLI

Before getting started, make sure you have WP-CLI installed on your system. If you haven't installed it yet, follow the instructions provided in the official documentation: https://wp-cli.org/#installing

Step 2: Navigate to Your WordPress Directory

Open your command prompt or terminal, and navigate to your WordPress installation directory.

Step 3: List All Menus

Use the following command to list all menus available on your website:

wp menu list

Identify the menu you want to duplicate and note down its "term_id" from the output.

Step 4: Export the Original Menu

Export the menu you want to duplicate, including the menu class, description, and hierarchy, using the following command, replacing MENU_ID with the "term_id" you noted earlier:

wp menu item list MENU_ID --fields=ID,type,title,url,classes,description,attr_title,menu_item_parent --format=json > menu_items.json

This command creates a file named "menu_items.json" containing the details of all menu items in the original menu.

Step 5: Create a New Menu

Now, create a new menu with a desired name using the following command:

wp menu create "New Menu Name"

Replace "New Menu Name" with your desired menu name. Note down the new menu's "term_id" from the output.

Step 6: Create the Duplicate Menu Script

Create a script named duplicate_menu.php in your WordPress root directory with the following content:

<?php
/**
 * Duplicate Menu Items Script
 */

// Include WordPress
define('WP_USE_THEMES', false);
require_once('wp-load.php');

// Check for required arguments
if ($argc < 3) {
    echo "Usage: php duplicate_menu.php <source_menu_items_json> <new_menu_id>\n";
    exit(1);
}

$source_menu_items_json = $argv[1];
$new_menu_id = intval($argv[2]);

// Read menu items JSON file
$menu_items_json = file_get_contents($source_menu_items_json);
$menu_items = json_decode($menu_items_json, true);

// Function to add menu item recursively
function add_menu_item($menu_item, $new_menu_id, $new_parent_id = 0) {
    $new_item = wp_update_nav_menu_item($new_menu_id, 0, array(
        'menu-item-title' => $menu_item['title'],
        'menu-item-url' => $menu_item['url'],
        'menu-item-classes' => implode(' ', $menu_item['classes']),
        'menu-item-description' => $menu_item['description'],
        'menu-item-attr-title' => $menu_item['attr_title'],
        'menu-item-status' => 'publish',
        'menu-item-parent-id' => $new_parent_id
    ));

    return $new_item;
}

// Function to duplicate menu items recursively
function duplicate_menu_items($menu_items, $new_menu_id, &$new_items_map, $old_parent_id = 0) {
    foreach ($menu_items as $menu_item) {
        if ($menu_item['menu_item_parent'] == $old_parent_id) {
            $new_item_id = add_menu_item($menu_item, $new_menu_id, isset($new_items_map[$menu_item['menu_item_parent']]) ? $new_items_map[$menu_item['menu_item_parent']] : 0);
            $new_items_map[$menu_item['ID']] = $new_item_id;
            duplicate_menu_items($menu_items, $new_menu_id, $new_items_map, $menu_item['ID']);
        }
    }
}

// Duplicate menu items
$new_items_map = [];
duplicate_menu_items($menu_items, $new_menu_id, $new_items_map);

Step 7: Execute the Script

To execute the script, open your command prompt or terminal, and navigate to your WordPress installation directory. Run the following command:

php duplicate_menu.php menu_items.json NEW_MENU_ID

Replace `NEW_MENU_ID` with the "term_id" of the new menu you created in Step 5.

This command will run the script and duplicate the menu items, including their classes, descriptions, and hierarchy, from the original menu to the new menu.

Step 8: Assign the New Menu

Once the process is complete, you can assign the new menu to a theme location or display it using a shortcode or widget.

Step 9: Clean Up

After verifying the new menu is working correctly, delete the "menu_items.json" file created in Step 4 and the `duplicate_menu.php` script from your WordPress root directory.

By following this comprehensive guide, you can quickly and easily duplicate a WordPress menu with classes, descriptions, and hierarchy using WP-CLI and a custom PHP script. This process will help you enhance your website's navigation experience and save valuable time while managing your site.