2016-01-11 4 views
3

Проблемы: я написал условный VH (простирающийся AbstractConditionViewHelper), и она работает, как обычно, во всяком случае, я понял, что в некэшируемого версии она вычисляется только один раз. Initialy Я думал, что это моя ошибка, но проверил общие <f:if> и проблема идентична: STYPO3 ver. 7.6.2 - Состояние ViewHelpers оценивается только один раз

В общем, когда я посещаю мою страницу в первый раз, состояние оценивается и действительный результат дается, но когда я освежить страница VH больше не вызывается (проверяется установкой точки останова внутри VH), а VH всегда рассматривается как FALSE. Только любое изменение в коде просмотра приведет к тому, что VH будет оцениваться один раз, и снова следующее обновление (обновления) больше не будет вызывать VH.

typo3conf/внутр/Инструментальный ящик/Классы/ViewHelpers/IsFieldRequiredViewHelper.php:

<?php 
namespace Vendor\Toolbox\ViewHelpers; 

class IsFieldRequiredViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractConditionViewHelper { 

    /** 
    * @param string $fieldName  Current field name 
    * @param string $requiredFields List of required names separated by commas 
    * 
    * @return string the rendered string 
    */ 
    public function render($fieldName, $requiredFields) { 

     $requiredArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $requiredFields, true); 

     return (in_array($fieldName, $requiredArray)) 
      ? $this->renderThenChild() 
      : $this->renderElseChild(); 
    } 
} 

Использование:

{namespace toolbox=Vendor\Toolbox\ViewHelpers} 

<toolbox:isFieldRequired fieldName="foo" requiredFields="foo, bar, baz"> 
    <f:then>TRUE</f:then> 
    <f:else>FALSE</f:else> 
</toolbox:isFieldRequired> 

Для первого удара я имею TRUE, но позже только FALSE.

Любые предложения? Я пропустил некоторые важные изменения в API ViewHelpers с 7.x-?

Конечно, если расширение кэшировано, оно не будет видно, так как первый хит будет сохранен в кеше с правильным возвратом VH.

ответ

6

AbstractConditionViewHelper реализует интерфейс TYPO3\CMS\Fluid\Core\ViewHelper\Facets\CompilableInterface. Это означает, что он реализует метод compile, который фактически возвращает PHP-код, который будет храниться в скомпилированных представлениях Fluid.

Посмотрите на этот метод в source code:

public function compile($argumentsVariableName, $renderChildrenClosureVariableName, &$initializationPhpCode, \TYPO3\CMS\Fluid\Core\Parser\SyntaxTree\AbstractNode $syntaxTreeNode, \TYPO3\CMS\Fluid\Core\Compiler\TemplateCompiler $templateCompiler) 
{ 
    foreach ($syntaxTreeNode->getChildNodes() as $childNode) { 
     if ($childNode instanceof ViewHelperNode 
      && $childNode->getViewHelperClassName() === ThenViewHelper::class) { 
      $childNodesAsClosure = $templateCompiler->wrapChildNodesInClosure($childNode); 
      $initializationPhpCode .= sprintf('%s[\'__thenClosure\'] = %s;', $argumentsVariableName, $childNodesAsClosure) . LF; 
     } 
     if ($childNode instanceof ViewHelperNode 
      && $childNode->getViewHelperClassName() === ElseViewHelper::class) { 
      $childNodesAsClosure = $templateCompiler->wrapChildNodesInClosure($childNode); 
      $initializationPhpCode .= sprintf('%s[\'__elseClosure\'] = %s;', $argumentsVariableName, $childNodesAsClosure) . LF; 
     } 
    } 

    return sprintf('%s::renderStatic(%s, %s, $renderingContext)', 
     get_class($this), $argumentsVariableName, $renderChildrenClosureVariableName); 
} 

После компиляции, метод render() не будет называться больше (он будет на первом вызове, когда шаблон еще не составлен). Вместо этого вызывается метод renderStatic().

Решение: Вы можете

  1. также переопределить метод renderStatic() и реализовать ViewHelper логику там (снова)
  2. не реализует render() метод и просто перезаписывает статическую evaluateCondition($arguments) метод. Этот метод на самом деле предназначен для перезаписи - реализации по умолчанию обоих render() и renderStatic() называют этот метод:

    Этот метод решает, если условие имеет значение ИСТИНА или ЛОЖЬ. Его можно переопределить, расширяя возможности просмотра, чтобы настроить функциональность.

    static protected function evaluateCondition($arguments = null) 
    { 
        $requiredArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $arguments['requiredFields'], true); 
        return (in_array($arguments['fieldName'], $requiredArray)); 
    } 
    
+0

Отлично! спасибо за подробное объяснение, просто любопытно, в каком API он был введен точно? – biesior

+1

[Передача '1beb07f'] (https://git.typo3.org/Packages/TYPO3.CMS.git/commit/1beb07f03e0dd9316f8bb96d8ef2a75803cda69d), похоже, является виновником. Он был введен в TYPO3 7.3.0 (в соответствии с 'git tag - содержит 1beb07f03e0dd9316f8bb96d8ef2a75803cda69d') – helmbert

Смежные вопросы