Problems, need help? Have a tip or advice? Post it here.
8 posts Page 1 of 1
Hi there,

I'm scratching my head right now, I can't figure out why below IF clause doesn't work - any ideas where I go wrong?

Code: Select all
<cms:repeatable name='inclusions' label='Inclusions'>
  <cms:editable name='inclusion' type='text' label='Inclusion item' />
</cms:repeatable>

<cms:if inclusions>
                <div id="inclusions">
                    <h3>Inclusions</h3>
                    <ul>
                      <cms:show_repeatable 'inclusions'>
                        <li class="details-lists">
                            <cms:show inclusion />
                        </li>
                      </cms:show_repeatable>
                    </ul>
                </div>
</cms:if>


:roll:
Hi,

An idiosyncrasy of regular repeatable-region (i.e. non-stacked) is that it will always contain at least one row (try deleting all rows and upon save you'll find that a blank row has been automatically added).

This makes it difficult to use the count of rows for figuring out if the region is actually empty.
As a workaround, we can use the 'Buffering output' technique described in our tutorial (https://docs.couchcms.com/tutorials/por ... -form.html). For your case, the code could become like this -
Code: Select all
<cms:capture into='my_buffer'>
    <div id="inclusions">
        <h3>Inclusions</h3>
        <ul>
          <cms:show_repeatable 'inclusions'>
            <li class="details-lists">
                <cms:if "<cms:strlen inclusion />">
                    <cms:show inclusion />
                    <cms:set my_has_data='1' 'global' />
                </cms:if>   
            </li>
          </cms:show_repeatable>
        </ul>
    </div>
</cms:capture>

<cms:if my_has_data>
    <cms:show my_buffer />
</cms:if>

As you can see, as we loop through the rows we make a note (via a global variable) if there is any contained data and then accordingly choose to show the output or not.

Hope this helps.
KK wrote: Hi,

An idiosyncrasy of regular repeatable-region (i.e. non-stacked) is that it will always contain at least one row (try deleting all rows and upon save you'll find that a blank row has been automatically added).


Hi KK, thank you so very much for your reply, I hope the new year will bring you joy and prosperity:)

I noticed exactly this, that when I remove all the rows, one row will always be there once I hit reload. And I assumed this is why the IF statement will fail.


KK wrote: This makes it difficult to use the count of rows for figuring out if the region is actually empty.
As a workaround, we can use the 'Buffering output' technique described in our tutorial (https://docs.couchcms.com/tutorials/por ... -form.html). For your case, the code could become like this -
Code: Select all
<cms:capture into='my_buffer'>
    <div id="inclusions">
        <h3>Inclusions</h3>
        <ul>
          <cms:show_repeatable 'inclusions'>
            <li class="details-lists">
                <cms:if "<cms:strlen inclusion />">
                    <cms:show inclusion />
                    <cms:set my_has_data='1' 'global' />
                </cms:if>   
            </li>
          </cms:show_repeatable>
        </ul>
    </div>
</cms:capture>

<cms:if my_has_data>
    <cms:show my_buffer />
</cms:if>

As you can see, as we loop through the rows we make a note (via a global variable) if there is any contained data and then accordingly choose to show the output or not.

Hope this helps.


I just tried above code, and it works like a charm! It of course adds a lot of extra code on the page (need to do these for 6 different repeatables on the page). Will it slow things down a lot? To be honest, I do not fully comprehend how it works, I will do some testing with using capture to get a hang of it, I saw it mentioned in the contact form tutorial.

Anyhow, it works now and that's the key - I'm grateful for your quick reply, thanks mate :)
Hi again,

Just a little follow up. Since I have a working if clause for the repeatables, I thought - aha! I can use the same code to show the link to the list, but only if it exists. But since the menu is higher up in the document, it doesn't seem to work unless places after. Any ideas on this?

Code: Select all
<li><a href="#inclusions">Inclusions</a></li>
<li><a href="#optionals">Optionals</a></li>


Code: Select all
<cms:if inclusions_has_data>
  <li><a href="#inclusions">Inclusions</a></li>
</cms:if>
<cms:if optionals_has_data>
  <li><a href="#optionals">Optionals</a></li>
</cms:if>
But since the menu is higher up in the document, it doesn't seem to work unless places after. Any ideas on this?

This, again, is one of the use-cases where buffering will help.

If you take a look at the original solution above, you'll notice that there are two parts to it - one block (<cms:capture into='my_buffer'>..</cms:capture>) creates the output but does not show it. The second block (<cms:if my_has_data></cms:if>) actually goes on to show it if conditions are right.

In my code the two blocks came right one after the other but there is no problem in separating them. So, coming to your problem, you can keep the first block (the buffer) up in your document even before the menu (it is not outputting anything so it will add nothing to the markup).

This way, the menu can have access to the calculations made by the first block.
As for the second block, place it in your document precisely where you want to show the buffered contents.
This way the buffer can be used by both the menu as well as the previous code,

Hope this helps.
KK wrote:
But since the menu is higher up in the document, it doesn't seem to work unless places after. Any ideas on this?

This, again, is one of the use-cases where buffering will help.

If you take a look at the original solution above, you'll notice that there are two parts to it - one block (<cms:capture into='my_buffer'>..</cms:capture>) creates the output but does not show it. The second block (<cms:if my_has_data></cms:if>) actually goes on to show it if conditions are right.

In my code the two blocks came right one after the other but there is no problem in separating them. So, coming to your problem, you can keep the first block (the buffer) up in your document even before the menu (it is not outputting anything so it will add nothing to the markup).

This way, the menu can have access to the calculations made by the first block.
As for the second block, place it in your document precisely where you want to show the buffered contents.
This way the buffer can be used by both the menu as well as the previous code,

Hope this helps.


KK, Again - thank you very much, your explaination really helped me to grasp how it works much better. I modified the code and it works like a charm! cms:capture sure is a powerful tool in couch, I can vision other areas where this can come in handy!

Couch rocks!
Thanks. You are welcome :)
Just a note.
For me it didn't work, as the repeatable region always generated an empty slot.

So I did :

Code: Select all
<cms:capture into='my_buffer'>
    <div class="row">
       <div class="col-xs-12 col-md-offset-2 col-md-8">   
            <div id="articleslinks">
                <h3>Some articles about <cms:show name /></h3>
                <ul>
                  <cms:show_repeatable 'linkarticles'>
                    <cms:if articlelink!=''><cms:set my_has_data='1' 'global' /></cms:if>
                    <li><a href="<cms:show articlelink />" target="_blank"><cms:show desclink /></a></li>
                   
                  </cms:show_repeatable>
                </ul>
            </div>
        </div>
    </div>
</cms:capture>

<cms:if my_has_data>
    <cms:show my_buffer />
</cms:if>


And the
Code: Select all
<cms:if articlelink!=''><cms:set my_has_data='1' 'global' /></cms:if>

Made it work.

In case someone has the same problem. Not sure why it didn't work like in KK exemple, thought.

Cheers
8 posts Page 1 of 1