WordPress 5.4 introduces new hooks to add custom fields to menu items

WordPress 5.4 introduces two new actions you can use to add custom fields to menu items, in both the Menu screen and the Customizer’s menu editor.

The following hooks are now available:

Menus 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 Menu 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 JavaScript.

This brings parity with the wp_nav_menu_item_custom_fields action.

Compatibility with existing custom walkers

These new action hooks 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 Trac ticket #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

Feature Plugin: WP Auto-updates

In 2018, @matt posted 9 projects for Core to focus on in 2019. This roadmap was updated for 2020. Plugins and Themes automatic updates is one of those 9 projects. WordPress contributors did a lot of work on the two related tickets during WP 5.4 development cycle, but decided to give it more time for testing as it’s an important feature. This project is now planned for WordPress 5.5 and the feature is going to be tested in a Feature Plugin.

For reference, see the two related Trac tickets:

A lot of interesting points were discussed in the tickets above, including the scope of the feature and the user interface/design. Many thanks to everyone who already contributed to this exciting new feature ♥️

Now, the development that happened in the related tickets are moved into WP-Auto-updates Feature Plugin which is available for testing and feedback. Contributions from the WordPress community are welcome on the plugin’s GitHub repository.

Project overview

As a quick reminder of what this project is trying to achieve, here are the main features that are being worked on:

  • Ability for website administrators to opt-in to automatic updates for plugins and themes in the related WP-Admin screens.
  • Ability to enable/disable auto-updates on a plugin-by-plugin and theme-by-theme basis.
  • Email notifications to send regular auto-update summaries to website administrators.
  • Hooks and constants to help developers disable or programmatically define auto-update settings.

Design considerations

The current design of the feature plugin reflects the last ideas that were discussed in #48850. This is still a work in progress and the implementation will probably evolve, as WordPress contributors discuss the feature on GitHub.

Latest Plugin screen mockup in #48850
WP Autoupdates screenshot
Current implementation in WP Auto-updates Feature Plugin – version 0.1.2

Here is the proposed roadmap:

  • ✅ Create feature plugin
  • ✅ Submit feature plugin to WordPress.org repository
  • ✅ Get the plugin featured as beta plugin on WordPress.org
  • 🔲 Move the repository to WordPress.org GitHub account
  • ✅ Publish the feature plugin proposal
  • 🔲 Open a dedicated Slack channel on Make WordPress (if needed)
  • ✅ Handle plugins auto-updates
  • 🔲 Handle themes auto-updates
  • ✅ Handle plugins auto-updates in a multisite context
  • 🔲 Handle themes auto-updates in a multisite context
  • ✅ Add hooks and constants for plugins
  • 🔲 Add hooks and constants for themes
  • 🔲 Add email notifications for plugins
  • 🔲 Add email notifications for themes
  • ✅ Add auto-updates information in update-core screen
  • 🔲 Validate design for plugins screen
  • 🔲 Validate design for themes screen
  • 🔲 Validate design for update-core screen
  • 🔲 Full documentation for new functions, hooks and constants
  • 🔲 Copy review
  • 🔲 Accessibility review
  • 🔲 Security review
  • 🔲 Coding standards review
  • 🔲 Inline Docs review

Next steps

The release of the WP-Auto-updates feature plugin is an early step in the process of having this functionality included in WordPress Core. Now, your help is needed to test, validate, and improve the current feature to ensure that it meets the needs of the WordPress community. Plugin and theme authors, hosting companies, WordPress developers and users are welcome to share their thoughts about this feature.

#5-5, #feature-plugins, #feature-autoupdates

Introduce block variations API

Just as you can declare a block’s style variations when you register a block, a block type can define block variations the user can pick from. The difference is that, beyond changing the look, this field offers a way to apply initial custom attributes and inner blocks at the point of insertion.

By default, all the variations will show up in the Inserter in addition to the regular block-type item. But setting the isDefault flag for any of the listed variations will override the regular block type in the Inserter.

