Duplicate Menu (CC) Hooks Reference

Last updated: 5th May 2026 for Duplicate Menu (CC) version 1.0

Overview

Duplicate Menu (CC) provides a comprehensive set of WordPress actions and filters that allow developers to customise:

  • Menu duplication behaviour
  • Menu naming logic
  • Menu item processing
  • Metadata handling
  • Post-duplication workflows

These hooks are designed to allow deep customisation without modifying plugin core files.


Duplication context

Many hooks include a $duplicate_context parameter.

Structure

array(
'source_menu_id' => (int) $menu_id,
'requested_name' => (string) $requested_name,
)

Purpose

This allows you to:

  • Detect whether a custom name was requested
  • Apply conditional logic based on duplication source
  • Build environment-aware duplication workflows

Filters


cc_duplicate_menu_capability

Filters the required capability for duplicating menus.

Default

edit_theme_options

Parameters

$capability // string

Return

string

Use cases

  • Restrict duplication to administrators
  • Allow custom roles to duplicate menus

cc_duplicate_menu_button_class

Filters the CSS classes applied to the duplicate button.

Default

button button-secondary

Parameters

$button_class // string

Return

string

cc_duplicate_menu_button_position

Filters the logical insertion position used by the admin JavaScript.

Default

after-save-button

Parameters

$position // string

Return

string

cc_duplicate_menu_show_in_header

Controls whether duplicate controls appear in the header area.

Default

false

Parameters

$show // bool

Return

bool

cc_duplicate_menu_show_in_footer

Controls whether duplicate controls appear in the footer area.

Default

true

Parameters

$show // bool

Return

bool

cc_duplicate_menu_redirect_to_new_menu

Controls whether the user is redirected after duplication.

Default

true

Parameters

$redirect_to_new_menu // bool
$new_menu_id // int
$menu_id // int

Return

bool

cc_duplicate_menu_requested_name

Filters the final menu name when a user-supplied name is provided.

Parameters

$name           // string
$requested_name // string

Return

string

Use cases

  • Append environment labels
  • Enforce naming conventions

cc_duplicate_menu_copy_suffix

Filters the suffix appended when no custom name is provided.

Default

(copy)

Parameters

$suffix        // string
$original_name // string

Return

string

cc_duplicate_menu_generated_name

Filters the automatically generated duplicate name after uniqueness checks.

Parameters

$name          // string
$original_name // string
$base_name // string

Return

string

cc_duplicate_menu_final_menu_name

Final filter before menu creation.

Parameters

$new_menu_name     // string
$menu // WP_Term
$duplicate_context // array

Return

string

Use cases

  • Centralised naming control
  • Environment-aware naming

cc_duplicate_menu_new_menu_args

Filters arguments passed to wp_update_nav_menu_object().

Parameters

$new_menu_args     // array
$menu // WP_Term
$duplicate_context // array

Return

array

cc_duplicate_menu_items

Filters the full set of menu items before duplication begins.

Parameters

$items             // array
$menu // WP_Term
$duplicate_context // array

Return

array

Use cases

  • Bulk filtering items
  • Reordering items
  • Removing groups of items

cc_duplicate_menu_skip_item

Determines whether an individual item should be skipped.

Parameters

$skip_item         // bool
$item // object
$new_menu_id // int
$menu_id // int
$duplicate_context // array

Return

bool

cc_duplicate_menu_pre_insert_item

Filters the menu item object before arguments are generated.

Parameters

$item              // object
$original_item // object
$new_menu_id // int
$menu_id // int
$duplicate_context // array

Return

object

cc_duplicate_menu_item_args

Filters first-pass item creation arguments.

Parameters

$args              // array
$item // object
$new_menu_id // int
$menu_id // int
$duplicate_context // array

Return

array

cc_duplicate_menu_item_update_args

Filters second-pass item update arguments (hierarchy restoration).

Parameters

$args              // array
$item // object
$new_parent_id // int
$new_menu_id // int
$menu_id // int
$duplicate_context // array

Return

array

cc_duplicate_menu_copy_item_meta

Controls whether additional metadata is copied.

Default

true

Parameters

$copy_meta         // bool
$old_item_id // int
$new_item_id // int
$new_menu_id // int
$menu_id // int
$item // object
$duplicate_context // array

Return

bool

cc_duplicate_menu_item_meta

