2

Typo3 のニュース拡張 tx_news 用の特別なテンプレートに取り組んでいます。私はTypo3、特にFluidに完全に慣れていません。

私が欲しいのは、正確に 4 つのニュース項目の出力ですが、これらの各項目には画像が必要です。

私が必要としているのは、次のようなプログラミング ロジックです。そうでなければ何もしないでください。

私はこの質問と回答を読みました: TYPO3 Fluid complex if conditions なので、viewhelper のようなものが必要だと思います。

これまでのところ、私のテンプレートにはアイテムを出力するための次のコードがあります。

    <f:for each="{news}" as="newsItem" iteration="iterator">
        <f:if condition="{newsItem.falMedia}">
            <f:if condition="{iterator.cycle}<=4">
                <f:render partial="List/TeaserItem" arguments="{newsItem: newsItem,settings:settings,iterator:iterator, contentObjectData:contentObjectData}" />
            </f:if>
        </f:if>
    </f:for>

しかしもちろん、ニュースを 4 回繰り返した後、これは停止します。したがって、画像のない 1 つのエントリがレンダリングされなかった場合、3 つのアイテムのみが出力されます。

次のようなif条件が必要です。

if ({newsItem.falMedia} && {iterator.cycle}<=4){
      render image }
else {iterator.cycle--}

しかし、for ループのイテレータ変数を新しいビューヘルパーに渡す方法、特に for ループに戻す方法がわかりません。

4

1 に答える 1

1

要するに、この種のロジックは Fluid では不可能です。理由は単純です。それはテンプレート エンジンです。

独自の拡張機能を作成し、その中に ViewHelper を作成する必要があります。これは News のコレクションを取得し、必要な設定 (falMediaこの場合は既存) があるかどうかを確認し、反復できる限定された配列を返します。実際、再利用f:forが最速の解決策になります。

恐れ入りますが、それしか方法がありません。

サンプルは次のとおりです (元のビューヘルパーと比較してf:forください)。

<?php
namespace TYPO3\CMS\Fluid\ViewHelpers;

class ForNewsWithMediaViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {

    /**
     * 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 boolean $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 $limit Limit of the news items to show
     * @return string Rendered string
     * @api
     */
    public function render($each, $as, $key = '', $reverse = FALSE, $iteration = NULL, $limit = NULL) {
        return self::renderStatic($this->arguments, $this->buildRenderChildrenClosure(), $this->renderingContext, $limit);
    }

    /**
     * @param array $arguments
     * @param \Closure $renderChildrenClosure
     * @param \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
     * @param int $limit Limit of the news items to show
     * @return string
     * @throws \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
     */
    static public function renderStatic(array $arguments, \Closure $renderChildrenClosure, \TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface $renderingContext, $limit = NULL) {
        $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']);
        }
        $iterationData = array(
            'index' => 0,
            'cycle' => 1,
            'total' => count($arguments['each'])
        );

        $limitCycle = 1;
        $output = '';
        /**
         * @type  $singleElement Tx_News_Domain_Model_News
         */
        foreach ($arguments['each'] as $keyValue => $singleElement) {

            if (is_null($singleElement->getFalMedia())
                || !is_null($limit) && $limitCycle > $limit
            ) {
                continue;
            }

            $limitCycle++;

            $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'];
                $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;
    }
}

したがって、ビューで次のように使用できます。

<f:forNewsWithMedia each="{news}" as="newsItem" iteration="iterator" limit="4">
    <f:render partial="List/TeaserItem" arguments="{newsItem: newsItem,settings:settings,iterator:iterator, contentObjectData:contentObjectData}" />
</f:forNewsWithMedia>
于 2015-01-28T09:56:36.867 に答える