How to handle nested repeating regions in Dreamweaver TBBs in SDL Tridion 2011 SP1
Asked Answered
O

5

7

I am working on DWT TBB in SDL Tridion 2011 SP1.

I have a embedded field "body" which is multivalued. In this embedded field I have one more simple Text field "value", which is again multivalued.

To render the "value" field I have to use two repeating loops.

But I am unable to differentiate the Indeces of the both loops.

I have written as follows.

<!-- TemplateBeginRepeat name="Component.Fields.body" -->
    <!-- TemplateBeginRepeat name="Component.Fields.body[${TemplateRepeatIndex}].value" -->
    <div>@@RenderComponentField("Fields.body[${TemplateRepeatIndex}].value", TemplateRepeatIndex)@@ </div>
    <!-- TemplateEndRepeat -->
<!-- TemplateEndRepeat -->

I am unable to render the fields.

Can any one help how to handle multiple nested regions in DWT TBB.

Thank you.

Outmaneuver answered 25/4, 2012 at 5:0 Comment(1)
Your problem is in trying to access the current field with TemplateRepeatIndex as Neil says. I'll write up a minimal sample in a separate answer (since that allows me to include formatting).Dillondillow
D
15

The Tridion practice page that Neil referred to is a good reference. But that page shows how to generically iterate over all embedded fields. In cases where you know the field name, things get a bit easier. In you case, this is all that is needed in your DWT:

<!-- TemplateBeginRepeat name="body" -->
    <!-- TemplateBeginRepeat name="Field.value" -->
        <div>@@RenderComponentField(FieldPath+".value", 
                                               TemplateRepeatIndex)@@ </div>
    <!-- TemplateEndRepeat -->
<!-- TemplateEndRepeat -->

Line by line:

  1. Iterate over the values of the body field of your Component
  2. Iterate over the values of the value subfield of your body embeddable schema
  3. At this stage the FieldPath refers to the current body value, so body[0], body[1], etc. and TemplateRepeatIndex is the index of the current value. So we can construct the correct RenderComponentField call with this knowledge.

Example

I have a Component with two body fields, each with two value fields. So the XML is:

<Content xmlns="uuid:8841d68e-7b1b-45cd-a6d6-7e7da5de3ef9">
    <body>
        <value>body1.value1</value>
        <value>body1.value2</value>
    </body>
    <body>
        <value>body2.value1</value>
        <value>body2.value2</value>
    </body>
</Content>

The output from the above DWT on this Component is:

<div><tcdl:ComponentField name="body[0].value"
                          index="0">body1.value1</tcdl:ComponentField></div>
<div><tcdl:ComponentField name="body[0].value" 
                          index="1">body1.value2</tcdl:ComponentField></div>
<div><tcdl:ComponentField name="body[1].value" 
                          index="0">body2.value1</tcdl:ComponentField></div>
<div><tcdl:ComponentField name="body[1].value" 
                          index="1">body2.value2</tcdl:ComponentField></div>

Debugging these situations

Many people have problems writing constructs like these. I am no exception, I have just found that I can get most cases working by knowing that the crucial variables are: Field, FieldPath and TemplateRepeatIndex. When in doubt, simply embed this fragment into your DWT inside every TemplateBeginRepeat.

(FieldPath=@@FieldPath@@, TemplateRepeatIndex=@@TemplateRepeatIndex@@)
Dillondillow answered 25/4, 2012 at 19:38 Comment(0)
I
5

Does the FieldPath variable not help you here?

See the Tridion Practice site for an example of iterating over multivalue embedded fields.

Injurious answered 25/4, 2012 at 7:53 Comment(2)
I tried with FieldPath variable. But still no reslult. <!-- TemplateBeginRepeat name="Component.Fields.body" -->aaa <!-- TemplateBeginRepeat name="Component.Fields.body[${TemplateRepeatIndex}].value" -->aa <div>@@RenderComponentField(FieldPath, TemplateRepeatIndex)@@ </div> <!-- TemplateEndRepeat --> <!-- TemplateEndRepeat -->Outmaneuver
You are right Neil, the problem is in not following that example correctly. I'll write up how to do this in a separate example.Dillondillow
H
3

