1

Hello, I got a problem with looping over my linked component.
I created a EmailSetup(View UML diagram) Component with a product item.
The product Component has schema (EmailBlockWithCode).

Product:

  • - Code = "wms_III"
  • - Item:
    • - Key = "ProductKey"
    • - Content = "ProductContent"
    • - CallToAction :
  • - Item:
    • - Key = "BluetoothKey"
    • - Content = "BluetoothContent"

    When i loop over this component with the code :

      <products>
                <!-- TemplateBeginRepeat name="Component.Fields.Product" -->
                @@GetComponent(Field,'Product')@@
                <product name="@@Product.Code@@">   
                  <!-- TemplateBeginRepeat name="Product.Fields.Item" -->
                    <@@Product.Fields.Item.Key@@><![CDATA[@@Product.Fields.Item.Content@@]]></@@Product.Fields.Item.Key@@>
                  <!-- TemplateEndRepeat -->
                  <!-- TemplateBeginRepeat name="Product.Fields.CallToAction" -->
                    @@GetComponent(Field,'CallToAction')@@
                    <@@CallToAction.Fields.Item.Key@@><![CDATA[@@CallToAction.Fields.Item.Content@@]]></@@CallToAction.Fields.Item.Key@@>
                  <!-- TemplateEndRepeat -->    
                </product>
             <!-- TemplateEndRepeat -->
        </products>
    


    This is the function GetComponent

    [TemplateCallable]
            public string GetComponent(string tcmUri, string packageVariable) {
                Assert.NotEmpty("tcmUri", tcmUri);
                Assert.NotEmpty("packageVariable", packageVariable);
                IdentifiableObject identifiableObject = m_Engine.GetObject(new TcmUri(tcmUri));
    
                if (identifiableObject as Component == null) {
                    throw new BuildingBlockException("Given tcmUri '" + tcmUri + "' is not a Component.");
                }
    
                Item previousItem = m_Package.GetByName(packageVariable);
                if (previousItem != null) {
                    m_Package.Remove(previousItem);
                }
                Component component = identifiableObject as Component;
                m_Package.PushItem(packageVariable, m_Package.CreateTridionItem(ContentType.Component, component));
                return "";
            }
    

    My output is :

    <products>
            <product name="wms_III">    
    
            </product>
        </products>
    

    So my problem is that the code doesn't loop
    over the 'item' (key = ProductKey; content = ProductContent) I have found a function IteratingOverMultivalueEmbeddedFields but this also won't loop my product. code:

    <!-- TemplateBeginRepeat name="Component.Fields.Product" -->
                @@GetComponent(Field,'Product')@@
           <!-- TemplateBeginRepeat name="Product.Fields" -->
      @@Field.Name@@
      <!-- TemplateBeginRepeat name="Field.Values" -->
        <!-- TemplateBeginIf cond="Field.ContentType = 'text/plain'" -->      
        @@RenderComponentField(FieldPath, TemplateRepeatIndex)@@
        <!-- TemplateEndIf -->
        <!-- TemplateBeginIf cond="Field.ContentType = 'tridion/field'" -->
          <!-- TemplateBeginRepeat name="Field.Fields" -->
            @@Field.Name@@
            <!-- TemplateBeginRepeat name="Field.Values" -->
              @@RenderComponentField(FieldPath, TemplateRepeatIndex)@@        
            <!-- TemplateEndRepeat -->
          <!-- TemplateEndRepeat -->
        <!-- TemplateEndIf -->
      <!-- TemplateEndRepeat -->
    <!-- TemplateEndRepeat -->
    


    UML diagram

    Bert Coenen
    • 143
    • 1
    • 8

    3 Answers3

    1

    So it looks like you can't access the components in the package after your DW function pushes them in?

    With the DGX, your code would be approximately like this, have you considered using it instead?

    <products>
        <!-- TemplateBeginRepeat name="Component.Fields.Product" -->
        <product name="@@Get('Fields.Product[${TemplateRepeatIndex}].Code')@@">   
          <!-- TemplateBeginRepeat name="Product.Fields.Item" -->
            <@@Get('Fields.Product[${TemplateRepeatIndex}].Fields.Item.Key')@@><![CDATA[@@Get('Fields.Product[${TemplateRepeatIndex}].Fields.Item.Content')@@]]></@@Get('Fields.Product[${TemplateRepeatIndex}].Fields.Item.Key')@@>
          <!-- TemplateEndRepeat -->
          <!-- TemplateBeginRepeat name="Product.Fields.CallToAction" -->
            <@@Get('Fields.CallToAction[${TemplateRepeatIndex}].Fields.Item.Key')@@><![CDATA[@@Get('CallToAction[${TemplateRepeatIndex}].Fields.Item.Content')@@]]></@@Get('Fields.CallToAction[${TemplateRepeatIndex}].Fields.Item.Key')@@>
          <!-- TemplateEndRepeat -->    
        </product>
        <!-- TemplateEndRepeat -->
    </products>
    
    Nuno Linhares
    • 10,214
    • 1
    • 22
    • 42
    • That's correct, we can't acces the components in the package. I installed the DGX & the code works. but still The code "" still doens't wants to loop over the 'Item' – Bert Coenen Mar 05 '13 at 09:52
    • Right --- it won't look in a field of a component that is not in the package. Not sure how to work around that TBH, I didn't build the DGX for this use case, and not sure it works at all - mixed reports from the field on using DGX in Repeats and Conditions – Nuno Linhares Mar 05 '13 at 09:58
    • It's weird because if I do "@@Count(Field,'Item')@@" it says that there are 2 counts. & @@Get('Product.Fields.Item[1].Key')@@ it return the value inside! but not when i'm looping – Bert Coenen Mar 05 '13 at 10:08
    • The looping logic in DW is quite complex - and as far as I understood at the time not extensible. This might have changed meanwhile (I wrote the DGX almost 4 years ago) but didn't have time or need to go back to it – Nuno Linhares Mar 05 '13 at 12:12
    • Bert, is your code something like this? [repeat] Get Product [repeat] Get value from product [/repeat] [/repeat] – Arjen Stobbe Mar 07 '13 at 10:07
    • Yes, and the "[repeat] Get value from product [/repeat]" goes over an embedded field where multiple values are allowed. – Bert Coenen Mar 11 '13 at 08:15
    1

    This has probably something to do with how the template is executed. The most inner repeating regions are rendered first, and then the renderer works its way outwards.

    So in the inner repeating region you don't have access yet to the component you get earlier.

    Yes, this is not intuitive at all, but that's how it works.

    What you can do is go through all linked components and push them into the package using the field name in a .NET TBB which is executed before the DWT.

    http://80000ft.blogspot.nl/2011/09/render-order-of-repeating-regions-and.html

    Arjen Stobbe
    • 1,684
    • 9
    • 15
    1

    I fixed this by using this code. Not the best but it works.

    <products>
            <!-- TemplateBeginRepeat name="Component.Fields.Product" -->
                @@RenderComponentPresentation(Field, "tcm:75-72162-32")@@
            <!-- TemplateEndRepeat -->
    </products>
    

    and the renderComponentPresentation loads another dwt with this:

     <product name="@@Component.Fields.Code@@">
              <!-- TemplateBeginRepeat name="Component.Fields.Item" -->
                  <@@Field.Key@@><![CDATA[@@Field.Content@@]]></@@Field.Key@@>
              <!-- TemplateEndRepeat -->
              <!-- TemplateBeginRepeat name="Component.Fields.CallToAction" -->
                  @@GetComponent(Field,'CallToAction')@@
                  <@@CallToAction.Fields.Item.Key@@><![CDATA[@@CallToAction.Fields.Item.Content@@]]></@@CallToAction.Fields.Item.Key@@>
              <!-- TemplateEndRepeat -->    
          </product>  
    
    Bert Coenen
    • 143
    • 1
    • 8