[TYPO3]

Fluid FOR mit Modulo

Ja, ich weiß, man kann ziemliches Geschwurbel in Fluid machen, man kann auch die VHS Extension installieren und den lieben Gott einen guten Mann sein lassen und man kann sich auch mit 'nem Hammer selbst den Schädel einschlagen.

Falls man aber tatsächlich mal echtes Modulo braucht, mit sinnvollen Features, kann man sich lieber 'nen ViewHelper selber stricken, so wie diesen hier. Ist einfach 'ne stupide Kopie vom f:for ViewHelper, dem ich 'ne zusätzliche Option hinzugefügt habe.

Classes/ViewHelpers/ForViewHelper.php:


<?php
namespace My\Fucking\Namespace\ViewHelpers;

/***
 *
 * for ViewHelper variant with modulo feature for the iterator
 * iterator.moduloMax is just added for convencience as one can not count in fluid.
 *
 * iterator.modulo = iterator.index % iterationModulo
 * iterator.moduloCycle = iterator.modulo == 0 ? ++iterator.moduloCycle : iterator.moduloCycle
 * iterator.moduloFirst = iterator.modulo == 0
 * iterator.moduloLast = iterator.modulo == iterationModulo - 1
 *
 * <code title="Iteration information">
 * {namespace mfn=My\Fucking\Namespace\ViewHelpers}
 * <ul>
 *   <mfn:for each="{0:1, 1:2, 2:3, 3:4}" as="foo" iteration="fooIterator" iterationModulo="3">
 *     <li>Index: {fooIterator.index} Cycle: {fooIterator.cycle} Total: {fooIterator.total}{f:if(condition: fooIterator.isEven, then: ' Even')}{f:if(condition: fooIterator.isOdd, then: ' Odd')}{f:if(condition: fooIterator.isFirst, then: ' First')}{f:if(condition: fooIterator.isLast, then: ' Last')} Modulo: {fooIterator.modulo} ModuloCycle: {fooIterator.moduloCycle}{f:if(condition: fooIterator.moduloFirst, then: ' ModuloFirst')}{f:if(condition: fooIterator.moduloLast, then: ' ModuloLast')}</li>
 *   </mfn:for>
 * </ul>
 * </code>
 * <output>
 * <ul>
 *   <li>Index: 0 Cycle: 1 Total: 4 Odd First Modulo: 0 ModuloCycle: 1 ModuloFirst</li>
 *   <li>Index: 1 Cycle: 2 Total: 4 Even Modulo: 1 ModuloCycle: 1</li>
 *   <li>Index: 2 Cycle: 3 Total: 4 Odd Modulo: 2 ModuloCycle: 1 ModuloLast</li>
 *   <li>Index: 3 Cycle: 4 Total: 4 Even Last Modulo: 0 ModuloCycle: 2 ModuloFirst</li>
 * </ul>
 * </output>
 *
 * see: TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper
 *
 ***/

class ForViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper implements \TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface
{
    /**
     * Iterates through elements of $each and renders child nodes
     *
     * @param array $each The array or \TYPO3\CMS\Extbase\Persistence\ObjectStorage to iterated over
     * @param string $as The name of the iteration variable
     * @param string $key The name of the variable to store the current array key
     * @param bool $reverse If enabled, the iterator will start with the last element and proceed reversely
     * @param string $iteration The name of the variable to store iteration information (index, cycle, isFirst, isLast, isEven, isOdd)
     * @param int $iterationModulo
     * @return string Rendered string
     * @api
     */
    public function render($each, $as, $key = '', $reverse = false, $iteration = null, $iterationModulo = null)
    {
        return static::renderStatic(
            $this->arguments,
            $this->buildRenderChildrenClosure(),
            $this->renderingContext
        );
    }

    /**
     * @param array $arguments
     * @param \Closure $renderChildrenClosure
     * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
     * @return string
     * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
     */
    public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext)
    {
        $templateVariableContainer = $renderingContext->getTemplateVariableContainer();
        if ($arguments['each'] === null) {
            return '';
        }
        if (is_object($arguments['each']) && !$arguments['each'] instanceof \Traversable) {
            throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('ForViewHelper only supports arrays and objects implementing \Traversable interface', 1248728393);
        }

        if ($arguments['reverse'] === true) {
            // array_reverse only supports arrays
            if (is_object($arguments['each'])) {
                $arguments['each'] = iterator_to_array($arguments['each']);
            }
            $arguments['each'] = array_reverse($arguments['each']);
        }
        if ($arguments['iteration'] !== null) {
            $iterationData = [
                'index' => 0,
                'cycle' => 1,
                'total' => count($arguments['each']),
                'modulo' => 0,
                'moduloCycle' => 0
            ];
        }

        $output = '';
        foreach ($arguments['each'] as $keyValue => $singleElement) {
            $templateVariableContainer->add($arguments['as'], $singleElement);
            if ($arguments['key'] !== '') {
                $templateVariableContainer->add($arguments['key'], $keyValue);
            }
            if ($arguments['iteration'] !== null) {
                $iterationData['isFirst'] = $iterationData['cycle'] === 1;
                $iterationData['isLast'] = $iterationData['cycle'] === $iterationData['total'];
                $iterationData['isEven'] = $iterationData['cycle'] % 2 === 0;
                $iterationData['isOdd'] = !$iterationData['isEven'];
                if ($arguments['iterationModulo'] !== null ) {
                    $iterationData['modulo'] = $iterationData['index'] % $arguments['iterationModulo'];
                    $iterationData['moduloCycle'] = $iterationData['modulo'] == 0 ? ++$iterationData['moduloCycle'] : $iterationData['moduloCycle'];
                    $iterationData['moduloFirst'] = $iterationData['modulo'] == 0;
                    $iterationData['moduloLast'] = $iterationData['modulo'] == $arguments['iterationModulo'] - 1;
                }
                $templateVariableContainer->add($arguments['iteration'], $iterationData);
                $iterationData['index']++;
                $iterationData['cycle']++;
            }
            $output .= $renderChildrenClosure();
            $templateVariableContainer->remove($arguments['as']);
            if ($arguments['key'] !== '') {
                $templateVariableContainer->remove($arguments['key']);
            }
            if ($arguments['iteration'] !== null) {
                $templateVariableContainer->remove($arguments['iteration']);
            }
        }
        return $output;
    }
}

#fluid#typo3#viewhelper

L16HT|D@RK
Top