I know from this post that I can get posts by tag name by just specifying a filter[tag]
query parameter. And similarly with filter[category_name]
.
Is there a way to get posts that are not in a list of tags or categories for the purpose of excluding posts? I would prefer to do it with the name, or else I would have to make another request just to get the ID of the category, which would just slow down my overall response time in my app.
I know from this post that I can get posts by tag name by just specifying a filter[tag]
query parameter. And similarly with filter[category_name]
.
Is there a way to get posts that are not in a list of tags or categories for the purpose of excluding posts? I would prefer to do it with the name, or else I would have to make another request just to get the ID of the category, which would just slow down my overall response time in my app.
So one way this can be done is by creating a filter to check for a custom query string parameter that represents a tag name or names.
I added a function similar to this to my theme. It modifies the global WP_Query object before a request is made for posts by the REST API.
add_filter('pre_get_posts', function ($query) {
// I couldn't read from query_vars for some reason, so using global $_GET
$exclude_tag_name = isset($_GET['exclude_tag_name']);
if (!$exclude_tag_name) {
return; // Nothing to do
}
// Whitelist for security
// Add to this list as needed
$whitelist = ['SomeExcludedTagNameHere'];
$tag_name = $exclude_tag_name;
// Additional logic goes here to handle multiple names, such as splitting
// Check if tag name is in white list (with strict type checking)
// For security, you could also probably use a REGEX to sanitize
// or one of WP's built in sanitizing functions.
if (!in_array($tag_name, $whitelist, true)) {
return; // nothing to do
}
// Get all tags that contain this name (case insensitive)
// Or just use the tag directly if it doesn't matter to you.
$tags = get_tags([
'search' => $tag_name
]);
$tag_ids = [];
foreach ($tags as $tag) {
$tag_ids[] = $tag->term_id;
}
// Exclude these category IDs from the query
if (!empty($tag_ids)) {
// Modify the query object that was passed in by reference
// This function uses the tag ID's not names!
$query->set('tag__not_in', $tag_ids);
}
});
Similar code can be used to include only posts that have been tagged with a particular tag.
You could try using the rest_post_query
action to add exclusion filters for categories and tags. Try something like the below.
This adds ['filter']['exclude_categories']
and ['filter']['exclude_tags']
as options to use in the WP REST API. Each filter accepts multiple categories/tags seperated by a comma.
add_action( 'rest_post_query', 'your_exclude_query', 10, 2 );
function your_exclude_query( $args, $request ) {
// Exclude Query
if ( isset($request['filter']['exclude_categories']) || isset($request['filter']['exclude_tags']) ) {
// If the exclude categories filter is set
if ( isset($request['filter']['exclude_categories']) ) {
$categories = explode( ',', $request['filter']['exclude_categories'] ); // NOTE: Assumes comma separated taxonomies
array_push( $pre_tax_query, array(
'taxonomy' => 'category',
'field' => 'name',
'terms' => array( $categories ),
'operator' => 'NOT IN'
));
}
// If the exclude tags filter is set
if ( isset($request['filter']['exclude_tags']) ) {
$tags = explode( ',', $request['filter']['exclude_tags'] ); // NOTE: Assumes comma separated taxonomies
array_push( $pre_tax_query, array(
'taxonomy' => 'post_tag',
'field' => 'name',
'terms' => array( $tags ),
'operator' => 'NOT IN'
));
}
$tax_query = array(
'relation' => 'AND',
$pre_tax_query
);
$args[ 'tax_query' ] = $tax_query;
}
return $args;
} // end your_exclude_query
This is an old question but I think for now the solution exists.
We can use the tags_exclude=<tag-id>
to execlude specifix tags.