Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ add_filter( 'query_filter_term_counts', function ( $counts, $query_vars, $taxono
}, 10, 4 );
```

### Linking to filtered results

Each filter is a URL parameter, so a link elsewhere on the page — outside the Query Loop, in a hero or a menu — can apply one. The parameter's name depends on the loop: `query-{taxonomy}` for a loop that inherits the main query, `query-{id}-{taxonomy}` for one with its own. Rather than build it by hand, ask for it with the loop's block context:

```php
// "query-12-category", or "query-category" if the loop inherits its query.
$param = HM\Query_Loop_Filter\get_query_param( 'category', [
'query' => [ 'inherit' => false ],
'queryId' => 12,
] );
```

The key is a taxonomy name, `post_type`, `s` for the search or `page` for pagination.

## Installation

### Using Composer
Expand Down
36 changes: 28 additions & 8 deletions inc/namespace.php
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,32 @@ function filter_block_type_metadata( array $metadata ) : array {
return $metadata;
}

/**
* Name the URL parameter that sets a filter on a query.
*
* An inherited query is the main query, which reads `query-{key}`, with WordPress's own
* `s` and `page` for search and pagination. Any other query reads `query-{id}-{key}`,
* and its pagination is named as core's pagination block names it.
*
* Public so that controls outside a Query Loop, such as links built by a theme, can
* name the same parameters as the filter blocks inside it.
*
* @param string $key Taxonomy name, `post_type`, `s` or `page`.
* @param array $context Block context of the query: its `query` and `queryId`.
* @return string Parameter name.
*/
function get_query_param( string $key, array $context ) : string {
if ( ! empty( $context['query']['inherit'] ) ) {
return in_array( $key, [ 's', 'page' ], true ) ? $key : "query-{$key}";
}

if ( 'page' === $key ) {
return isset( $context['queryId'] ) ? "query-{$context['queryId']}-page" : 'query-page';
}

return sprintf( 'query-%d-%s', $context['queryId'] ?? 0, $key );
}

/**
* Sanitize a search query value.
*
Expand Down Expand Up @@ -749,26 +775,20 @@ function render_block_search( string $block_content, array $block, \WP_Block $in

wp_enqueue_script_module( 'query-filter-taxonomy-view-script-module' );

$inherit = ! empty( $instance->context['query']['inherit'] );

// An inherited query is the main query, and WordPress resolves that from
// its own `s`: a term only reaches the search template because `s` is what
// routing reads. Naming the field anything else leaves the field blank on
// arrival, and clearing it deletes a parameter the URL never carried, so
// the results never change. `query-s` is still transposed onto the main
// query for anything that already links to it.
$query_var = $inherit
? 's'
: sprintf( 'query-%d-s', $instance->context['queryId'] ?? 0 );
$query_var = get_query_param( 's', $instance->context );

// A search is a new set of results, so it belongs on the first page. Left
// in place, the page the visitor happened to be on is carried into the
// search and a term with fewer pages of matches than that renders empty.
// Named as core names it, so the parameter the pagination block wrote is
// the one that gets dropped.
$page_var = $inherit
? 'page'
: ( isset( $instance->context['queryId'] ) ? 'query-' . $instance->context['queryId'] . '-page' : 'query-page' );
$page_var = get_query_param( 'page', $instance->context );

$action = remove_query_arg( $page_var, add_query_arg( [ $query_var => '' ] ) );
$action = str_replace( '/page/' . get_query_var( 'paged', 1 ), '', $action );
Expand Down
13 changes: 5 additions & 8 deletions src/post-type/render.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@
// rather than warning about an undefined index.
$inherit = ! empty( $block->context['query']['inherit'] );

$query_var = \HM\Query_Loop_Filter\get_query_param( 'post_type', $block->context );
$page_var = \HM\Query_Loop_Filter\get_query_param( 'page', $block->context );
$base_url = remove_query_arg( [ $query_var, $page_var ] );

if ( $inherit ) {
$query_var = 'query-post_type';
$page_var = 'page';
$base_url = str_replace( '/page/' . get_query_var( 'paged' ), '', remove_query_arg( [ $query_var, $page_var ] ) );
} else {
$query_id = $block->context['queryId'] ?? 0;
$query_var = sprintf( 'query-%d-post_type', $query_id );
$page_var = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page';
$base_url = remove_query_arg( [ $query_var, $page_var ] );
$base_url = str_replace( '/page/' . get_query_var( 'paged' ), '', $base_url );
}

$post_types = array_map( 'trim', explode( ',', $block->context['query']['postType'] ?? 'post' ) );
Expand Down
15 changes: 6 additions & 9 deletions src/taxonomy/render.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,12 @@
$layout_direction = $attributes['layoutDirection'] ?? 'vertical';
$hierarchy = \HM\Query_Loop_Filter\get_hierarchy_mode( $attributes, $taxonomy->name );

if ( empty( $block->context['query']['inherit'] ) ) {
$query_id = $block->context['queryId'] ?? 0;
$query_var = sprintf( 'query-%d-%s', $query_id, $attributes['taxonomy'] );
$page_var = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page';
$base_url = remove_query_arg( [ $query_var, $page_var ] );
} else {
$query_var = sprintf( 'query-%s', $attributes['taxonomy'] );
$page_var = 'page';
$base_url = str_replace( '/page/' . get_query_var( 'paged' ), '', remove_query_arg( [ $query_var, $page_var ] ) );
$query_var = \HM\Query_Loop_Filter\get_query_param( $attributes['taxonomy'], $block->context );
$page_var = \HM\Query_Loop_Filter\get_query_param( 'page', $block->context );
$base_url = remove_query_arg( [ $query_var, $page_var ] );

if ( ! empty( $block->context['query']['inherit'] ) ) {
$base_url = str_replace( '/page/' . get_query_var( 'paged' ), '', $base_url );
}

// Non-ASCII term slugs are stored URL-encoded (e.g. "%e6%97%a5"), but arrive from $_GET
Expand Down
Loading