Search code examples
phptypo3fluidtypo3-9.x

How do you access THEN and ELSE tag in TYPO3Fluid AbstractViewHelper?


There is a new AbstractViewHelper in TYPO3 (TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper) and I try to implement a very simple InArrayViewHelper to my project with that.

The problem is you should use render() if you like to access then or else sub tags according to https://docs.typo3.org/m/typo3/book-extbasefluid/master/en-us/8-Fluid/8-developing-a-custom-viewhelper.html#renderstatic-method

So I do something like

<?php
namespace Vendor\Project\ViewHelpers;

use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;

class InArrayViewHelper extends AbstractViewHelper {

    //use CompileWithRenderStatic;

    public function initializeArguments() {
        $this->registerArgument('haystack', 'mixed', 'View helper haystack ', TRUE);
        $this->registerArgument('needle', 'string', 'View helper needle', TRUE);
    }

    public function render() {  
        $needle = $this->arguments['needle'];
        $haystack = $this->arguments['haystack'];
        if(!is_array($haystack)) { 
            return $this->renderElseChild();
        }
        if(in_array($needle, $haystack)) {
            return $this->renderThenChild();
        } else {
            return $this->renderElseChild();
        }  
    }

}

Well but they removed renderThenChild and renderElseChild in there. What is the right way to do so. Can I do it without using \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractConditionViewHelper?


Solution

  • First of all: if you want your ViewHelper to be a condition ViewHelper you should be subclassing TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper, not TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper. The former contains a collection of assistance methods, e.g. renderThenChild (which renders either the f:then node or returns the then argument, whichever is present).

    Second: access to the tags (as opposed to a closure which renders either the tag or the compiled execution) can only happen while the template is not yet compiled, and can be achieved through overriding public static function postParseEvent which receives the ViewHelperNode which allows you to read the child nodes with getChildNodes and/or add additional child nodes through addChildNode.

    Implementations based on TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper and using manually registered then and else arguments can also work, but will not support child nodes like f:then without replicating almost all of the assistance methods from TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper.

    So the answer is: yes, you can do it without AbstractConditionViewHelper - but you shouldn't.