A Strategy for Custom Colors in the Customizer

The customizer is a framework for live-previewing any change to a WordPress site, and it is particularly useful for previewing visual changes. It has always shipped with a color control and the ability to preview custom colors with little effort, but the previewing experience has often been a bit slow. This post outlines a strategy for custom color options that leverages instant JS-based previewing in conjunction with selective refresh.

Demo of instant custom color previews in the customizer with the Linework theme.
Demo of instant custom color previews in the customizer with the Linework theme.

Example Plugin: Custom Highlight Color

I’ll leverage the custom highlight color plugin as an example of this approach. I recommend downloading it from WordPress.org to follow along with, and I’ll provide a detailed walkthrough of the code with excerpts here.

This plugin only has one option – the highlight color. However, this approach can easily scale to additional options. As I’ll show later, it’s best to minimize your options and instead rely on code logic to generate or select variations as needed so that users can achieve custom results with minimal effort and decision-making. Finding the right balance of color options is an important step in the product design process, and one where even the past couple of default WordPress themes leaned a bit too far in the direction of options, in my opinion.

Adding Customizer Objects

The first step is to register your color options in the customizer via the PHP API. We can use the colors section provided by core, leaving the setting and control to be registered in your theme or plugin. The transport will be postMessage, indicating that we’ll preview the setting with JavaScript:

function custom_highlight_color_customize( $wp_customize ) {
	$wp_customize->add_setting( 'custom_highlight_color', array(
		'type' => 'option', // Change to theme_mod when using in a theme.
		'default' => '#ff0',
		'sanitize_callback' => 'sanitize_hex_color',
		'transport' => 'postMessage',
	) );

	$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'custom_highlight_color', array(
		'section' => 'colors',
		'label' => __( 'Highlight Color', 'custom-highlight-color' ),
	) ) );
}
add_action( 'customize_register', 'custom_highlight_color_customize' );

The setting will use sanitize_hex_color, ensuring that a single secure hex color code is saved in the database for each option. For themes, you should set the type to theme_mod instead of option, and it’ll be stored with the rest of the theme-specific options automatically.

Color Patterns and Calculations

Next, we need to define the CSS that will display the custom color options. By putting this into a distinct function, the code can be leveraged in multiple preview and output contexts. When there’s a lot of CSS, I prefer to break this into a separate file to make it easier to maintain. You can even split distinct parts of the color CSS into different functions. For a simple example, here’s what Custom Highlight Color does:

function custom_highlight_color_css() {
	require_once( 'color-calculations.php' ); // Load the color calculations library.
	$background = get_option( 'custom_highlight_color', '#ff0' ); // The second argument is the default color when the theme mod is undefined.
	// Set the text color to black or white, whichever provides higher contrast with the highlight color.
	if ( custom_highlight_color_contrast_ratio( $background, '#000' ) > custom_highlight_color_contrast_ratio( $background, '#fff' ) ) {
		$color = '#000';
	} else {
		$color = '#fff';
	}

	$css = '
		::-moz-selection {
			background: ' . $background . ';
			color: ' . $color . ';
		}
		::selection {
			background: ' . $background . ';
			color: ' . $color . ';
		}';
	return $css;
}

You’ll notice that there are some color contrast checks here, which automatically set the text color to ensure that it contrasts with the highlight color. In this case it looks for the higher contrast between two colors, but typically you’ll want to ensure that the contrast is at least 4.5 between background and text colors. These checks leverage the color-calculations.php functions that I originally developed for the Fourteen Colors plugin. Feel free to take this file from the custom highlight color plugin and ship it with your project (make sure you update the function prefixes to match your plugin or theme).

In addition to the contrast check (which is done per the WCAG guidelines), the color calculations library has a handy function to “adjust” a color. You can use this to brighten or darken a color by a numeric amount, generating color variations automatically. The Fourteen Colors plugin uses this technique extensively.

Color Output

Now that our color patterns are defined, it’s easy to display the color CSS within style tags in wp_head. However, in the customizer preview, we also need an easy way to get the current colors in JavaScript. To do that, we’ll conditionally add the colors as data- attributes when is_customize_preview():

add_action( 'wp_head', 'custom_highlight_color' );
function custom_highlight_color() {
	if ( is_customize_preview() ) { 
		$data = 'data-color="' . get_option( 'custom_highlight_color', '#ff0' ) . '"'; 
	} else {
		$data = '';
	}
?>
	<style type="text/css" id="custom-highlight-color" <?php echo $data; ?>>
		<?php echo custom_highlight_color_css(); ?>
	</style>
<?php }

The colors should now display on the front end, but they won’t preview in the customizer just yet.

Instant Custoizer Previews with JavaScript

To preview the color changes instantly in the customizer, we first need to enqueue a JS file to manage color previews (if your theme already loads a customizer JS file, you can add to that in lieu of introducing another one):