variations: [
        name: 'wordpress',
        isDefault: true,
        title: __( 'WordPress' ),
        description: __( 'Code is poetry!' ),
        icon: WordPressIcon,
        attributes: { service: 'wordpress' },
        name: 'google',
        title: __( 'Google' ),
        icon: GoogleIcon,
        attributes: { service: 'google' },
        name: 'twitter',
        title: __( 'Twitter' ),
        icon: TwitterIcon,
        attributes: { service: 'twitter' },

An object describing a variation defined for the block type can contain these fields:

  • name (type string) – The unique and machine-readable name.
  • title (type string) – A human-readable variation title.
  • description (optional, type string) – A detailed variation description.
  • icon (optional, type String | Object) – An icon helping to visualize the variation. It can have the same shape as the block type.
  • isDefault (optional, type boolean) – Indicates whether the current variation is the default one. Defaults to false.
  • attributes (optional, type Object) – Values that override block attributes.
  • innerBlocks (optional, type Array[]) – Initial configuration of nested blocks.
  • example (optional, type Object) – Example provides structured data for the block preview. You can set to undefined to disable the preview shown for the block type.
  • scope (optional, type String[]) – the list of scopes where the variation is applicable. When not provided, it assumes all available scopes. Available options: block, inserter.

#5-4, #block-editor, #dev-notes

Block Collections

Collections allow specific block types to be grouped together for added visibility in the editor’s Inserter menu, regardless of their categories. For instance, a plugin such as CoBlocks may register a Map block of category Widgets and a Post Carousel block of category Layout. By registering a collection for the coblocks namespace, these blocks will appear in the Inserter under their respective categories but also grouped under a CoBlocks collection.

The Block Collections API thus aims to improve the relationship of block discovery between users and plugin authors without compromising the semantics of block types, notably around categories (e.g. formatting, layout, widget, embed).

registerBlockCollection( 'coblocks', {
	title: 'CoBlocks',
	icon: brandAssets.categoryIcon,
} );

#5-4, #block-editor, #dev-notes

New or Updated Blocks in WordPress 5.4

Social Icons Block

This new block lets users link to social media and other popular websites by using those sites’ logos. Initially called Social Links, Social Icons were an experimental feature in Gutenberg 6.5 but held out of WordPress 5.3. Since then, the Block Variations API has progressed to the point that Social Icons in Gutenberg 7.5 are much simpler and more stable – and ready for merge in WordPress 5.4.

This reimplementation is a breaking change in the way Social Icons are saved (see details). Only sites that have run the Gutenberg plugin since September are potentially concerned. 

In WordPress 5.4, the core block editor will not recognize any Social Icons blocks built before Gutenberg 7.5.

There are two ways to deal with this:

  • (Recommended method) Manually migrate any content with old Social Icons. Here’s how: load a post in the block editor (Gutenberg 7.5 or higher) and save it. The block editor will automatically update its contents. 
  • Keep the Gutenberg plugin installed after upgrading to WordPress 5.4. The plugin will give you manual backwards compatibility for the old Social Icons.

Buttons Block

This new block is a collection of buttons, because authors often need to use several at a time (for instance: download and read more buttons).

The buttons block shows each button as an individual button-block child of the Buttons block. You won’t be able to insert a button block outside Buttons, but your existing button blocks will work the way they always have.

In case you were using the button block as part of a template or a system that automatically inserted a button block, you’ll want to use the Buttons block with a nested button instead.

Plus, here’s some good news: you won’t need to migrate your existing button blocks. They’ll just work — again, as they always have.

#5-4, #block-editor, #dev-notes

Miscellaneous Developer Focused Changes in WordPress 5.4

WordPress 5.4 adds a handful of small developer-focused changes. Let’s take a look!

Better information about errors in wp_login_failed

A new parameter, $error, gets passed in the wp_login_failed action, to get you more information about the error that caused login failure.

It’s the second argument of the action and holds a WP_Error object with the authentication failure details.

Find it in wp-includes/pluggable.php:

 * Fires after a user login has failed.
 * @since 2.5.0
 * @since 4.5.0 The value of `$username` can now be an email address.
 * @since 5.4.0 The `$error` parameter was added.
 * @param string   $username Username or email address.
 * @param WP_Error $error    A WP_Error object with the authentication failure details.
do_action( 'wp_login_failed', $username, $error );

See this related ticket on Trac: #49007

Multisite: add site ID to newblog_notify_siteadmin filter

A new parameter, website ID, gets passed in the newblog_notify_siteadmin filter, to help you to customize site admins notifications depending on the website ID.

Find it in wp-includes/ms-functions.php:

 * Filters the message body of the new site activation email sent
 * to the network administrator.
 * @since MU (3.0.0)
 * @since 5.4.0 The `$blog_id` parameter was added.
 * @param string $msg Email body.
 * @param int$blog_id The new site's ID.
$msg = apply_filters( 'newblog_notify_siteadmin', $msg, $blog_id );

For more, see the relevant ticket: #48554

Introducing TikTok videos embed

WordPress 5.4 introduces TikTok as a new oEmbed provider.

As of version 5.4, WordPress will recognize TikTok video URLs that follow this pattern:


TikTok support also comes with its own block for the editor.

Plus, TikTok embeds work in the Block and Classic Editors, in the Text Widget — and anywhere else you can use Embeds now.

For more, see:

  • Related ticket on Trac: #49083
  • Related pull request on Gutenberg GitHub repository: 19345

Removal of CollegeHumor video embed

Since the CollegeHumor service no longer exists, its oEmbed provider was removed from Core in WordPress 5.3.1.

With version 5.4, the service is now completely gone from WordPress and the corresponding Gutenberg Embed block is deprecated. For backward compatibility, existing CollegeHumor blocks will automatically be converted into a generic embed block.

For reference, see:

  • Related ticket on Trac: #48696
  • Related pull request on Gutenberg GitHub repository: 18591

Media: store the original URL of the attachment in the _source_url post meta value

When you use media_sideload_image to sideload a file from a URL, the original URL is now automatically stored as metadata.

You can also use media_sideload_image to store a local copy of a file.

This is great for two reasons. First, for copyright and fairness, storing the source URL gives you an easy way to find out where that file was originally hosted. Plus, you can query existing attachments and not sideload the same file twice.

The original URL of the attachment is stored in the _source_url post meta:

add_post_meta( $id, '_source_url', $file );

For reference, see the related Trac ticket: #48164

Accessibility: the Admin Bar is now loaded with wp_body_open when available

It’s a first principle of accessibility that the look of a page and its source order should match. And for far too long, it’s been a principle WordPress has observed inconsistently.

Consider the Admin Bar. Up to now, it’s been loaded with the wp_footer hook:

add_action( 'wp_footer', 'wp_admin_bar_render', 1000 );

In WordPress 5.4, the Admin Bar loads in the hook wp_body_open(new since WP 5.2) and fixes that source-order problem:

add_action( 'wp_body_open', 'wp_admin_bar_render', 0 );

Of course, some older themes don’t yet support the wp_body_open hook. For them, there’s a fallback in the wp_footer function:

function wp_footer() {
     * Sets up the Admin Bar if the current theme does not use `wp_body_open`.
     * @since 5.4.0
    if ( ! did_action( 'wp_body_open' ) ) {
        add_action( 'wp_footer', 'wp_admin_bar_render', 1000 );

See the relevant Trac ticket: #47053

Widgets: avoid duplicate IDs in Recent Comments

In WordPress 5.4, the Recent Comments widget will no longer generate widgets with the same HTML id.

Even if having duplicate instances of Recent Comments widgets on the same patch is considered as an edge case, theme authors are invited to avoid to style this widget using the ID applied on the <ul> HTML element, as the ID will be different for each instance of the widget.

For reference, see the related Trac ticket: #46747

Login and Registration: new parameter passed into the lostpassword_post action in retrieve_password()

In WordPress 5.4, the $user_data parameter gets passed into the lostpassword_post action in retrieve_password().

If the user exists, $user_data will return the corresponding WP_User object. Otherwise, the parameter will return false.

Either way, developers have one more piece of information to act on.

See the related Trac ticket: #38334

Themes headers now support “Requires at least” and “Requires PHP” declarations

WordPress 5.4 adds support for required WordPress and PHP versions to themes.

Theme authors are invited to declare the following header entries in their main stylesheet:

Requires PHP: declare the minimal required PHP version.

Requires at least: declare the minimal WordPress version.

Post types capabilities improvements in WordPress 5.4

In WordPress 5.4, delete_posts capability will be included in default post type capabilities regardless of map_meta_cap value.

This resolves eventual PHP notices in a few places in WordPress core where this capability is checked. Before WP 5.4, PHP notices could be triggered by using 'map_meta_cap' => false in the post type declaration.

With delete_posts added to the get_post_type_capabilities() function, no PHP notices will be triggered anymore for this capability.

For reference, see the related Trac ticket: #30991

#5-4, #dev-notes

WordPress 5.4 introduces apply_shortcodes() as an alias for do_shortcode()

WordPress 5.4 introduces a new function – apply_shortcodes(). It’s an alias for the current do_shortcode() function.

The semantics of do_* implies the function displays the result of the shortcode. But that’s not actually the case. In fact, do_shortcode() needs to be echoed to display its result.

Here is the current implementation:

echo do_shortcode( '[wporg]My Text[/wporg]' );
// Displays the result of the shortcode

Semantically, we should be able to do this:

do_shortcode( '[wporg]My Text[/wporg]' );
// but it doesn’t display anything…

As you may know, do_shortcode() is used in countless plugins and themes. So there is currently no option to deprecate it. But if the community can start building a consensus around the alias, apply_shortcodes(), then deprecation may eventually become a real option in the future.

There is a precedent for making this move. It’s the same process the core team followed with get_permalink() and get_the_permalink().

apply_shortcodes is meant to get better semantics: instead of performing an action and outputting to the current buffer, the idea is to apply filters to the input and return a result. The process is simpler, cleaner and more maintainable – not to mention easier to teach new developers.

apply_shortcodes() can be used the same way do_shortcode() is currently used:

echo apply_shortcodes( '[wporg]My Text[/wporg]' );
// Displays the result of the shortcode

Themes/Plugins authors and WordPress developers are invited to start using apply_shortcodes() instead of do_shortcode().

To be clear, there is no plan for deprecating the former function right now. But the sooner developers can all switch to the much more semantic apply_shortcodes(), the sooner the core team can plan to deprecate the old function. With WordPress 5.4, apply_shortcodes() is now the recommended way to display the result of a shortcode.

For reference, see the related Trac ticket: #37422

Copy review: @marybaum

#5-4, #dev-notes, #shortcodes

Dev Chat Agenda for February 26, 2020 (5.4 Week 7)

Here is the agenda for the weekly meeting happening later today: Wednesday, February 26, 2020, at 09:00 PM UTC.


  • This week marks week 6 of the 5.4 release cycle 🙌
  • WordPress 5.4 Beta 3 was released yesterday, February 25, as scheduled.

Highlighted Blog Posts

Upcoming Releases – 5.4

Components Check-in

  • News from components
  • Components up for adoption (Filesystem API and Rewrite Rules)
  • Components that need help
  • Cross component collaboration

Open Floor

If you have anything to propose for the agenda or specific items related to those listed above, please leave a comment below.

This meeting is held in the #core channel. To join the meeting, you’ll need an account on the Making WordPress Slack.

#5-4, #agenda, #devchat

Editor Chat Agenda: 26th February, 2020

Note taker: @ajitbohra

This is the agenda for the weekly editor chat scheduled for 2020-02-26 14:00 UTC. This meeting is held in the #core-editor WordPress Slack channel.

  • WordPress 5.4 Upcoming Release
  • Gutenberg version 7.6.0
  • Weekly Priorities
  • Task Coordination
  • Open Floor

If you have anything to share for the Task Coordination section, please leave it as a comment on this post. If you have anything to propose for the agenda or other specific items related to those listed above, please leave a comment below.


Navigation block exclusion from WP 5.4

After plenty of great discussions about the Navigation block recently, the Gutenberg Team, including Dev Lead @jorgefilipecosta and me ( I’m the Design Lead), has decided not to include it in the WordPress 5.4 release.

We’ve been sharing this decision with the Release Squad for 5.4 and among many seasoned contributors to get a perspective on how everyone felt about this. The general consensus: people understand why the Gutenberg Team has made this call, and they support the decision.

Navigation block

Historical context

The Navigation block was a priority project for 2019. It was also planned for the WordPress 5.4 release. So we absolutely did not make this decision lightly. Ultimately, we recognize that although the block itself is ready to merge into Core, the Gutenberg Team believes this move is premature.


As I said, the Navigation block is usable right now. But we don’t think it’s useful yet – at least not until it has an intuitive place to live.

It’s hard to imagine cases where users would want to add a Navigation block to the post or page content. It’s much more likely that a given user would want to add a Navigation block to Header or Footer block areas – maybe even a Sidebar. However, that functionality in Gutenberg just isn’t ready.

Now, let me add this: if a user does want a set of links in a page, the new Buttons block in WordPress 5.4 can probably meet that need.

Buttons block

As I look back at the WordPress Project’s to-do list for 2019, the Navigation block didn’t exist in a vacuum. There was also the matter of Themes registering content areas which is still in progress as we speak. Both of those should co-exist and be released together. To include the Navigation block without a proper home isn’t really useful for users, and it doesn’t seem to justify a feature mention in the 5.4 release.

Going forward

Our next steps include adding a few more features to the block:

  • Creating a new page from within the block (19775).
  • Creating a Navigation block based on existing menu structures (18869).
  • Indicating “current” menu items visually (20076).

So that’s what’s happening with the Navigation Block and WordPress 5.4.

I want to ask you, personally, to join us in Core and in the Gutenberg Team discussions and give us your thoughts. Please review this block, to help further testing around it.

I’ll be picking up usability testing for this block again soon, and I’m looking forward to hearing from you how we can improve it.

And don’t forget to install the Gutenberg plugin to test the Navigation block in near-real-world conditions. With your feedback, we can make this block a great success.

#5-4, #gutenberg