{"id":292190,"date":"2026-04-20T06:22:03","date_gmt":"2026-04-20T06:22:03","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/classic-menu-duplicator\/"},"modified":"2026-08-03T10:21:29","modified_gmt":"2026-08-03T10:21:29","slug":"swift-menu-duplicator","status":"publish","type":"plugin","link":"https:\/\/et.wordpress.org\/plugins\/swift-menu-duplicator\/","author":20002658,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.1.0","stable_tag":"1.1.0","tested":"7.0.2","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"Swift Menu Duplicator","header_author":"Al Amin Ahamed","header_description":"Duplicate menus and items, snapshot revisions, export\/import JSON, manage all menus in bulk, copy across multisite, automate with WP-CLI, and integrate via REST API.","assets_banners_color":"164c60","last_updated":"2026-08-03 10:21:29","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/mralaminahamed\/swift-menu-duplicator","header_author_uri":"https:\/\/github.com\/mralaminahamed","rating":0,"author_block_rating":0,"active_installs":0,"downloads":253,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"mralaminahamed","date":"2026-04-20 06:28:19"},"1.0.1":{"tag":"1.0.1","author":"mralaminahamed","date":"2026-04-20 06:29:54"},"1.1.0":{"tag":"1.1.0","author":"mralaminahamed","date":"2026-08-03 10:21:29"}},"upgrade_notice":{"1.1.0":"<p>Large release. Snapshot restore now exists, block themes are supported, deleting a menu can be undone, and duplication goes through WordPress&#039;s own menu-item API so translation and caching plugins see cloned items. Breaking: the REST namespace is now <code>swift-menu-duplicator\/v1<\/code> and the WP-CLI group is <code>wp swift-menu-duplicator<\/code>.<\/p>","1.0.1":"<p>WP-CLI users: the command has been renamed from <code>wp menu-duplicator<\/code> to <code>wp swift-menu-duplicator<\/code>. Update any scripts or aliases accordingly.<\/p>","1.0.0":"<p>Initial release \u2014 no upgrade steps required.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3632693,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3632693,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3632693,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3632693,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3632693,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3632693,"resolution":false,"location":"assets","locale":"","contents":"{\"$schema\":\"https:\\\/\\\/playground.wordpress.net\\\/blueprint-schema.json\",\"landingPage\":\"\\\/wp-admin\\\/nav-menus.php\",\"preferredVersions\":{\"php\":\"8.2\",\"wp\":\"latest\"},\"steps\":[{\"step\":\"login\",\"username\":\"admin\",\"password\":\"password\"},{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"swift-menu-duplicator\"},\"options\":{\"activate\":true}}]}"}},"all_blocks":[],"tagged_versions":["1.0.0","1.0.1","1.1.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3632693,"resolution":"1","location":"assets","locale":"","width":1440,"height":900},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3632693,"resolution":"2","location":"assets","locale":"","width":1440,"height":900},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3632693,"resolution":"3","location":"assets","locale":"","width":1440,"height":900},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3632693,"resolution":"4","location":"assets","locale":"","width":1440,"height":900},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3632693,"resolution":"5","location":"assets","locale":"","width":1440,"height":900}},"screenshots":{"1":"Duplicating a menu from the menu editor \u2014 name the copy before it is created.","2":"Menu Manager \u2014 every menu on the site, with item and snapshot counts, sortable columns, and bulk actions.","3":"Snapshot panel in the menu editor \u2014 save, browse, restore, and delete revisions.","4":"JSON import with URL find &amp; replace, for moving menus between environments.","5":"Deleting a menu can be undone, theme locations included."}},"plugin_section":[],"plugin_tags":[2738,9055,42018,231,1753],"plugin_category":[43],"plugin_contributors":[221130],"plugin_business_model":[],"class_list":["post-292190","plugin","type-plugin","status-publish","hentry","plugin_tags-copy","plugin_tags-duplicate","plugin_tags-menu-manager","plugin_tags-menus","plugin_tags-navigation","plugin_category-customization","plugin_contributors-mralaminahamed","plugin_committers-mralaminahamed"],"banners":{"banner":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/banner-772x250.png?rev=3632693","banner_2x":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/banner-1544x500.png?rev=3632693","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/icon.svg?rev=3632693","icon":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/icon.svg?rev=3632693","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/screenshot-1.png?rev=3632693","caption":"Duplicating a menu from the menu editor \u2014 name the copy before it is created."},{"src":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/screenshot-2.png?rev=3632693","caption":"Menu Manager \u2014 every menu on the site, with item and snapshot counts, sortable columns, and bulk actions."},{"src":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/screenshot-3.png?rev=3632693","caption":"Snapshot panel in the menu editor \u2014 save, browse, restore, and delete revisions."},{"src":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/screenshot-4.png?rev=3632693","caption":"JSON import with URL find &amp; replace, for moving menus between environments."},{"src":"https:\/\/ps.w.org\/swift-menu-duplicator\/assets\/screenshot-5.png?rev=3632693","caption":"Deleting a menu can be undone, theme locations included."}],"raw_content":"<!--section=description-->\n<p><strong>Swift Menu Duplicator<\/strong> gives you full control over your WordPress navigation menus. Clone any menu in one click, manage all menus from a dedicated admin page, version them with snapshots, move them across Multisite sub-sites, and automate everything from the command line or REST API.<\/p>\n\n<h3>One-Click Duplication<\/h3>\n\n<ul>\n<li>Duplicate button right in the menu editor footer \u2014 no page reload required<\/li>\n<li>Full hierarchy preserved via a two-pass clone that remaps all parent-child item IDs<\/li>\n<li>All item metadata copied \u2014 type, object, URL, target, CSS classes, XFN, description<\/li>\n<li>Duplicate individual menu items directly from the menu editor<\/li>\n<li>Custom name support \u2014 filter <code>swift_menu_duplicator_new_menu_name<\/code> to override the default \"(Copy)\" suffix<\/li>\n<\/ul>\n\n<h3>Snapshot Revisions<\/h3>\n\n<ul>\n<li><strong>Auto-snapshot<\/strong> \u2014 a snapshot is saved automatically before every menu save<\/li>\n<li><strong>Manual snapshots<\/strong> \u2014 save named snapshots from the menu editor at any time<\/li>\n<li><strong>Browse &amp; restore<\/strong> \u2014 view all snapshots in an expandable panel and restore with one click; the pre-restore state is snapshotted first<\/li>\n<li><strong>Housekeeping<\/strong> \u2014 delete individual snapshots you no longer need<\/li>\n<\/ul>\n\n<h3>Menu Manager (Appearance \u2192 Menu Manager)<\/h3>\n\n<ul>\n<li>Dedicated page listing every menu on the site in a sortable WP_List_Table<\/li>\n<li><strong>Bulk duplicate<\/strong> \u2014 clone multiple menus at once<\/li>\n<li><strong>Bulk export<\/strong> \u2014 download selected menus as a single ZIP archive<\/li>\n<li><strong>Bulk delete<\/strong> \u2014 remove multiple menus in one action<\/li>\n<li>Row actions \u2014 duplicate or export individual menus directly from the list<\/li>\n<\/ul>\n\n<h3>JSON Export \/ Import<\/h3>\n\n<ul>\n<li>Export any menu to a portable JSON file (via admin or REST API)<\/li>\n<li>Import from a JSON file upload or paste JSON directly into the text area<\/li>\n<li><strong>URL find &amp; replace<\/strong> \u2014 swap domain names during import for staging \u2192 production migrations<\/li>\n<li><strong>Dry-run preview<\/strong> \u2014 review what will be imported before making any changes to the database<\/li>\n<\/ul>\n\n<h3>Deletion Safety<\/h3>\n\n<ul>\n<li>Deleting a menu \u2014 from the Menu Manager, the row action, or the Delete Menu button in the editor \u2014 captures it first<\/li>\n<li>An <strong>Undo<\/strong> link appears while the deletion is still recoverable (one hour by default, filterable)<\/li>\n<li>Restoring recreates the menu and its items and puts it back in the theme locations it occupied<\/li>\n<\/ul>\n\n<h3>Block Themes<\/h3>\n\n<ul>\n<li>Duplicate, export, and import the <strong>Navigation menus block themes actually render<\/strong> (<code>wp_navigation<\/code> posts), not just classic menus<\/li>\n<li>A dedicated <strong>Navigation (Block)<\/strong> tab in the Menu Manager, with per-row Duplicate and Export JSON plus bulk duplicate and trash<\/li>\n<li>Link counts per menu, and one-click access to the Site Editor<\/li>\n<li>Available from WP-CLI and the REST API alongside the classic-menu commands<\/li>\n<\/ul>\n\n<h3>Multisite Support<\/h3>\n\n<ul>\n<li>Copy any menu to another site in your WordPress Multisite network<\/li>\n<li>Optional URL find &amp; replace applied to item URLs on the destination site<\/li>\n<\/ul>\n\n<h3>REST API<\/h3>\n\n<p>Full REST API at <code>\/wp-json\/swift-menu-duplicator\/v1\/<\/code> for headless and block-editor integrations:<\/p>\n\n<ul>\n<li><code>POST \/menus\/{id}\/duplicate<\/code> \u2014 duplicate a menu (optional <code>name<\/code> parameter)<\/li>\n<li><code>GET  \/menus\/{id}\/export<\/code> \u2014 export a menu as a JSON payload<\/li>\n<li><code>POST \/menus\/{id}\/items\/{item_id}\/duplicate<\/code> \u2014 duplicate a single menu item<\/li>\n<li><code>POST \/menus\/import<\/code> \u2014 import a menu from an export payload<\/li>\n<li><code>GET  \/menus\/{id}\/snapshots<\/code> \u2014 list snapshots<\/li>\n<li><code>POST \/menus\/{id}\/snapshots<\/code> \u2014 save a snapshot<\/li>\n<li><code>POST \/menus\/{id}\/snapshots\/{snapshot_id}<\/code> \u2014 restore a snapshot<\/li>\n<li><code>DELETE \/menus\/{id}\/snapshots\/{snapshot_id}<\/code> \u2014 delete a snapshot<\/li>\n<li><code>GET  \/navigations<\/code> \u2014 list block navigation menus<\/li>\n<li><code>POST \/navigations\/{id}\/duplicate<\/code> \u2014 duplicate a block navigation menu<\/li>\n<li><code>GET  \/navigations\/{id}\/export<\/code> \u2014 export a block navigation menu<\/li>\n<li><code>POST \/navigations\/import<\/code> \u2014 import a block navigation menu<\/li>\n<\/ul>\n\n<p>Permission is controlled by the <code>swift_menu_duplicator_rest_permission<\/code> filter (defaults to <code>edit_theme_options<\/code>).<\/p>\n\n<h3>WP-CLI<\/h3>\n\n<p>Full command-line support under the <code>wp swift-menu-duplicator<\/code> command group:<\/p>\n\n<ul>\n<li><code>wp swift-menu-duplicator duplicate &lt;menu-id&gt; [--name=&lt;name&gt;]<\/code> \u2014 duplicate a menu<\/li>\n<li><code>wp swift-menu-duplicator export &lt;menu-id&gt; [--output=&lt;file&gt;]<\/code> \u2014 export to JSON<\/li>\n<li><code>wp swift-menu-duplicator import &lt;file&gt; [--name=&lt;name&gt;] [--find=&lt;str&gt;] [--replace=&lt;str&gt;] [--dry-run] [--porcelain]<\/code> \u2014 import from JSON<\/li>\n<li><code>wp swift-menu-duplicator copy-to-site &lt;menu-id&gt; --target-blog=&lt;id&gt; [--name=&lt;name&gt;] [--find=&lt;str&gt;] [--replace=&lt;str&gt;]<\/code> \u2014 copy to a sub-site<\/li>\n<li><code>wp swift-menu-duplicator snapshot list|save|restore|delete &lt;menu-id&gt; [--label=&lt;label&gt;] [--id=&lt;uuid&gt;]<\/code> \u2014 manage snapshots<\/li>\n<li><code>wp swift-menu-duplicator navigation list|duplicate|export|import [&lt;id-or-file&gt;] [--title=&lt;title&gt;] [--output=&lt;file&gt;]<\/code> \u2014 block navigation menus<\/li>\n<\/ul>\n\n<h3>Multilingual Compatibility<\/h3>\n\n<ul>\n<li><strong>WPML<\/strong> \u2014 translation meta keys (<code>_icl_lang_duplicate_of<\/code>, <code>wpml_language<\/code>, etc.) are stripped from duplicated items automatically<\/li>\n<li><strong>Polylang<\/strong> \u2014 language meta keys (<code>_pll_synced_taxonomies<\/code>, <code>_pll_menu_language<\/code>, etc.) are stripped from duplicated items automatically<\/li>\n<li>Additional keys can be excluded via the <code>swift_menu_duplicator_compat_excluded_meta_keys<\/code> filter<\/li>\n<\/ul>\n\n<h3>Developer Hooks<\/h3>\n\n<ul>\n<li><code>swift_menu_duplicator_new_menu_name<\/code> \u2014 customise the default duplicate name<\/li>\n<li><code>swift_menu_duplicator_rest_permission<\/code> \u2014 control REST API access<\/li>\n<li><code>swift_menu_duplicator_before_duplicate_item<\/code> \/ <code>swift_menu_duplicator_after_duplicate_menu_item<\/code> \u2014 fired around item duplication<\/li>\n<li><code>swift_menu_duplicator_after_import_menu<\/code> \u2014 fired after a successful import<\/li>\n<li><code>swift_menu_duplicator_before_restore_snapshot<\/code> \/ <code>swift_menu_duplicator_after_restore_snapshot<\/code> \u2014 fired around a snapshot restore<\/li>\n<li><code>swift_menu_duplicator_after_undo_delete<\/code> \u2014 fired after a deleted menu is restored<\/li>\n<li><code>swift_menu_duplicator_undo_ttl<\/code> \/ <code>swift_menu_duplicator_undo_limit<\/code> \u2014 how long deletions stay recoverable, and how many are kept<\/li>\n<li><code>swift_menu_duplicator_item_meta_keys<\/code> \u2014 control which meta keys are copied<\/li>\n<li><code>swift_menu_duplicator_compat_excluded_meta_keys<\/code> \u2014 extend the multilingual meta exclusion list<\/li>\n<li><code>wp_update_nav_menu<\/code> \u2014 triggers auto-snapshot before every menu save<\/li>\n<\/ul>\n\n<h3>Security<\/h3>\n\n<ul>\n<li>All AJAX actions verified with nonces and <code>edit_theme_options<\/code> capability checks<\/li>\n<li>All output escaped; all input sanitized<\/li>\n<li>Database queries use <code>$wpdb-&gt;prepare()<\/code> \u2014 no string concatenation<\/li>\n<li>REST API permission is filterable but defaults to <code>edit_theme_options<\/code><\/li>\n<li>WordPress Filesystem API used for all file read\/write\/delete operations<\/li>\n<\/ul>\n\n<p><strong>Requirements<\/strong><\/p>\n\n<ul>\n<li>WordPress 6.0 or higher<\/li>\n<li>PHP 7.4 or higher<\/li>\n<li>User with <code>edit_theme_options<\/code> capability<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>swift-menu-duplicator<\/code> directory to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate the plugin through <strong>Plugins \u2192 Installed Plugins<\/strong>.<\/li>\n<li>Go to <strong>Appearance \u2192 Menus<\/strong>, select a menu, and click <strong>Duplicate Menu<\/strong> in the footer.<\/li>\n<li>For bulk management, snapshots, and import, visit <strong>Appearance \u2192 Menu Manager<\/strong>.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20it%20copy%20theme%20location%20assignments%3F\"><h3>Does it copy theme location assignments?<\/h3><\/dt>\n<dd><p>No. Theme location assignments are site-specific and intentionally not copied, so the duplicate does not silently replace an active menu in any location.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20sub-menu%20items%3F\"><h3>What happens to sub-menu items?<\/h3><\/dt>\n<dd><p>All parent-child relationships are preserved exactly. The plugin uses a two-pass approach: items are cloned first, then parent ID references are re-mapped to the newly created item IDs.<\/p><\/dd>\n<dt id=\"can%20i%20rename%20the%20duplicate%20before%20it%20is%20created%3F\"><h3>Can I rename the duplicate before it is created?<\/h3><\/dt>\n<dd><p>Yes. A name field is shown in the duplicate modal. You can also change the default suffix globally by filtering <code>swift_menu_duplicator_new_menu_name<\/code>.<\/p><\/dd>\n<dt id=\"is%20it%20compatible%20with%20wpml%20or%20polylang%3F\"><h3>Is it compatible with WPML or Polylang?<\/h3><\/dt>\n<dd><p>Yes. Translation and language meta keys are automatically stripped from duplicated items so the copy starts as a clean, language-neutral menu.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20block%20themes%3F\"><h3>Does it work with block themes?<\/h3><\/dt>\n<dd><p>Yes. Block themes render Navigation blocks (<code>wp_navigation<\/code> posts) rather than classic menus, and the Menu Manager has a <strong>Navigation (Block)<\/strong> tab for exactly those: duplicate, export, import, bulk duplicate, and move to trash, with an Edit in Site Editor link on every row. Classic menus keep their own tab, so a site part-way through a theme migration can manage both.<\/p>\n\n<p>The tab appears when the active theme is a block theme, or whenever the site already has block navigation menus \u2014 a classic theme can still have them left over from a previous theme.<\/p><\/dd>\n<dt id=\"is%20it%20compatible%20with%20woocommerce%20%2F%20hpos%3F\"><h3>Is it compatible with WooCommerce \/ HPOS?<\/h3><\/dt>\n<dd><p>Yes. The plugin only interacts with <code>nav_menu_item<\/code> posts and the <code>nav_menu<\/code> taxonomy. It has no dependency on WooCommerce or its High-Performance Order Storage.<\/p><\/dd>\n<dt id=\"can%20i%20duplicate%20a%20menu%20that%20contains%20draft%20items%3F\"><h3>Can I duplicate a menu that contains draft items?<\/h3><\/dt>\n<dd><p>Yes. All items are duplicated regardless of their post status.<\/p><\/dd>\n<dt id=\"how%20do%20i%20use%20the%20rest%20api%3F\"><h3>How do I use the REST API?<\/h3><\/dt>\n<dd><p>Authenticate with a cookie session or an Application Password, then send:<\/p>\n\n<pre><code>POST \/wp-json\/swift-menu-duplicator\/v1\/menus\/{menu_id}\/duplicate\n<\/code><\/pre>\n\n<p>The response includes the new menu's <code>id<\/code>, <code>name<\/code>, and <code>edit_url<\/code>.<\/p><\/dd>\n<dt id=\"how%20do%20i%20migrate%20menus%20between%20environments%3F\"><h3>How do I migrate menus between environments?<\/h3><\/dt>\n<dd><p>Export the source menu to JSON (admin UI or <code>wp swift-menu-duplicator export<\/code>), transfer the file, then import it on the target site. Use the find\/replace fields to rewrite domain-specific URLs during import.<\/p><\/dd>\n<dt id=\"what%20capability%20is%20required%3F\"><h3>What capability is required?<\/h3><\/dt>\n<dd><p>edit_theme_options for all duplication, snapshot, export, and import actions. Multisite copy-to-site additionally requires the network <code>manage_network<\/code> capability.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.1.0<\/h4>\n\n<p>Everything below shipped as one release: versions 1.0.2 through 1.0.8 were development iterations that never reached the directory, so 1.0.1 is the version you are upgrading from.<\/p>\n\n<p><strong>New<\/strong><\/p>\n\n<ul>\n<li>Snapshot restore. The panel could save and delete revisions but never restore one \u2014 the feature was documented from 1.0.0 and missing until now. Restoring replaces the menu's items in place and snapshots the current state first, so a restore can itself be undone.<\/li>\n<li>Block theme support. Navigation menus stored as <code>wp_navigation<\/code> posts \u2014 the ones block themes actually render \u2014 can be duplicated, exported, and imported from a dedicated Menu Manager tab, WP-CLI, and REST.<\/li>\n<li>Deleting a menu can be undone, theme locations included, for an hour afterwards.<\/li>\n<li>The Menu Manager gained Slug, Description, and Snapshots columns, sortable counts, a working Screen Options panel, and a stylesheet \u2014 the screen previously had none.<\/li>\n<li>REST API gained import and snapshot endpoints, and every route now publishes a schema.<\/li>\n<li>New WP-CLI commands: <code>snapshot list|save|restore|delete<\/code> and <code>navigation list|duplicate|export|import<\/code>.<\/li>\n<li>JSON can be pasted into the import screen instead of uploading a file.<\/li>\n<\/ul>\n\n<p><strong>Fixed<\/strong><\/p>\n\n<ul>\n<li>Duplication and import now write menu items through core's <code>wp_update_nav_menu_item()<\/code> instead of inserting posts and postmeta directly, so WPML, Polylang, caching, and mega-menu plugins finally see cloned items.<\/li>\n<li>Menu item descriptions and menu descriptions were silently dropped by duplication, export, and import.<\/li>\n<li>Importing to a different site now re-resolves each item's target by slug, falling back to a custom link, instead of keeping an ID that points at unrelated content on the destination.<\/li>\n<li>Importing a file back into the site it came from failed outright; the name now falls back to \"{name} (2)\".<\/li>\n<li>Bulk \"Duplicate\" and \"Export as JSON\" silently did nothing without JavaScript.<\/li>\n<li>The multisite copy ignored the URL find\/replace it documented.<\/li>\n<li>Duplicated custom links carried the source item's object ID.<\/li>\n<li>The snapshot panel sat behind the admin bar, and could not be operated by keyboard at all. The duplicate dialog claimed to be modal without trapping focus.<\/li>\n<li>Notices are announced to screen readers, and accessible names are translatable rather than hardcoded English.<\/li>\n<li>Uninstall now removes the plugin's term meta; snapshots used to survive deleting the plugin.<\/li>\n<li>Snapshots are stored one row each instead of rewriting the whole stack on every save.<\/li>\n<\/ul>\n\n<p><strong>Security<\/strong><\/p>\n\n<ul>\n<li>Imported menu fields are sanitized field-by-field, uploads are validated and size-capped, and the bundled coding-standards dependency was updated for CVE-2026-45293.<\/li>\n<\/ul>\n\n<p><strong>Changed<\/strong><\/p>\n\n<ul>\n<li><strong>Breaking:<\/strong> the REST namespace moved from <code>cmd\/v1<\/code> to <code>swift-menu-duplicator\/v1<\/code>. Update any REST clients.<\/li>\n<li><strong>Breaking:<\/strong> the WP-CLI command group is <code>wp swift-menu-duplicator<\/code>, not <code>wp menu-duplicator<\/code>.<\/li>\n<li>New plugin icon, banners, and screenshots.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Fix: WP-CLI command renamed from <code>wp menu-duplicator<\/code> to <code>wp swift-menu-duplicator<\/code> for consistency with the plugin slug.<\/li>\n<li>Fix: <code>composer.lock<\/code> was excluded by <code>.gitignore<\/code> glob pattern causing the SVN deploy workflow to fail.<\/li>\n<li>Fix: Short description trimmed to satisfy the WordPress.org 150-character limit.<\/li>\n<li>Tested up to WordPress 7.0.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<li>One-click menu duplication from the WordPress menu editor with hierarchy preserved.<\/li>\n<li>Duplicate individual menu items from the editor.<\/li>\n<li>Snapshot system: auto-snapshot before every save, manual snapshots, restore and delete.<\/li>\n<li>Appearance \u2192 Menu Manager page with sortable table, bulk duplicate, bulk export (ZIP), and bulk delete.<\/li>\n<li>JSON export and import with URL find &amp; replace and dry-run preview.<\/li>\n<li>Multisite support: copy menus to any sub-site with optional URL rewriting.<\/li>\n<li>REST API at <code>\/wp-json\/cmd\/v1\/<\/code> \u2014 duplicate menu, export menu, duplicate item.<\/li>\n<li>WP-CLI command group <code>wp swift-menu-duplicator<\/code> \u2014 duplicate, export, import, copy-to-site.<\/li>\n<li>WPML and Polylang compatibility \u2014 translation and language meta stripped from duplicates.<\/li>\n<li>Developer hooks and filters throughout for extensibility.<\/li>\n<\/ul>","raw_excerpt":"Duplicate WordPress menus in one click. Snapshot revisions, export\/import JSON, bulk-manage all menus, copy across Multisite, automate with WP-CLI.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/et.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/292190","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/et.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/et.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/et.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=292190"}],"author":[{"embeddable":true,"href":"https:\/\/et.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/mralaminahamed"}],"wp:attachment":[{"href":"https:\/\/et.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=292190"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/et.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=292190"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/et.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=292190"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/et.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=292190"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/et.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=292190"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/et.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=292190"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}