Servus,
also es gibt da mehrere Lösungsansätze. Beispielsweise könnte man die Teaser-Klasse durch eine eigene Version, die dann einen entsprechenden Counter Platzhalter setzt, mittels Plugin austauschen/ersetzen. Nachteil dabei, bei einem Update des Core müssen eventuelle Änderungen auch in der eigenen Klasse eingepflegt werden.
Ich habe mich für eine andere Alternative, nämlich den Einsatz einer Chain-Funktion mittels der CECRegistry, entschieden. Das ist eigentlich recht simpel und es bietet sich dafür die entsprechende Schnittstelle in der Methode 
generate() der Template-Klasse 
(cTemplate) an.
Die Funktion 
addLoopCounter() nimmt den von der Chain aus der Template-Klasse gelieferten Content, prüft ihn auf das Vorhandensein einer Schleife und ersetzt ihn dann, und nur dann, durch einen geparsten Content mit dem zusätzlichen Platzhalter {LOOP_COUNT}.
Diese Erweiterung, bzw. deren Umsetzung, zeigt auch beispielhaft den Einsatz der CONTENIDO CHAIN-Schnittstelle in Modulen und wird sicherlich auch Teil meines Buches für Entwickler sein.
Hier nun der entsprechende modifizierte Modul-Output des Standard-Modules:
Code: Alles auswählen
<?php
/**
 * description: standard teaser - text teaser with loop count placeholder
 *
 * @package Module
 * @subpackage ContentTeaserText
 * @version SVN Revision $Rev:$
 *
 * @author timo.trautmann@4fb.de
 * @author Ortwin Pinke <o.pinke@conlite.org>
 * @copyright four for business AG <www.4fb.de>
 * @license http://www.contenido.org/license/LIZENZ.txt
 * @link http://www.4fb.de
 * @link http://www.contenido.org
 */
/**
 * Adds a template placeholder for counting the loop of dynamic content
 * using chain in cTemplate::render()
 * 
 * You may use it with placeholder {LOOP_COUNT} in your teaser templates
 * 
 * @author Ortwin Pinke <o.pinke@conlite.org>
 * @copyright (c) 2015, Ortwin Pinke
 * @version 1.0.0
 * 
 * @param string $sContent template content give by class cTemplate
 * @param cTemplate $oTpl use class object readonly
 * @return string new content if dynamic content was found, otherwise bypassed content
 */
if (!function_exists("addLoopCounter")) {
    function addLoopCounter($sContent, cTemplate $oTpl) {
        // If content has dynamic blocks we have to parse it
        // otherwise we will just return it
        $startQ = preg_quote($oTpl->tags['start'], '/');
        $endQ = preg_quote($oTpl->tags['end'], '/');
        if (preg_match('/^.*' . $startQ . '.*?' . $endQ . '.*$/s', $sContent)) {
            $pieces = array();
            preg_match_all('/^(.*)' . $startQ . '(.*?)' . $endQ . '(.*)$/s', $sContent, $pieces);
            // Safe memory
            array_shift($pieces);
            $sContent = '';
            // Now combine pieces together
            // Start block
            $sContent .= str_replace($oTpl->needles, $oTpl->replacements, $pieces[0][0]);
            unset($pieces[0][0]);
            // Generate dynamic blocks
            for ($a = 0; $a < $oTpl->dyn_cnt; $a++) {
                $aNeedles = $oTpl->Dyn_needles[$a];
                $aReplacements = $oTpl->Dyn_replacements[$a];
                // now we add our own loop replacements we need
                $aNeedles[] = "{LOOP_COUNT}";
                $aReplacements[] = $a + 1;
                $sContent .= str_replace($aNeedles, $aReplacements, $pieces[1][0]);
            }
            unset($pieces[1][0]);
            // End block
            $sContent .= str_replace($oTpl->needles, $oTpl->replacements, $pieces[2][0]);
            unset($pieces[2][0]);
        }
        return $sContent;
    }
}
$oCecReg = cApiCecRegistry::getInstance();
$oCecReg->addChainFunction("Contenido.Template.BeforeParse", "addLoopCounter");
echo "CMS_TEASER[3]";
$oCecReg->removeChainFunction("Contenido.Template.BeforeParse", "addLoopCounter");
mi18n("MORE");
?>
Das Ganze ist getestet und funktionierte bei mir in einem Demomandanten problemlos. Solltet ihr Probleme oder Fragen dazu haben, dann immer her damit.
Gruß aus Franken
Ortwin