Week In Core, June 7 – June 15 2016

Welcome back the latest issue of Week in Core, covering changes [37659-37720]. Here are the highlights:

  • 62 commits
  • 67 contributors
  • 61 tickets created
  • 15 tickets reopened
  • 80 tickets closed

Ticket numbers based on trac timeline for the period above. The following is a summary of commits, organized by component.

Code Changes



  • Set a defined line-height for number type inputs to fix display issue in Safari. [37693] #37024


Bundled Theme

  • Twenty Ten: Revert pot changes after update test.[37715]



  • Do not flag a comment as a duplicate if the comment_author_email is provided but not a match. [37713] #37093
  • Fix pagination totals in the response of the inline delete actions when filtering the List Table by comment_type. [37664] #36991


  • Ensure MediaControl fetches the necessary attachment data for rendering when dynamically added via JS. [37701] #36521
  • Update server-sent setting validation notifications as changes are entered. [37700] #36944


  • Prevent jumping when using the backspace button in the Text editor in Firefox and IE. [37684] #37072
  • quickTags: when the user selects some text by triple-clicking, then wraps it in a tag, and the last selected char is \n, insert the closing tag before the line break. [37661] #29571
  • Adjust the sidebar position when moving a postbox from one column to another. [37659] #35230



  • Docs: Add extensive documentation to the remove_accents() DocBlock outlining the accented characters core replaces. 37669] #34677


  • After [37702], correct the expected result in test_size_format(). [37705] #37037
  • In size_format() and wp_convert_bytes_to_hr(), replace kB with KB for consistency with other units. [37702] #37037
  • Docs: Replace HTTP links with HTTPS. [37674] #36993
  • Docs: Improve the DocBlock summary for add_theme_support(). [37673] #32246
  • Docs: Add documentation for the variadic second parameter, $args, accepted by add_theme_support(). [37672] #37067
  • Docs: Improve documentation for the $feature parameter in the DocBlock for add_theme_support(). [37671] #32246, #37067



  • Revert the test added in [37716], as it causes errors when running the full suite. [37718] #36790
  • Adjust the regex in wp_maybe_decline_date() to handle word boundaries correctly. [37717] #36790
  • Add a unit test for wp_maybe_decline_date(). [37716] #36790
  • Add context and translator comments to Back to %s strings. [37703] #37095
  • In remove_accents(), add support for de_CH and de_CH_informal. [37698] #37076
  • Simplify the WordPress update notice for translators. [37675] #35721

Login and Registration

  • Fire wp_no_robots() in wp_die() only if function exists. This covers cases where wp_die() is used before general-template.php is loaded. [37689] #34401


Networks and Sites

  • Docs: Update the documentation for get_site() and the get_site filter following the removal of the $output parameter in [37652]. [37699] #35791
  • Use to_array() method on WP_Site objects in wp_get_sites(). [37667] #36717
  • Introduce get_current_network_id(). [37670] #33900
  • Tests: Split get_blog_details() test into individual tests [37666] #36566
  • Tests: Move get_blog_details() tests to their own file [37665] #36566
  • Tests: User a data provider for wp_get_sites() tests. [37662] #36566
  • Tests: Move wp_get_sites() tests to their own file [37660] #36566
  • Avoid a PHP notice in get_permalink() if default category is unavailable. [37707] #36529


  • Normalize WP_PLUGIN_DIR in the test added in [37332], otherwise it fails on Windows. [37719] #29154
  • Fix edge-case where the tab=upload page can be accessed directly. [37681] #35429

Posts, Post Types

  • Docs: Improve the return description for wp_get_post_categories() to include more information about possible return values. [37686] #37002


  • After [37692], don’t skip set_found_posts() when no posts are found. [37712] #36687
  • Allow plugins to supply post results instead of having WP_Query fetch them from the database. [37692] #36687
  • Docs: Improve first-order clause documentation for the $meta_query parameter in the constructor for WP_Meta_Query. [37688] #32659


  • Introduce a redirect_term_location filter to change the redirect on term editing. [37696] #36367
  • More specific cap check when processing category data on post save. [37691] #36379
  • Introduce term_taxonomy_id parameter for WP_Term_Query. [37683] #37074
  • Tests: Move WP_Tax_Query tests to a more appropriate file. [37682] #37074

