Skip to content

Content Loop Block: Load More option doesn't preserve custom taxonomies argument #2239

@psorensen

Description

@psorensen

Bug Report: customTaxonomies Not Applied in REST API /articles Endpoint

Summary

The customTaxonomies block attribute is not applied when fetching posts via the /newspack-blocks/v1/articles REST endpoint. The view.php file flattens customTaxonomies into individual taxonomy slug parameters, but these are filtered out by WordPress REST API schema validation before reaching the controller.

Environment

  • Plugin: Newspack Blocks
  • Affected Files:
    • src/blocks/homepage-articles/view.php (lines 326-337)
    • src/blocks/homepage-articles/class-wp-rest-newspack-articles-controller.php (lines 118-132)
    • includes/class-newspack-blocks.php (lines 619, 677-688)

Steps to Reproduce

  1. Create a homepage-articles block with customTaxonomies:

    <!-- wp:newspack-blocks/homepage-articles {"customTaxonomies":[{"slug":"example_taxonomy","terms":["123"]}],"moreButton":true} /-->
  2. View the page in the frontend and click the "More" button or trigger pagination

  3. Inspect the REST API request URL - it contains example_taxonomy[0]=123 but NOT customTaxonomies

  4. In the REST controller, $request->get_params()['customTaxonomies'] is empty

Expected Behavior

The customTaxonomies attribute should be preserved and applied to the WP_Query, filtering posts by the specified custom taxonomy terms.

Actual Behavior

  1. customTaxonomies gets flattened into individual taxonomy slug parameters (e.g., example_taxonomy[0]=123)
  2. WordPress REST API filters out any parameters not defined in the route args schema
  3. get_items() receives an empty customTaxonomies array (default from block.json)
  4. Posts are not filtered by custom taxonomy

Root Cause Analysis

Issue 1: In view.php (lines 327-337), when building the REST URL, the code:

  • Removes customTaxonomies from attributes
  • Flattens it into individual taxonomy slug parameters: $attributes[$tax['slug']] = $tax['terms']
  • Builds a URL like ?example_taxonomy[0]=123 instead of preserving customTaxonomies

Issue 2: The REST endpoint registers args via get_attribute_schema() which only includes block.json attributes. Dynamic taxonomy slugs (like example_taxonomy) are not in the schema.

Issue 3: WordPress REST API's sanitize_params() method (line 834 of wp-includes/rest-api/class-wp-rest-request.php) skips parameters not in the registered args:

if ( ! isset( $attributes['args'][ $key ] ) ) {
    continue;
}

Issue 4: build_articles_query() (line 619) only checks $attributes['customTaxonomies'] and doesn't look for flattened taxonomy parameters.

Code References

  • view.php:327-337 - Flattens customTaxonomies for REST URL
  • class-wp-rest-newspack-articles-controller.php:45 - Registers route with get_attribute_schema()
  • class-wp-rest-newspack-articles-controller.php:122-125 - Merges params, customTaxonomies defaults to empty array
  • class-newspack-blocks.php:619 - Only checks $attributes['customTaxonomies'], doesn't handle flattened params

Workaround

Intercept rest_pre_dispatch to reconstruct customTaxonomies from raw query parameters:

add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) {
    if ( '/newspack-blocks/v1/articles' !== $request->get_route() ) {
        return $result;
    }

    $raw_params = $request->get_query_params();
    $custom_taxonomies = [];
    $registered_taxonomies = get_taxonomies( [ 'public' => true ], 'objects' );
    
    foreach ( $registered_taxonomies as $taxonomy ) {
        if ( isset( $raw_params[ $taxonomy->name ] ) ) {
            $terms = $raw_params[ $taxonomy->name ];
            if ( ! is_array( $terms ) ) {
                $terms = [ $terms ];
            }
            $terms = array_filter( array_map( 'intval', $terms ) );
            if ( ! empty( $terms ) ) {
                $custom_taxonomies[] = [
                    'slug'  => $taxonomy->name,
                    'terms' => array_values( $terms ),
                ];
            }
        }
    }
    
    if ( ! empty( $custom_taxonomies ) ) {
        $request->set_param( 'customTaxonomies', $custom_taxonomies );
    }
    
    return $result;
}, 10, 3 );

Suggested Fix

Option 1 (Recommended): Modify view.php to preserve customTaxonomies in the REST URL

  • Keep customTaxonomies in the attributes array when building the REST URL
  • Ensure it's properly serialized for URL query strings (e.g., JSON encoding)

Option 2: Modify get_items() in the REST controller

  • Check for flattened taxonomy parameters in $request->get_params()
  • Reconstruct customTaxonomies before calling build_articles_query()

Option 3: Modify build_articles_query()

  • Check for individual taxonomy slug parameters in $attributes
  • Convert them to tax_query entries if customTaxonomies is empty

Additional Notes

  • This affects any pagination or "More" button functionality that relies on the REST endpoint
  • Initial server-side rendering works correctly because it calls build_articles_query() directly with the full attributes array
  • Only affects the /articles endpoint; the /newspack-blocks-posts endpoint may not have this issue if it handles attributes differently

Priority

High - Custom taxonomy filtering is completely broken for paginated/fetched results via REST API.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions