New hooks let you add custom fields to menu items

WordPress 5.4 gives you two new actions that let you add custom fields to menu items—in the Menu screen and in the CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings.’s menu editor.

Menus adminadmin (and super admin) screen

The new wp_nav_menu_item_custom_fields action fires just before the move buttons of a nav menu item in the menu editor.

You can assign five parameters:

  • $item_id: the menu item ID (integer)
  • $item: the menu item data object (object)
  • $depth: the depth of the menu item (integer)
  • $args: an object of menu item arguments (object)
  • $id: the Navigation MenuNavigation Menu A theme feature introduced with Version 3.0. WordPress includes an easy to use mechanism for giving various control options to get users to click from one place to another on a site. ID (integer)

Here’s a simple example:

function wporg_my_custom_field() {
	esc_html_e( 'Howdy! WordPress 5.4 is coming!', 'wporg' );
}
add_action( 'wp_nav_menu_item_custom_fields', 'wporg_my_custom_field' );

And here’s the result (highlighted in green dashed border):

The Customizer menu editor

The new wp_nav_menu_item_custom_fields_customize_template action fires at the end of the form-fields template for navigation menu items in the customizer.

The hook lets you render extra fields there and manage them with JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/..

This brings parity with the wp_nav_menu_item_custom_fields action.

Compatibility with existing custom walkers

These new action hooksHooks In WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same. can replace the custom walkers you’ve been using for your nav-menu fields. You’ll want to check your existing code to see where that replacement makes sense.

For more, see the related TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker. #47056.

For more help managing duplication in custom fields, see Trac ticket #49500. In plugins, you can avoid the issue entirely with a check for the WordPress version.

#5-4, #dev-notes, #menu-customizer, #menus

Fast previewing changes to Menus in the Customizer

The foundation of the CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings. is built on the concept of the “setting”, an abstract representation of anything in WordPress: options, theme mods, posts, terms, and so on. Settings are linked to controls which are responsible for manipulating them. When a setting is changed it gets pushed into the preview window so that the modification can be reviewed before being published live.

There are two ways (transports) for how a setting can be pushed into the preview: refresh and postMessage. The refresh transport does a full page refresh with the modified settings applied, and so it relies on PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher to apply the setting changes. The refresh transport is designed to be compatible with all themes, but for heavy sites refresh can be excruciating slow and taxing on the server. For this reason, the postMessage transport was introduced for previewing changes. This transport uses JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. to apply the changes instantly in the preview without any Ajax requests or PHP calls. This is great, but themes have to opt-in to postMessage transport for settings because they must also include JavaScript code which duplicates the logic which is already being executed on the server by PHP. The postMessage transport violates the DRY principle.

With that background out of the way…

Partial Refresh of Menus

In WordPress 4.3 menu management is being added to the Customizer, extending the types of objects that the Customizer can manipulate to include nav_menu taxonomyTaxonomy A taxonomy is a way to group things together. In WordPress, some common taxonomies are category, link, tag, or post format. https://codex.wordpress.org/Taxonomies#Default_Taxonomies. terms and nav_menu_item posts. We wanted this menu management experience to be fast so it had to avoid the slow full-page refresh transport. Nevertheless, the postMessage transport wasn’t possible to use either since we wouldn’t be able to duplicate all of the PHP menu walker logic and theme/pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party extensions for rendering menus purely in JavaScript. We also wanted to enable fast previewing of menu changes by default. So we implemented a postMessage/refresh hybrid approach which uses postMessage to sync the menus settings to the preview, and then the preview does an Ajax request to render just the contents of the menu container, and this Ajax response is then inserted into the DOM to replace the previous menu container. The technical name for this approach we have been calling “partial refresh”, but you can call it “fast preview”.

When the Customizer determines it can’t do a partial refresh, it falls back to performing a full page refresh. Conditions for why a menu change will get a full page refresh include:

  • if the menu was just assigned to a location for the first time or removed from being assigned to a location, since the theme may have some changes to the layout that it may need to perform;
  • or if wp_nav_menu() is called with with echo being false, since the theme may be doing some string replacement in this case which we can’t replicate in the partial-refresh Ajax request;
  • or if wp_nav_menu() is called with with a non-JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. serializable fallback_cb, such as a closure or a object method—this arg has to be empty or a string;
  • or if wp_nav_menu() is called with with a walker object instance, as opposed to a class name string;
  • or if wp_nav_menu() is called without a theme_location arg and the menu arg is not an term ID or a menu object;
  • or if the menu selected in a Custom Menu widgetWidget A WordPress Widget is a small block that performs a specific function. You can add these widgets in sidebars also known as widget-ready areas on your web page. WordPress widgets were originally created to provide a simple and easy-to-use way of giving design and structure control of the WordPress theme to the user. is changed, since partial refresh for widgets is not yet supported (however, see feature plugin)—subsequent changes to the menu will result in fast partial refreshes if the above conditions

When a menu is being updated via partial refresh, the menu container will receive a classname customize-partial-refreshing, which by default changes the opacity to 25%.

Theme Support

The fast preview for menu changes is being enabled by default so that theme authors don’t have to opt-in to the functionality like they do for instant preview (postMessage transport). In general this should be fine. However, if the theme includes some JavaScript which dynamically manipulates the rendered menu container, such as adding event handlers for expanding/collapsing submenus, then the theme would need to include some JSJS JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors. to re-apply the modifications once the menu is partial-refreshed, as the old DOM for the menu container gets replaced.

The Twenty Fifteen theme actually uses JS to expand/collapse submenu items, so it needed a patchpatch A special text file that describes changes to code, by identifying the files and lines which are added, removed, and altered. It may also be referred to as a diff. A patch can be applied to a codebase for testing. in 4.3 to re-setup a partial-refreshed main nav menu. In addition to firing the menu container DOM setup logic once at jQuery.ready(), it now invokes the functionality whenever the menu is partial-refreshed. See the initMainNavigation() JS function.

So in general, if your theme needs to dynamically initialize menus with JavaScript, the pattern for the initialization code should be:

jQuery(function($) {
	function initMainNavigation( container ) {
		/* set up container... */
	}
	initMainNavigation( $( '.main-navigation' ) );

	$( document ).on( 'customize-preview-menu-refreshed', function( e, params ) {
		if ( 'primary' === params.wpNavMenuArgs.theme_location ) {
			initMainNavigation( params.newContainer );
			/* optionally sync a previous menu state from params.oldContainer... */
		}
	});
});

