Extbase/Fluid news Prev/Next

You would like to implement a next/prev ViewHelper in news based on extbase/fluid from Georg Ringer?
Great. Here you are.

First of all we need just two ViewHelpers:


<?php

namespace MyExt\Whatever\ViewHelpers;

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

    /**
     * @return void
     */
    public function initializeArguments() {
        $this->registerArgument('prevAs', 'string', 'Which variable to update in the TemplateVariableContainer for prev object', FALSE, 'prev');
        $this->registerArgument('nextAs', 'string', 'Which variable to update in the TemplateVariableContainer for next object ', FALSE, 'next');
        $this->registerArgument('positionAs', 'string', 'Which variable to update in the TemplateVariableContainer for the position of current object ', FALSE, 'position');
        $this->registerArgument('loop', 'boolean', 'Is the menu loopable?', FALSE, FALSE);
    }

    /**
     *
     * @param \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject $currentElement
     * @param mixed $allElements
     */
    public function render(\TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject $currentElement, $allElements) {

        $pos = 0;
        $num = count($allElements);
        
        foreach ($allElements as $element) {
            if ($element->getUid() === $currentElement->getUid()) {
                // Set previous element
                if ($pos != 0) {
                    $prev = $allElements[$pos - 1];
                    if ($this->templateVariableContainer->exists($this->arguments['prevAs'])) {
                        $this->templateVariableContainer->remove($this->arguments['prevAs']);
                    }
                    $this->templateVariableContainer->add($this->arguments['prevAs'], $prev);
                } elseif (TRUE === $this->arguments['loop']) {
                    $prev = $allElements[count($allElements) - 1];
                    if ($this->templateVariableContainer->exists($this->arguments['prevAs'])) {
                        $this->templateVariableContainer->remove($this->arguments['prevAs']);
                    }
                    $this->templateVariableContainer->add($this->arguments['prevAs'], $prev);
                }
                // Set next element
                if (($pos + 1) != $num) {
                    $next = $allElements[$pos + 1];
                    if ($this->templateVariableContainer->exists($this->arguments['nextAs'])) {
                        $this->templateVariableContainer->remove($this->arguments['nextAs']);
                    }
                    $this->templateVariableContainer->add($this->arguments['nextAs'], $next);
                } elseif (TRUE === $this->arguments['loop']) {
                    $next = $allElements[0];
                    if ($this->templateVariableContainer->exists($this->arguments['nextAs'])) {
                        $this->templateVariableContainer->remove($this->arguments['nextAs']);
                    }
                    $this->templateVariableContainer->add($this->arguments['nextAs'], $next);
                }
                break;
            }
            ++$pos;
        }
        if ($this->templateVariableContainer->exists($this->arguments['positionAs'])) {
            $this->templateVariableContainer->remove($this->arguments['positionAs']);
        }
        $this->templateVariableContainer->add($this->arguments['positionAs'], $pos + 1);
    }

}

?>

<?php