As you noticed already, you cannot use the outer loop index inside the inner loop. The inner loop index will hide the outer loop index. Therefore, you need a workaround. I can think of 2 that I used in the past:

  1. Use a C# TBB (either assembly or fragment) to generate the output. This is not a very nice solution, but it is practical. You could at least generate the output of the inner loop and store the individual values in Package variables. Then in the outer loop you can simply iterate over the values and include them in the output. Example: create variables called body_0, body_1, etc. Then output them inside the outer loop using @@body_${TemplateRepeatIndex}@@

  2. Use Dreamweaver functions to simulate the inner loop index. You can have a function to Set a Package item variable, and one to Increment it. Then use this variable inside the loops. Example:

<!-- TemplateBeginRepeat name="Component.Fields.body" -->
    @@Set("i", 0)@@
    <!-- TemplateBeginRepeat name="Component.Fields.body[${i}].value" -->
        <div>@@Component.Fields.body[${i}].value[${TemplateRepeatIndex}]</div>
    <!-- TempalteEndRepeat -->
    @@Increment("i")@@

You will have to write the Set and Increment DWT functions yourself to store and increment a value in the Package.

Hydromagnetics answered 25/4, 2012 at 6:35 Comment(3)
Thank you for the info. Can you also help me out in writing increment functiions in DWTOutmaneuver
The SDL Live documentation provides a good section on how to implement custom fucntions. Also there is an example by Nickoli Roussakov here: tridiondeveloper.com/get-and-set-variables-in-dwtsSlovene
No custom function nor a custom TBB is needed to accomplish this. See my answer and upvote it if you agree.Dillondillow
L
1

Try this way:-

<!-- TemplateBeginRepeat name="Component.Fields.body" -->
    @@Push("PrimaryIndex", TemplateRepeatIndex)@@
    <!-- TemplateBeginRepeat name="Component.Fields.body[${PrimaryIndex}].value" -->
            @@Push("SecondaryIndex", TemplateRepeatIndex)@@
            <div>@@RenderComponentField("Fields.body[${PrimaryIndex}].value", ${SecondaryIndex})@@ </div>
    <!-- TemplateEndRepeat -->
<!-- TemplateEndRepeat -->

UPDATE 1:

Just I got an idea on this. How about doing this way?

<!-- TemplateBeginRepeat name="Component.Fields.body" -->
    <!-- TemplateBeginRepeat name="value" -->               
            <div>@@Field@@</div> 
    <!-- TemplateEndRepeat -->
<!-- TemplateEndRepeat -->

Without using any TemplateRepeatIndex

Liborio answered 25/4, 2012 at 6:25 Comment(5)
I am getting the error like Push function is not available. Can you help me in overcoming this error.Outmaneuver
I think Push must be a Custom function Siva is using. It is not available by default.Slovene
@DaveHoulker: Push is a custom function.Liborio
@Siva Charan. I think it will not allow us to implement site edit function. Correct me if I am wrongOutmaneuver
@Siva: you are really close with that last example. The only think needed is a @@RenderComponentField(FieldPath, TemplateRepeatIndex)@@ in that inner <div>. I'll write it up in a separate answer.Dillondillow
E
0

For those who are using Tridion 2009 without SP1 version (like our customer), 'FieldPath' variable cannot be used as suggested in the earlier answers. But there is a simple way to achieve this in DWT itself as given below in the example code:

    <!-- TemplateBeginRepeat name="Component.body" -->
        <!-- TemplateBeginRepeat name="Field.value" -->
         <div> @@Field@@> </div>
        <!-- TemplateEndRepeat -->
    <!-- TemplateEndRepeat -->
Epidiascope answered 20/3, 2013 at 17:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.