Filters all metadata before processing.

Parameters

$meta              // array
$old_item_id // int
$new_item_id // int
$new_menu_id // int
$menu_id // int
$item // object
$duplicate_context // array

Return

array

cc_duplicate_menu_skip_meta_keys

Filters protected meta keys.

Parameters

$protected_meta_keys // array
$old_item_id // int
$new_item_id // int
$new_menu_id // int
$menu_id // int
$item // object
$duplicate_context // array

Return

array

cc_duplicate_menu_skip_meta_key

Filters individual meta key skipping.

Parameters

$skip_meta_key     // bool
$meta_key // string
$values // array
$old_item_id // int
$new_item_id // int
$new_menu_id // int
$menu_id // int
$item // object
$duplicate_context // array

Return

bool

cc_duplicate_menu_meta_value

Filters meta values before saving.

Parameters

$meta_value        // mixed
$meta_key // string
$old_item_id // int
$new_item_id // int
$new_menu_id // int
$menu_id // int
$item // object
$duplicate_context // array

Return

mixed

Actions


cc_duplicate_menu_before_duplicate

Fires before duplication begins.

Parameters

$menu_id        // int
$menu // WP_Term
$requested_name // string

cc_duplicate_menu_before_duplicate_context

Fires after context is prepared.

Parameters

$menu              // WP_Term
$duplicate_context // array

cc_duplicate_menu_before_menu_insert

Fires before the new menu is created.

Parameters

$new_menu_args     // array
$menu // WP_Term
$duplicate_context // array

cc_duplicate_menu_before_item_processing

Fires before item duplication begins.

Parameters

$items             // array
$new_menu_id // int
$menu_id // int
$menu // WP_Term
$duplicate_context // array

cc_duplicate_menu_after_item_create

Fires after an item is created (first pass).

Parameters

$new_item_id       // int
$new_menu_id // int
$item // object
$menu_id // int
$duplicate_context // array

cc_duplicate_menu_after_item_meta_copy

Fires after metadata is copied.

Parameters

$old_item_id       // int
$new_item_id // int
$new_menu_id // int
$menu_id // int
$item // object
$duplicate_context // array

cc_duplicate_menu_after_duplicate

Fires after duplication completes.

Parameters

$new_menu_id       // int
$menu_id // int
$menu // WP_Term
$old_to_new_map // array
$duplicate_context // array

Notes on Hook Usage

Two-pass duplication system

First pass

  • Items created with parent = 0
  • Hooks:
cc_duplicate_menu_item_args
cc_duplicate_menu_after_item_create

Second pass

  • Hierarchy restored
  • Hook:
cc_duplicate_menu_item_update_args

👉 Use second-pass hooks or cc_duplicate_menu_after_duplicate for final structure.


Metadata handling

Metadata copying is:

  • Enabled by default
  • Fully filterable
  • Safe for third-party extensions

Naming pipeline

Order of execution:

requested_name OR copy_suffix
→ generated_name
→ final_menu_name
→ new_menu_args

Recommended extension points

Use caseHook
Naming controlcc_duplicate_menu_final_menu_name
Skip itemscc_duplicate_menu_skip_item
Modify itemscc_duplicate_menu_item_args
Modify hierarchycc_duplicate_menu_item_update_args
Metadata controlmetadata filters
Post-processingcc_duplicate_menu_after_duplicate

Real-world example: mark duplicated menu items for internal auditing

This example adds a small custom meta value to each duplicated menu item after it has been created. A developer could use this later for diagnostics, reporting or integration with an internal workflow.

add_action(
'cc_duplicate_menu_after_item_create',
function( $new_item_id, $new_menu_id, $item, $menu_id, $duplicate_context ) {
update_post_meta( $new_item_id, '_cc_duplicate_menu_audit_source_item', absint( $item->ID ) );
update_post_meta( $new_item_id, '_cc_duplicate_menu_audit_source_menu', absint( $menu_id ) );
update_post_meta( $new_item_id, '_cc_duplicate_menu_audit_created_at', current_time( 'mysql' ) );
},
10,
5
);

What this does

When a menu item is duplicated, the code stores:

_cc_duplicate_menu_audit_source_item
_cc_duplicate_menu_audit_source_menu
_cc_duplicate_menu_audit_created_at

This makes it possible to identify where a duplicated menu item originally came from, without changing the duplication process itself.