Text Changes

  • Text Changes: Simplify two strings in wp_password_change_notification(). [37704] #35736


  • Make default “read more” link more accessible. [37706] #36572




  • Embeds: In WP_oEmbed::get_provider() and WP_oEmbed::get_html(), parse the $args string to an array, as we treat it as an array later. [37720] #37071
  • wp_signon() expects an array as the $credentials argument, not a string. [37697] #37071
  • Stop WP_List_Table notices from persisting on pagination navigation. [37663] #35620

Thanks to @flixos90, @adamsilverstein, @AdamSoucie, @afercia, @afragen, @alexvandervegt, @azaozz, @boonebgorges, @dashaluna, @dd32, @dlh, @DrewAPicture, @EFAREM, @ethitter, @flixos90, @grapplerulrich, @Ipstenu, @iseulde, @j-falk, @jeherve, @jeremyfelt, @jipmoors, @jnylen0, @joelwills, @joemcgill, @john_schlick, @johnbillion, @johnjamesjacoby, @johnpgreen, @joostdevalk, @jorbin, @JoshuaGoodwin, @azaozz, @jpdavoutian, @Kau-Boy, @khag7, @kraftbj, @mapk, @melchoyce, @michael-arestad, @obenland, @ocean90, @odysseygate, @pansotdev, @paulwilde, @pento, @peterwilsoncc, @Presskopp, @rachelbaker, @ramiy, @ramiy, @rmccue, @ronalfy, @ryelle, @semil, @SergeyBiryukov, @simonvik, @spacedmonkey, @stephdau, @svovaf, @swissspidy, @TimothyBlynJacobs, @tlovett1, @westonruter, and @zakb8 for their contributions!

#4-6, #week-in-core

Shiny Updates Chat Summary 5/17/16

This is a summary of the shiny updates chat from May 17. (Slack log)

Attendees: @ocean90, @swissspidy, @j-falk, @mapk, @ethitter, @obenland


  • Accomplished work since last week
    • Review requests were posted to the Accessibility, Flow, Polyglots, and Design teams.
    • The feature project landing page was written and published.
    • @swissspidy merged update-core.php into master.
    • Lots of bug fixes and smaller enhancements went in.
  • Activate after install
    We discussed what the best way would be to provide users with the ability to activate a plugin after it was installed. @swissspidy offered to work on a way that would switch the install button to an activation link after the install queue emptied, so it can be user tested for a more informed decision.
  • Update core
    @swissspidy‘s update-core work was merged into master, where it will remain to receive a broader test coverage than it would in a branch. All updates (except for ‘update all’ button) work via ajax.
  • Open floor
    We decided on a new meeting time, 20:00 UTC, that is one hour later than before.

Next meeting is therefore on Tuesday May 24, 20:00 UTC.

#4-6, #shiny-updates, #upgrade-install

Shiny Updates Chat Summary 5/3/16

This is a summary of the shiny updates chat from May 3. (Slack log)

Attendees: @ocean90, @swissspidy, @ethitter, @adamsilverstein, @mapk, @obenland


  • Accomplished work since last week
  • Remaining work
    @obenland will work on the Shiny Updates landing page for feature projects and fix a bug that were discovered during the most recent user test. @mapk offered to conduct another user test focused on the new interactions with some learnings from the previous one. Goal is to identify any hiccups or behaviors that are unexpected to users. @swissspidy wants to continue working on update-core.php and see if we can get it into shape for 4.6.
  • Most recent user tests
    We briefly talked about the most recent user test (linked above). It showed a variety of bugs that @obenland initially assumed were based on being in subviews of the plugin list. After the meeting it turned out that the test site ran an outdated version of WordPress that didn’t include some of the date that Shiny Update needs to work. It was a good demonstration of progressive enhancement here though, as all actions still worked, they just weren’t shiny. More user tests to come, to make sure that users agree with the new interactions.
  • Schedule for 4.6 inclusion
    Next up is writing the merge proposal that was requested to be published around 6/1, definitely before 6/8.