function custom_highlight_color_customize_preview_js() {
	wp_enqueue_script( 'custom_highlight_color_customizer', plugins_url( '/customizer.js', __FILE__ ), array( 'customize-preview' ), '20160830', true );
}
add_action( 'customize_preview_init', 'custom_highlight_color_customize_preview_js' );

In that file, we’ll follow the standard customizer preview conventions and bind to changes on our settings. For each of the colors, we’ll search for instances of the original color in the CSS, and replace them with the new color:

( function( $ ) {
	wp.customize( 'custom_highlight_color', function( value ) {
		value.bind( function( to ) {
			// Update custom color CSS
			var style = $( '#custom-highlight-color' ),
			    color = style.data( 'color' ),
			    css = style.html();
			//css = css.replace( color, to );
			css = css.split( color ).join( to ); // equivalent to css.replaceAll.
			style.html( css )
			     .data( 'color', to );
		} );
	} );
} )( jQuery );

You’ll need to bind changes to each of your color settings if you have multiple color options. Now, you’ll be able to preview color changes instantly in the customizer. But what about the colors generated using color calculations in PHP?

Adding Selective Refresh for Secondary Colors

To supplement the instant JS previewing that updates the CSS with a search-and-replace of the color value, we need to add selective refresh support so that the CSS is re-rendered from PHP with our color calculations applied. The color patterns and calculations could be duplicated in JS, but that would become quite difficult to maintain and offers only a slight usability benefit. With selective refresh, we can leverage the existing function in PHP; it’s only a matter of adding a customizer partial that will be refreshed when one of the associated colors changes:

$wp_customize->selective_refresh->add_partial( 'custom_highlight_color', array(
	'selector'        => '#custom-highlight-color',
	'settings'        => array( 'custom_highlight_color' ),
	'render_callback' => 'custom_highlight_color_css',
) );

This code should be added within the same callback to the customize_register action that we added earlier. Multiple settings can be associated with a single partial; add the other setting ids to the array of settings.

Once that’s complete, you should be able to preview all of your custom colors in the customizer, with instant updates to base colors and updates to generated colors happening on a slight delay. Colors are safely stored in the database without the security issues of saving CSS there, and styles are applied on the front end as expected. I’m now leveraging this approach in all of my themes and plugins as I find it to provide a nice balance between user experience and code simplicity.

The custom highlight color plugin is a simple example, built specifically to be an example, but this approach easily scales to more colors as needed. For a more complex example, check out the code for the Fourteen Colors Plugin or the Figure/Ground theme (which runs this site and lets users customize every color).

The Customizer is the Future for Themes and Theme Options

There has been a lot of backlash from the WordPress community recently over the theme review team’s decision to require theme options to be implemented in the Customizer. But this decision really is in everyone’s best interest.

WordPress 4.2 shipped with the ability to switch themes in the Customizer. When theme-installation is incorporated in a future release, the entire theme selection and customization process will be streamlined to a seamless workflow in which the user never enters the WordPress admin. This functionality is specifically targeted to users that leverage free WordPress.org themes, so it just makes sense for all themes hosted there to be Customizer-optimized. But the real win is the ability to live-preview changes before publishing them. With the Customizer, users know exactly what their site will look like when they publish their changes, a critical feature for anyone who cares what their site looks like when it’s publicly available.

Many people have been critical of the user-oriented nature of the Customizer. But its power is much stronger than most realize; one of my favorite use-cases for the customizer is custom CSS. This is the easiest way for users who want to go further to get into coding and offers a seamless experience that is infinitely better than the easy-to-kill-your-site-or-lose-your-changes-with code editor in the admin. In fact, I’d love to see a customizer-based custom CSS functionality in core as a replacement for the code editor, although I have a feeling that proposal may be too political to advance to an implementation. Bottom line, the customizer lowers the barrier to entry into WordPress development, contrary to many people’s thinking.

Yes, free themes requiring use of the Customizer will lead to a similar movement for client themes and premium themes. And that’s okay. In fact, by having everyone using the same underlying framework, users know where to look for options and have the confidence that live previewing provides. And WordPress will provide a more consistent visual experience for users as well.

You can really build any functionality into the Customizer. Theme-switching, widgets, and menus were all built as plugins first and continue to use the publicly available customizer API to run. So if you must, you can still create ridiculously complicated UI elements that no one will be able to figure out how to use, but you really don’t need to.

And complaints about the amount of screen real estate available and the 300px default width show a lack of creativity and resistance for the sake of resistance to change. Start by removing all of the ads, external links, unnecessary branding, unnecessary options, and general clutter. Make your options self-explanatory – if you need a paragraph to describe what it does, it probably shouldn’t be a user-facing option. Do you still have so much UI that the experience is completely unusable? Try an outside-the-box solution, like utilizing the core media modal (header images and core media controls use it), a custom modal (theme details modal in core), or a slide-out panel (widgets in core and eventually menus in core as well).

