6

I want to find a way to create a counter that I can control the incrementing of. For example in generic programming, if I have an unknown array, and I want the first 5 items, it would look something like:

var i = 0;
foreach(var item in ItemArray){
     if (something == "valueA" && i<=5) {
            do something;
            i++}
}

In Tridion it would look something like

<!-- TemplateBeginRepeat name="items" -->
    <!-- TemplateBeginIf cond="(something == 'valueA') && (TemplateRepeatIndex <= 5)" -->
        Do something
    <!-- TemplateEndIf -->
 <!-- TemplateEndRepeat -->

The problem is obviously that TemplateRepeatIndex increments each time, and I don't want it to. I'd like something like this:

Somehow define customCounter    
<!-- TemplateBeginRepeat name="items" -->
        <!-- TemplateBeginIf cond="(something == 'valueA') && (customCounter <= 5)" -->
            Do something
            customCounter++;
        <!-- TemplateEndIf -->
     <!-- TemplateEndRepeat -->

I'm hoping there is something out of the box that I don't know about.

1
  • 1
    I understand Tridion 2013 SP1 adds the ability to add and iterate over string arrays, something that we've approached with "Dummy" Component Arrays. Either give a bit more flexibility to handle unknown values and quantities, but it'll help to get the count from the "matching" items. In other words, make the array ("collection") first then loop over all of it. Commented Jan 2, 2014 at 8:24

4 Answers 4

7

Dreamweaver templating is not really intended to support generic programming constructs beyond simple loops and conditionals. Yes - you can manage to get it to do more than that, especially if you are prepared to create and install a function source assembly. There are enough people who will be happy to share tricks to make Dreamweaver templating do your bidding, but you're not exactly going to be sailing with the wind.

There are two other approaches you should consider:

  1. Use an assembly template building block to construct the output that requires programming logic. Your Dreamweaver TBB can then place this output correctly in your page or component presentation.
  2. Use a different mediator instead of the built-in Dreamweaver templating mediator. The Razor Mediator For Tridion would allow you to use Razor syntax, giving you C#-based logic directly in your template.
4

The thing I usually do in this case is structure my algorithm differently so that you can use TemplateRepeatIndex, for example use a modulator or some formula (e.g. TemplateRepeatIndex%5).

If you're adamate about having this custom counter, then you have more options: Write a C# TBB that finds the specific collection of the items you want to loop over and creates the count variable, then dumps it onto the package, so you'd have a variable on the package called 'customCounter'. So you can do ${customCounter} or @@customCounter@@ inside your DWT syntax.

The other option is to write a DWT Function that does the similar thing, pass in the TCM ID of your item (or the container item), count them up in your special way and then return the number. The docs on how to implement the custom functions are here (login required): http://sdllivecontent.sdl.com/LiveContent/content/en-US/SDL_Tridion_2011_SPONE/task_EFD94BC0585D4186A13F7F3C3B6F47EA

Another option you can try is set the counter into Context Variables as described here: http://www.tridiondeveloper.com/get-and-set-variables-in-dwts. A word of caution with this though, the DWT Mediator evaluates nested expressions in a funky way, so the scopes in which you can create/access your counters are limited.

3
  • the first option doesnt work because I am paring it with another conditional and since its a component query I have no idea what items will be in the collection when I start processing them, the second one doesn't allow me to add to the counter, the third one I dont have a TCM number as the collection is created via component query, and I dont know what items are even there until after the template runs. And unfortunately the GetVariable doesn't seem to work in a conditional statement. :(
    – Daryl H
    Commented Dec 31, 2013 at 18:59
  • All options work. You can run the exact same looping algorithm using C# as you would with DWT, but only print the counters (I.e. push vars onto package). Then run the algorithm again in DWT using the printed (pushed) counters, but this time render your actual markup. Commented Dec 31, 2013 at 19:46
  • 1
    For the example in the question, the C# TBB could add the first 5 items where something == 'valueA'. The DWT would then loop over all of them--no additional conditional needed unless I'm missing something? Commented Jan 2, 2014 at 8:12
2

Out-of-the-box: I think Nick already covers most options, and I don't think there's much you can use there.

I would probably just create a custom Function to be called from DWT, that would take an int as a parameter (or just increment by 1 every time it's called).

Creating a custom Function is really simple, and there's quite a few examples in Tridion World.

2

Here is a possible solution with the Razor Mediator on a page template with your values:

@{int customCounter = 0;}

@foreach (var cp in ComponentPresentations) {
  if ((cp.Component.something == "valueA") && (customCounter++ <= 5)) {
    ***Do something***
  }
}

Most of the credit goes to Dominic Cronin for pointing me to Razor in the 1st place. Hope that helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.