Support Forum
Hi,
I'm having an issue with creating a tax_query with Twig. My view gets posts using get_posts(args), and the tax_query within args should filter on multiple taxonomies. It works fine if hard coded like this:
{% set tax_query = [[{relation: 'OR'}],
[{taxonomy: 'taxonomyslug1', terms: [336]}],
[{taxonomy: 'taxonomyslug2', terms: [324]}]
]
%}
However, I need to check if the taxonomy of the current post actually has terms selected. If so, the taxonomy should be included in the tax_query. If not, it should not be included.
In the below code, I'm using the Twig merge function to compose the tax_query. I loop through an array of arrays with terms that I composed earlier, and I skip the empty arrays of terms. The array taxonomies_to_match contains the taxonomy slugs.
{% set tax_query = [{relation: 'OR'}] %}
{% for taxonomy_terms_to_match_ids in taxonomies_terms_to_match_ids %}
{% if taxonomy_terms_to_match_ids is not empty %}
{% set tax_query = tax_query|merge([{taxonomy: taxonomies_to_match[loop.index0], terms: taxonomy_terms_to_match_ids}]) %}
{% endif %}
{% endfor %}
This does return posts in some cases, but the results are not ok. I think the problem is that tax_query should be an array containing arrays. I think the merge messes things up and somehow forces everything into a one-dimensional array. Is there another way to dynamically create the tax_query?
Hi Arno,
You can refer to this topic to create a tax_query parameter with multiple taxonomies https://support.metabox.io/topic/querying-terms-from-multiple-taxonomies/#post-36948
Then follow this topic to know how to update the object property in Twig https://stackoverflow.com/questions/7719838/updating-object-properties-in-twig
Let me know how it goes.
Hi Long,
Thank you. Yes, your first example works. This is what I have and it works fine:
{% set args = {
post_type: 'promotion',
numberposts: 3,
orderby: 'meta_value_num',
meta_key: 'content_popularity',
order: 'DESC',
meta_query: [{
key: 'promotion_start_date',
value: 'now'|date("Y-m-d H:i"),
compare: '<=',
},
{
key: 'promotion_end_date',
value: 'now'|date("Y-m-d H:i"),
compare: '>=',
}],
tax_query: {
"relation": "OR",
0: {
taxonomy: "travel-tickets",
terms: "336"
},
1: {
taxonomy: "activities",
terms: "324"
}
}
However, whatever I try, creating the tax_query dynamically with "merge" fails (no results). And I don't understand the "do" example in your second link, to be honest.
I think what goes wrong with the Twig merge, is that it looks at the key-value pairs and overwrites the values already in the array. If this is in the array:
taxonomy: "travel-tickets"
and I want to add this:
taxonomy: "activities"
it will actually replace it. I think.
I can't find a way to solve this in Twig. The merge filter does not seem to work for this scenario. It looks like there are/were Twig "add" and "push" filters too, but they're not recognized in the view code.
For others with this issue: I created a PHP function to compose the tax query. As arguments, it takes the relation (AND/OR), an array of taxonomy slugs, and an array containing an array of terms.
function get_tax_query($relation, $taxonomy_slugs = array(), $term_ids = array()) {
$tax_query = array();
if (count($taxonomy_slugs) > 1) {
$tax_query['relation'] = $relation;
}
foreach ($taxonomy_slugs as $key => $taxonomy_slug) {
array_push($tax_query, array('taxonomy' => $taxonomy_slug, 'terms' => $term_ids[$key] ));
}
return $tax_query;
}
So far this seems to work well.
If you know a way to do this directly in Twig, please share.
Hi,
To merge an object to an object in View with Twig code you can follow this example code:
{% set my_tax_query = { "relation": "OR" } %}
{% set my_tax_query = my_tax_query|merge({ 0: {
taxonomy: "category",
field: "slug",
terms: "aciform"
} }) %}
{% set my_tax_query = my_tax_query|merge({ 1: {
taxonomy: "category",
field: "slug",
terms: "cat-a"
} }) %}
{% set args = { post_type: "post", posts_per_page: 5, tax_query: my_tax_query } %}
{% set posts = mb.get_posts( args ) %}
{% for post in posts %}
{{ post.post_title }}
{% endfor %}
Hope that makes sense.
Much appreciated, thank you. Will try it out later.