[wp-trac] [WordPress Trac] #38072: Eliminate placeholder nav menu items in favor of auto-drafts in Customizer

WordPress Trac noreply at wordpress.org
Tue Jan 24 18:27:21 UTC 2017


#38072: Eliminate placeholder nav menu items in favor of auto-drafts in Customizer
-------------------------+------------------
 Reporter:  westonruter  |       Owner:
     Type:  enhancement  |      Status:  new
 Priority:  normal       |   Milestone:  4.8
Component:  Customize    |     Version:  4.3
 Severity:  normal       |  Resolution:
 Keywords:  needs-patch  |     Focuses:
-------------------------+------------------
Changes (by westonruter):

 * milestone:  Future Release => 4.8


Old description:

> When nav menus were added to the customizer in 4.3, newly-created nav
> menu items were assigned a random negative integer to represent the ID
> for that `nav_menu_item` post. (This was also true of `nav_menu` terms
> for newly-created nav menus.) Upon saving the customized state, any such
> `nav_menu_item[...]` settings with negative IDs would then get inserted
> and assigned actual IDs which would then get sent back in the
> `customize_save_response` and the UI then replaces the placeholder nav
> menu item's control with the newly-inserted nav menu item's control. The
> key motivation here was to ensure that changes made in the customizer
> would not have an impact any part of WP until hitting Save. (What happens
> in the customizer stays in the customizer… until you hit Save.)
>
> Now, aside from a momentary flicker of placeholder nav menu item controls
> that get replaced with actual nav menu item controls, there is a key
> disadvantage to using such placeholder nav menu items (with negative post
> IDs): it is not possible to relate postmeta to them. There is a long-
> standing ticket #18584 for allowing nav menu items to be extensible to
> add custom fields in the customizer (and in the admin screen). In the
> call to `get_metadata` it has a behavior whereby it passes the supplied
> post ID through `absint` so if any postmeta are attempted to be related
> to placeholder `nav_menu_item` posts, they will fail to be accessed when
> calling `get_post_meta()`.
>
> Now, in #34923 there was the introduction of being able to create stubs
> for posts and pages inside the customizer so that they can have nav menu
> items created for them. The stubs created here are `auto-draft` posts
> which ensures that they do not affect other parts of WordPress and they
> will be automatically garbage-collected if never published. Now, the
> original Menu Customizer plugin did make an Ajax request for each created
> new nav menu items but they were `nav_menu_item` posts that were not
> related to a `nav_menu` (they were orphaned) rather than being `auto-
> draft`. We could consider going back to making an Ajax request to create
> each `nav_menu_item` (now an `auto-draft`) in the same way that is being
> done for post/page stubs.
>
> A downside of going to using Ajax to create new nav menu items (to
> reserve an auto-incremented post ID) is that adding a new nav menu item
> would no longer be instant. However, it would mean that upon save there
> wouldn't be any rebuild of nav menu item controls replacing placeholders
> with actuals, and as such it could mean a lot of code could be removed.
> But the most important benefit of switching to use `auto-draft` posts for
> nav menu items is that postmeta could then be created in the customizer
> and related to actual post IDs which could then be properly targeted in
> `get_post_metadata`filters.
>
> Alternatively, `get_post_meta` could just replace the `absint` with a
> call to `intval` and then ensure that the `get_post_metadata` filters
> apply with that negative ID, but then short-circuit if the filter doesn't
> return with `null` (since it wouldn't be able to find entries with
> negative IDs in the database).
>
> See feature plugin for adding custom fields to the customizer:
> https://github.com/xwp/wp-customize-nav-menu-item-custom-fields
> Note how the plugin has to postpone the presentation of custom fields
> until a newly-added nav menu item is saved the first time:
> https://github.com/xwp/wp-customize-nav-menu-item-custom-
> fields/blob/2ad056634441a74ba91982ca88b089297f630971/customize-nav-menu-
> item-custom-fields.js#L279-L284

New description:

 When nav menus were added to the customizer in 4.3, newly-created nav menu
 items were assigned a random negative integer to represent the ID for that
 `nav_menu_item` post. (This was also true of `nav_menu` terms for newly-
 created nav menus.) Upon saving the customized state, any such
 `nav_menu_item[...]` settings with negative IDs would then get inserted
 and assigned actual IDs which would then get sent back in the
 `customize_save_response` and the UI then replaces the placeholder nav
 menu item's control with the newly-inserted nav menu item's control. The
 key motivation here was to ensure that changes made in the customizer
 would not have an impact any part of WP until hitting Save. (What happens
 in the customizer stays in the customizer… until you hit Save.)

 Now, aside from a momentary flicker of placeholder nav menu item controls
 that get replaced with actual nav menu item controls, there is a key
 disadvantage to using such placeholder nav menu items (with negative post
 IDs): it is not possible to relate postmeta to them. There is a long-
 standing ticket #18584 for allowing nav menu items to be extensible to add
 custom fields in the customizer (and in the admin screen). In the call to
 `get_metadata` it has a behavior whereby it passes the supplied post ID
 through `absint` so if any postmeta are attempted to be related to
 placeholder `nav_menu_item` posts, they will fail to be accessed when
 calling `get_post_meta()`.

 Now, in #34923 there was the introduction of being able to create stubs
 for posts and pages inside the customizer so that they can have nav menu
 items created for them. The stubs created here are `auto-draft` posts
 which ensures that they do not affect other parts of WordPress and they
 will be automatically garbage-collected if never published. Now, the
 original Menu Customizer plugin did make an Ajax request for each created
 new nav menu items but they were `nav_menu_item` posts that were not
 related to a `nav_menu` (they were orphaned) rather than being `auto-
 draft`. We could consider going back to making an Ajax request to create
 each `nav_menu_item` (now an `auto-draft`) in the same way that is being
 done for post/page stubs.

 A downside of going to using Ajax to create new nav menu items (to reserve
 an auto-incremented post ID) is that adding a new nav menu item would no
 longer be instant. However, it would mean that upon save there wouldn't be
 any rebuild of nav menu item controls replacing placeholders with actuals,
 and as such it could mean a lot of code could be removed. But the most
 important benefit of switching to use `auto-draft` posts for nav menu
 items is that postmeta could then be created in the customizer and related
 to actual post IDs which could then be properly targeted in
 `get_post_metadata`filters.

 Alternatively, `get_post_meta` could just replace the `absint` with a call
 to `intval` and then ensure that the `get_post_metadata` filters apply
 with that negative ID, but then short-circuit if the filter doesn't return
 with `null` (since it wouldn't be able to find entries with negative IDs
 in the database).

 See feature plugin for adding custom fields to the customizer:
 https://github.com/xwp/wp-customize-nav-menu-item-custom-fields
 Note how the plugin has to postpone the presentation of custom fields
 until a newly-added nav menu item is saved the first time:
 https://github.com/xwp/wp-customize-nav-menu-item-custom-
 fields/blob/2ad056634441a74ba91982ca88b089297f630971/customize-nav-menu-
 item-custom-fields.js#L279-L284

 Dependency for: #18584

--

--
Ticket URL: <https://core.trac.wordpress.org/ticket/38072#comment:6>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list