Repository navigation
Conversation
`WP_REST_Templates_Controller::prepare_links()` receives only the template ID. When the post type supports revisions, it called `get_block_template()` for every item to read the template's post ID. For each template in `/wp/v2/templates` and `/wp/v2/template-parts` responses, that ran another `WP_Query` and, for theme file templates, read the file again and re-applied Block Hooks, only to discard the result. Reuse the template that `prepare_item_for_response()` is already preparing. The signature of `prepare_links()` is unchanged, so subclasses that override it keep working. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
See #66381. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. Props Bot commandsYou can trigger Props Bot actions by commenting on this PR:
|
…p fallback runs. Use a typed `?WP_Block_Template` property instead of an `@var` tag, as suggested in review, and say that the `get_block_template()` fallback in `prepare_links()` is only reached when a subclass calls `prepare_links()` outside of `prepare_item_for_response()`. See #66381. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| $refetched = 0; | ||
| $counter = static function ( $template ) use ( &$refetched ) { | ||
| ++$refetched; | ||
| return $template; | ||
| }; | ||
| add_filter( 'pre_get_block_template', $counter ); | ||
| $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', '/wp/v2/templates' ) ); | ||
| remove_filter( 'pre_get_block_template', $counter ); | ||
|
|
||
| $this->assertSame( 200, $response->get_status(), 'The request should succeed.' ); | ||
| $this->assertSame( 0, $refetched, 'Templates should not be fetched again to prepare their links.' ); |
There was a problem hiding this comment.
This can be simplified using MockAction:
| $refetched = 0; | |
| $counter = static function ( $template ) use ( &$refetched ) { | |
| ++$refetched; | |
| return $template; | |
| }; | |
| add_filter( 'pre_get_block_template', $counter ); | |
| $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', '/wp/v2/templates' ) ); | |
| remove_filter( 'pre_get_block_template', $counter ); | |
| $this->assertSame( 200, $response->get_status(), 'The request should succeed.' ); | |
| $this->assertSame( 0, $refetched, 'Templates should not be fetched again to prepare their links.' ); | |
| $mock = new MockAction(); | |
| add_filter( 'pre_get_block_template', array( $mock, 'filter' ) ); | |
| $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', '/wp/v2/templates' ) ); | |
| $this->assertSame( 200, $response->get_status(), 'The request should succeed.' ); | |
| $this->assertSame( 0, $mock->get_call_count(), 'Templates should not be fetched again to prepare their links.' ); |
| wp_update_post( | ||
| array( | ||
| 'ID' => self::$template_post->ID, | ||
| 'post_content' => 'Content for a revision.', | ||
| ) | ||
| ); |
There was a problem hiding this comment.
Just to make sure the update actually happened:
| wp_update_post( | |
| array( | |
| 'ID' => self::$template_post->ID, | |
| 'post_content' => 'Content for a revision.', | |
| ) | |
| ); | |
| $this->assertIsInt( | |
| wp_update_post( | |
| array( | |
| 'ID' => self::$template_post->ID, | |
| 'post_content' => 'Content for a revision.', | |
| ) | |
| ), | |
| true | |
| ); |
There was a problem hiding this comment.
Applied in 44f2c6b, with true moved inside wp_update_post() as its $wp_error argument. As the second argument of assertIsInt() it would be the failure message, and a failed update returns 0, which would still pass.
Co-authored-by: Weston Ruter <westonruter@gmail.com>
Count `pre_get_block_template` calls with `MockAction`, assert that the template update succeeds before checking its revision links, and read the found template with `array_first()`. The update assertion passes `true` as the `$wp_error` argument of `wp_update_post()`, so a failed update returns a `WP_Error` and fails `assertIsInt()` instead of returning 0. See #66381. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WP_REST_Templates_Controller::prepare_links()receives only the template ID. When the post type supports revisions, it calledget_block_template()for every item only to readwp_idfor the revision links (r56819): anotherWP_Queryper item, and for theme file templates another file read and Block Hooks pass, all discarded.This reuses the template that
prepare_item_for_response()is already preparing, handed over through a private property so theprepare_links( $id )signature stays the same for subclasses.Measured on 7.2-beta1 with Ipsum, as admin,
rest_do_request(), median of 5:/wp/v2/template-parts(8 items)/wp/v2/templates(11 items)Trac ticket: https://core.trac.wordpress.org/ticket/66381
Testing
vendor/bin/phpunit --filter test_get_items_should_not_refetch_each_template_for_linksfails without the patch and passes with it; a second test checks that the revision links are unchanged.vendor/bin/phpunit --filter Tests_REST_WpRestTemplatesController(52 tests) and--group block-templates(130 tests) pass.Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5.5
Used for: finding the issue, drafting the fix and tests, and measuring. I reviewed every line.
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.
🤖 Generated with Claude Code