Next meeting is on Tuesday May 10, 19:00 UTC.

#4-6, #shiny-updates, #upgrade-install

Shiny Updates Kickoff for 4.6 Chat Summary

This is a summary of the shiny updates chat from April 26. (Slack log)

Attendees: @ocean90, @swissspidy, @ethitter, @adamsilverstein, @karmatosed, @obenland


  • Remaining work
    On the updates-core.php side there is quite a bit of work remaining. On the plugin/theme management part outside of that, there is actually fairly little work remaining.
    Since the two parts vary in their readiness so much, it was proposed to go ahead with the theme/plugin management part and propose that for 4.6, while leaving the rest to be continued to be iterated on.
  • More user tests
    @obenland will reach out to @mapk and @karmatosed to get a final round of user tests in, to make sure the new workflows are up to par.
  • update-core.php changes
    Autoupdate settings will be pulled as they are not ready to be worked on yet. @swissspidy volunteered to work on #5, mainly merging the three tables and adding JS handlers for core and language updates.
  • Schedule for 4.6 inclusion
    Core patch should be ready by June 1 for merge on June 8. The remaining time is for creating visual records, user tests, and a merge proposal.

Next meeting is on Tuesday May 3, 19:00 UTC.

#4-6, #shiny-updates, #upgrade-install

Week in Core, Feb. 16-23 2016

Welcome back the latest issue of Week in Core, covering changes [36671-36541]. Here are the highlights:

  • 131 commits
  • 82 contributors
  • 89 tickets created
  • 9 tickets reopened
  • 140 tickets closed

Ticket numbers based on trac timeline for the period above.

Note: If you want to help write the next WordPress Core Weekly summary, check out the schedule over at make/docs and get in touch in the #core-weekly-update Slack channel.

Code Changes


  • Improve the color contrast ratio for the input placeholders. [36619] #35777
  • Remove title attributes from the Plugin details modal. [36618] #35111
  • Remove the revisions limit warning from the Publish box. [36612] #35029
  • Fix displaying of Universal time and Local time info on the General Settings screen. [36585] #35064
  • Improve color contrast updating any #999 gray used for text or icons to a darker gray. [36587] #35660
  • Accessibility: after [36000] conditionally print out the aria-describedby attribute on the Featured Image postbox. [36584] #35076
  • Accessibility: Reduce the WordPress shades of grey, Episode 2. [36582] #35783


  • Replace the custom comment form with comment_form() and reduce number of links. [36595] #35888
  • Remove extra spaces between function names and brackets [36572] #16774, #34365
  • Remove slashes from search terms and use urldecode() in non-URL contexts. [36560] #35712


  • Allow users to log in using their email address. [36617] #9568


  • Do not strip slashes from the whole &_POST when doing autosaves. [36543] #35408


