WordPress.org

WordPress build repository browser

Changeset 41077


Ignore:
Timestamp:
08/09/17 21:04:47 (12 days ago)
Author:
obenland
Message:

Map nav menu locations on theme switch

This will send nav menu locations through three levels of mapping:

  1. If both themes have only one location, that gets mapped.
  2. If both themes have locations with the same slug, they get mapped.
  3. Locations that (even partially) match slugs from a similar kind of menu location will get mapped.

Menu locations are mapped for Live Previews in the Customizer and during theme switches.

Props westonruter, obenland, welcher, melchoyce.
Fixes #39692.

Built from https://develop.svn.wordpress.org/trunk@41237

Location:
trunk/wp-includes
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/class-wp-customize-nav-menus.php

    r41045 r41077  
    2828 
    2929    /** 
    30      * Previewed Menus. 
    31      * 
    32      * @since 4.3.0 
     30     * Original nav menu locations before the theme was switched. 
     31     * 
     32     * @since 4.9.0 
    3333     * @var array 
    3434     */ 
    35     public $previewed_menus; 
     35    protected $original_nav_menu_locations; 
    3636 
    3737    /** 
     
    4343     */ 
    4444    public function __construct( $manager ) { 
    45         $this->previewed_menus = array(); 
    46         $this->manager         = $manager; 
     45        $this->manager = $manager; 
     46        $this->original_nav_menu_locations = get_nav_menu_locations(); 
    4747 
    4848        // See https://github.com/xwp/wp-customize-snapshots/blob/962586659688a5b1fd9ae93618b7ce2d4e7a421c/php/class-customize-snapshot-manager.php#L469-L499 
     
    583583        } 
    584584 
     585        // Attempt to re-map the nav menu location assignments when previewing a theme switch. 
     586        $mapped_nav_menu_locations = array(); 
     587        if ( ! $this->manager->is_theme_active() ) { 
     588            $mapped_nav_menu_locations = wp_map_nav_menu_locations( get_nav_menu_locations(), $this->original_nav_menu_locations ); 
     589        } 
     590 
    585591        foreach ( $locations as $location => $description ) { 
    586592            $setting_id = "nav_menu_locations[{$location}]"; 
     
    599605                    'default'           => 0, 
    600606                ) ); 
     607            } 
     608 
     609            // Override the assigned nav menu location if mapped during previewed theme switch. 
     610            if ( isset( $mapped_nav_menu_locations[ $location ] ) ) { 
     611                $this->manager->set_post_value( $setting_id, $mapped_nav_menu_locations[ $location ] ); 
    601612            } 
    602613 
  • trunk/wp-includes/default-filters.php

    r41072 r41077  
    263263add_action( 'wp_print_footer_scripts', '_wp_footer_scripts'                 ); 
    264264add_action( 'init',                'check_theme_switched',            99    ); 
     265add_action( 'after_switch_theme',  '_wp_menus_changed'                      ); 
    265266add_action( 'after_switch_theme',  '_wp_sidebars_changed'                   ); 
    266267add_action( 'wp_print_styles',     'print_emoji_styles'                     ); 
  • trunk/wp-includes/nav-menu.php

    r40819 r41077  
    10271027    add_action( 'delete_post', '_wp_delete_customize_changeset_dependent_auto_drafts' ); 
    10281028} 
     1029 
     1030/** 
     1031 * Handle menu config after theme change. 
     1032 * 
     1033 * @access private 
     1034 * @since 4.9.0 
     1035 */ 
     1036function _wp_menus_changed() { 
     1037    $old_nav_menu_locations    = get_option( 'theme_switch_menu_locations', array() ); 
     1038    $new_nav_menu_locations    = get_nav_menu_locations(); 
     1039    $mapped_nav_menu_locations = wp_map_nav_menu_locations( $new_nav_menu_locations, $old_nav_menu_locations ); 
     1040 
     1041    set_theme_mod( 'nav_menu_locations', $mapped_nav_menu_locations ); 
     1042    delete_option( 'theme_switch_menu_locations' ); 
     1043} 
     1044 
     1045/** 
     1046 * Maps nav menu locations according to assignments in previously active theme. 
     1047 * 
     1048 * @since 4.9.0 
     1049 * 
     1050 * @param array $new_nav_menu_locations New nav menu locations assignments. 
     1051 * @param array $old_nav_menu_locations Old nav menu locations assignments. 
     1052 * @return array Nav menus mapped to new nav menu locations. 
     1053 */ 
     1054function wp_map_nav_menu_locations( $new_nav_menu_locations, $old_nav_menu_locations ) { 
     1055    $registered_nav_menus = get_registered_nav_menus(); 
     1056 
     1057    // Short-circuit if there are no old nav menu location assignments to map. 
     1058    if ( empty( $old_nav_menu_locations ) ) { 
     1059        return $new_nav_menu_locations; 
     1060    } 
     1061 
     1062    // If old and new theme have just one location, map it and we're done. 
     1063    if ( 1 === count( $old_nav_menu_locations ) && 1 === count( $registered_nav_menus ) ) { 
     1064        $new_nav_menu_locations[ key( $registered_nav_menus ) ] = array_pop( $old_nav_menu_locations ); 
     1065        return $new_nav_menu_locations; 
     1066    } 
     1067 
     1068    $old_locations = array_keys( $old_nav_menu_locations ); 
     1069 
     1070    // Map locations with the same slug. 
     1071    foreach ( $registered_nav_menus as $location => $name ) { 
     1072        if ( in_array( $location, $old_locations, true ) ) { 
     1073            $new_nav_menu_locations[ $location ] = $old_nav_menu_locations[ $location ]; 
     1074            unset( $old_nav_menu_locations[ $location ] ); 
     1075        } 
     1076    } 
     1077 
     1078    // If there are no old nav menu locations left, then we're done. 
     1079    if ( empty( $old_nav_menu_locations ) ) { 
     1080        return $new_nav_menu_locations; 
     1081    } 
     1082 
     1083    /* 
     1084     * If old and new theme both have locations that contain phrases 
     1085     * from within the same group, make an educated guess and map it. 
     1086     */ 
     1087    $common_slug_groups = array( 
     1088        array( 'header', 'main', 'navigation', 'primary', 'top' ), 
     1089        array( 'bottom', 'footer', 'secondary', 'subsidiary' ), 
     1090    ); 
     1091 
     1092    // Go through each group... 
     1093    foreach ( $common_slug_groups as $slug_group ) { 
     1094 
     1095        // ...and see if any of these slugs... 
     1096        foreach ( $slug_group as $slug ) { 
     1097 
     1098            // ...and any of the new menu locations... 
     1099            foreach ( $registered_nav_menus as $new_location => $name ) { 
     1100 
     1101                // ...actually match! 
     1102                if ( false === stripos( $new_location, $slug ) && false === stripos( $slug, $new_location ) ) { 
     1103                    continue; 
     1104                } 
     1105 
     1106                // Then see if any of the old locations... 
     1107                foreach ( $old_nav_menu_locations as $location => $menu_id ) { 
     1108 
     1109                    // ...and any slug in the same group... 
     1110                    foreach ( $slug_group as $slug ) { 
     1111 
     1112                        // ... have a match as well. 
     1113                        if ( false === stripos( $location, $slug ) && false === stripos( $slug, $location ) ) { 
     1114                            continue; 
     1115                        } 
     1116 
     1117                        // Make sure this location wasn't mapped and removed previously. 
     1118                        if ( ! empty( $old_nav_menu_locations[ $location ] ) ) { 
     1119 
     1120                            // We have a match that can be mapped! 
     1121                            $new_nav_menu_locations[ $new_location ] = $old_nav_menu_locations[ $location ]; 
     1122 
     1123                            // Remove the mapped location so it can't be mapped again. 
     1124                            unset( $old_nav_menu_locations[ $location ] ); 
     1125 
     1126                            // Go back and check the next new menu location. 
     1127                            continue 3; 
     1128                        } 
     1129                    } // endforeach ( $slug_group as $slug ) 
     1130                } // endforeach ( $old_nav_menu_locations as $location => $menu_id ) 
     1131            } // endforeach foreach ( $registered_nav_menus as $new_location => $name ) 
     1132        } // endforeach ( $slug_group as $slug ) 
     1133    } // endforeach ( $common_slug_groups as $slug_group ) 
     1134 
     1135    return $new_nav_menu_locations; 
     1136} 
  • trunk/wp-includes/theme.php

    r41059 r41077  
    692692 
    693693    $nav_menu_locations = get_theme_mod( 'nav_menu_locations' ); 
     694    add_option( 'theme_switch_menu_locations', $nav_menu_locations ); 
    694695 
    695696    if ( func_num_args() > 1 ) { 
     
    731732        if ( 'wp_ajax_customize_save' === current_action() ) { 
    732733            remove_theme_mod( 'sidebars_widgets' ); 
    733         } 
    734  
    735         if ( ! empty( $nav_menu_locations ) ) { 
    736             $nav_mods = get_theme_mod( 'nav_menu_locations' ); 
    737             if ( empty( $nav_mods ) ) { 
    738                 set_theme_mod( 'nav_menu_locations', $nav_menu_locations ); 
    739             } 
    740734        } 
    741735    } 
  • trunk/wp-includes/version.php

    r41076 r41077  
    55 * @global string $wp_version 
    66 */ 
    7 $wp_version = '4.9-alpha-41236'; 
     7$wp_version = '4.9-alpha-41237'; 
    88 
    99/** 
Note: See TracChangeset for help on using the changeset viewer.