For the complete documentation index, see llms.txt. This page is also available as Markdown.

Porter_QueryFilter_Base

Porter_QueryFilter_Base is a theme-facing helper class bundled by PorterWP. Extend it when you need to customise a Query Loop or an inherited archive/search query without duplicating block-detection and query-scoping logic.

Location

  • includes/helpers/class-Porter_QueryFilter_Base.php

  • Auto-loaded by includes/porter-helper-functions.php

What it solves

  • Targets a specific core/query block by CSS class.

  • Applies changes safely to non-inherited Query Loops.

  • Applies changes to the main query when the Query Loop inherits.

  • Strips empty s values so a page does not accidentally become a search results page.

  • Limits non-inherited changes to the matching Query Loop instance by queryId.

Minimum implementation

class Porter_Filter_UpcomingEvents extends Porter_QueryFilter_Base {
    protected string $className = 'upcoming-events';

    protected function should_apply_to_main( WP_Query $q ): bool {
        return $q->is_post_type_archive( 'event' ) || $q->is_tax( [ 'event-type', 'event-format' ] );
    }

    protected function filter_args( array $args, array $context ): array {
        $args['post_type'] = 'event';
        $args['post_status'] = [ 'publish' ];
        $args['meta_key'] = 'start_date';
        $args['orderby'] = 'meta_value_num';
        $args['order'] = 'ASC';

        if ( is_singular( 'event' ) ) {
            $args['post__not_in'] = [ get_the_ID() ];
        }

        return $args;
    }
}

new Porter_Filter_UpcomingEvents();

Required and optional members

Member
Required
Purpose

$className

Yes, in practice

Matches the CSS class on the target core/query block.

filter_args( array $args, array $context ): array

Yes

Returns the amended query vars.

should_apply_to_main( WP_Query $q ): bool

Only for inherited loops

Declares when the inherited main query should be modified.

treat_post_type_change_as_real(): bool

No

Controls whether a post-type-only change counts as a meaningful main-query change.

$blockName

No

Defaults to core/query. Override only if you have a strong reason.

How it works

  1. The constructor attaches to pre_render_block.

  2. When a matching core/query block is found, the class checks whether the block className contains your $className.

  3. For non-inherited loops, it captures the block queryId and filters query_loop_block_query_vars.

  4. For inherited loops, it hooks pre_get_posts and only proceeds when should_apply_to_main() returns true.

filter_args() context

filter_args() receives the current query args plus a context array:

Key
Value

scope

'block' or 'main'

block

WP_Block for non-inherited loops, otherwise null

wp_query

WP_Query for inherited loops, otherwise null

This makes it easy to branch logic if the same class supports both block queries and inherited archive/search queries.

Usage pattern

  1. Add a custom class such as upcoming-events to the target Query Loop block.

  2. Create a child class in your theme, usually inside porter/inc/.

  3. Set $className to match the block class.

  4. Implement filter_args() with the exact WP_Query vars you need.

  5. If the Query Loop inherits from the current request, override should_apply_to_main().

  6. Instantiate the class once.

Notes

  • Class matching uses strpos(), so use a distinctive class name rather than something overly generic.

  • If the Query Loop inherits the main query, nothing changes unless should_apply_to_main() explicitly returns true.

  • PORTER_QUERY_FILTER_DEBUG enables diff logging for before/after query args. It does not turn on the internal verbose trace logger.

Last updated