Build/Test Tools


  • Rename $linea to $remote_source for clarity. Add remote_source to comment data, so it’s available to preprocess_comment and comment_post filters. Pass the original (unfiltered) response source to the filters too (as remote_source_original in comment data). [36661] #34141
  • Pass comment data to the comment_post filter. [36660] #34141
  • Look for wp_error when checking whether $wpdb->get_col_length() has failed. [36542] #10377
  • Refresh the Moderate Comment screen for a friendlier experience with email moderation actions. [36588] #34133


  • Let WP_Customize_Selective_Refresh class be final to match manager and other component classes. [36624] #27355
  • Ensure dynamic_sidebar() finishes with removing the sidebar ID from the current_dynamic_sidebar_id_stack. [36623] #27355
  • Prevent dropping backslashes from input on general settings and settings for nav menus and some widgets. [36622] #35898
  • Fix and extend broken ajax unit tests to account for partials being skipped from rendering. [36650] #35914
  • Skip exporting partials to client and handling rendering requests if user can’t modify associated settings. [36643] #27355, #35914
  • Add visual feedback to reorder buttons. [36641] #35041
  • Contain “No image set/selected” in dashed border. [36639] #35826
  • Update unit test for WP_Customize_Nav_Menu_Item_Setting::value_as_wp_post_nav_menu_item() to account for slashing if user can’t unfiltered_html. [36610] #35869
  • Prevent PHP notice and JS error caused by widgets and nav menus components if user only has customize capability. [36611] #35895
  • Fix previewing and updating of nav menu items containing slashed/slashable characters. [36608] #35869
  • Fix “Loading…” message from persisting in panel title when user does not have manage_options cap to edit blogname. [36606] #35579
  • Add selective refresh framework with implementation for widgets and re-implementation for nav menus. [36586] #27355
  • Prevent consecutive refresh requests from preview from causing JS error. [36583] #27355, #35866
  • In nav menus show the location name instead of slug. [36573] #34755
  • Add missing test changes for [36573]. [36574] #34755
  • Autoprefixer for [36532]. [36548] #31195


  • Correct $number type in number_format_i18n(). [36644] #35893
  • Update the type for $callback parameters to callable in DocBlocks for add_settings_section() and add_settings_field(). [36642] #35772
  • Improve documentation for WP_REST_Request to highlight a caveat of ArrayAccess when it comes to passing similar arguments for multiple request methods. [36636] #35799
  • Improve description of get_term() return value. [36634] #35919
  • Correct param types on some filters in wp_filter_comment(). [36626] #35908
  • WP_Meta_Query accepts ‘EXISTS’ or ‘NOT EXISTS’ for $compare. [36609] #35891
  • Fix two incorrect notations of the $show_admin_bar global to specify a boolean type, not WP_Admin_Bar. [36601] #35686
  • Add missing since and access tags to get_curies method and filter from r36533 [36593] #34729, #32246
  • Add an explanation for the dynamic portion of the {$taxonomy}_term_edit_form_top hook, introduced in [36526]. [36577] #32246
  • Add formatting to a changelog entry in the hook doc for the rest_dispatch_request filter. [36576] #32246
  • Remove a duplicate @static tag from the WP_Customize_Panel->instance_count property DocBlock. [36568] #32246


  • Only display an iframe when it was successfully loaded. This prevents showing a blank iframe by first checking if a message was successfully received from it. [36648] #35894
  • Make the click event handler work for dynamically added links. [36637] #35630
  • Load the default site icon from the wp-includes directory. [36635] #35322

External Libraries

  • Update Backbone and Underscore to the latest versions. [36546] #34350



  • Avoid a PHP warning when wptexturize() is called with a trailing less-than symbol. [36578] #35864



  • Certificate bundle: Attempt to move a certificate lower in the file to allow older OpenSSL versions to parse it & communicate with WordPress.org securely again. The OpenSSL version which was failing in this case was OpenSSL 0.9.8e 23 Feb 2007. [36570] #35637, #30434, #25007


  • Add translator comments and context to “New Site Created” email notification strings. [36669] #35716
  • Replace hardcoded URL in a translatable string with a placeholder in wp-admin/upload.php. [36668] #35743
  • Add missing periods to two strings in wp-admin/network/sites.php [36664] #35720
  • Add translators comments to wp-admin/users.php. [36621] #35885
  • Remove HTML tags from translatable strings in wp-admin/plugins.php. [36662] #35679
  • Add the ability to parse a whole directory with add-textdomain.php. [36600] #35499
  • Remove PHP4 constructor from add-textdomain.php. [36599] #31982
  • Add test for wp_dropdown_languages(). [36631] #35294
  • Respect the coding standards when adding textdomains with add-textdomain.php. [36603] #21616
  • Remove tag from translatable string in wp-admin/includes/class-wp-filesystem-ssh2.php. [36670] #35741
  • Remove tag from translatable string in wp-admin/includes/class-wp-ms-sites-list-table.php. [36663] #35676
  • Remove tag from translatable string in wp-admin/theme-install.php. [36666] #35739
  • Remove tag from translatable string in wp-admin/options-general.php[36656] #35673
  • Remove tags from translatable strings in wp-admin/install.php. [36665] #35738
  • Remove tags from translatable strings in wp-admin/custom-header.php[36658] #35675
  • Remove tags from translatable strings in wp-admin/themes.php. [36657] #35745
  • Remove tag from translatable string in wp-admin/user-edit.php[36655] #35672
  • Remove tag from translatable string in wp-admin/import.php[36653] #35671



  • Ensure backslashes are saved in menu item fields. [36613] #14134


  • Make view mode sticky for network users and sites list tables. [36562] #34365
  • Avoid a PHP Notice when saving a site address without a path. [36561] #35631


  • In wp_upload_dir() do not cache error from wp_mkdir_p() when a directory cannot be created. Keep trying to create the dirs. This happens mostly in file upload context. [36628] #34359
  • Replace wp_upload_dir() with the new wp_get_upload_dir() in all cases where a file is not being uploaded. Deprecate _wp_upload_dir_baseurl(), and replace it with wp_get_upload_dir(). [36569] #34359
  • Reintroduce term meta unit test accidentally removed in [36566]. [36567]
  • More performance improvements to metadata lazyloading. [36566] #35816
  • Improve the performance of wp_upload_dir(): [36565] #34359



  • Introduce get_post_types_by_support(). Similar to get_post_types(), this new function returns a list of post type names that support a specific feature. [36652] #34010
  • Non-trashed posts should take slug priority over trashed posts. [36607] #11863


  • Search should match post_excerpt in addition to title and content. When ordering search results, exact matches in the post excerpt are weighted above those in post content, but below those in the post title. [36647] #35762
  • Allow a seed value to be passed when using ‘rand’ $orderby. [36632] #35692
  • In WP::handle_404() introduce a filter pre_handle_404 to short-circuit default header status handling. [36629] #10722
  • is_*( $int ) should not falsely match strings starting with “$int”. [36625] #24674, #35902



Script Loader

  • Don’t parse $src if the current color scheme isn’t registered. [36591] #35882
  • Pass the media attribute as an argument to the style_loader_tag filter. [36592] #34765
  • Bail if WP_Styles::_css_href() returns an empty value. [36590] #35229
  • Make sure that inline styles for handles without a source are printed. [36550] #35229
  • JSHint for [36602]. [36605] #33301
  • Fix missing script output when the groups of dependencies are different. [36604] #35873
  • Introduce wp_add_inline_script(). [36633] #14853
  • Restore loading order for wp-admin: open-sans, dashicons, etc. [36551] #35229


  • Clarify the allowed values for the $media parameter of wp_register_style()/wp_enqueue_style(). [36649] #35921


  • Make $taxonomy parameter optional in get_edit_term_link(). [36646] #35922
  • Allow get_terms() to fetch terms regardless of taxonomy. [36614] #35495
  • In get_terms(), assemble WHERE conditions in an array instead of concatenating. [36598] #35495
  • Add changelog entry for publicly_queryable argument in register_taxonomy(). [36564] #34491





  • Pass locales of all available languages to the themes/plugins update API. [36630] #34937


  • Prevent further actions if an update button is disabled. [36558] #35257
  • Add a hook to the end of the network’s Add New User form. [36556] #15389
  • Add a hook to the end of the Add Site form. [36555] #34739
  • Enhance the language of the “Success” message. [36553] #34897
  • Improve wording on the page for the database connection details. [36545] #26879
  • Use “Username” instead of “User Name”. [36544] #35850


  • Pass the array of user IDs being deleted to the delete_user_form action hook in two places. [36640] #35063
  • Introduce _wp_get_current_user() for improved backward compatibility. [36651] #19615


  • Avoid a PHP notice in is_dynamic_sidebar() is a sidebar is registered but does not yet have an index in the sidebars_widgets option. [36667] #35928