The params being passed to the event handler consists of the following properties:

  • newContainer: jQuery object containing the new menu container element retrieved from Ajax; this is what you would manipulate to initialize.
  • oldContainer: the previous jQuery object holding the element for the replaced menu container; this is useful if there is any state in the old menu that should persist in the new menu, such as which submenus are expanded (as in Twenty Fifteen).
  • wpNavMenuArgs: The array of arguments passed to wp_nav_menu() in the template, such as template_location.
  • instanceNumber: The index for which wp_nav_menu() call being updated.

The Future

Partial refresh is an “experimental transport” introduced here specifically for menus. In 4.4 we hope to generalize the framework so that any setting can be setup for fast preview, starting with widgets (see #27355). There is a Customize Partial Refresh feature pluginFeature Plugin A plugin that was created with the intention of eventually being proposed for inclusion in WordPress Core. See Features as Plugins. that implements widget partial refresh in a betaBeta A pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process. state. This partial refresh functionality I’ve also identified as being critical for Customizer Transactions.

#4-3, #customize, #dev-notes, #feature-plugins, #feature-selective-refresh, #kickoff, #menu-customizer, #menus, #partial-refresh, #proposal

Feature Plugin Merge Proposal: Menu Customizer

The Customizer team is proposing to merge the Menu Customizer plugin into coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. for WordPress 4.3. In this post, I’ll outline the purpose and history of this project, as well as highlighting the improvements that we have made.

Purpose & Goals

The purpose of the Menu CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings. project is to move navigation menu management from the WordPress adminadmin (and super admin) to the Customizer. In the process, we hope to offer an updated design with improved user flow, a mobile-first interface, improved accessibilityAccessibility Accessibility (commonly shortened to a11y) refers to the design of products, devices, services, or environments for people with disabilities. The concept of accessible design ensures both “direct access” (i.e. unassisted) and “indirect access” meaning compatibility with a person’s assistive technology (for example, computer screen readers). (https://en.wikipedia.org/wiki/Accessibility), rebuild the administration UIUI User interface from the ground up to be JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/.-driven, solve long-standing problems with the current implementation (#14134), and clarify the purposes and capabilities of the menus feature. Additionally, Menu Customizer contributes significantly to the long-term goal to move all appearance functionality and, really, everything that could benefit from live previewing, from the admin to the Customizer.

Background

Menu Customizer started out as my Google Summer of Code 2014 Project. The initial proposal and revised schedule highlight the initial goals and provide good perspective for where we’ve come in the past year. See also the periodic posts here on make/core for updates. Development has happened on GitHub since the project opened to the community.

Core APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. Improvements

As I began developing this feature in pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party form, it became clear that the core Customizer API would need a lot of improvements to support something as complex as menus. Countless tickets have worked towards this goal over the past year, from the addition of the concept of Panels ( #27406) to JSJS JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors./Underscore-templated controls ( #29572), and now, full support for dynamically-added sections and controls ( #30737, #30738, and #30741).

Developers are still realizing the full potential of the Customizer API, and Menu Customizer pushes the boundaries of what can be done here pretty far. One of the goals with our approach is to bring as much functionality that should be natively available in the API into core as possible. With the improvements made here already, as well as the future potential to continue abstracting functionality like the add-menu-items fly-out panel or the ability to add screen options in Customizer Panels, Menu Customizer broadens the potential for developers to extend the Customizer to do anything, in core, plugins, and themes.

Contributors

In the initial GSoC project, I (@celloexpressions) developed the plugin from scratch, using Widgets in the Customizer as the design basis, with @ethitter and @obenland serving as my mentors. When the project was opened to the community for contributions, several designers and developers stepped up to help. Code contributors to date include @westonruter, @valendesigns, @voldemortensen, @adamsilverstein, and @kucrut. @designsimply and @folletto have also put in a tremendous amount of time helping with design and usability.

Plugin Overview

I highly recommend trying the plugin, which currently requires the latest version of 4.3 alpha. @designsimply has prepared a video demo:

I’ve posted a comparison of the mobile menus flow in the admin and the Customizer on make/flow, and @designsimply has also posted flows there (more flows with more recent versions of the plugin on trunktrunk A directory in Subversion containing the latest development code in preparation for the next major release cycle. If you are running "trunk", then you are on the latest revision. are still needed). Usability testing has been conducted on usertesting.com, with results posted on make/design. As further refinements are made, additional testing and feedback can be incorporated to make the new experience as polished as possible.

A couple of technical details: each menu is a Customizer section, and new menus can be added (dynamically adding new Customizer sections and controls in the process). Menu items are Customizer controls. To maximize scalability, menu items are all rendered using a single JS template, only when their containing menu section is expanded. The add-menu-item panel loads available menu items on an as-needed basis via ajax. The plugin uses several custom Customizer objects including a custom panel that implements screen options, two custom sections (menus, for lazy-loading of menu items, and new menus, which is rendered as a button toggle), and several custom controls. But everything is built off of the core Customizer API.

A summary of some key improvements that the plugin includes:

  • Modernized, simplified, and more compact UI
  • Mobile-first design that leverages the Customizer
  • Scalable, JavaScript-driven and avoids performance issues ( #14134)
  • All menus easily accessible in one place, without page reloads
  • Live previews of active menus as they are edited
  • Menu locations that can be set from the main panel or while editing
  • Global search that includes all post types and terms in all taxonomies
  • Quick-delete for deleting several items sequentially
  • “Original” item links open directly into the live preview
  • The Customizer API can be used to hook into the experience in countless ways with plugins. Support for additional menu item fields can be added much more easily now in a future release, potentially leveraging the Fields API

Core Tickets Fixed

Menu Customizer fixes numerous tickets on core tracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress.. This is not an exhaustive list, but covers many bigger ones:

  • #14134: Menus item are limited to 16 item and will not save more than that
  • #28138: Updating menu item requires passing all of a menu item’s data to wp_update_nav_menu_item() (The plugin steps around this, we can actually fix it in core on merge)
  • #32218: Remove title attribute option in Menu Editor (off by default)
  • #19272: Add FilterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. to Nav Menu Support Themes Text (can modify via Customizer API)
  • #21603: Add ability to delete multiple menu items
  • #16828: Add filter on initial_meta_boxes for nav menu Probably fixed, all are shown currently, which could use improvement but it will default to more being shown at least
  • #19464: Auto add do_action for menu in admin (can use Customizer API)
  • #31391: Make the list of registered nav menus (locations) filterable (can use Customizer API)
  • #32440: on Menu page, turn posts by default on “view options”
  • #18517: Visual Feedback for Nav Menu UI

The Plan for the Menus Component

This project has a very explicit goal of not just adding menu management to the Customizer, but also removing the existing admin page in the process. The menu management screen has significant, fundamental problems in its implementation and will never scale (see #14134) without a significant refactoring along the lines of what we’ve done with the Customizer. Additionally, the new UI in the Customizer is considerably more polished than the admin screen and already includes numerous features and bugfixes proposed for core (see above). Ultimately, the new UI provides a much better experience for all users, including desktop, mobile, accessibility, etc.

The plan for the “removal” of the old menus admin screen is as follows:

  • Immediately and officially “deprecate” it: wind down any ongoing development efforts and focus all new administration-focused Menus component work on the new UI in the Customizer. Update trac tickets accordingly, and add a “Manage in Customize” link to the existing screen. Any existing tickets proposing enhancements or new features for menu administration would be required to be adapted to the Customizer version, with the (discouraged) option of also making changes to the old screen.
  • Point the “Menus” link in the admin bar to Menus in the Customizer in 4.3. Remove that menu from the admin bar in 4.4 in favor of a top-level Customize link, and put something more useful in its place (as all of its core links will point to the Customizer now).
  • Retain the admin screen codebase, along with existing links to it throughout the admin.
  • In WordPress 4.5 or 4.6, remove all core links (including admin menu) to the Menus admin screen, or point them to the Customizer. This would likely coincide with a similar change for Widgets and Themes to use the Customizer versions exclusively, once full feature-parity is achieved with the Customizer versions of the other features (Menus has it now). At this point the admin screen would be accessible only by plugin-added links or for users who cannot access the Customizer (no-js, IE7, IE8&9 with domain mapping, a very small percentage of users overall).
  • The admin screen and related code would likely not be removed entirely from core in the foreseeable future, and critical bugs or security issues would still be addressed. New feature development and enhancements would be restricted to the Customizer version.

The above plan is fairly aggressive, to eliminate any ambiguity about future plans and intentions and to avoid the potential for mass trac ticketticket Created for both bug reports and feature development on the bug tracker. rot. The fact that the Menus component has no maintainers and has not received significant attention since the 3.6 release indicates that there is a general lack of developer interest in dealing with the mess that the current system is. I am willing to step up as a component maintainer for Menus if the above plan is implemented.

Ongoing Work

We have a few issues left that work working on. Notably, @westonruter has proposed refactoring the way menu item settings are handled, along with menu creation and deleted, and has begun work there, but wouldn’t finish until after a core merge due to time constraints and integration with core code. @adamsilverstein is working on improving drag & drop to work with sub menus. There are also several minor issues remaining on GitHub, which would either be handled in the next couplle days or after merge (many issues have been punted to after a potential merge already).

#customize, #feature-plugins, #menu-customizer, #menus, #merge, #proposal

Customize Component Update – 5/25/15

The CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings. team has been busy working on some major user-facing and behind-the-scenes changes targeting WordPress 4.3. This update will provide an overview of our goals, current status, and pathways for contributors to get involved.

We’re planning on holding an extra meeting in #core-customize at 5pm PDT today, 5/25, (May 26, 00:00 UTC) to discuss progress and assignments/plans for the coming week-plus before the feature-pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party merge window opens. This time won’t work for our European contributors but hopefully more of us can make it than can make the old Friday time. (cc @westonruter, @valendesigns, @voldemortensen, @ocean90, @folletto).

Redesigned Customizer Flow/UXUX User experience

Customizer mobile flow redesign walkthrough gif

New Customizer flow introduced in #31336, on a mobile viewport with a recent (not latest) patchpatch A special text file that describes changes to code, by identifying the files and lines which are added, removed, and altered. It may also be referred to as a diff. A patch can be applied to a codebase for testing..

#31336 introduces a re-imagined Customizer experience that clarifies the flow, distinguishes navigation from control UIUI User interface, and improves design through careful adjustments to colors, contrast, and spacing. The primary changes are centered around removing the accordion UI in favor of panel-like horizontal sliding for sections, allowing us to introduce consistent headers across panels and sections to build on the work that was started in 4.2 with the new themes section. Design work for this change was started at the end of 4.0 last August, and @folletto has continued refining the flows since then while I’ve done most of the patching work.

At this stage, we’re trying to get a first-pass patch committed as soon as possible as it’s holding up some of our other priorities including #30737 and Menu Customizer work. We need help testing the patch on different browsers & devices, as well as for any further usability feedback. Once the initial patch is committed, it will be easier to contribute via additional smaller patches.

In addition to this broad UI/UX change, we have several other proposed UI changes being considered for 4.3. Icons for Customizer sections and panels are ready to go pending feedback ( #28504). If time allows and there is enough interest, we could also potentially introduce an improved collapsed mode ( #29949) and device-size preview for the Customizer preview ( #31195) in 4.3. We may also do a full accessibilityAccessibility Accessibility (commonly shortened to a11y) refers to the design of products, devices, services, or environments for people with disabilities. The concept of accessible design ensures both “direct access” (i.e. unassisted) and “indirect access” meaning compatibility with a person’s assistive technology (for example, computer screen readers). (https://en.wikipedia.org/wiki/Accessibility) audit and make fixes accordingly later in the release, per recent discussion on #31336.

Menu Customizer

I just pushed version 0.4, which includes:

  • In-Customizer previewing of “original” menu item links
  • A redesign of the screen options popup
  • The addition of theme location checkboxes within menu sections (which fully cross-sync with the menu locations section)
  • Theme locations listed within menu section names
  • Menus can only be deleted when they aren’t assigned to any locations
  • Available menu item searching, and a first-pass redesign of the available menu items panel to match the new look for coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. in #31336 (more to come here)
  • Integration of the existing theme location controls into the plugin
  • Also notable, I compiled a list of ~10 (and counting) core tickets that Menu Customizer fixes; most notably, #14134

Big thanks to @valendesigns, @folletto, and @voldemortensen for helping out with these changes. We have several major issues to fix still, so please jump in on GitHub if you’re interested in helping out.

Now is also the time for an extensive review process to begin on all fronts, so that we can address any issues in time to make core merge in just a few short weeks. We need several kinds of feedback:

  • General usability feedback
  • Usability testing
  • Accessibility review/feedback
  • Design/UI/UX feedback (test with #31336)
  • Inline documentation review (should be mostly there, but needs a thorough review and cleanup)
  • Code review/cleanup
  • Lead dev/committercommitter A developer with commit access. WordPress has five lead developers and four permanent core developers with commit access. Additionally, the project usually has a few guest or component committers - a developer receiving commit access, generally for a single release cycle (sometimes renewed) and/or for a specific component. review for additional issues

Note that testing should be done with the Menu Customizer plugin and WordPress 4.3 alpha, and that the patch on #31336 is currently a dependency for everything design-related. The plugin can be tested on 4.2 right now, but some pieces of the UI may be a bit off, and we’ll be breaking 4.2-compat in the near future as critical dependencies are merged into core. The most urgent dependencies are #31336 and #30737 (both of which require updates in the plugin and prevent key functionality from working). #30738 and #30741 would be really nice to have, but we can more comfortably hack around those issues at the time of core merge if we have to.

Partial Refresh

@westonruter has finished integrating partial refresh into Menu Customizer (it already worked for widgets), and is now abstracting it one layer further to be available for general use via the APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways.. Partial refresh is an in-between option for setting previewing between doing a full refresh of the preview and fully implementing setting changes in JSJS JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors. via postMessage; settings are previewed by refreshing only part of the preview window.

Other Updates

We’ve made some changes to our component page. Customize is no longer a sub-component of Themes (note the URL change). I also added a summary of our major projects over the past several releases, as well as a brief roadmap/wishlist for future-release projects, and a few routes for getting involved in contributing. @valendesigns and I also triaged the roughly-20 tickets needed a response yesterday, as well as triaging a good chunk of the enhancementenhancement Enhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature. tickets in the component that haven’t had activity in more then 4 months. @valendesigns has also stepped up as another component maintainer, joining @westonruter, @voldemortensen, and myself.

#4-3, #customize, #menu-customizer, #menus

Customizer Chat Summary

Priorities for CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings. development in 4.3:
1) Customizer Concurrency (aka Control Locking)
2) Partial Refresh
3) Menu Customizer
4) Theme Installation
5) UIUI User interface/UXUX User experience changes

Customizer Concurrency doesn’t need much Core changes to implement (except for temp hooks maybe), so it makes sense to remain as a plugin, living here: https://github.com/xwp/wp-customize-widgets-plus
@westonruter aims to have betaBeta A pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process. ready by end of this week.

Partial Refresh is available as a feature plugin and can be tried out now: https://wordpress.org/plugins/customize-partial-refresh/
There are a couple issues still needed for that one and feedback on the APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. for opt-in.

Menu Customizer will be picked back up to have that ready ASAP for merge review (probably needs about a month). @voldemortensen, @valendesigns, @westonruter, and @celloexpressions will all work on dev, as well as anyone else who wants to jump in. @sheri will get started with design review, possibly with help from others (@folletto). The pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party currently works with WordPress 4.1 or 4.2. We can push lots of testing to start happening now since it’s pretty much functionally complete. It just needs a lot of back-end improvements.

Theme Installation and UI/UX changes were not discussed in more detail and will be worked on as time allows after completing the first three items.

Slack logs.

#4-3, #customize, #menu-customizer, #menus

Menu Customizer: Call for Contributors

After a few months off from working on the Menu Customizer to focus on improving the CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings. APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. in coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress., I’m starting to pick up development on the feature-plugin. Now that it’s approaching a reasonably usable state, and is compatible with the latest major releasemajor release A release, identified by the first two numbers (3.6), which is the focus of a full release cycle and feature development. WordPress uses decimaling count for major release versions, so 2.8, 2.9, 3.0, and 3.1 are sequential and comparable in scope. of WordPress (4.1), I’d like to begin efforts to see if we can propose merging it into core for WordPress 4.2.

But there is a lot of work to be done. When Menu Customizer was my GSoC project, it was closed to contributors per GSoC rules. But development is now open to everyone, and I could use a lot of help with both development and non-development tasks. Here’s a list of items that need work:

  •  Development
    • Build-out the core API for adding Customizer sections and controls entirely with JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/., #30741 and its related tickets (PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher, JSJS JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors.)
    • Drag & Drop menu item reordering needs to do sub-menus (code imported from nav-menus.php is commented out in menu-customizer.js currently) (JS)
    • Fix problems with previewing updates to menu items, and with previewing newly-added menus once items are added (JS)
    • Eliminate the PHP closure that currently facilitates menu previewing, for PHP 5.2 compatibility (PHP)
    • Redo the add-menu-items “panel” to lazy-load its contents & utilize Backbone sub-views (PHP, JS)
    • Improve the core Customizer on mobile, then make Menu Customizer work on mobile (CSSCSS Cascading Style Sheets.)
    • Think about an API or otherwise action hooksHooks In WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same. to allow plugins to add menu item fields, #27066, #21898, #18584, etc. (PHP)
    • Inline docsinline docs (phpdoc, docblock, xref) audit, once we’re mostly done (PHP, JS)
    • Comprehensive code review by people like @westonruter, @ocean90, or @nacin, once we’re mostly “done”, preferably before a core merge proposal. Initial code review/cleanup from anyone can start now
  • Design
    • Overall UIUI User interface audit/review, propose changes
    • Consider things like #29158 in relation to how the menus UI looks
    • Discuss approach to screen options (currently an icon in the Menus panel headerHeader The header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitor’s opinion about your content and you/ your organization’s brand. It may also look different on different screen sizes.)
    • UXUX User experience audit, propose changes
    • Evaluate user flows & menus use-cases
    • Conduct user tests
  • Other
    • General user feedback – getting the word out about the pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party and collecting feedback (reviews & support forms on the .org repo would be a good place for feedback). Anyone reading this can try the plugin and provide feedback too 🙂
    • AccessibilityAccessibility Accessibility (commonly shortened to a11y) refers to the design of products, devices, services, or environments for people with disabilities. The concept of accessible design ensures both “direct access” (i.e. unassisted) and “indirect access” meaning compatibility with a person’s assistive technology (for example, computer screen readers). (https://en.wikipedia.org/wiki/Accessibility) audit
    • Backwards-compatibility audit; in particular, assessing whether Menu Customizer could replace the Menus adminadmin (and super admin) screen, and what further features or use-cases would need to be addressed to do so
    • Research the history of the Menus UI in core and document how Menu Customizer addresses ongoing concerns; also consider open tickets in the Menus component (for merge proposal)

Development is happening on the WordPress.orgWordPress.org The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/ plugins repo the a GitHub repo. Some helpful links: create a ticket, Menu Customizer tickets, development log. It’ll probably also be possible to contribute via GithubGitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/ if that’s your preference – talk to @westonruter about how he does it.

This project will primarily take place over the next month, when core development is largely on hold for the holidays and between releases, and when I’m in between semesters at school. The goal is to be merge-ready before the 4.2 feature-plugin merge consideration happens in January. If you’re interested in helping out, please comment on this post or pingPing The act of sending a very small amount of data to an end point. Ping is used in computer science to illicit a response from a target server to test it’s connection. Ping is also a term used by Slack users to @ someone or send them a direct message (DM). Users might say something along the lines of “Ping me when the meeting starts.” me in WordPress Slack in #core (@celloexpressions).

Due to the timing of this project around the holidays, we’ll probably do mostly asynchronous communication, but I would like to try a kick-off meeting in #core SlackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/. on Monday, December 22, 2014 18:00 UTC; please come by if you’re interested!

#customize, #menu-customizer, #menus

JS/Underscore-template-rendered Custom Customizer Controls in WordPress 4.1

The CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings. is a JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/.-driven feature of WordPress coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress., but until recently, most of the APIs for extending it in themes and plugins were PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher-oriented. In WordPress 4.1, we’re introducing more complete JS models for the different UIUI User interface objects that comprise the Customizer. In the process, all controls are now placed into the DOM with JavaScript, rather than being output directly in PHP.

At the same time, we’ve been working on issues of scalability and performance. In particular, bringing the navigation menu management experience into the Customizer has highlighted several areas with room for improvement. With menus, each menu item is a Customizer control with several fields, so a site with hundreds of menu items across different menus will end up sending a lot of repetitive HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. down from PHP, and we currently have to send the full markup for a menu item control down from the server when adding menu items in an Ajax call.

#29572 offered a solution to these challenges: an optional APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. that allows Customizer controls to be written as JavaScript templates. Rather than populating a control’s container with markup rendered on the server and obtained via an Ajax call, we can now use JSJS JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors. templates to render these controls on the client without any server-side call. In the future, new controls could be added dynamically (lazy-loaded, #28580) by leveraging the control-type templates already loaded in the Customizer.

In the remainder of this post, I’ll walk through how to use this API, its benefits, and example use-cases that are already benefiting WordPress core in 4.1.

Registered Control Types

In order to introduce a concept of having one template for multiple Customizer controls of the same type, we needed to introduce a way to register a type of control with the Customize Manager. Previously, custom control objects were only encountered when custom controls were added using WP_Customize_Manager::add_control(). But detecting added control types to render one template per type wouldn’t allow new controls to be created dynamically if no other instances of that type were loaded. So we’ve introduced WP_Customize_Manager::register_control_type(). Usage is simple:

add_action( 'customize_register', '29527_customize_register' );
function 29527_customize_register( $wp_customize ) {
	// Define a custom control class, WP_Customize_Custom_Control.
	// Register the class so that it's JS template is available in the Customizer.
	$wp_customize->register_control_type( 'WP_Customize_Custom_Control' );
}

All registered control types will have their templates printed to the Customizer by WP_Customize_Manager::print_control_templates().

Sending PHP Control Data to JavaScript

While Customizer control data has always been passed to the control JS models, and this has always been able to be extended, you’re much more likely to need to send data down when working with JS templates. Anything that you would want access to in render_content() in PHP will need to be exported to JavaScript to be accessible in your control template. WP_Customize_Control exports the following control class variables by default:

  • type
  • label
  • description
  • active (boolean state)

You can add additional parameters specific to your custom control by overriding WP_Customize_Control::to_json() in your custom control subclass. In most cases, you’ll want to call the parent class’ to_json method also, to ensure that all core variables are exported as well. Here’s an example from the core color control:

public function to_json() {
	parent::to_json();
	$this->json['statuses'] = $this->statuses;
	$this->json['defaultValue'] = $this->setting->default;
}

JS/Underscore Templating, + examples

Once you’ve registered your custom control class as a control type and exported any custom class variables, you can create the template that will render the control UI. You’ll override WP_Customize_Control::content_template() (empty by default) as a replacement for WP_Customize_Control::render_content(). Render content is still called, so be sure to override it with an empty function in your subclass as well.

Underscore-style custom control templates are very similar to PHP. As more and more of WordPress core becomes JavaScript-driven, these templates are becoming increasingly more common. Some sample template code in core can be found in media, revisions, the theme browser, and even in the Twenty Fifteen theme, where a JS template is used to both save the color scheme data and instantly preview color scheme changes in the Customizer. The best way to learn how these templates work is to study similar code in core and, accordingly, I’ll briefly explain an example here now.

class WP_Customize_Color_Control extends WP_Customize_Control {
	public $type = 'color';
// ...
	/**
	 * Render a JS template for the content of the color picker control.
	 */
	public function content_template() {
		?>
		<# var defaultValue = '';
		if ( data.defaultValue ) {
			if ( '#' !== data.defaultValue.substring( 0, 1 ) ) {
				defaultValue = '#' + data.defaultValue;
			} else {
				defaultValue = data.defaultValue;
			}
			defaultValue = ' data-default-color=' + defaultValue; // Quotes added automatically.
		} #>
		<label>
			<# if ( data.label ) { #>
				<span class="customize-control-title">{{{ data.label }}}</span>
			<# } #>
			<# if ( data.description ) { #>
				<span class="description customize-control-description">{{{ data.description }}}</span>
			<# } #>
			<div class="customize-control-content">
				<input class="color-picker-hex" type="text" maxlength="7" placeholder="<?php esc_attr_e( 'Hex Value' ); ?>" {{ defaultValue }} />
			</div>
		</label>
		<?php
	}
}

In the above template for the core custom color control, you can see that after the closing PHP tagtag A directory in Subversion. WordPress uses tags to store a single snapshot of a version (3.6, 3.6.1, etc.), the common convention of tags in version control systems. (Not to be confused with post tags.), we have a JS template. <# #> notation is used around statements to be evaluated – in most cases, this is used for conditionals. All of the control instance data that we exported to JS is stored in the `data` object, and we can print a variable using double or triple brace notation {{ }}. As I said before, the best way to get the hang of writing controls like this is to read through existing examples. WP_Customize_Upload_Control was recently updated to leverage this API as well, integrating nicely with the way the media manager is implemented, and squeezing a ton of functionality out of a minimal amount of code. If you want some really good practice, try converting some of the other core controls to use this API – and submit patches to core too, of course!

Working with Controls in JavaScript

The Customizer has always had an API for working with controls in JavaScript. Now that the Customizer supports JS-rendered controls, this API will be even more useful, as you can do things like re-rendering the entire control if its data changes significantly (think media attachment previewing, for example), rather than doing direct DOM manipulation. Again, the core code is the best place to start getting a feel for this API, but it essentially works like subclasses do in PHP. See @westonruter‘s post for details on how this side of the API has evolved in 4.1, and take a look at the control-related models in wp-admin/js/customize-controls.js.

Putting the pieces together

Here’s a summary of what’s needed to leverage the new API in a custom Customizer control subclass:

  1. Make your render_content() function empty (but it does need to exist to override the default one).
  2. Create a new function, content_template(), and put the old contents of render_content() there.
  3. Add any custom class variables that are needed for the control to be exported to the JavaScript in the browser (the JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. data) by modifying the to_json() function (see WP_Customize_Color_Control for an example).
  4. Convert the PHP from render_content() into a JS template, using <# #> around JS statements to evaluate and {{ }} around variables to print. PHP class variables are available in the data object; for example, the label can be printed with {{ data.label }}.
  5. Register the custom control class/type. This critical step tells the Customizer to print the template for this control. This is distinct from just printing templates for all controls that were added because the ideas are that many instances of this control type could be rendered from one template, and that any registered control types would be available for dynamic control-creation in the future. Just do something like $wp_customize->register_control_type( 'WP_Customize_Color_Control' );.

The PHP-only parts of the API are still fully supported and perfectly fine to use. But, with WordPress 4.0’s decreased need for custom controls, and given our long term goals for making the Customizer more flexible for doing things like switching themes in the Customizer without a pageload, I strongly encourage using this new API for all custom Customizer controls where feasible.

#4-1, #customize, #dev-notes, #menu-customizer, #menus

Toward a Complete JavaScript API for the Customizer

The CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings. is the first true JS-driven feature in core. That’s awesome, especially coming out of WCSF where JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. has been highlighted so prominently between Backbone.js, the WP REST API, Node.js, and socket.io. The Customizer has a great architecture with models for settings, controls, watchable-values, collections, events, and asynchronous callbacks. Nevertheless, the JavaScript APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. in the Customizer is incomplete.

Existing Challenges

When widgets were added to the Customizer in 3.9, adding widgetWidget A WordPress Widget is a small block that performs a specific function. You can add these widgets in sidebars also known as widget-ready areas on your web page. WordPress widgets were originally created to provide a simple and easy-to-use way of giving design and structure control of the WordPress theme to the user. controls to sidebarSidebar A sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme. sections required direct DOM manipulation. For controls there is at least a Control model to manage state For sections and panels, however, there are no JSJS JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors. models at all, and so adding them dynamically is even more of a challenge. And this is the exact challenge that Nick Halsey’s Menu Customizer pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party currently has to struggle through.

When Customizer panels were added in 4.0 to group all widget area sections into a “Widgets” panel, a bug was introduced whereby shift-clicking a widget in the preview no longer revealed the widget control in the Customizer pane because the sections were inside of the collapsed Widgets panel: there were no models to represent the state for whether or not a panel or section were currently expanded. Without models, a fix of this would require more messy DOM traversal to check if parent accordion sections were expanded or not. Storing data in the DOM is bad.

In 4.0 the concept of contextual controls were added to the Customizer. This allowed controls to be registered with an active_callback, such as is_front_page, which the preview would execute and pass back up to the Customizer pane to then show/hide the control based on which URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org was being previewed. This worked well, except when all controls in a section were inactive: then the result was a Customizer section without any visible controls. Instead, the expected behavior would be for the section to automatically collapse as well when all controls inside become inactive. Again, this problem stems from the fact that there is no JS model to represent a section and to list out the controls associated with it.

For the past three weeks I’ve been focused on fleshing out the Customizer API to address these challenges, and to facilitate doing new dynamic things in the Customizer. The parent ticketticket Created for both bug reports and feature development on the bug tracker. for this is #28709: Improve/introduce Customizer JS models for Controls, Sections, and Panels.

Models for Panels and Sections

As noted above, there is a wp.customize.Control model, and then there is a wp.customize.control collection (yes, it is singular) to store all control instances. So to follow the pattern established by controls, in the patch there is a wp.customize.Panel and wp.customize.Section, along with wp.customize.panel and wp.customize.section collections (both singular again). So just as with controls, you can iterate over panels and sections via:

wp.customize.panel.each( function ( panel ) { /* ... */ } );
wp.customize.section.each( function ( section ) { /* ... */ } );

Relating Controls, Sections, and Panels together

When registering a new control in PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher, you pass in the parent section ID:

$wp_customize->add_control( 'blogname', array(
	'label' => __( 'Site Title' ),
	'section' => 'title_tagline',
) );

In the proposed JavaScript API, a control’s section can be obtained predictably:

id = wp.customize.control( 'blogname' ).section(); // => title_tagline

To get the section object from the ID, you just look up the section by the ID as normal: wp.customize.section( id ).

You can move a control to another section using this section state as well, here moving it to the Navigation section:

wp.customize.control( 'blogname' ).section( 'nav' );

Likewise, you can get a section’s panel ID in the same way:

id = wp.customize.section( 'sidebar-widgets-sidebar-1' ).panel(); // => widgets

You can go the other way as well, to get the children of panels and sections:

sections = wp.customize.panel( 'widgets' ).sections();
controls = wp.customize.section( 'title_tagline' ).controls();

You can use these to move all controls from one section to another:

_.each( wp.customize.section( 'title_tagline' ).controls(), function ( control ) {
	control.section( 'nav' );
});

Contextual Panels and Sections

Also just as with controls, when you invoke $wp_customize->add_section() you can pass an active_callback param to indicate whether the section is relevant to the currently-previewed URL; the same goes for panels. A good example of a contextual section is only showing the “Static Front PageStatic Front Page A WordPress website can have a dynamic blog-like front page, or a “static front page” which is used to show customized content. Typically this is the first page you see when you visit a site url, like wordpress.org for example.” section if the preview is currently on the front-page:

function contextual_static_front_page_section( $wp_customize ) {
	$wp_customize->get_section( 'static_front_page' )->active_callback = 'is_front_page';
}
add_action( 'customize_register', 'contextual_static_front_page_section', 11 );

Nevertheless, this will not usually be needed because a section inherits its active state from its control children (and a panel inherits from its section children), via the new isContextuallyActive() method. If all controls within a section become inactive, then the section will automatically become inactive.

As with controls, Panel and Section instances have an active state (a wp.customize.Value instance). When the active state changes, the panel, section, and control instances invoke their respective onChangeActive method, which by default slides the container element up and down, if false and true respectively. There are also activate() and deactivate() methods now for manipulating this active state, for panels, sections, and controls:

wp.customize.section( 'nav' ).deactivate(); // slide up
wp.customize.section( 'nav' ).activate({ duration: 1000 }); // slide down slowly
wp.customize.section( 'colors' ).deactivate({ duration: 0 }); // hide immediately
wp.customize.section( 'nav' ).deactivate({ completeCallback: function () {
	wp.customize.section( 'colors' ).activate(); // show after nav hides completely
} });

Note that manually changing the active state would only stick until the preview refreshes or loads another URL. The activate()/deactivate() methods are designed to follow the pattern of the new expanded state.

Expanded State

As noted above, in 4.0 when panels were introduced, a bug was introduced whereby shift-clicking a widget in the preview fails to show the widget control if the Widgets panel is not already open. With the proposed changes, panels, sections, and (widget) controls have an expanded state (another wp.customize.Value instance). When the state changes, the onChangeExpanded method is called which by will handle Panels sliding in and out, and sections sliding up and down (and widget controls up and down, as they are like sections). So now when a widget control needs to be shown, the control’s section and panel can simply have their expanded state to true in order to reveal the control. Expanding a section automatically expands its parent panel. Expanding a widget control, automatically expands its containing section and that section’s panel.

As with activate()/deactivate() to manage the active state, there are expand() and collapse() methods to manage the expanded state. These methods also take a similar params object, including duration and completeCallback. The params object for Section.expand() accepts an additional parameter “allowMultiple” to facilitate dragging widget controls between sidebar sections. By default expanding one section will automatically collapse all other open sections, and so this param overrides that. You can use this, for instance, to expand all sections at once so you can see all controls without having to click to reveal each accordion section one by one:

wp.customize.section.each(function ( section ) {
	if ( ! section.panel() ) {
		section.expand({ allowMultiple: true });
	}
});

Focusing

Building upon the expand()/collapse() methods for panels, sections, and controls, these models also support a focus() method which not only expands all of the necessary element, but also scrolls the target container into view and puts the browser focus on the first focusable element in the container. For instance, to expand the “Static Front Page” section and focus on select dropdown for the “Front page”:

wp.customize.control( 'page_on_front' ).focus()

This naturally fixes the #29529, mentioned above.

The focus functionality is used to implement autofocus: deep-linking to panels, sections, and controls inside of the customizer. Consider these URLs:

  • …/wp-adminadmin (and super admin)/customize.php?autofocus[panel]=widgets
  • …/wp-admin/customize.php?autofocus[section]=colors
  • …/wp-admin/customize.php?autofocus[control]=blogname

This can be used to add a link on the widgets admin page to link directly to the widgets panel within the Customizer.

Priorities

When registering a panel, section, or control in PHP, you can supply a priority parameter. This value is now stored in a wp.customize.Value instance for each respective Panel, Section, and Control instance. For example, you can obtain the priority for the widgets panel via:

priority = wp.customize.panel( 'widgets' ).priority(); // => 110

You can then dynamically change the priority and the Customizer panel will automatically re-arrange to reflect the new priorities:

wp.customize.panel( 'widgets' ).priority( 1 ); // move Widgets to the top

Custom types for Panels and Sections

Just as Customizer controls can have custom types (ColorControlImageControlHeaderControl…) which have custom behaviors in JS:

wp.customize.controlConstructor.FooControl = wp.customize.Control.extend({ /*...*/ });

So too can Panels and Sections have custom behaviors in the proposed changes. A type parameter can be passed when creating a Panel or Section, and then in JavaScript a constructor corresponding to that type can be registered. For instance:

PHP:

add_action( 'customize_register', function ( $wp_customize ) {
	class WP_Customize_Harlem_Shake_Section extends WP_Customize_Section {
		public $type = 'HarlemShake';
	}
	$section = new WP_Customize_Harlem_Shake_Section(
		$wp_customize,
		'harlem_shake',
		array( 'title' => __( 'Harlem Shake' ) )
	);
	$wp_customize->add_section( $section );
	$wp_customize->add_setting( 'harlem_shake_countdown', array(
		'default' => 15,
	));
	$wp_customize->add_control( 'harlem_shake_countdown', array(
		'label' => __( 'Countdown' ),
		'section' => 'harlem_shake',
		'setting' => 'harlem_shake_countdown',
		'type' => 'number',
	));
});

JS:

wp.customize.sectionConstructor.HarlemShake = wp.customize.Section.extend({
	shake: function () {
		// This can be invoked via wp.customize.section( 'harlem_shake' ).shake();
		console.info( 'SHAKE!!' );
	}
});

Next Steps

  • Continue discussion on parent ticket #28709: Improve/introduce Customizer JS models for Controls, Sections, and Panels.
  • Review JavaScript changes in pull request. Anyone is free to open a PR to onto the existing branchbranch A directory in Subversion. WordPress uses branches to store the latest development code for each major release (3.9, 4.0, etc.). Branches are then updated with code for any minor releases of that branch. Sometimes, a major version of WordPress and its minor versions are collectively referred to as a "branch", such as "the 4.0 branch". on GitHubGitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/ to make changes. Props to Ryan Kienstra (@ryankienstra) and Nick Halsey (@celloexpressions) for their contributions.
  • Update logic for adding widget controls to use new API (adding widgets is using the old pseudo-API and it is currently broken); allow controls to be added manually.
  • Work with Nick Halsey to make sure that dynamically-created sections and controls suit the needs of Menu Customizer, and make sure that it works for other plugins like Customize Posts.
  • Build upon the initial QUnit tests to add coverage for existing JS API and newly added API (#28579).
  • Harden the logic for animating the Customizer panel into view.
  • Get feedback from other CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. devs and get initial patchpatch A special text file that describes changes to code, by identifying the files and lines which are added, removed, and altered. It may also be referred to as a diff. A patch can be applied to a codebase for testing. committed.

Thanks to Nick Halsey (@celloexpressions) for his proofreading and feedback on the drafts of this blogblog (versus network, site) post.

#customize, #menu-customizer, #menus, #widget-customizer

GSoC Menu Customizer Update: Live-previewing Menus

I’ve finished implementing menu-previewing in the Menu CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings. pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party, building on the scalable approach to saving menus that I discussed in my last update. The entire Menus experience is now consolidated into a Menus panel in the Customizer, where you can preview your menus as you make changes. It’s really nice to have Menus easily accessible alongside the rest of the site-appearance-management tools in the Customizer.

I only have about a week and a half left in my GSoC project, and I’m hoping to focus on improving the add-new-menu-item panel in my remaining time, making it scale and implementing the search functionality. I’m also planning on cleaning up the codebase and implementing the ability to manage menu hierarchy (submenus).

If you’re interested in testing the Menu Customizer, and live-previewing changes to your menus, you can get the plugin here. Please note that it currently requires PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher 5.3+, but it’s getting less and less alpha by the day.

Post-GSoC Plans

After the GSoC coding period is over, I’m planning on transitioning Menu Customizer development to the feature-plugin format, gathering a group of interested contributors and holding weekly meetings to coordinate our efforts. While it won’t be ready for coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. consideration by 4.1, and requires some more core Customizer infrastructure to really work well, we’ll continue working on the plugin until menus in the Customizer really shine, and are ready for core.

#customize, #gsoc, #gsoc2014, #menu-customizer, #menus

GSoC Menu Customizer Update: Scalable Menus

Since my last GSoC update, I’ve spent a fair amount of time helping prepare the Customizer for 4.0 beta 1. But I’ve also continued working on the Menu CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings. and have a lot of progress to report.

Add & Delete Menus

You can now add new menus, via the “+ New Menu” section. Added menus currently have some issues, though; you’ll probably need to reload the page before adding items works. The problems stem from the lack of a proper JSJS JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors. APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. for adding, deleting, and managing Sections and Settings (and Panels), and the incompleteness of the existing Control JS API. This will probably need to be resolved in coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. before the Menu Customizer can be considered for core integration, see #28709.

I’ve also implemented a menu-deletion mode, which can be toggled from the add-menu section. It’s too easy to delete menus otherwise, even with an AYS confirming the delete, because deleted menus cannot be restored, and are not “previewed” before being published to the db (added menus aren’t either). It’s probably worth augmenting the AYS to state the menu name being deleted, and to add an extra warning if it’s active in a theme location or a widgetWidget A WordPress Widget is a small block that performs a specific function. You can add these widgets in sidebars also known as widget-ready areas on your web page. WordPress widgets were originally created to provide a simple and easy-to-use way of giving design and structure control of the WordPress theme to the user..

Saving Menus and Menu Item Data in a Scalable Way

In core, menus do not scale well at all. You don’t have to look very deep into the code to see why – massive amounts of data for each item are hidden on the adminadmin (and super admin) screens (much of which never changes) and then must be updated every time a change is made.

Since one of the goals of this project is to experiment with new approaches, I’ve begun implementing a new approach for saving menu data, which is currently in use in the plugin. Thanks to my mentors @ethitter and @obenland for guiding me on the best approach to take here, and @westonruter for the way he implemented the Widget Customizer UIUI User interface, which inspired this exact approach. Here’s how it works:

  • Each menu has a nav_menu Customizer control that contains an ordered array of numerical menu item ids (known throughout the core menus codebase as their db ids).
  • When an item is added, it is created as an orphaned draft via ajax, and its id is added to the nav_menu setting’s array.
  • When an item is deleted, its id is removed from the nav_menu setting’s array.
  • When menu items are reordered, the order of ids in the nav_menu id is updated to match.
  • When menu items are moved into and out of sub-menus, the parent menu item id is updated in the individual item’s data (not yet implemented).
  • When a menu item field is changed (by default, this would mean changing the label or, for custom items, url fileds; there are screen options for several others), the original item is cloned and the copy is updated with the new data, using a wrapper for wp_update_nav_menu_item() that doesn’t require passing all existing (unchanged) menu item data. The cloned item’s id is returned and replaces the original id in the nav_menu setting (thereby marking the original item for deletion). Additional changes are saved to the cloned item until the settings are saved, at which point all items are marked for a new clone to be created if changes are made (not yet implemented).
  • When the user saves their changes from the Customizer (via the customize_update_nav_menu action), the array of ids is compared to the currently-published menu’s items. If there are items that are no longer present, those are marked for deletion. For each of the new ids, the corresponding menu item (which already exists) is updated to be published, assigned to the corresponding menu (for the new items created as orphaned drafts), and the item’s menu_order is set to the id’s position in the nav_menus setting array. Finally, all of the removed items are deleted.

While menu previewing in the customizer is not yet implemented, it will also be able to use the nav_menu setting’s array of ids to display an augmented set of menu items. I’m also still working on ensuring that menu item data is not posted during the customize-save ajax, but the data isn’t needed so we’re most of the way there already.

UI Aside

customize-header-bigflat-buttons-close

Quick aside: @DrewAPicture pointed out in IRC that the new Customizer close and panel-back icons don’t really match the save button. I’ve done some rough explorations of potential alternatives; if anyone’s interested in discussing them and possibly implementing a change here, feel free to pingPing The act of sending a very small amount of data to an end point. Ping is used in computer science to illicit a response from a target server to test it’s connection. Ping is also a term used by Slack users to @ someone or send them a direct message (DM). Users might say something along the lines of “Ping me when the meeting starts.” me in IRCIRC Internet Relay Chat, a network where users can have conversations online. IRC channels are used widely by open source projects, and by WordPress. The primary WordPress channels are #wordpress and #wordpress-dev, on irc.freenode.net. (@celloexpressions) and/or create a ticketticket Created for both bug reports and feature development on the bug tracker. and/or comment here.

Finally, I’m hoping to finish implementing menu previewing by the end of this week, fully utilizing the Customizer. Once this is done, I’ll essentially be at feature-complete stage (other than some little details and several known bugs) and ready to iterate (I’m already planning on working on the add-menu-items backend, as it currently doesn’t scale).

#customize, #gsoc, #gsoc2014, #menu-customizer, #menus