#62014 closed enhancement (fixed)
Editor: Add a 'format' parameter to query to enable filtering post formats in the Query Loop block
Reported by: | poena | Owned by: | peterwilsoncc |
---|---|---|---|
Milestone: | 6.7 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Editor | Keywords: | has-patch has-testing-info needs-testing needs-unit-tests |
Focuses: | Cc: |
Description (last modified by )
This ticket is for adding the PHP changes from this Gutenberg PR:
Query loop / Post template: Enable post format filter
The Gutenberg PR linked above adds a new filter and a new interface control to the Query Loop block, that the user can use to display posts (or other post types) that have post formats assigned.
The PR for this Trac ticket adds a new parameter called 'format' to the class
WP_REST_Posts_Controller
. Changes are made to these class methods: 'get_item' and 'get_collection_params'.
'Format' is also added to the function build_query_vars_from_query_block
, to ensure that it is passed correctly to 'WP_Query' during the server-side render of the block.
The test test_registered_query_params
on the test class WP_Test_REST_Posts_Controller
is also updated to include the format parameter.
Testing instructions
How to test the post formats filter without the rest of the Gutenberg changes.
First, please enable post formats on the active theme. Example:
function twentytwentyfour_post_formats() { add_theme_support( 'post-formats', array( 'aside', 'gallery', 'link', 'image', 'quote', 'status', 'video', 'audio', 'chat' ) ); } add_action( 'after_setup_theme', 'twentytwentyfour_post_formats' );
On your WordPress test install, create a few posts with and without formats assigned.
In the Site Editor or block editor, insert a query loop with a format filter.
Since the control itself is not included in this PR, you will need to open the code editor mode in the editor and manually add the format.
In this example, I have used the gallery post format. I have added
"format":["gallery"]
inside query
:
<!-- wp:query {"query":{"perPage":10,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true,"format":["gallery"]}} --> <div class="wp-block-query"> <!-- wp:post-template --> <!-- wp:post-title /--> <!-- /wp:post-template --> </div> <!-- /wp:query -->
In the editor and front, the query loop should only display posts with the gallery post format.
Next, change the format to standard:
<!-- wp:query {"query":{"perPage":10,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true,"format":["standard"]}} --> <div class="wp-block-query"> <!-- wp:post-template --> <!-- wp:post-title /--> <!-- /wp:post-template --> </div> <!-- /wp:query -->
In the editor and front, the query loop should only display posts that have no post format assigned.
Testing the query pagination:
Set the number of posts to display per page to something low, so that the query pagination block shows on the front.
Then move between the listed pages and confirm that page 2 etc also shows posts with the correct post formats.
Change History (27)
This ticket was mentioned in PR #7314 on WordPress/wordpress-develop by @poena.
5 weeks ago
#1
- Keywords has-patch added
This ticket was mentioned in Slack in #core-editor by poena. View the logs.
4 weeks ago
#9
@
4 weeks ago
Am I able to clarify the intent a little more here.
If I set up a Query Loop with the following:
- Categories: some-category
- Tags: some-tag
- Post Format: link
Is the intention that it will perform the AND
pseudo query post format == link AND ( post tag == some-tag OR post category == some-category)
?
Or is the intention that it will perform the OR
pseudo query post format == link OR post tag == some-tag OR post category == some-category
?
Taxonomy queries within WP_Query
are really flexible in that they allow for a combination matching the first option but I'm not sure if the REST API is as flexible, @TimothyBlynJacobs are you able to provide some guidance on this?
Once I hear back on whether it's an OR or AND, I can follow up further with code review on the pull request.
#10
@
4 weeks ago
If I enter both a category and a tag into the existing filter settings on the query loop block,
the block displays posts that have both the category and the tag. Not posts that have either.
It should work the same when the format filter is used.
#11
@
4 weeks ago
Yeah right now, each REST API filter is "and"ed with each other. What makes this a bit more nebulous here potentially is that the Posts Controller introduced a tax_relation
query parameter. That can be used by users to make the taxonomy queries ORed with each other. Right now, the patch isn't built as a tax query, so the tax_relation
query parameter wouldn't apply.
I think this is the correct way of handling this. Because the API isn't treating post formats as just another taxonomy, but a specifically handled flag.
So right now, I believe, if I ran a query of /posts?category=5&tag=7&tax_relation=OR&format=audio
, we would return posts that have (either cat:5 OR tag:7) AND (format=audio). Might be worth adding a unit test specifically demonstrating this?
#13
@
3 weeks ago
When building the query in blocks.php, I think it will need a nested query based on the above.
<?php 'tax_query' => array( 'relation' = 'AND', array( // Taxonomy query from block args tags, cateagory and tax_query ), array( relation = 'OR', array( 'taxonomy' => 'post_format', 'slug' => ( 'link', 'gallery' ), ), array( 'taxonomy' => 'post_format', 'operator' => 'NOT EXISTS', // Standard post type ) ), );
#14
@
3 weeks ago
Yes, in blocks.php the condition that is already in WP_REST_Posts_Controller
is missing.
#15
@
3 weeks ago
Would this be correct?
The AND
is not directly inside 'tax_query' => array(
, it is still nested:
[19-Sep-2024 06:39:44 UTC] Array ( [post_type] => post [order] => DESC [orderby] => date [post__not_in] => Array ( ) [offset] => 0 [posts_per_page] => 10 [tax_query] => Array ( [0] => Array ( [taxonomy] => category [terms] => Array ( [0] => 4 ) [include_children] => ) [1] => Array ( [relation] => AND [0] => Array ( [relation] => OR [0] => Array ( [taxonomy] => post_format [field] => slug [operator] => NOT EXISTS ) [1] => Array ( [taxonomy] => post_format [field] => slug [terms] => Array ( [0] => post-format-link [2] => post-format-gallery ) [operator] => IN ) ) ) ) )
@noisysocks commented on PR #7314:
3 weeks ago
#16
Hey @carolinan. JavaScript packages were updated in r59072 so you might wish to rebase this for easier testing. The deadline to commit this backport is 6.7 Beta 1 which is scheduled for 1 October.
@peterwilsoncc commented on PR #7314:
3 weeks ago
#17
I tested this with the updated packages and was getting a block error when I tried to add the format. Is there something that needs to be merged to the packages in the GB repo before it should work?
It's a little confusing with the same variable name in both the legacy query, the tax query so I'm wondering if we can do a little more tidying up there:
-
src/wp-includes/blocks.php
diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index f3d138475f..25cb1c0d24 100644
a b function build_query_vars_from_query_block( $block, $page ) { 2346 2346 'order' => 'DESC', 2347 2347 'orderby' => 'date', 2348 2348 'post__not_in' => array(), 2349 'tax_query' => array(), 2349 2350 ); 2350 2351 2351 2352 if ( isset( $block->context['query'] ) ) { … … function build_query_vars_from_query_block( $block, $page ) { 2395 2396 } 2396 2397 // Migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility. 2397 2398 if ( ! empty( $block->context['query']['categoryIds'] ) || ! empty( $block->context['query']['tagIds'] ) ) { 2398 $tax_query = array();2399 $tax_query_back_compat = array(); 2399 2400 if ( ! empty( $block->context['query']['categoryIds'] ) ) { 2400 $tax_query [] = array(2401 $tax_query_back_compat[] = array( 2401 2402 'taxonomy' => 'category', 2402 2403 'terms' => array_filter( array_map( 'intval', $block->context['query']['categoryIds'] ) ), 2403 2404 'include_children' => false, 2404 2405 ); 2405 2406 } 2406 2407 if ( ! empty( $block->context['query']['tagIds'] ) ) { 2407 $tax_query [] = array(2408 $tax_query_back_compat[] = array( 2408 2409 'taxonomy' => 'post_tag', 2409 2410 'terms' => array_filter( array_map( 'intval', $block->context['query']['tagIds'] ) ), 2410 2411 'include_children' => false, 2411 2412 ); 2412 2413 } 2413 $query['tax_query'] = $tax_query;2414 $query['tax_query'] = array_merge( $query['tax_query'], $tax_query_back_compat ); 2414 2415 } 2415 2416 if ( ! empty( $block->context['query']['taxQuery'] ) ) { 2416 $ query['tax_query']= array();2417 $tax_query = array(); 2417 2418 foreach ( $block->context['query']['taxQuery'] as $taxonomy => $terms ) { 2418 2419 if ( is_taxonomy_viewable( $taxonomy ) && ! empty( $terms ) ) { 2419 $ query['tax_query'][] = array(2420 $tax_query[] = array( 2420 2421 'taxonomy' => $taxonomy, 2421 2422 'terms' => array_filter( array_map( 'intval', $terms ) ), 2422 2423 'include_children' => false, 2423 2424 ); 2424 2425 } 2425 2426 } 2427 $query['tax_query'] = array_merge( $query['tax_query'], $tax_query ); 2426 2428 } 2427 2429 if ( ! empty( $block->context['query']['format'] ) && is_array( $block->context['query']['format'] ) ) { 2428 2430 $formats = $block->context['query']['format']; … … function build_query_vars_from_query_block( $block, $page ) { 2479 2481 */ 2480 2482 if ( count( $formats_query ) > 1 ) { 2481 2483 // Enable filtering by both post formats and other taxonomies by combining them with `AND`. 2482 if ( isset( $query['tax_query'] ) ) { 2483 $query['tax_query'][] = array( 2484 if ( empty( $query['tax_query'] ) ) { 2485 $query['tax_query'] = $formats_query; 2486 } else { 2487 $query['tax_query'] = array( 2484 2488 'relation' => 'AND', 2489 $query['tax_query'], 2485 2490 $formats_query, 2486 2491 ); 2487 } else {2488 $query['tax_query'] = $formats_query;2489 2492 } 2490 2493 } 2491 2494 }
However, the code looks good to me in terms of PHP, it's just the blcok crashing that needs to be figured out.
3 weeks ago
#18
I have submitted a pull request that fixes this bug and it is waiting for review.
#19
@
3 weeks ago
Unfortunately, realistically I will not find the time to create the tests before Beta 1 as I also need to help finish Twenty Twenty-Five.
2 weeks ago
#21
@peterwilsoncc My only question is about the first array_merge
. The previous code replaced $query['tax_query']
, the suggested update merges them, I would like to understand why?
- $query['tax_query'] = $tax_query; + $query['tax_query'] = array_merge( $query['tax_query'], $tax_query_back_compat );
#22
@
2 weeks ago
I wanted to confirm that with the changes that @peterwilsoncc proposed, the log of the query is as follows, with the AND
nested at the correct level:
[25-Sep-2024 05:22:23 UTC] Array ( [post_type] => post [order] => DESC [orderby] => date [post__not_in] => Array ( ) [tax_query] => Array ( [relation] => AND [0] => Array ( [0] => Array ( [taxonomy] => category [terms] => Array ( [0] => 4 ) [include_children] => ) ) [1] => Array ( [relation] => OR [0] => Array ( [taxonomy] => post_format [field] => slug [operator] => NOT EXISTS ) [1] => Array ( [taxonomy] => post_format [field] => slug [terms] => Array ( [0] => post-format-link [2] => post-format-gallery ) [operator] => IN ) ) ) [offset] => 0 [posts_per_page] => 10 [author__in] => Array ( ) )
This ticket was mentioned in Slack in #core by poena. View the logs.
2 weeks ago
@peterwilsoncc commented on PR #7314:
13 days ago
#24
@peterwilsoncc[[Image(moz-extension://e0755463-33bf-47f8-a715-eba3a5588485/images/wp-logo.png)]] My only question is about the first
array_merge
. The previous code replaced$query['tax_query']
, the suggested update merges them, I would like to understand why?
The suggested change always defined $query['tax_query']
and renamed the variables so they differed for the legacy queries, current query and formats. As a result it needed to merge rather than append the item.
However, I'm glad you asked because I want to double check I didn't just introduce a bug. I'll double check that prior to merge.
#25
@
12 days ago
- Owner set to peterwilsoncc
- Resolution set to fixed
- Status changed from new to closed
In 59115:
Adds handling the format property (
$request['format']
) in the class WP_REST_Posts_Controller.Adds handling the format property (
$block->context['query']['format']
) in the functionbuild_query_vars_from_query_block
.Trac ticket: https://core.trac.wordpress.org/ticket/62014