NO BUG: Query Loop wrapping element

Update - see comment below: NO BUG: Query Loop wrapping element - #4 by mizzinc

Browser: Opera
OS: \Windows
URL:


** Bricks**: 1.7.3

Been playing with ACF Flexible Content and Query Loop.
When inspecting code, the element with the query loop wraps each layout. i.e. a block wraps a section.

For example:

<div class="block with queryloop">
<section></section>
</div>
<div class="block with queryloop">
<section></section>
</div>

Sure, I could change the block to a section and the child section to a div. But then, I need to create a custom class to remove the default ACCS styling on the parent section and, of course, reapply all section css styling to the now div.

Plus this adds an extra element.

Code should appear as:

<main>
<article> (with query loop)
<section></section>
<section></section>
<section></section>
</article>
</main>

I would do that.

It’s different to a ‘repeater’ element from other builders, the query loop is applied to the element that you wish to duplicate.

1 Like

Went with this method. Maybe a filter or control in future to remove the wrapper element could be useful.

Worthwhile adding a feature request?

Given this some further consideration and reverted the title to a bug, or maybe it should be WIP?

Consider the following HTML structure in Bricks.

The expected output on the frontend is:

<article> (with query loop)
<section> <div class="container"><h3>Post Title</h3></div></section>
<section> <div class="container"><h3>Post Title</h3></div></section>
<section> <div class="container"><h3>Post Title</h3></div></section>
</article>

Yes, I am going over this again. My point is. If I hand coded this query loop, then the result would be as above. The query element wraps all child elements.

However, Bricks decides to use the query element to wrap each child element. That is not the expected result, it’s also not true to what’s been designed in the structure panel.

As developers, we don’t like surprises. Bricks gives us granular control, that’s the buy-in and this current output is not true to let’s say Brick ethos. If I wanted each child element to have a wrapping element, then I would add it.

I think, I have a strong case on this one. Could we add a control to disable the default behaviour for backwards compatibility?

What say you?

This is definitely a feature request and not a bug, the element with the query loop is supposed to duplicate (along with all content inside of it) because it’s now in a loop.

You may be best writing up a new feature request with an example of how you imagine it working and what problem it solves, so people can upvote or comment. I can’t currently see the benefit, as it looks like we’d always need to add the query loop to a container, meaning always having to add an extra element if we want something to loop, rather than just directly duplicating any element. (for example you can already achieve the output you’re lookng for by moving the query loop onto a child of the ‘article’ element, rather than applying it to the article element) But adding more specific examples may help more people get behind the idea.

i think if you leave this post as ‘bug’ it could just get remarked as ‘no bug’ and may just get lost. imo I’d write up a new feature request or add to the ideas board.

However, Bricks decides to use the query element to wrap each child element. That is not the expected result,

Just noting this part is incorrect, to clarify incase of a misunderstanding. Bricks isn’t wrapping anythng. It’s just duplicating the ‘article’ element from your structure panel, because that’s the element in the loop. The element you add the query loop to is added inside the loop.

The code version would be…

if( have_rows('content') ):
    while ( have_rows('content') ) : the_row();

    /* your <article> element */

    endwhile;
endif;
1 Like

Hi MIchael,
Thanks so much for your report!

As David said, this is not a bug. This is exactly how the query loop works. The element on which the loop is located is repeated.

In your example, the query loop should be on the section to get the desired result.

<article>
<section> <div class="container"><h3>Post Title</h3></div></section> (loop should be here)
...
</article>

Best regards,
timmse

Thanks everyone for the responses.

Timmse - If I use your suggested method, then I lose the ability to customise individual sections.

For example, the next section might require ACCS var(–section-space-xs) or a unique class. At least that’s how I interpret it.

I went ahead and changed:

  • the block to a section and applied class pad–none to override ACSS base spacing.
  • the child element from a section to a div
  • applied ACCS section padding using variables as a workaround on the div. Use of variables still allows for scalability, I suppose.

Respect, this is not a bug. Updated the title.

Alternatively, I could use a code element rather than query loop. Ideally, I refer to the OP.
Maybe I’m not seeing this correctly, as per everyone’s responses.

To assign different styles to the children, you can use nth-child for example.

Currently, each child gets the exact same styling and classes (because it is a repeated element), but this would also be the case in a normal WordPress loop unless you add a separate index.

Hmm - maybe I’m trying to make the query loop fit into a box it shouldn’t be in.

nth-child styling is an option, not ideal if every single section is unique. I don’t think that’s the right approach.

Maybe the answer is to feature request the query-builder function being added to the code element, whereby it generates the php. Which is kind of similar to a nested element…

OR

Add an option in the query builder to output the PHP to copy/paste into code element.

I think there is room for improvement, especially in a use case which requires accounting for many possible variables (css/classes).

Depending on what you’re looping over or where it comes from, you could always pass an attribute to assign styling. Take the most common example of looping though a cpt. If you add a custom field to that cpt, you can output that in the section your repeating and then set up styles based on that.

The field could be a radio group for various layout or spacing options or whatever. Seems the most painless way to me anyway :slight_smile:

Something similar to this just with an acf field instead: How to set a background color based on post category - #2 by manc

1 Like

Looping over ACF Flexible Content manc, so assigning radio groups (for admins only) to each layout is a good workaround idea. Thanks for submitting a response :slight_smile:

@timmse - Trying to build a dynamic template based on ACF repeater fields. A very common case no doubt. The issue I have is similar because the tag assigned to the repeating element is indeed wrapping each element being repeated inside if that element itself does not have a repeater. An example of this:

On the front end, the element is wrapped inside the most-near parent’s HTML tag. It equates to a semantically messy DOM. I tried to pull the inner elements out, but I could not find any way to repeat without it being in a block/div with at least some HTML tag. Regardless of argument on if it matters or not for SEO or other purposes, it bloats the BOM and minimum, when all I want to do is repeat ‘p’ or ‘h2’ or ‘img’ tags inside of a repeater field being looped through.

Do you have any suggestions on how to queryloop just the actual inner elements without wrapping them in the outer element? I even tried custom code block to build the HTML myself, but alas, that code block does not allow a query loop. We need some query-loopable method on all elements, really. Why not allow a query loop on heading elements? On text elements? What does it hurt to allow that, vs just allowing it on “outer” structural elements? Is there any element that would let me do what I need to do? Is there a filter I can use to enable query looping on any element I want?

It doesn’t make sense right? If you’ve originally created layouts using code, the query loop should just be the equivalent of the PHP while() function. Instead it outputs a dom element.

This frustrated me to no end when I started working with ACF Flexible layouts, because my query loop was on the section element and depending on the layout, each section has different CSS attributes applied. Doesn’t work in this setup.

Therefore, I had to output a dumb section element, then apply all the section styling to the first inner tag to maintain good markup.

E.g Section > .container or .wrap or something.

I don’t think my answer directly addresses your issue, but maybe assists looking at things from a different perspective to solve the problem.

Ideally it would be cool to set a query loop but output no wrapper.

Similar to the code element. Or if you want, use the code element to write your ACF while function. That works too!

OR could a query loop be applied to the code element?

Aside. Gutenbricks is a cool solution for flexible layouts using Gutenberg.