/**
  * Render an array of data entries with an html template. The html template should look like this:
  * ###DATAS###
  * ###DATA###
  * ###DATA_UID###
  * ###DATA###
  * ###DATAEMPTYLIST###
  * Shown if list is empty
  * ###DATAEMPTYLIST###
  * ###DATAS###
  * We have some conventions here:
  * The given parameter $marker should be named 'DATA' for this example. The the list subpart
  * is experted to be named '###'.$marker.'S###'. Please notice the trailing S!
  * If you want to render a pagebrowser add it to the $viewData with key 'pagebrowser'.
  * A filter will be detected and rendered too. It should be available in $viewData with key 'filter'.
  *
  * @param array|Traversable $dataArr entries
  * @param string $template
  * @param string $markerClassname item-marker class
  * @param string $confId ts-Config for data entries like team.
  * @param string $marker name of marker like TEAM
  * @param tx_rnbase_util_FormatUtil $formatter
  * @param array $markerParams array of settings for itemmarker
  * @return string
  */
 function render(&$dataArr, $viewData, $template, $markerClassname, $confId, $marker, $formatter, $markerParams = NULL)
 {
     $viewData = is_object($viewData) ? $viewData : new ArrayObject();
     $debugKey = $formatter->getConfigurations()->get($confId . '_debuglb');
     $debug = $debugKey && ($debugKey === '1' || $_GET['debug'] && array_key_exists($debugKey, array_flip(tx_rnbase_util_Strings::trimExplode(',', $_GET['debug']))) || $_POST['debug'] && array_key_exists($debugKey, array_flip(tx_rnbase_util_Strings::trimExplode(',', $_POST['debug']))));
     if ($debug) {
         $time = microtime(TRUE);
         $mem = memory_get_usage();
         $wrapTime = tx_rnbase_util_FormatUtil::$time;
         $wrapMem = tx_rnbase_util_FormatUtil::$mem;
     }
     $outerMarker = $this->getOuterMarker($marker, $template);
     $htmlParser = tx_rnbase_util_Typo3Classes::getHtmlParserClass();
     while ($templateList = $htmlParser::getSubpart($template, '###' . $outerMarker . 'S###')) {
         if ((is_array($dataArr) || $dataArr instanceof Traversable) && count($dataArr)) {
             /* @var $listMarker tx_rnbase_util_ListMarker */
             $listMarker = tx_rnbase::makeInstance('tx_rnbase_util_ListMarker', $this->info->getListMarkerInfo());
             $templateEntry = $htmlParser::getSubpart($templateList, '###' . $marker . '###');
             $offset = 0;
             $pageBrowser = $viewData->offsetGet('pagebrowser');
             if ($pageBrowser) {
                 $state = $pageBrowser->getState();
                 $offset = $state['offset'];
             }
             $markerArray = $subpartArray = array();
             $listMarker->addVisitors($this->visitors);
             $out = $listMarker->render($dataArr, $templateEntry, $markerClassname, $confId, $marker, $formatter, $markerParams, $offset);
             $subpartArray['###' . $marker . '###'] = $out;
             $subpartArray['###' . $marker . 'EMPTYLIST###'] = '';
             // Das Menu für den PageBrowser einsetzen
             if ($pageBrowser) {
                 $subpartArray['###PAGEBROWSER###'] = tx_rnbase_util_BaseMarker::fillPageBrowser($htmlParser::getSubpart($template, '###PAGEBROWSER###'), $pageBrowser, $formatter, $confId . 'pagebrowser.');
                 $listSize = $pageBrowser->getListSize();
             } else {
                 $listSize = count($dataArr);
             }
             $markerArray['###' . $marker . 'COUNT###'] = $formatter->wrap($listSize, $confId . 'count.');
             // charbrowser
             $pagerData = $viewData->offsetGet('pagerData');
             $charPointer = $viewData->offsetGet('charpointer');
             $subpartArray['###CHARBROWSER###'] = tx_rnbase_util_BaseMarker::fillCharBrowser(tx_rnbase_util_Templates::getSubpart($template, '###CHARBROWSER###'), $markerArray, $pagerData, $charPointer, $formatter->getConfigurations(), $confId . 'charbrowser.');
             $out = tx_rnbase_util_BaseMarker::substituteMarkerArrayCached($templateList, $markerArray, $subpartArray);
         } else {
             // Support für EMPTYLIST-Block
             if (tx_rnbase_util_BaseMarker::containsMarker($template, $marker . 'EMPTYLIST')) {
                 $out = $htmlParser::getSubpart($template, '###' . $marker . 'EMPTYLIST###');
             } else {
                 $out = $this->info->getEmptyListMessage($confId, $viewData, $formatter->getConfigurations());
             }
         }
         $template = tx_rnbase_util_Templates::substituteSubpart($template, '###' . $outerMarker . 'S###', $out, 0);
     }
     $markerArray = array();
     $subpartArray = array();
     // Muss ein Formular mit angezeigt werden
     // Zuerst auf einen Filter prüfen
     $filter = $viewData->offsetGet('filter');
     if ($filter) {
         $template = $filter->getMarker()->parseTemplate($template, $formatter, $confId . 'filter.', $marker);
     }
     // Jetzt noch die alte Variante
     $markerArray['###SEARCHFORM###'] = '';
     $seachform = $viewData->offsetGet('searchform');
     if ($seachform) {
         $markerArray['###SEARCHFORM###'] = $seachform;
     }
     $out = tx_rnbase_util_BaseMarker::substituteMarkerArrayCached($template, $markerArray, $subpartArray);
     if ($debug) {
         tx_rnbase::load('class.tx_rnbase_util_Misc.php');
         $wrapTime = tx_rnbase_util_FormatUtil::$time - $wrapTime;
         $wrapMem = tx_rnbase_util_FormatUtil::$mem - $wrapMem;
         tx_rnbase_util_Debug::debug(array('Rows' => count($dataArr), 'Execustion time' => microtime(TRUE) - $time, 'WrapTime' => $wrapTime, 'WrapMem' => $wrapMem, 'Memory start' => $mem, 'Memory consumed' => memory_get_usage() - $mem), 'ListBuilder Statistics for: ' . $confId . ' Key: ' . $debugKey);
     }
     return $out;
 }