No, the customizer isn’t perfect. But it’s time to give it the respect it deserves as a significant part of WordPress. After three years of slow adoption, the theme review team’s decision to enforce its use is a welcome sign for users and a positive decision for the WordPress community as a whole. I’m excited to see what developers do with the Customizer’s amazingly powerful API and what core contributors come up with to improve its design and usability.

Proposed WordPress Customizer Theme-Switching UX

This is a proposal for how theme-switching and theme-installation could be incorporated into WordPress’ Customizer. This will eventually be attempted in some form as a feature-plugin to later be merged into WordPress core. The goal is to soften the distinction between themes and theme options and to make theme switching a fast, streamlined experience built-in with other Customization options in a unified interface.

Themes is a panel, but with backwards-sliding, coming in from the left instead of the right. This implies a new layer of hierarchy above the top-level controls. Switching contexts to the theme-browser is just like switching contexts to a panel, but to exit the themes context, you select a theme. The currently active/currently previewed theme is selected and has an arrow back to the right, to slide back to the top-level controls. All of this sliding can also be triggered by swiping on touch devices.

When a different theme is selected from the theme browser, it instantly slides back to the main panel of top-level controls, but now reflects the controls available in the new theme. This is accomplished by rendering the controls specific to the new theme via ajax and the new customizer sections/panels JS API, and then deleting the controls that were specific to the old theme. This should be doable in a back-compatible way by working some trickery with the existing customizer APIs, caching stuff, and/or leveraging WP-API.

The preview would instantly need to switch to a loading indicator until the front-end re-rendered with the new theme, but that shouldn’t take too long and is unavoidable regardless of the implementation here.

In the theme browser, the add-new-theme functionality would be present via a + new theme tile matching the one in the current interface, and bring up a modal containing the 3.9 pieces of THX. From there, the theme-installer previewer (also containing the theme details) would need to either remain in the (almost-full-screen) modal or open in a new tab that closed on install/close-button-click (or, do a full-screen iframe on top of the customizer and modal with the theme-install-preview, although that might get a bit crazy).

We would need a solution for unsaved changes in previewed themes that are not activated, as theme-specific controls are hidden/removed when previewing another theme.

Prerequisites:

  • JS API for adding and deleting panels, sections, settings, and controls, to complement the existing controls API.
  • Distinction/ability to save changes without publishing and/or the ability to save without activating a new theme. Although, not distinguishing between saving and saving and activating would probably make more sense here.

WordPress 4.0 Customizer API Improvements

I cross-posted much of this post to Make WordPress Core before WordPress 4.0 Beta 1. I’ll be updating this version with more examples throughout the beta period.

WordPress 4.0 features several new additions to the Customizer API (see also Theme Customization API). In this post, I’ll discuss the improvements in detail.

Customizer Panels

The Customizer now includes a new way to group options together: panels. Just like a section is a container for controls, a panel is a container for sections. This was implemented in #27406. In WordPress Core, widget management in the customizer has been consolidated into the “Widgets” panel. Instead of having as many sections as there are widget areas making a mess out of the customization experience, only one widgets section appears alongside the other customizer sections. But when you select it, rather then sliding down like regular sections, it slides over to reveal a new context for the entire customizer controls area. My Menu Customizer project also relies on this new panels functionality, as all menus can be consolidated into one panel. But themes and/or plugins with extensive options may also wish to create their own panels to better organize their controls, so we built an API for customizer panels. The Panels API is easy-to-use and works almost identically to the existing customizer section API. Add a panel with the following, within the customize_register action:

$wp_customize->add_panel( 'panel_id', array(
	'priority' => 10,
	'capability' => 'edit_theme_options',
	'theme_supports' => '',
	'title' => '',
	'description' => '',
) );

As always, only use the arguments where you aren’t using the default values. Note that the panel will not be displayed unless sections are assigned to it. To add a section to a panel, just use the panel id for the new panel argument:

$wp_customize->add_section( 'section_id', array(
	'priority' => 10,
	'capability' => 'edit_theme_options',
	'theme_supports' => '',
	'title' => '',
	'description' => '',
	'panel' => 'panel_id',
) );

You may notice that $wp_customize->add_panel and $wp_customize->add_section have the same arguments (other than panel, of course). This is because panels are a special type of section; technically speaking, WP_Customize_Panel extends WP_Customize_Section. Your sections are backwards-compatible: you can add the panel argument to existing sections without issues. However, you do need to check for the existence of WP_Customize_Manager->add_panel() if you’re maintaining pre-4.0 compatibility. As with Customizer Sections, you can access and modify Panels via:

  • $wp_customize->get_panel( $id );
  • $wp_customize->remove_panel( $id );

New Built-in Customizer Controls

WordPress core now provides support for a much wider array of Customizer controls. Implemented in #28477, these changes eliminate the need to create custom controls for most common use cases. The textarea type is now supported in core. For any type of input that uses an input element, you can simply specify the type attribute using the type parameter of $wp_customize->add_control(). Here’s an example:

$wp_customize->add_control( 'setting_id', array(
	'type' => 'url',
	'priority' => 10,
	'section' => 'title_tagline',
	'label' => 'URL Field',
) );

Which results in the following markup in the Customizer:

<li id="customize-control-setting_id" class="customize-control customize-control-url">
<label>
<span class="customize-control-title">URL Field</span>
<input type="url" value="" data-customize-setting-link="setting_id">
</label>
</li>

This is pretty powerful, as you can now use the built-in WP_Customize_Control for most common use-cases rather than creating a custom control. But what about input types like number and range that require additional attributes like min, max, and step?

New Built-in Customizer Control Parameters

First of all, all of the built-in Customizer controls (including the custom controls such as WP_Customizer_Color_Control) now support descriptions, just like Customizer sections have descriptions (see #27981). This was much-needed and allows for inline help text at the control level. More interestingly, to complement the new support for arbitrary input types, a new input_attrs parameter allows you to add attributes to the input element (also implemented in #28477). This extends beyond just using min, max, and step for number and range, to the ability to add custom classes, placeholders, the pattern attribute, and anything else you need to the input element. Here’s an example:

$wp_customize->add_control( 'setting_id', array(
	'type' => 'range',
	'priority' => 10,
	'section' => 'title_tagline',
	'label' => 'Range',
	'description' => 'This is the range control description.',
	'input_attrs' => array(
		'min' => 0,
		'max' => 10,
		'step' => 2,
		'class' => 'test-class test',
		'style' => 'color: #0a0',
	),
) );

Which results in the following markup in the Customizer:

<li id="customize-control-setting_id" class="customize-control customize-control-range">
	 <label>
		 <span class="customize-control-title">Range</span>
		 <span class="description customize-control-description">This is the range control description.</span>
 <input type="range" min="0" max="10" step="2" class="test-class test" style="color: #0a0;" value="" data-customize-setting-link="setting_id">
	 </label>
 </li>

Which displays as follows (in Chrome 35): customizer-4.0-range-control

The ability to add classes is particularly useful if you need to target specific controls with CSS or JS, but it doesn’t need to have any special markup. I’m using this in the Menu Customizer for the Menu Name field, which is just an ordinary text control with a special setting type.

Contextual Controls

Customizer controls can now be displayed or hidden based on the Customizer’s preview context. For example, options that are only relevant to the front page can be shown only when the user is previewing their front page in the Customizer (see #27993). This is already implemented in core for Widgets; Widgets have always been contextually faded and shown/hidden based on their visibility in the preview, but this functionality is now built off of the core active_callback API in both PHP and JS. There are three different ways to specify whether a given control should only be displayed in a certain context. The first, and most straightforward, is to use the active_callback argument in $wp_customize->add_control().

$wp_customize->add_control( 'front_page_greeting', array(
	'label'      => __( 'Greeting' ),
	'type' => 'textarea',
	'section' =>
	'title_tagline',
	'active_callback' => 'is_front_page',
) );

Note that you may use either built-in conditional functions or a custom function. If you have a custom control (via a subclass of WP_Customize_Control) and a custom callback function, you can skip the active_callback argument and override the active_callback function instead:

class WP_Greeting_Control extends WP_Customize_Control {
	// ...

	function active_callback() {
		return is_front_page();
	}
}

Finally, the customize_control_active filter will override all of the other active callback options and may be a better solution in certain cases (note that this particular example will be avoidable with future work on expanding the Customizer’s JS API, and does not hide the title_tagline section, only the controls in it):

function titletagline_customize_control_active_filter( $active, $control ) {
	if ( 'title_tagline' === $control->section ) {
		$active = is_front_page();
	}
	return $active;
}
add_filter( 'customize_control_active', 'titletagline_customize_control_active_filter', 10, 2 );

In addition to the PHP API for contextual controls, you can override the control-visibility-toggle function on the JS side. By default, controls will slideUp and slideDown as they become visible or hidden when the Customizer preview is navigated. If you’re familiar with the Customizer control JS API (see wp-admin/js/customize-controls.js, and wp.customize.Control), the Widgets implementation of a custom toggle function is a good example:

api.Widgets.WidgetControl = api.Control.extend({
// ...
   /**
    * Update widget control to indicate whether it is currently rendered.
    *
    * Overrides api.Control.toggle()
    *
    * <a href='http://profiles.wordpress.org/param' class='mention'>@param</a> {Boolean} active
    */
    toggle: function ( active ) {
        this.container.toggleClass( 'widget-rendered', active );
    },
// ...
) };

/**
 * Extends wp.customize.controlConstructor with control constructor for widget_form.
 */
$.extend( api.controlConstructor, {
    widget_form: api.Widgets.WidgetControl,
} );

Changes to the customize_update_ and customize_preview_ Actions

You probably already know that the Customizer supports both option and theme_mod types for settings. But did you know that you can register arbitrary types? Since this is generally undocumented, I’ll show how it works (this has been in place since 3.4):

$wp_customize->add_setting( 'setting_id', array(
	'type' => 'custom_type',
	'capability' => 'edit_theme_options',
	'theme_supports' => '',
	'default' => '',
	'transport' => 'refresh',
	'sanitize_callback' => '',
	'sanitize_js_callback' => '',
) );

There are a few actions that you can use to handle saving and previewing of custom types (option and theme_mod are handled automatically). Namely, customize_update_$type and customize_preview_$type are useful here. Previously, the value of the setting was passed to these actions, but there was no context. In 4.0, via #27979, the WP_Customize_Setting instance is passed to these actions, allowing more advanced saving and previewing operations. Here’s an example from my Menu Customizer project:

function menu_customizer_update_menu_name( $value, $setting ) {
...
	// Update the menu name with the new $value.
	wp_update_nav_menu_object( $setting->menu_id, array( 'menu-name' => trim( esc_html( $value ) ) ) );
}
add_action( 'customize_update_menu_name', 'menu_customizer_update_menu_name' );

This part of the Customizer API is a bit too complex to fully explain here, as most of it already existed, but suffice to say that the addition of the setting instance to these actions greatly expands the possibilities of working with custom setting types in the Customizer.

New “customize” Capability

Note: this API component is coming in 4.0 beta 2.

The Customizer has been decoupled from edit_theme_options in favor of a customize meta capability, which is mapped to edit_theme_options by default. This allows for wider use of the Customizer’s extensive capability-access options, which are built into panels, sections, and settings. Additionally, this makes it possible to allow non-administrators to use the customizer for, for example, customizing posts. This change is an important step to expanding the scope of the Customizer beyond themes. See #28605. To allow users with lower capabilities to access the Customizer, use something like the following:

function allow_users_who_can_edit_posts_to_customize( $caps, $cap, $user_id ) {
        $required_cap = 'edit_posts';
        if ( 'customize' === $cap && user_can( $user_id, $required_cap ) ) {
                $caps = array( $required_cap );
        }
        return $caps;
}
add_filter( 'map_meta_cap', 'allow_users_who_can_edit_posts_to_customize', 10, 3 );

Customizer Conditional Function

The new is_customize_preview() conditional function can be used to check whether the front-end is being displayed in the Customizer. The naming derives from the fact that the term “preview” applies to both theme previews and previewing changes before saving them. See #23509 for some sample use-cases from WordPress.com.

Examples

Look at the Widget Customizer and Menu Customizer code for more examples of many of these features. Please feel free to ask in the comments if you have you questions with any of these implementations; I spent a good amount of time preparing and reviewing the associated patches and soliciting feedback in the process of adding these changes to core.

Use This API for Good, not Evil

These new additions to the Customizer API greatly expand the ability to create intricate options for users. But please don’t forget about WordPress’ core philosophies. So, before you go adding entire panels full of new options, remember to strive for simplicity and design for the majority, even in themes and plugins. These additions make the Customizer better for developers; now, let’s make it as good as it can be for our end-users.

GSoC Menu Customizer Revised Schedule/Scope

Previously: GSoC Project Proposal: WordPress Menu Customizer.

Week 1 – 5/19: Introduce the ability to view all existing menus as customizer sections with menu items as customizer controls.

Week 2 – 5/26: Add the ability to edit menus (change labels, attributes, re-order items), including a temporary solution that includes the screen options found on the existing menus screen. Run user tests on the existing menu management screen to inform UI decisions for the initial iteration, coordinating with the WordPress core UI team.

Week 3 – 6/2: Implement an input-type-agnostic re-ordering mode, merging the existing UIs on the Menus screen and in the Widget Customizer (should particularly help with touch & keyboard input). Implement a version of #27406 into the plugin (pending its completion for core, potentially also assist with the core patch if needed), to maintain 3.9 compatibility. Move all menus (customizer sections) to the menus/navigation super-section, and implement the theme location controls in the new interface. Begin implementing a panel to add new widgets, potentially re-using components from the Widget Customizer’s equivalent UI (and potentially making it more easily re-usable outside of core).

Week 4 – 6/9: Create the ability to add items to menus, utilizing the slide-out panel from the Widget Customizer. For the first iteration, include sections containing pages, custom links, and categories, similar to those on the existing menus page.

Week 5 – 6/16: Second iteration of the add-new interface. Introduce a global search feature, an experimental approach to adding custom links, add all appropriate post types and taxonomies, and create a one-click add/remove menu items mode. Implement any additional ideas for adding items proposed by the WordPress core UI team.

Week 6 – 6/23: Midterm evaluations – critical functionality should be complete (editing & adding to menus, changing menu locations). Publish plugin (with WordPress 3.9 compatibility) on WordPress.org repository to facilitate community testing & feedback. Begin extensive user testing to facilitate further UI iterations. Add ability to create new menus, and delete menus, with the appropriate corresponding menu location UIs adapting accordingly.

Week 7 – 6/30: Address the need to implement screen options into the new menus interface. Work through the list of outstanding issues with the implementation, and begin responding to community feedback. Much of these will likely be UI/UX quirks that come up through the development process and are delayed in favor of completing the basic functionality. Examples could include dealing with deep menu-nesting (sub-menus) within the narrow customize controls area.

Week 8 – 7/7: Implement refinements for simplified use-cases, such as those added in WordPress 3.6 (#23119). Continue addressing bug fixes and enhancements based on community feedback. Add new hooks and create usage examples for them (#18584), if scaling issues can be resolved.

Weeks 9 – 12 – 7/14-8/4: Run user tests on the existing menus screen and the Menu Customizer. Iterate the UI and codebase based on user tests and feedback from WordPress core designers and developers, giving special attention to the experience for new users and a stronger emphasis on the ability to use menus in widget areas. Ensure the code is thoroughly documented and meets all core style guidelines. Test in all supported browsers and devices, with as many themes as possible, and with as many edge-cases as is feasible (ie, massive menus, huge numbers of menus, deep hierarchies, etc.). Fix bugs as they come up. Address whether the functionality is ready for core. If all goes well, consider whether the Menu Customizer could potentially replace the existing menus screen for supported users and develop approaches for user-discovery (for example, deep-linking).

Week 13 – 8/11: Prepare a core patch for the plugin merge, and draft final proposals for inclusion of the feature in core. Final project, as both a functioning plugin and a core patch, should be competed by the firm pencils-down date of 8/18. In the event that the plugin is unlikely to be accepted for core inclusion, continue development of outstanding issues and gathering feedback from the community, with the goal of reaching a good stopping point for the official end of GSoC.

GSoC Project Proposal: WordPress Menu Customizer

Please note that this post only contains the Project Description and Schedule of Deliverables sections, as they are the most relevant to public discussion.

Project Description

Describe your idea in detail:

WordPress 3.9 introduces the Widget Customizer: a better way to edit widgets. This is a major step in the process of migrating every component of WordPress’ Appearance menu to the Theme Customizer, where users can live-preview their changes before publishing them. The remaining features that should be incorporated into the Customizer are theme-switching, menu management, and improved background-image handling. Once the Customizer is feature-complete, we can begin to experiment with alternative approaches to accessing the customizer, making it feel more like an editing mode on the front-end of the site, alongside the front-end content-editor.

Menu management would be a particularly useful addition, as it could address long-standing usability concerns with menus and theme locations. The Menu Customizer would offer the ability to visualize where menus are located, as well as how the order of menu items and sub-menus are displayed in the theme. The menus screen was refreshed a year ago in WordPress 3.6, and the research and user testing completed during that process provides a good starting point for implementing menu management in the customizer.

The user interface of menu management in the customizer would be comparable to that of the Widget Customizer. The first step would be to either implement or abstract functionality for super-sections in customizer controls, where the top-level section heading slides over to reveal sub-sections containing each menu (and for widgets, each widget area, see #27406). The scope of my work here depends somewhat on whether this is addressed before GSoC starts, but the goal will be for this functionality to exist in an API in core, which is utilized by both menus and widgets.

Unlike widgets, menus are not theme-specific, and new menus can be created at-will. The existing menus / theme locations paradigm should be maintained by migrating the existing theme locations selector to the new interface, and adding the ability to create, edit, and add to individual menus, all within the super-section of customizer controls. There should be a mechanism to easily identify the currently active menu in the preview, and to identify the corresponding menu in the controls when exploring the preview. Menu items should be able to be re-ordered and moved into and out of sub-menus several levels deep. New items should be able to be added from all of the sources available on the menu management screen (post types, taxonomies, and custom links). Ideally, support for custom post types and taxonomies should be added as well (see #16075). Adding menu items could work similarly to adding widgets, with a slide-out panel, but the visual organization of items within the panel would need work, as widgets do not have hierarchy. The entire interface must be accessible for all input types, including keyboard, mouse, and touch. Since the Customizer doesn’t have a concept of “Screen Options,” the screen options in the current menus interface should be ported to the Menu Customizer in some way if possible.

The technical implementation would likely be similar to that of the Widget Customizer feature. Like many JavaScript-based features in WordPress, including the Widget Customizer, the Menu Customizer would be implemented with Backbone.js. Technical improvements to menu-management could also potentially be ported back to the existing menu management screen, eliminating the current issues with scaling by only saving data that is changed (#14134). While re-factoring nav-menus.php would not be in scope for the Menu Customizer project initially, the work done here should be able to be ported to the old interface easily and could potentially be added to the scope of the project if it is ahead of schedule. The Menu Customizer would provide a workaround for users affected by #14134, too, as the new Backbone-powered UI shouldn’t have scaling issues. If the Menu Customizer provides all of the features of the existing menu management screen, while clearly demonstrating that it is a better solution than the existing screen in user tests, it could potentially replace the existing screen entirely for users that can access the Customizer (JS enabled, IE8+, IE 10+ with domain-mapped front-end).

In addition to adding the menu management functionality, this project would make other small improvements to the customizer as necessary, such as an API for super-sections and the slide-out item-adding panel, and better documentation and code examples of the customizer, as time allows.

What have you done so far with this idea:

I have shared a broader customizer-improvements proposal on wp-hackers and discussed it with Andrew Nacin and Lance Willett. Of the ideas I proposed, menu management and theme switching in the customizer are the most intriguing, and the most complex.

Lance indicated that there is ongoing work in many of the areas of the customizer, including background image improvements and conceptual theme-switching ideas. Other ideas I proposed, such as adjusting the way users access the customizer to make it feel more like an editing mode, like front-end-editing, would benefit from the customizer being more feature-complete first. Theme-switching would require extensive new UI/UX development, while Menu Management would use a similar UI to the Widget Customizer. Therefore, menu-management in the customizer seems to be a good place for a GSoC project to develop a new solution.

Nacin suggested that menus should be implemented in Backbone.js, and that the current menu management screen could also benefit from this improved approach. Perhaps both UIs could share the same core interface and code. I’ve began investigating existing Backbone.js implementations in WordPress core, such as the new “THX” themes screen, as well as researching the principles behind Backbone.js. I’ve also added consideration for potential improvements to the existing screen to my project description, although if the Menu Customizer is implemented well enough it could potentially replace the existing screen entirely for supported users. Unlike with widgets, it should be possible to incorporate all of the existing features within the customizer to the extent that there is no compelling reason to maintain the standalone menus screen. However, this consideration would be made near the end of the project and is more of a long-term implementation consideration than a definite objective.

Plugin, theme, or core: The Menu Customizer will be developed in a plugin, with every intention of being included in core. This means that all core coding and inline documentation standards must be observed throughout the project, and it should be as lean as possible in terms of both code and UI. Given the project timeline, it is likely that this plugin would be a proposed feature plugin for inclusion in WordPress 4.1.

Supporting code such as super-section and slide-out panel APIs in the customizer would likely be developed directly as core patches, but would potentially also be included with the plugin to facilitate testing the plugin while running older versions of WordPress.

Anticipated challenges: Menus are tricky, and core may not have found the best UI for them yet. While the Menu Customizer aims to fix many of the issues with the current interface, there is always the chance that it introduces additional usability issues. It has been proposed that menus should be tied to pages rather than site “appearance,” but there are inherent issues with this approach that have caused much pushback from the WordPress community. Therefore, the Menu Customizer project aims to maintain the paradigms of the existing system, while providing a new interface with which to manage it. Once the functionality is completed, any issues should be easy to identify by running user tests. If the internals are well-constructed, tweaking the interface to adapt to any issues that arise should be straightforward. The Backbone.js-based implementation will enable this flexibility. There is a good chance that the Menu Customizer combined with the Widget Customizer will make the ability to add menus to widgets clearer; some effort will be dedicated to ensuring that this interaction works well (adding a menu, then adding it to a widget).

Finding a good way to highlight menu edit-ability in the preview will likely be one of the more challenging UI aspects to consider after the functionality is complete, as that issue affected the Widget Customizer project.

Potential mentors: No preference.

Schedule of Deliverables

Milestones and deliverables schedule:

I plan to work 40-hour weeks throughout the project to ensure that the Menu Customizer can be completed and prepared for a potential core merge by the end of GSoC. Each week would function as a cycle with clearly defined progress goals to ensure that the entire project stays on schedule. Once enough of the functionality is in place, the plugin where the Menu Customizer is developed would be released on WordPress.org with updates being pushed every Friday at the completion of each cycle.

  • Community Bonding Period: work with mentor to adjust project scope and implementation strategies. Research the Widget Customizer implementation as well as other uses of Backbone.js in WordPress core to determine a specific plan for implementation. Research the WordPress 3.6 menus refresh for potential UI/UX considerations. Monitor potential progress of Customizer super-section support in core (for widgets), and adjust project schedule accordingly (much of the work scheduled for the first few weeks could be eliminated if someone else picks this up before GSoC starts, in which case more time could be devoted to working on the Menu Customizer itself). Super-sections are a prerequisite for implementing the Menu Customizer, but could be implemented via the plugin first if needed.
  • Week 1 – 5/19: develop (or abstract from widgets) an API for WordPress core that allows super-sections in the Theme Customizer, depending on potential work by others during the community bonding period (after the release of WordPress 3.9). Post a complete draft patch to core trac by the end of the week. Determine Menu Customizer plugin structure and create the plugin files and outline the structure with documentation. Continue researching specific implementation strategies based on existing work in WordPress Core.
  • Week 2 – 5/26: work with core developers to improve and finalize the Customizer super-section API and get it committed to core trunk. Develop an API for a slide-out panel in the customizer (this is the panel that is used to add widgets and would be used to add menu items; may end up being a full-fledged addition to the Customizer API, may only be extracting re-usable functionality from the add widgets panel to be used more generically), and submit as core patches. Begin modifying the core Widget Customizer implementation to utilize the new super-sections. Continue outlining the plugin structure.
  • Week 3 – 6/2: Begin working on the Menu Customizer itself in earnest. Introduce the ability to view all existing menus as customizer sections with menu items as customizer controls in the plugin by the end of the week. Migrate theme locations controls to the new interface. Submit core patches for using the new super-section API for managing widgets.
  • Week 4 – 6/9: Add the ability to edit menus (change labels, attributes, re-order items), with the Customizer’s live preview updating accordingly. Release initial version of plugin on WordPress.org.
  • Week 5 – 6/16: Add ability to add items to menus, utilizing the slide-out panel abstracted from the Widget Customizer.
  • Week 6 – 6/23: Midterm evaluations – critical functionality should be complete (editing & adding to menus, changing menu locations). Add ability to create new menus, and delete menus, with the theme location selectors adapting accordingly.
  • Week 7 – 6/30: Work through the list of outstanding issues with the implementation. Much of these will likely be UI/UX quirks that come up through the development process and are delayed in favor of completing the basic functionality. Examples could include addressing the screen options in the existing menu management interface and dealing with deep menu-nesting (sub-menus) within the narrow customize controls area.
  • Week 8 – 7/7: Complete all features and fixes in-scope for a solid 1.0 by the end of this cycle.
  • Weeks 9 – 12 – 7/14-8/4: Run user tests on the existing menus screen and the Menu Customizer. Iterate the UI based on user tests and feedback from WordPress core designers and developers. Ensure the code is thoroughly documented and meets all core style guidelines. Test in all supported browsers and devices, with as many themes as possible, and with as many edge-cases as is feasible (ie, massive menus, huge numbers of menus, deep hierarchies, etc.). Fix bugs as they come up. Address whether the functionality is ready for core. If all goes well, consider whether the Menu Customizer could potentially replace the existing menus screen for supported users and develop approaches for user-discovery (for example, deep-linking).
  • Week 13 – 8/11: Prepare a core patch for the plugin merge, and draft final proposals for inclusion of the feature in core. Goal to have final project, as both a functioning plugin and a core patch, competed by the firm pencils-down date of 8/18. In the event that the plugin is unlikely to be accepted for core inclusion, continue development of outstanding issues and gathering feedback from the community, with the goal of reaching a good stopping point for the official end of GSoC.

Other commitments: I will be taking exams during the community bonding period, but my semester ends the week before GSoC officially starts. Otherwise, I am available for the entire summer.

 

WordPress 3.8: MP6, on the post screen

WordPress 3.8 Is Going to be Awesome

WordPress 3.8 development is heating up, with huge developments in the last few days.

MP6, the now-infamous visual redesign of WordPress, DASH, a much-needed refresh of that Dashboard screen that we all habitually ignore, THX, a gorgeous new theme-browsing experience, and many smaller components have been merged into WordPress trunk, the development branch, after being developed as plugins first. And most significantly, for me at least, Twenty Fourteen is now undeniably the greatest default WordPress theme yet.

This morning I logged into my local install of trunk to try to reproduce a bug in Twenty Fourteen, and I was greeted with DASH.

WordPress 3.8 Dashboard Re-design

I proceeded to the themes page on my way to widgets, and met THX.

WordPress 3.8's New Theme Browsing Interface

Next, I went into widgets, where I discovered a ton of iterative updates that make the Widgets workflow incredibly easier (many were a part of MP6, and even more improvements are on the way for WordPress 3.9 and beyond).

WordPress 3.8's Re-designed Widgets Screen

Then, I went into the theme customizer to change the static frontpage setting. While there, I noticed that I had the wrong featured content tag set, and when I changed it the preview updated almost instantly (several nasty bugs had been squashed). I would’ve admired Twenty Fourteen more, had I not been helping develop it for the last few months. But for anyone following along, change the accent color. If you look carefully, you’ll see that the purple is not the default; I introduced the custom accent color feature, which lets you give your Twenty Fourteen site custom feel.

A Quick Preview of the Twenty Fourteen Theme Wearing Purple in the Theme Customizer

Yes, I did just happen to go through this exact sequence of screens this morning, basically hitting every single major improvement in this new version of WordPress (seriously, though, look at this bug report I was trying to reproduce). But even if most people won’t visit the themes or widgets pages regularly, or won’t use Twenty Fourteen, there are so many new features in WordPress 3.8 that everyone will get something. If you didn’t catch it, every screenshot features MP6, which re-skins WordPress in its entirety.

WordPress 3.8 will be released on December 12th, 2013 (a date that project lead Matt Mullenweg has committed to). If you can’t wait to try it out, grab the beta tester plugin, and help get it polished (but not on a production site)!