TLDR;
I have narrowed down that the <Loop> query param of exclude isn’t working in combination with an ACF relationship <Loop>. Any idea what is going on here?
I have a post type for artists and a post type for artwork. I have an ACF bidirectional relationship connecting them.
On the artwork page, I want to display other artwork by that artist. So I have this:
<Set current_id>
<Field id />
</Set>
<Loop acf_relationship=artist_artwork>
<Loop acf_relationship=artwork_artist exclude="{Get current_id}">
<ul>
<li><Field title /></li>
</ul>
</Loop>
</Loop>
The first loop gets you into the artist.
The second loop gets you into the artwork by at artist.
Then we list out all the artwork. That all works!
But since this is on an artwork page, I want to exclude the current art from that list. So I have a <Set> that captures the current artwork’s post id. That also works.
However when I then try to exclude that post ID in the art loop (inner loop), it doesn’t exclude it. It actually doesn’t even exclude it if I just hardcode an ID in there either like:
So that means I have narrowed down that it’s the exclude itself that isn’t working in combination with an ACF relationship loop. Any idea what is going on here?
I’ve asked Eliot whether we can make relationship loops natively accept query parameters from the post loop, so maybe that will get added in a future version.
Both include and id pull the relationship objects in.
But exclude still didn’t work for either of them? That seems unexpected? (but then again, it is a real query happening inside of a relationship query, which is a little odd?)
I also tried doing both Loops as the type=post and passing the acf relationship field that way, which pulls in values correctly but the exclude still didn’t work… I really thought that one was going to do it…
[EDIT]
Is there away to get the ACF Relationship’s data index?
If so, there might be a way using a conditional to detect if the current post is among the two first, and shift the output if this is the case.
[EDIT 2] <Get loop=count /> returns the data index in the loop
Weird, it worked for me, but in any case doing a format-replace doesn’t feel like a serious solution haha
Maybe the approach then would just be to run the conditional logic on a list variable beforehand instead of running the logic within the relationship loop. Something like this maybe:
<Set current_id><Field id /></Set>
<Loop type="post" id="419">
<List name="related_posts">
<Loop acf_relationship="my_relationship_field">
<If field="id" is not value="{Get current_id}">
<Item><Field id /></Item>
</If>
</Loop>
</List>
</Loop>
<ul>
<Loop post_type="post" id="{Get list=related_posts}" count=2>
<li><Field title /></li>
</Loop>
</ul>
My gut feeling is that a relationship field loop is just looping through the values in the field and isn’t actually making a query. If that’s actually the case, then it wouldn’t make sense for it to accept query parameters, since that would “force” the relationship loop type to act as a query, making it less efficient than it is currently. If my intuition is right, then our “hacky” approaches might really be as efficient an approach as any, since any approach that involves filtering with query parameters is going to be introducing an additional query. Hopefully @eliot can chime in with some clarification here about what’s going on behind the scenes.
If I’m right (I very well might not be), then the only change that would make sense to implement would be to have the values of include and exclude take precedence over the value of id so that you could specify a list of IDs and then exclude one/some of them, which doesn’t currently seem to be possible.
Yeah, as for fixing going forward, we can of course apply the same query params to the L&L syntax but do different things behind the scenes instead of forcing it into a query.
So doing exclude on a <Loop acf_relationship=field_name> could just do a separate function on the backend to remove that post from the array without “forcing” it into a loop query?
This has been remedied in L&L 4.0.2, where loop query parameters such as exclude (as well as sort, orderby, paged, etc.) now work with the ACF Relationship field.
I haven’t played around with it myself yet, but it seems that all the query parameters from the post loop now work on the acf_relationship loop. That being said, your particular example definitely wouldn’t work because that’s not what the exclude query parameter is meant for. The post loop docs mention this:
exclude - Exclude by ID or name
Rereading that now, I supposed it could be more clear that it’s intended to “exclude posts by post ID or post name,” but I think the idea was that that was implied since these are all post-related query parameters. I assume you’re trying to exclude something with a particular taxonomy term applied, in which case you’d want to use query parameters intended for that purpose. This might work but I don’t have your data structure to test it:
I knew the exclude was wrong, but I couldn’t figure out the taxonomy tags documentation for what I needed. This is great: taxonomy_compare=not terms=sold>
Having some examples on how to use those in the docs for the custom taxonomy (not categories or tags) would be great!
I ended up doing this in php, so I don’t have the setup to test your solution, but it looks accurate! (assuming acf_relationship can use taxonomy_compare - which I think was the root of my question)