-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Query terms by slug #36785
Comments
I found a way to work around this using a filter. It's a hack, and I definitely think this should be supported in core, but this might be of use for block theme development in the meantime: function custom_query_block_attributes( $parsed_block ) {
if ( 'core/query' === $parsed_block['blockName'] ) {
// If the block has a `category` attribute, then find the corresponding cat ID and set the `categoryIds` attribute.
// TODO: support multiple?
if ( isset( $parsed_block[ 'attrs' ][ 'query' ][ 'category' ] ) ) {
$category = get_category_by_slug( $parsed_block[ 'attrs' ][ 'query' ][ 'category' ] );
if ( $category ) {
$parsed_block[ 'attrs' ][ 'query' ][ 'categoryIds' ] = [ $category->term_id ];
}
}
}
return $parsed_block;
}
add_filter( 'render_block_data', 'custom_query_block_attributes' ); That's only lightly tested, and I haven't considered security. |
This idea supposes that for a given slug, there is one unique term per taxonomy. That's of course true on a default install. But the limitation that ensured this uniqueness has been removed since version 4.x (I don't remember exactly which one) when shared terms have been splitted. The uniqueness can now be ensured per taxonomy and per one or additionnal parameters that could be added by a plugin. It's thus now possible that a function like |
Querying by slug instead of term ID would mean that if a term slug is updated by a user existing query blocks referencing the term would no longer run the correct query. Querying by term ID offers some protection here, since this cannot be changed by users. |
Are you referring to https://core.trac.wordpress.org/ticket/22023 ? It seems like https://core.trac.wordpress.org/changeset/30238 protects against duplicate slugs within a taxonomy, but I'd be interested in hearing more. Can you link to a ticket or post that goes into detail? Otherwise, that seems like a situation that Core doesn't support. xref core changes: 4.1, 4.2, 4.3, 4.4
That's correct, but there are also downsides to querying by ID. Offering both options lets the developer choose which tradeoffs are best for their context. |
I agree, supporting both IDs and slugs allows theme devs to choose appropriately. IDs make sense when a theme is used on a single site. Slugs make sense for a downloadable theme that's designed to work anywhere. |
Agreed on this. Querying by tag name would be very useful for syncing across working environments. In my case, I have dev, staging, and production environments and am using Git to sync templates. However, hard-coded IDs for categories (and also for navigation) makes my dev process very cumbersome. Replicating the database across the environments just to address hard-coded numerical IDs isn't ideal for several reasons (for example, I want to have testing data in dev but not prod, syncing adds increased and largely unnecessary complexity). Also, I tried @tellyworth 's fix (adjusted for the new If anyone else has an idea, here's my code: function custom_query_block_attributes( $parsed_block ) {
if ( 'core/query' === $parsed_block['blockName'] ) {
if(is_array($parsed_block['attrs']['query']['taxQuery']['category'])) {
$category_slugs = $parsed_block['attrs']['query']['taxQuery']['category'];
$category_ids = [];
foreach($category_slugs as $slug) {
if(!is_numeric($slug)) {
$category = get_category_by_slug( $slug );
if($category) {
array_push($category_ids, $category->term_id);
}
}
}
$parsed_block['attrs']['query']['taxQuery']['category'] = $category_ids;
}
}
return $parsed_block;
}
add_filter( 'render_block_data', 'custom_query_block_attributes' ); |
I've made a quick modification of the above code to do several things:
function custom_query_block_attributes( array $parsed_block ) : array {
if ( 'core/query' !== $parsed_block['blockName'] ) {
return $parsed_block;
}
if ( ! is_array( $parsed_block['attrs']['query']['taxQuery'] ) ) {
return $parsed_block;
}
$taxQuery = $parsed_block['attrs']['query']['taxQuery'];
foreach ( $taxQuery as $tax => $slugs ) {
$ids = [];
foreach ( $slugs as $slug ) {
if ( is_numeric( $slug ) ) {
array_push( $ids, $slug );
continue;
}
$term = get_term_by( 'slug', $slug, $tax );
if ( $term instanceof WP_Term ) {
array_push( $ids, $term->term_id );
}
}
$parsed_block['attrs']['query']['taxQuery'][ $tax ] = $ids;
}
return $parsed_block;
}
add_filter( 'render_block_data', 'custom_query_block_attributes' ); |
What problem does this address?
Currently the Query block requires hardcoding
categoryIds
andtagIds
, which isn't always portable across development environments.One example is when a limited set of content is exported from production, to avoid leaking private data into local environments. When only exporting a specific post type, the WRX export file won't include meta data for categories. Instead, it includes the slug, and new categories are created with the next available ID.
When that happens, the local category IDs don't match production, and templates that work in one environment don't work in the other.
I assume there are other situations where hardcoding IDs is undesirable too.
What is your proposed solution?
Support querying by term slugs in addition to IDs.
That can still lead to problems in some situations, but it's much more portable, and much easier to fix when something does go wrong.
The text was updated successfully, but these errors were encountered: