Reset Variables in Nested Loops

Is it possible to reset all variable values that have been set using <Set variablename>value</Set>?

We use nested loops where the sub loop stores values to use in the main loop. We don’t want those values then carrying on to the next post in the loop.

Normally they’re overwritten, but in some cases they might not be (eg: empty sub loop).

Example (simplified):

<Loop type=cpt_one>
	<Set current_id><Field id /></Set>
	<Loop type=cpt_two field=cpt_one_post_object field_value="{Get current_id}">
		<Set some_value_from_cpt_two>value</Set>
	</Loop>
	Output for CPT One
	CPT Two: <Get somevalue />
</Loop>

In the above example the value for some_value_from_cpt_two would get overwritten each time, even if the value is null. But in more complicated templates the <Set></Set> takes place within logic and I have concerns that a scenario could appear where it might not get overwritten.

They also wouldn’t be overwritten if the sub loop is empty.

Would be good if we could do something to clear all the variables just in case.

I don’t think the solution here is to implement some mechanism to clear variables. Although you could very easily do that by simply adding <Set some_value_from_cpt_two></Set> at the end of each loop to avoid some value getting passed on to the next loop. But that seems inefficient.

I think the solution is instead to use conditional logic to do things like only set a variable if it needs to be set, or perhaps compare a value to a previously saved variable and only do something if those values match or don’t match.

That’s all kind of abstract since it depends on exactly what kind of functionality you’re trying to achieve. But I think it should be possible to just make better use of the If tag to add some smarts to your templates to avoid needing to set and reset stuff.

Here’s an example of one way to improve your template that I believe would work the same way, but without all the redundant variable setting. Again though, it all depends on what you’re trying to achieve:

<Loop type=cpt_one>
  Output for CPT One
  <If loop exists type=cpt_two field=cpt_one_post_object field_value="{Field id}">
    CPT Two: <Field some_field_name />
  </Loop>
</Loop>

The values need to be sent back to the main loop because the info is mixed in with data from the main loop, and possibly other nested loops. Sometimes in tables, sometimes within the general flow of the content.

Eg: CPT_one_field_one / CPT_two_field_two / CPT_one_field_three / CPT_three_field_four

There’s also fall backs where we use a value from CPT One if the value is not set in CPT Two.

If we don’t reset the values then the output would be wrong because it would have been set for a previous post in the loop.

Currently we’re resetting them individually if there’s no loop output using <If loop exists>, eg:

<If loop exists type=cpt_two field=the_field field_value="{Get current_id}" count=1>
	<Loop>
	  <Set variable_one><Field field_one /></Set>
	  <Set variable_two><Field field_two /></Set>
	  <Set variable_three><Field field_three /></Set>  
	  <Set variable_four><Field field_four /></Set>
	</Loop>
<Else />  
	  <Set variable_one></Set>
	  <Set variable_two></Set>
	  <Set variable_three></Set>  
	  <Set variable_four></Set>
</If>

NB: Slight simplification as we actually set the variable from another field for a couple of these, but you get the jist.

But it would be great if we could just reset them all in case we miss one.

2 Likes

I suppose you could create a list of all your variable names (perhaps in another nested template) and then loop through the list to reset each variable to avoid having to repeat yourself each time. Reduces your likelihood of missing any, but it’s still not very efficient.

Another way to achieve this that I just thought of would be to set up your template with one other variable that only serves to check whether the variable of the current loop instance is the same as the variable in the previous loop instance. Then when it comes to displaying your content, you could have some conditional logic that only displays this data if the two variables don’t match. I haven’t thought through exactly how this would be implemented, but it might be worth testing.

A third possible way to achieve this would be to simply set new variable names each time instead of setting and resetting your variables. For example, you might append a number with <Get loop=count /> or something that would iterate for each item in your loop, giving all the variables different names. I imagine that this would probably be more effective than worrying about resetting variables.

Sorry if these ideas were a little vague, I haven’t tested them myself but I imagine with the right implementation they would provide possible solutions to your conundrum. If you do trye these out, feel free to post here based on what you discover!

Another way to achieve this that I just thought of would be to set up your template with one other variable that only serves to check whether the variable of the current loop instance is the same as the variable in the previous loop instance. Then when it comes to displaying your content, you could have some conditional logic that only displays this data if the two variables don’t match. I haven’t thought through exactly how this would be implemented, but it might be worth testing.

The values could be the same, so unfortunately this wouldn’t work. Eg: the first post in the loop could set a variable as “Blue” and the second post could also use “Blue”.

A third possible way to achieve this would be to simply set new variable names each time instead of setting and resetting your variables. For example, you might append a number with <Get loop=count /> or something that would iterate for each item in your loop, giving all the variables different names. I imagine that this would probably be more effective than worrying about resetting variables.

This is a really interesting idea if it works and one that could have quite a lot of uses. Our main concern is having data output that’s incorrect (some of the industries we work in have strict compliance requirements), so with this it would ensure that doesn’t happen.

I’ll have a play around and see if we can get it to work. Thanks!

1 Like