Thanks to @dnewton,@joemcgill, @abiralneupane, @adamsilverstein, @afercia, @aidanlane, @Ankit, @apaliku, @atimmer, @azaozz, @barryceelen, @boonebgorges, @charlestonsw, @chris_dev, @ckoerner, @coffee2code, @coreymcollins, @danielbachhuber, @dd32, @Denis-de-Bernardy, @dlh, @DrewAPicture, @dshanske, @ericlewis, @ethitter, @flixos90, @GaryJ, @gitlost, @groovecoder, @Gupta, @hakre, @helen, @hlashbrooke, @iamntz, @igmoweb, @iseulde, @JamesDiGioia, @jdgrimes, @jeremyfelt, @JoeFusco, @joehoyle, @johnbillion, @jorbin, @K, @karmatosed, @kjbenk, @kovshenin, @lpawlik, @mayukojpn, @mdgl, @meitar, @melchoyce, @MikeHansenMe, @mikejolley, @mikeschroder, @netweb, @nicd, @ocean90, @pento, @prettyboymp, @ptahdunbar, @rachelbaker, @ramiy, @realloc, @ryan, @ryankienstra, @salcode, @sc0ttkclark, @sebastianpisula, @SergeyBiryukov, @stevegrunwell, @stevenkword, @swissspidy, @thewanderingbrit, @thisisit, @usermrpapa, @valendesigns, @vhomenko, @welcher, @westonruter, @williamsba1, and @wpsmith for their contributions! for their contributions!

#4-5, #week-in-core

Feature Plugin Merge Proposal: Menu Customizer

The Customizer team is proposing to merge the Menu Customizer plugin into core 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 Customizer project is to move navigation menu management from the WordPress admin to the Customizer. In the process, we hope to offer an updated design with improved user flow, a mobile-first interface, improved accessibility, rebuild the administration UI from the ground up to be JavaScript-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.


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 API Improvements

As I began developing this feature in plugin 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 JS/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.


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:

[wpvideo xdKZ9CeM]

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 trunk 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 trac. 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 Filter 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 ticket 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

Multisite Office Hours (Redux)

Several months ago, @wonderboymusic proposed office hours for Multisite. The response was great, but we kind of laxed on making it happen after the first one or two.

After talking with a few people at WCSF last month, I’d like to fire this up again. As Scott mentioned before, there is no master plan, though there is a roadmap.

We do have some interesting things that should be on the front of our minds:

  • What does a trusted network look like? #30145 introduced the concept and we need to figure out where to take it.
  • What kind of improvements could/should be made with a “feature as a plugin”? This may help to jump start some ideas, even if they aren’t merged into core immediately.
  • What steps should we take toward multi network? #29415 comes to mind immediately for a likely inclusion in 4.2. #30294 is another example.
  • Unit tests. I’d like to continue doing things like #30080 to really expand how we’re testing multisite.

Let’s do our first office hours at 20:00 UTC this coming Tuesday (November 25). We can decide then if it’s appropriate.

/cc’ing some that are likely interested – @ethitter, @johnjamesjacoby, @johnbillion, @ipstenu, @earnjam – but this is by no means a complete list.

Please stop by in #core on Tuesday and comment away on this post with other things you have your eyes on.


Feature Plugin Chat on September 23

Last week we mentioned holding a feature plugin chat today, but that didn’t happen. Let’s have it next week on September 23 2014 20:00 UTC.

We’ve done this before, but just to recap…

If you have an idea for a new feature, this will be a great opportunity to bring it up and find others interested in helping out.

