Die Pagination-Widgets von TYPO3 (bzw. Fluid) nehmen einem viel Arbeit ab. Jedoch verzweifelt so mancher, wenn es drum geht, auch Filter-Parameter an Folgeseiten weiterzureichen. Klappen tut’s sowohl im Frontend, wie auch im Backend. Ich erkläre kurz beide Fälle.
Pagination im Frontend samt Filterung
Für das Frontend ist das kleine geheimnis die Übertragungsmethode des Filter-Formularinhaltes. Wählt man hier „GET“, so greift das Pagination-Widget automatisch drauf zu und hängt die Parameter für die Folgeseiten an.
<f:form action="list" object="{demand}" objectName="demand" method="GET">
<f:form.textfield
property="searchtext"
/>
<f:form.button
name="submit"
type="submit"
/>
</f:form>
<f:widget.paginate
objects="{records}"
as="paginatedRecords"
configuration="{itemsPerPage: settings.pagination.itemsPerPage, insertAbove: 0, insertBelow: 1, maximumNumberOfLinks: 2}"
>
<f:for as="record" each="{paginatedRecords}">
<f:comment><!-- do your stuff --></f:comment>
</f:for>
</f:widget.paginate>
Pagination im Backend samt Filterung
Hier ist etwas mehr Kreativität gefragt. Versucht man’s mit obiger Methode, so führt das Absenden des Filter-Formulars dazu, dass im Hauptbereich des Backends sich das Backend erneut aufbaut – wohl eine Folge einer gescheiterten CSRF-Prüfung.
Eine Lösung relativ simple Lösung hat Georg in der news-Extension verbaut:
Zusätzliche Variablen bereitstellen
Letzten Endes benötigen wir im Filterformular noch drei zusätzliche versteckte Felder (Hierzu später mehr). Damit wir diese auch füllen können, benötigen wir die Seiten-UID, für die unser Backend-Modul aufgerufen wurde, sowie ein Module-Token (für CSRF-Absicherung).
Die Seiten-UID können wir uns z.B. per initialzeAction() im Controller setzen und in der Action mit an die View übergeben:
/**
* @var int
*/
protected $pageUid = 0;
/**
* Function will be called before every other action
*
* @return void
*/
public function initializeAction(): void
{
$this->pageUid = (int)\TYPO3\CMS\Core\Utility\GeneralUtility::_GET('id');
parent::initializeAction();
}
/**
* list action
*
* @param Demand|null $demand
*/
public function listAction(Demand $demand = null): void
{
// Do your other stuff
$this->view->assign('page', $this->pageUid);
}
Das Token müssen wir erst erzeugen, ist aber letztlich auch kein Hexenwerk:
/**
* Get a CSRF token
*
* @param bool $tokenOnly Set it to TRUE to get only the token, otherwise including the &moduleToken= as prefix
* @return string
*/
protected function getToken($tokenOnly = false): string
{
$token = FormProtectionFactory::get()->generateToken('moduleCall', '<moduleName>');
if ($tokenOnly) {
return $token;
}
return '&moduleToken=' . $token;
}
/**
* list action
*
* @param Demand|null $demand
*/
public function listAction(Demand $demand = null): void
{
// Do your other stuff
$this->view->assign('moduleToken', $this->getToken(true));
}
Template anpassen
Nun noch im Fluid-Template die Übertragungsmethode auf „GET“ umstellen und die drei eingangs erwähnten Felder ergänzen, und schon sind wir fertig:
<f:form action="list" objectName="demand" object="{demand}" method="get">
<input type="hidden" name="M" value="<moduleName>">
<input type="hidden" name="moduleToken" value="{moduleToken}">
<input type="hidden" name="id" value="{page}">
</f:form>