namespace MyExt\Whatever\ViewHelpers;


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

    /**
     *
     * @var \Tx_News_Domain_Repository_NewsRepository
     * @inject 
     */
    protected $newsRepository;

    /**
     * 
     * @param array $data
     * @return objects
     */
    public function render($settings = NULL) {
        if (NULL === $settings) {
            $settings = $this->renderChildren();
        }
        $demand = $this->createDemandObjectFromSettings($settings);
        return $this->newsRepository->findDemanded($demand);
    }

    /**
     * Create the demand object which define which records will get shown
     *
     * @param array $settings
     * @return Tx_News_Domain_Model_Dto_NewsDemand
     */
    protected function createDemandObjectFromSettings($settings) {
        /* @var $demand Tx_News_Domain_Model_Dto_NewsDemand */
        $demand = $this->objectManager->get('Tx_News_Domain_Model_Dto_NewsDemand');

        $demand->setCategories(\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $settings['categories'], TRUE));
        $demand->setCategoryConjunction($settings['categoryConjunction']);
        $demand->setIncludeSubCategories($settings['includeSubCategories']);
        $demand->setTags($settings['tags']);

        $demand->setTopNewsRestriction($settings['topNewsRestriction']);
        $demand->setTimeRestriction($settings['timeRestriction']);
        $demand->setTimeRestrictionHigh($settings['timeRestrictionHigh']);
        $demand->setArchiveRestriction($settings['archiveRestriction']);
        $demand->setExcludeAlreadyDisplayedNews($settings['excludeAlreadyDisplayedNews']);

        if ($settings['orderBy']) {
            $demand->setOrder($settings['orderBy'] . ' ' . $settings['orderDirection']);
        }
        $demand->setOrderByAllowed($settings['orderByAllowed']);

        $demand->setTopNewsFirst($settings['topNewsFirst']);

        $demand->setLimit($settings['limit']);
        $demand->setOffset($settings['offset']);

        $demand->setSearchFields($settings['search']['fields']);
        $demand->setDateField($settings['dateField']);
        $demand->setMonth($settings['month']);
        $demand->setYear($settings['year']);


        $demand->setStoragePage(\Tx_News_Utility_Page::extendPidListByChildren($settings['startingpoint'], $settings['recursive']));
        return $demand;
    }

}

Now you can modify your Fluid-Template for the detail action:

{namespace n=Tx_News_ViewHelpers}
{namespace my=MyExt\Whatever\ViewHelpers}

<my:nextPrev nextAs="next" prevAs="previous" loop="FALSE" currentElement="{newsItem}" allElements="{my:nextPrevNews(settings: settings)}" />
<f:if condition="{previous}">
   <n:link class="next-prev prev" rel="tooltip" title="{previous.title}" newsItem="{previous}" settings="{settings}">
      {previous.title}
   </n:link>                
</f:if>
<f:if condition="{next}">
   <n:link class="next-prev next" rel="tooltip" title="{next.title}" newsItem="{next}" settings="{settings}">
      {next.title}
   </n:link>
</f:if>

Veröffentlicht von

avatar

Sebastian Schreiber

Ich bin 1980 in Bergisch Gladbach geboren. Nach dem Abitur und Zivildienst habe ich 2000 an der Fachhochschule Lippe & Höxter das Studium der Medienproduktin begonnen und nach längeren Aufenthalten in Valencia und Berlin 2003 das Studium mit dem Abschluss Bachelor of Science in Medienproduktion abgeschlossen. Nach einer Festanstellung kurz nach dem Studium in einer kleinen Webagentur in Köln mit Schwerpunkt TYPO3 bin ich nun seit 2008 freiberuflicher Webentwickler.

3 Gedanken zu „Extbase/Fluid news Prev/Next“

  1. Thanks for sharing this nice code. however I want to add 3 things:
    * It would be a lot simpler to reuse the demandObject from the view as {demand} instead of rebuilding it.
    * Your way sucks if you need spped as you just iterate over all records which is not fast doing it with extbase!
    * I implemented a pagination in news itself already which does it in mysql only. Of course it got some drawbacks too but maybe it helps others a bit.

  2. Hi Georg,
    thanks for your comment.

    1st: I couldn´t see the assignment of the demand object to the view in the detailAction.
    Am i wrong? Otherwise you are absolutely right and my code smells

    2nd: We all need speed. But in my case i just have five news items. But of course you are right

    3rd: Didnt´t see it. So does that mean, my solution is obsolete and we already have a prev/next pagination for the news extension? That would be great news 😉

  3. Best solution which i founded. In default tx_news solution „n:simplePrevNext“absent categories filter. Also please add TS config for Detail page if somebody need limit categories.
    plugin.tx_news.settings {
    overrideFlexformSettingsIfEmpty := addToList(categories,categoryConjunction)
    categories = 1
    categoryConjunction = and
    }

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.