Please leave one comment per feature idea with the following information:

  • A brief (one paragraph) overview of your feature plugin proposal.
  • Current plugin status (idea stage, planning stage, under development, existing feature plugin, prior work, etc).
  • A list of those involved or already interested in your feature plugin (including you!)
  • What you’d like help with (scoping, planning, wireframing, development, design, etc).

This post and the accompanying chat are for posting ideas that you’d be interested in working on. It is not for posting every feature idea you have for WordPress.

Current feature plugin leads: Please post an update for your plugin here, along with the information above.

See you all at the chat!

#core-plugins, #feature-plugins

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 Customizer 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 JS API 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 core 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 widget.

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 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 UI, 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


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 ping me in IRC (@celloexpressions) and/or create a ticket 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

Last Weeks in WordPress Core

Hi! This is a late Last Week in WordPress Core for the two weeks of March 17-30. Lots going on as we approach RC.

Beta 3 is out, and you can check out the release post here. There are a few big things that have landed that are included. In particular, please test video and audio playlists by uploading more than one file of either, and check to see if you see any oddities in quote formatting, as much of wptexturize() was revamped.


  • Theme Installer: Restore the feature filter, improve responsiveness, update router, make ‘Upload Theme’ button more consistent with the admin, and avoid theme-count causing filters to jump. [27636] #27055
  • Theme Installer: Bring keyboard accessibility to the theme install screen and theme action buttons. [27804] #27521
  • Dashboard: Restore the update message in the dashboard that was removed in 3.8. [27711] #26664
  • Distraction Free Writing: Allow the fullscreen editor’s content area to be responsive. [27821] #27569
  • Accessibility: Better focus styles for form elements in the admin. [27741] #27173

Widget Customizer:

  • Restore highlighting of widgets in preview. [27584] [27702] #27358
  • Use WP_Error for errors, and add handling for when user is missing cap to change widgets or is logged out. [27652] #27419


  • Introduce HTML5 caption support: When supported by a theme via add_theme_support( 'html5', 'caption' ), use figure and figcaption instead of div and p. With HTML5 captions, no longer include extra 10 pixels within inline styles. img_caption_shortcode_width is skipped when the theme supports HTML5 captions. [27668] #26642 #9066
  • On attachment pages for audio and video, add support for players. [27622] #27243
  • Default Themes: Improve accessibility for keyboard and voice-over interactions. [27594] #27147 [27606] [27607] #24839
  • Default Themes: Update editor styles for A/V and Galleries. [27638] [27637] [27641] #27462
  • Default Themes: Enable thumbnail support for attachment:audio and attachment:video. Check for theme OR post type support when determining whether to enable Featured Image UI in the admin. [27657] #27460


  • There is no more video-playlist shortcode. To use video, it is now [playlist type='video' ...]. Core playlist styles removed; the style attribute is still supported, defaulting to light. [27785] [27812] #27552
  • Only enqueue the media modal image editor within the admin. [27625] #21811
  • Support a caption attribute for audio and video shortcodes. [27640] #27320
  • Create a new file, media-audiovideo.js, to house all of the audio and video JS code in core, and improve UX. [27608] [27631] #27437
  • With Plupload, switch to urlstream upload method when the flash runtime is used in non IE browsers. This ensures cookies are sent but limits the maximum file size that flash can handle. By default only IE9 and older use flash, so it would only affect things if a plugin disables the html5 runtime. [27662]
  • Provide a metabox to edit audio metadata (initially from ID3) on the “Edit Media” page. [27862] [27862] [27864] [27869] #27574.


  • Update TinyMCE to 4.0.20. [27603] #24067
  • Update tests. It’s now possible to run most TinyMCE tests directly from the cli using PhantomJS. [27679] [27680] #27014
  • Playlist Preview: Support playlist views in TinyMCE. [27640] #27320
  • Edit Image Modal: Bring back some of the advanced settings. [27797] #27366


  • Masonry: Update Masonry v2/v3 shim from upstream. [27779] [27780] [27781] #27510
  • Texturize: Massive performance improvements (~600% faster); better handling of braces, nbsp, double, and weird spaces; 136 new unit tests. [27839] [27844] #22692
  • Cookie Session Checks:: Only show test cookie warnings on submit as caching/proxies may intercept the test cookie for GET requests. Introduce a new string for when headers are sent and link them to a new Cookies page on the codex. [27859] #27373
  • Object Cache:: Introduce pre_update_option filter, available in update_option(). Allows filtering of any option before its value is (maybe) serialized and updated. [27815] #27504
  • wpautop: Remove select and input from wpautop()‘s HTML blocks list. [27761] #22230
  • Heartbeat: Hooks should always receive unslashed data. This affects the privileged hooks; the unprivileged hooks already did so. [27576] #27260
  • Customizer: Use esc_url_raw to escape customizer URL settings to prevent double encoding. [27574] #26569
  • Template: Encode spaces in get_template_directory_uri() and get_stylesheet_directory_uri(). [27710] #21969
  • Filesystem: Fix getchmod() for direct and ssh2 transports, for directories. [27566] #26598
  • Text/i18n Cleanup: Many text changes and updates. Check out all of them in the full log on Trac.
  • i18n: In is_serialized(), use substr() rather than array access, for compatibility with multibyte overloading. [27565] #18007
  • Postmeta: Return false from metadata_exists() if the get_$type_metadata filter returns a false value. [27562] #22746
  • Pagination: Introduce before_page_number and after_page_number arguments for paginate_links(). [27600] #24709
  • E-mail: Always decode special characters for email subjects. [27801] #25346
  • WP Class: Add post_parent to the private query vars list. Fixes detached media queries. [27782] #27532.
  • Post: Use wp_parse_id_list() when parsing exclude_tree in get_pages(). Ensure a URL string, array with string as value, and array with array as value for exclude_tree can be used to specify multiple IDs. [27767] #9153



  • Introduce a ms_site_not_found filter to replace NOBLOGREDIRECT. Bail if there’s no site. [27663] #21143; #27003
  • In multisite load, cache the main site lookup query. [27664] #27003
  • Ensure the $path is trailing-slashed in domain_exists(). [27717] #20589

