# Diving into nested templates and repeaters, is this right?

**URL:** <https://forum.inductiveautomation.com/t/diving-into-nested-templates-and-repeaters-is-this-right/100949>\
**Category:** Ignition\
**Tags:** scripting, ignition81, perspective, vision\
**Created:** [January 15, 2025, 9:24pm UTC](https://forum.inductiveautomation.com/t/diving-into-nested-templates-and-repeaters-is-this-right/100949 "2025-01-15T21:24:28Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [January 15, 2025, 9:24pm UTC](https://forum.inductiveautomation.com/t/diving-into-nested-templates-and-repeaters-is-this-right/100949/1 "2025-01-15T21:24:28Z")

</div>

Continuing my journey into nested templates, origin point is this [thread](https://forum.inductiveautomation.com/t/group-container-or-template-repeater/100745/5), but I did change the structure a little. My intent was to make it simpler, but I'm not sure if this is the right way to do it.

This is the lowest level template:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/d/bd579c06578710085c91f07450419c37e49d15b1.png)

I have three of these inside another template with an additional button:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/e/eee1dbc1562e63d6a3f68108a3f6f44f94ae0ec5.png)

This template, then, is used inside a Template Repeater, currently three repeated instances, with a total of **19** instances.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/3/3/33d4c6d191493af6f2885242fe37b820d27e6aa2.png)

_Note: I did post pictures like these in my previous thread, but I have slightly different question this time with a slightly different structure._

With this code, I have found a way to read from the UDT on the lowest level template and write to it's components. (I think I got the Java or Python(?) class descriptors from a post by @justinedwards.jle )

```python
repeater = event.source.parent.getComponent('Template Repeater 2')
templateList = repeater.getLoadedTemplates()
for template in templateList:
	for counter in range(3):
		for component in template.components:
		if 'TemplateHolder' in component. __class__. __name__ :
			compDir = component
			print compDir.name # the name of each instance of the Recipe_Manager_Crystal_1
			if compDir.UDT.Control.ON_OFF == False:
				tempComp = compDir.getComponent(0) # The name of the template Recipe_Manager_Crystal_1					
				numObj = tempComp.getComponent(5)
				numObj.value = 10.0

```

_Note: Don't mind the naming convention of some of those variables, I just reused them for different types/objects as I was going._

The _end goal_, here is to bring in a dataset of values to write to the `Numeric Text Field` (which is referenced by this: `numObj = tempComp.getComponent(5)`, then allow the user to adjust said value using the `+/-` buttons, and finally write those values to each `UDTs Control Value` for the selected positions.

One thing I am not sure about is how to count the number of templates within another template, hence the `counter in range(3)`. We will have templates with from two to four nested templates, so if there is a way to count the number of nested templates, I would love to learn it!

To re-posit the question: Is this code representing a good/right way of reading UDTs and writing to components in those lowest level nested templates, and the second part will this work to write to the UDTs? (Using `writeBlocking()`, of course.)

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 15, 2025, 9:45pm UTC](https://forum.inductiveautomation.com/t/diving-into-nested-templates-and-repeaters-is-this-right/100949/2 "2025-01-15T21:45:59Z")

</div>

Vision is perfectly happy to let you drill up or down in any component hierarchy--there's no barriers to any introspection.

As for lengths--any variable-size content in any Vision component is driven by some kind of dataset, which has a `.rowCount` property, or directly by a repeat count. No need to use constants. And for cases where you want to iterate through a list (of templates perhaps), you can use python's `enumerate()` function to supply integers with the objects.

---

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [February 4, 2025, 4:56pm UTC](https://forum.inductiveautomation.com/t/diving-into-nested-templates-and-repeaters-is-this-right/100949/3 "2025-02-04T16:56:43Z")

</div>

Instead of drilling down through the layers to pass values, I called Support and he helped me understand I could use the `repeater.templateParams` to pass values to the base layer templates.

That works well, however, the `button` in the middle layer, labeled "CZ01/02/02", needs to access and change some values in it's parent `Template Repeater`. So, I figured this much out:

```python
obj = system.gui.getParentWindow(event).getRootContainer().getComponent('Template Repeater 2') # This works
params = system.dataset.toPyDataSet(obj.templateParams)
output = []
for row in range(params.getRowCount()):
	output = system.dataset.setValue(params, row, 5, 1)
    print output.getValueAt(row,5)

```

The print statement prints the correct value (`1`), seven times. But, when I add this line to the code:

```python
obj.templateParams = output

```

I don't see seven one's. The only `1` I see is the last one, the other six values are unchanged.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/c/5/c52722d967d21f478c71d8aa0326700cb4f75daf.png)  
**Edit** : I manually changed the first row values.

Ok, I think I see why: the `setValue()` function returns a new dataset every time it's called...

I found out how to get a `dataset` into a `list`, like so:

```python
query = "Development/Recipe/ZoneNameList"
params = {}
results = system.db.runNamedQuery(query, params)
data = [[0] * results.getColumnCount() for _ in range(results.getRowCount())]
for i in range(results.getRowCount()):
	for j in range(results.getColumnCount()):
		data[i][j] = results[i][j]

```

Now, how do I take this `list` and set it as the new `templateParams`?

I figured that part out.

Now, I have two more questions:

1. How do I get the second level template, in a repeater, to know which repeater it's in? If I could say `If you're in repeater 1, else if you're in repeater 2...` Because there are many zones in each repeater, and each zone has from one to four positions. I need to change specific zone-position properties.

To access these properties, via the template parameters on the repeater, this is what I have:

```python
zone = event.source.parent.zone

obj = system.gui.getParentWindow(event).getRootContainer().getComponent('Template Repeater 2') # This works

row = params.getRowCount()
col = params.getColumnCount()
output = [[0] * col for _ in range(row)]
for row in range(row):
	for col in range(col):
		output[row][col] = params[row][col]

# Toggle the whole zone
if output[zone - 1][1] == 1:
	output[zone - 1][1] = 0
else:
	output[zone - 1][1] = 1

headers = params.getColumnNames()
headers2 = []
for item in headers:
	headers2.append(str(item))

outputDS = system.dataset.toDataSet(headers2, output)

obj.templateParams = outputDS

```

This code addresses changing the values in my second post, going from dataset to list and back to dataset for the `templateParams`. If this code does not know which repeater it is in, it won't be able to find it's zone number in the `templateParams` on the repeater, and won't be able to change the second field parameter value, in this case.

1. How can I count the number of objects (whether templates or components) nested in a template? @pturmel mentioned `.rowCount` and `repeat count` but I have not been able to successfully apply `.rowCount()` to any object, yet. If I take the loaded templates from a repeater and print that, I get an array.

```python
comp1 = event.source.parent.getComponent('Template Repeater')
comp1Objects = comp1.getLoadedTemplates()
print(comp1Objects)

```

What I would like to do is something like:

```python
for template in templates:
   if parameter1 == 1:
      parameter2 = 0

```

This is why I used the `for counter in range(3):` in my original post, but like I said, there could be 1 to 4, not just 3. I am referring to the lowest level templates to loop through, and the code would need to _exclude_ the button (which has a text like `CZ01`).
