Struggle with Logic and ACF

I love that in L&L the condition can be separated from the loop and it’s possible to create a complex query. I’ll use it extensively to display only certain posts that have particular ACF field values.

If I manage to understand how to use it…

Let’s say that I have a custom post type named Cars .
For each Car post type, I have an ACF field named Manufacturer which is a Radio Button field.
For each Car Manufacturer, I have multiple choices: Ford, Toyota, Mercedes, etc.

On my first attempt, I’ll try to use the Logic tag to define a single condition (but I will have to define multiple ones). I want to display only cars from Ford.

So I write the following code:

 <Set logic="is_electric" any=true>
  <If acf_radio="manufacturer" field="Ford">true<Else />false</If>
</Set>

<Loop type="cars">
  <If logic="is_electric">
    <Field title /><br />
  </If>
</Loop>

This code generates nothing. I’m assuming it’s a syntax error, but I can’t figure which one.

I tried all the following variants, which either ignore my condition or generate no results as well:

<If acf_radio="manufacturer" value="Ford">true<Else />false</If>

<If acf_radio="manufacturer" field="Ford">true<Else />false</If>

<If field="manufacturer" value="Ford">true<Else />false</If>

As soon as I figure this out, I’ll have to add a second condition so that I can display cars from either Ford or Toyota but not Mercedes.

Thank you and sorry if I missed something obvious.

Weird, i can’t even check a simple ACF Radio with the code below.

In the ACF Radio:

option_1 : Option 1
option_2 : Option 2

The L&L template:

ACF Radio: <Field my_test_radio /><br>

<If acf_radio=my_test_radio value=option_1>
  Option 1
<Else />
  Option 2
</If>

Output with option_2 selected in the posts:

ACF Radio: option_2
Option 1

The conditional alway returns the same value.
The doc doesn’t show much examples.

When i add is to the conditional, it always returns Option 2

<If acf_radio=my_test_radio is value=option_1>

I also tried:

<If acf_radio="my_test_radio" value="option_1">
<If acf_radio=my_test_radio is value="option_1">
<If acf_radio=my_test_radio is value="Option 1">

[Update] Swicth works…:

<Switch field="my_test_radio">
  <When value="option_1" />
    Option 1
  <When />
    Option 2
</Switch>

@avanti Switch is working for you because you’ve used field= instead of acf_radio= (the latter is not supported by the <If> tag)

I think the problem is that what gets output when you fetch an ACF radio field with the generic <Field> tag or <If field= depends on how you configured the Return Format of that ACF field: Value, Label or Both (array). I imagine that’s why your test with <If field="manufacturer" value="Ford">true<Else />false</If> didn’t work.

You’ll either need to make sure that your setting is correct (Label in your case), or we can modify the code a bit to make it more robust so it will work regardless of the Return Format setting.

 <Set logic="is_electric" any=true>
  <If check="{Field acf_radio=manufacturer field=label}" value="Ford">true<Else />false</If>
</Set>

<Loop type="cars">
  <If logic="is_electric">
    <Field title /><br />
  </If>
</Loop>

By using check instead of field on the <If> tag I give myself freedom to use a more complex field configuration, because check accepts any text or L&L. I used the proper markup for an acf_radio field and added field=label to specify which value I want to retrieve (the label).

Let me know if this works for you @S1S2

I cannot make it work @julia.

Test 1: I tried changing the ACF field return format to Label and then used the syntax:
<If field="manufacturer" value="Ford">true<Else />false</If>

It displays nothing.

Test 2: I reverted back the ACF field return format to Value and then used the syntax:
<If check="{Field acf_radio=manufacturer field=label}" value="Ford">true<Else />false</If>

It displays nothing.

Test 3: I even tried a variant of #2 syntax:
<If check="{Field acf_radio=manufacturer field=value}" value="Ford">true<Else />false</If>

It displays nothing.

Notice that, once removed the Logic tag, a simple Loop displays the value of the Radio Button without problems:

<Loop type="cars">

    <Field title /> - <Field manufacturer /><br />

</Loop>

So I am not sure what’s the issue.

Oh right @julia, i didn’t noticed i used field instead of acf_radio in the Switch conditional.
You’re also right about using field in the If conditional, it works fine too.
My ACF Radio is set to return a value (ACF default).

So, both of these codes work to check an ACF Radio:

<If field="my_test_radio" value="option_1">
  Option 1
<Else />
  Option 2
</If>
<Switch field="my_test_radio">
  <When value="option_1" />
    Option 1
  <When />
    Option 2
</Switch>

@S1S2 I think I’ll need to test in context to help you solve this. I’ll send you a PM

All ACF field types are supported by the If tag now, including acf_radio. So I believe the following should work:

<If acf_radio="my_test_radio" value="option_1">
2 Likes

I can’t make the If condition work with your syntax, but it works with the following one:

<If field="acf_radio_field_name" value="option_1">

However, my original problem is not solved. Now that I know which syntax works, I put it back into the Logic tag:

<Set logic="is_electric" any=true>
  <If field="manufacturer_acf_radio_field_name" value="Ford">true<Else />false</If>
</Set>

<Loop type="cars">
  <If logic="is_electric">
    <Field title /><br />
  </If>
</Loop>

And this displays nothing.

In other words, the same If condition works if it’s defined by itself and nested inside a Loop tag, but it doesn’t work if it’s defined inside a Logic tag and then nested inside a Loop tag.

If I add the debug=true flag to the Logic tag, I get the following output:

Logic variable: is_electric
Content: false
Result: FALSE

It shouldn’t happen given that the same standalone If condition is satisfied and the Loop tag correctly returns the content I want.

Maybe I’m not understanding how Logic works?

Hi @S1S2 - sorry for the late reply!

…the same If condition works if it’s defined by itself and nested inside a Loop tag, but it doesn’t work if it’s defined inside a Logic tag and then nested inside a Loop tag.

Right, that’s how the logic variable type works currently: it sets its final value when the Set tag is called, not when it’s accessed by the Get tag.

However, I remember there was another person who expected different behavior, as you described, so that the logic variable evaluates its condition every time the Get tag is called.

OK, thinking it through, I believe the behavior can be changed to the latter way, and still be backward compatible.

I’ll add a comment here when it’s implemented.

It was probably me as well, @eliot, as I opened about two different issues that ultimately reconduct to this fundamental question.

I am not sure I need the behaviour to change in the way you are willing to consider.

I rather think I am trying to use L&L in a way it was not intended: as a simple query system for the Loop tag. That is the fundamental driver for all my questions.

As I think I explained in the other post, writing Loop query conditions with CCS can be convoluted for me. So I was hoping to write all my query conditions with the Logic tag and then apply that Logic to a Loop tag.

From our exchanges, I think I’m realizing that it’s really not what Logic is for and I should abandon the idea.

I was hoping to write all my query conditions with the Logic tag and then apply that Logic to a Loop tag

I see what I mean… What if there was a shortcut like this?

<Loop type=cars logic=is_electric>

It could filter the result of a Loop tag with the condition defined by Logic tag.

…Hmm, but on second thought, this is actually not the best way to query things. It would need to get all posts first, then apply If logic to each one.

The query condition is best to construct using Loop tag attributes. They are converted into parameters for the WP_Query class, which creates an SQL statement to query the database.


One reason why it’s difficult to support complex queries is that there are limitations to the kinds of queries that WP_Query can perform.

For example, some field types created by ACF - or other plugins like WooCommerce, LearnDash, etc. - cannot be queried directly because they’re not simple text values. It could be a list of multiple values; post IDs for relationship; or an object with sub-fields…

(There are even some fields that are “virtual”, in that they’re actually not saved as post meta fields, but retrieved by the plugin from a custom database table. Some fields are “derived”, which means every time you ask the plugin to get the field value, it needs to do some processing or calculations.)

To query such non-simple values, it’s necessary to get a larger amount of posts first - which often means all of them - then filter each post with logic conditions.


Another difficulty is that tag attributes are limited in terms of syntax, and not very expressive.

For example, there cannot be multiple attributes of the same name - which means the Loop tag (or any other tags) can’t support multiple conditions with and and or.

To partly get around this, CCS had field, field_2, value, value_2, and so on, to query multiple field values, for example. (Actually L&L does not support this yet - I made a note to add it.)


There’s a new feature added in a recent plugin version, called Query variable type (documented here).

This seems close to what you’re describing, a way to build a query and apply it to a Loop tag. But it’s very minimal currently, and just accepts the same tag attributes as the Loop tag.

From our discussion so far, I wonder if this feature can be developed further, to somehow make it easier to build complex queries like you described.


Well, that was an unexpectedly long comment, haha… I just wanted to explain why things are not as simple as it could be, due to internal constraints of L&L and WordPress itself.

But I’d like to get the template language closer to the ideal, to achieve this “simple query system for the Loop tag”. There’s plenty of room for improvement.

That’s exactly my problem @eliot: I have to query a database where multiple custom post types are linked between each other through ACF relationships fields.

The limitations of WP_Query (and the fact that I don’t know how to code directly in PHP) forced me to write a CCS loop that has to go through all posts multiple times. It’s terribly inefficient and the page rendering takes forever (even with caching plugins enabled).

So I really appreciate the long answer.

I might have written my CCS code in a very inefficient way, but I can’t migrate to L&L until the latter supports multiple query values.

I just took a look at the Query tag. It does exactly what I was hoping to do with the Logic tag (I like the Logic tag more because you can define one condition per line, which improves readability), but it sounds like it won’t solve the inefficiency of having to loop through all posts multiple times.

I don’t mean to force the conversation in a direction it was not meant to go, but if you are interested in using my website as an example to explore the solution, feel free to reach out privately and I’ll show you.

Sure, that sounds interesting. I think seeing the existing CCS code will help me understand what’s necessary for L&L to achieve the same (or better) functionality.


query a database where multiple custom post types are linked between each other through ACF relationships fields

Right, I see. There’s no simple or efficient way to query like that, unfortunately, because of how the database schema is set up in WordPress.

Ideally, the best setup would be to use custom database tables with columns that are indexed properly, to be able to perform efficient queries with relationships.

I think maybe the plugin Pods might be able to create that kind of custom post types and fields… But L&L currently doesn’t have any specific support for Pods and its query system.

Funny you mention that @Eliot. When I started working on WordPress customizations, my first choice was Pods, not ACF. I preferred it because their shortcode system allowed me to visualize the custom fields without writing code, differently from ACF.

But Pods has really poor documentation and close to no support within the WP ecosystem. So I had to abandon the plan.

I could finally embrace ACF only after I discovered your CCS. That was a game-changer.

I still keep an eye on Pods development for certain reasons, and I know that they are about to introduce ACF relationship traversal if I understood it correctly, but it’s not there yet.

I’d rather keep using ACF+L&L because of the documentation. I’ll follow up for more details. Thanks for all the help.