For the complete list of commits to trunk, check out the log on Trac. Interested in helping close out the release? Write or test a patch for 3.9.

Thanks to @adamsilverstein, @adelval, @afercia, @aliso, @aubreypwd, @avryl, @azaozz, @barry, @bcworkz, @celloexpressions, @cgaffga, @Chouby, @chriseverson, @chrisguitarguy, @cramdesign, @danielbachhuber, @dannydehaan, @DavidAnderson, @DrewAPicture, @drozdz, @dustyf, @eatingrules, @ehg, @eightface, @ejdanderson, @eliorivero, @empireoflight, @ericlewis, @ericmann, @ethitter, @fahmiadib, @frank-klein, @gcorne, @grahamarmfield, @GregLone, @hakre, @helen, @jackreichert, @janw.oostendorp, @jartes, @jbkkd, @jdgrimes, @jeremyfelt, @joedolson, @johnbillion, @jorbin, @kawauso, @kovshenin, @kpdesign, @kwight, @lancewillett, @lkwdwrd, @markjaquith, @mattheu, @mattonomics, @matveb, @mauryaratan, @mcsf, @melchoyce, @MikeHansenMe, @miqrogroove, @mordauk, @nacin, @Nao, @Nessworthy, @nofearinc, @obenland, @ocean90, @paulwilde, @pavelevap, @pbearne, @philiparthurmoore, @prettyboymp, @raamdev, @rachelbaker, @ramonchiara, @roothorick, @ryelle, @sabreuse, @sandyr, @SergeyBiryukov, @shahpranaf, @siobhyb, @spmlucas, @stevenkword, @tbrams, @tlovett1, @TobiasBg, @tomauger, @Toru, @vanillalounge, @westonruter, @wonderboymusic, @xknown, and @yoavf for their efforts!

#3-9, #week-in-core