Painless theme switching in WordPress

Abstract: analysis of some WordPress issues when switching from a theme to another. Or from a base theme to a child theme. 

The issue: menus and widgets are systematically lost when switching themes.

What should happen: as long as the declared menu locations and widget locations are the same (have the same ID), the settings should be retained.

The same goes when switching from mother-theme to child theme. Currently, the menu connections are lost, which makes no sense.


As an example, let’s use the theme TwentyTwelve, which has a wp_nav_menu location named ‘primary’:

register_nav_menu( 'primary', __( 'Primary Menu', 'twentytwelve' ) );

Now, let’s create a menu, and assign it to the available area (Primary Menu).

Then, switch to TwentyThirteen which has the following areas:

register_nav_menu( 'primary', __( 'Navigation Menu', 'twentythirteen' ) );

Ideal result:
Our menu should still be assigned to the “primary” location.

Actual result:
No menu is assigned to the “primary” location. Switching the theme has broken the connection.


What about widgets?

Now, let’s see what happens with the widgets.

TwentyTwelve has three sidebar areas:

'name' => __( 'Main Sidebar', 'twentytwelve' ),
'id' => 'sidebar-1',

'name' => __( 'First Front Page Widget Area', 'twentytwelve' ),
'id' => 'sidebar-2'

'name' => __( 'Second Front Page Widget Area', 'twentytwelve' ),
'id' => 'sidebar-3'

In TwentyThirteen, there are two areas:

'name' => __( 'Main Widget Area', 'twentythirteen' ),
'id' => 'sidebar-1',

'name' => __( 'Secondary Widget Area', 'twentythirteen' ),
'id' => 'sidebar-2'

Interesting: they have the same IDs!

Ideal result:
Based on those areas having the same ID, the widgets should remain where they are.

Actual result:
Our widgets have been lost (not entirely, fortunately, they have been moved to the “Inactive Widgets” area). But there seems to be no way to retain the Widget-Sidebar relationship, even if they are named consistently across themes.

This is sub-optimal user experience.

Let’s launch a new data portability campaign! Menus and Widgets should be retained, if the menu and sidebar areas of the themes have the same identifiers.

In addition, we should create some general guidelines about how to name typical Menu and Widget locations (the main menu, the main sidebar, the footer area…). This would allow themes to be compatible with each other. Much like it is the case with post formats.

Optionally, we could restrict this a little bit for widgets, and say “if the ID and Name are identical, settings are retained”.