From c0a80afba7a2d6cab0bd0604f411d07b6c83a2d8 Mon Sep 17 00:00:00 2001
From: Fabian Galinski <fabian@sgalinski.de>
Date: Wed, 22 Jun 2016 00:57:17 +0200
Subject: [PATCH] [FEATURE] Turn the page browser into an extbase plugin

---
 .../Controller/ListByCategoryController.php   |   2 +-
 Classes/Controller/OverviewController.php     |   2 +-
 Classes/Controller/PageBrowserController.php  | 145 +++++++
 Classes/UserFunc/class.tx_pagebrowse_pi1.php  | 373 ------------------
 Classes/ViewHelpers/PageBrowserViewHelper.php |  17 +-
 .../TypoScript/Frontend/constants.txt         |  14 +-
 Configuration/TypoScript/Frontend/setup.txt   |  56 +--
 .../Private/Language/de.locallang_backend.xlf |   6 +-
 .../Private/Language/locallang_backend.xlf    |   5 +-
 Resources/Private/Layouts/PageBrowser.html    |   3 +
 .../Partials/Pagebrowser/Pagebrowser.html     |  49 ---
 .../Private/Templates/PageBrowser/Index.html  |  85 ++++
 Resources/Public/Scripts/ScrollBrowser.js     |   4 +-
 ext_localconf.php                             |  12 +-
 ext_tables.php                                |   5 +
 15 files changed, 303 insertions(+), 475 deletions(-)
 create mode 100644 Classes/Controller/PageBrowserController.php
 delete mode 100644 Classes/UserFunc/class.tx_pagebrowse_pi1.php
 create mode 100644 Resources/Private/Layouts/PageBrowser.html
 delete mode 100755 Resources/Private/Partials/Pagebrowser/Pagebrowser.html
 create mode 100644 Resources/Private/Templates/PageBrowser/Index.html

diff --git a/Classes/Controller/ListByCategoryController.php b/Classes/Controller/ListByCategoryController.php
index 21c9436..5301fb1 100644
--- a/Classes/Controller/ListByCategoryController.php
+++ b/Classes/Controller/ListByCategoryController.php
@@ -73,7 +73,7 @@ class ListByCategoryController extends AbstractController {
 
 		$offset = 0;
 		$newsPerPage = (int) $this->settings['newsLimitPerPage'];
-		$currentPageBrowserPage = (int) GeneralUtility::_GP('tx_pagebrowse_pi1')['page'];
+		$currentPageBrowserPage = (int) GeneralUtility::_GP('tx_sgnews_pagebrowser')['currentPage'];
 		if ($currentPageBrowserPage && $newsPerPage) {
 			$offset = $currentPageBrowserPage * $newsPerPage;
 		}
diff --git a/Classes/Controller/OverviewController.php b/Classes/Controller/OverviewController.php
index b9410ef..2b4db41 100644
--- a/Classes/Controller/OverviewController.php
+++ b/Classes/Controller/OverviewController.php
@@ -124,7 +124,7 @@ class OverviewController extends AbstractController {
 	protected function overviewWithoutCategoriesAction() {
 		$offset = 0;
 		$newsPerPage = (int) $this->settings['newsLimit'];
-		$currentPageBrowserPage = (int) GeneralUtility::_GP('tx_pagebrowse_pi1')['page'];
+		$currentPageBrowserPage = (int) GeneralUtility::_GP('tx_sgnews_pagebrowser')['page'];
 		if ($currentPageBrowserPage && $newsPerPage) {
 			$offset = $currentPageBrowserPage * $newsPerPage;
 		}
diff --git a/Classes/Controller/PageBrowserController.php b/Classes/Controller/PageBrowserController.php
new file mode 100644
index 0000000..58a497f
--- /dev/null
+++ b/Classes/Controller/PageBrowserController.php
@@ -0,0 +1,145 @@
+<?php
+
+namespace SGalinski\SgNews\Controller;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) sgalinski Internet Services (http://www.sgalinski.de)
+ *
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+
+/**
+ * Controller that handles the page browser.
+ */
+class PageBrowserController extends ActionController {
+	/**
+	 * @var string
+	 */
+	protected $pageParameterName = '';
+
+	/**
+	 * @var int
+	 */
+	protected $numberOfPages = 0;
+
+	/**
+	 * @var int
+	 */
+	protected $currentPage = 0;
+
+	/**
+	 * @var int
+	 */
+	protected $pagesBefore = 0;
+
+	/**
+	 * @var int
+	 */
+	protected $pagesAfter = 0;
+
+	/**
+	 * @var bool
+	 */
+	protected $enableMorePages = FALSE;
+
+	/**
+	 * @var bool
+	 */
+	protected $enableLessPages = FALSE;
+
+	/**
+	 * Renders the index view.
+	 *
+	 * @param int $currentPage
+	 * @return void
+	 */
+	public function indexAction($currentPage = 0) {
+		$this->currentPage = (int) $currentPage;
+
+		$this->initializeConfiguration();
+		$this->addDataToView();
+	}
+
+	/**
+	 * Initializes the configuration.
+	 *
+	 * @return	void
+	 */
+	protected function initializeConfiguration() {
+		$this->pageParameterName = 'tx_sgnews_pagebrowser[currentPage]';
+		$this->numberOfPages = (int) $this->settings['numberOfPages'];
+		$this->pagesBefore = (int) $this->settings['pagesBefore'];
+		$this->pagesAfter = (int) $this->settings['pagesAfter'];
+		$this->enableMorePages = ($this->settings['enableMorePages'] == TRUE);
+		$this->enableLessPages = ($this->settings['enableLessPages'] == TRUE);
+	}
+
+	/**
+	 * Adds the necessary data to the view.
+	 *
+	 * @return void
+	 */
+	protected function addDataToView() {
+		if ($this->numberOfPages <= 1) {
+			$this->view = NULL;
+			return;
+		}
+
+		$pageLinks = [];
+		$start = max($this->currentPage - $this->pagesBefore, 0);
+		$end = min($this->numberOfPages, $this->currentPage + $this->pagesAfter + 1);
+		for ($i = $start; $i < $end; $i++) {
+			$pageLinks[] = [
+				'number' => $i + 1,
+				'link' => $this->getPageLink($i),
+				'isCurrentPage' => ($i == $this->currentPage),
+			];
+		}
+
+		$this->view->assignMultiple([
+			'enableLessPages' => $this->enableLessPages,
+			'enableMorePages' => $this->enableMorePages,
+			'previousLink' => $this->getPageLink($this->currentPage - 1),
+			'nextLink' => $this->getPageLink($this->currentPage + 1),
+			'enableLessPagesLink' => $this->getPageLink($this->currentPage - $this->pagesBefore - 1),
+			'enableMorePagesLink' => $this->getPageLink($this->currentPage + $this->pagesAfter + 1),
+			'pageLinks' => $pageLinks,
+			'prevPageExist' => $this->currentPage > 0,
+			'showLessPages' => ($this->currentPage - $this->pagesBefore) > 0,
+			'showNextPages' => ($this->currentPage + $this->pagesAfter + 1) < $this->numberOfPages,
+			'nextPageExist' => $this->currentPage < ($this->numberOfPages - 1),
+		]);
+	}
+
+	/**
+	 * Generates page link. Keeps all current URL parameters except for cHash and tx_pagebrowse_pi1[page].
+	 *
+	 * @param int $page Page number starting from 1
+	 * @return string
+	 */
+	protected function getPageLink($page) {
+		return $this->uriBuilder->reset()->setUseCacheHash(FALSE)->uriFor('index', ['currentPage' => $page,]);
+	}
+}
+
+?>
diff --git a/Classes/UserFunc/class.tx_pagebrowse_pi1.php b/Classes/UserFunc/class.tx_pagebrowse_pi1.php
deleted file mode 100644
index a097727..0000000
--- a/Classes/UserFunc/class.tx_pagebrowse_pi1.php
+++ /dev/null
@@ -1,373 +0,0 @@
-<?php
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2008 Dmitry Dulepov (dmitry@typo3.org)
-*  All rights reserved
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*  A copy is found in the textfile GPL.txt and important notices to the license
-*  from the author is found in LICENSE.txt distributed with these scripts.
-*
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-
-/**
- * This file contains a class with page browser implementation.
- *
- * @author	Dmitry Dulepov [netcreators] <dmitry@typo3.org>
- */
-
-
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-/**
- * This class implements page browser plugin
- *
- * @author	Dmitry Dulepov [netcreators] <dmitry@typo3.org>
- */
-class tx_pagebrowse_pi1 extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin {
-	// Default plugin variables:
-	public $prefixId = 'tx_pagebrowse_pi1';
-	public $scriptRelPath = 'Classes/UserFunc/class.tx_pagebrowse_pi1.php';
-	public $extKey = 'sg_news';
-	public $pi_checkCHash = true;				// Required for proper caching! See in the typo3/sysext/cms/tslib/class.tslib_pibase.php
-	public $pi_USER_INT_obj = false;
-
-	protected $numberOfPages;
-	protected $pageParameterName;
-	protected $currentPage;
-	protected $pagesBefore = 3;
-	protected $pagesAfter = 3;
-	protected $templateCode;
-
-	const PAGE_FIRST = 0;
-	const PAGE_PREV = 1;
-	const PAGE_BEFORE = 2;
-	const PAGE_CURRENT = 3;
-	const PAGE_AFTER = 4;
-	const PAGE_NEXT = 5;
-	const PAGE_LAST = 6;
-
-	/**
-	 * Produces plugin's output.
-	 *
-	 * @param	string	$content	Unused
-	 * @param	array	$conf	Configuration
-	 * @return	string	Generated content
-	 */
-	public function main($content, $conf) {
-		$this->conf = $conf;
-		$this->pi_loadLL();
-
-		if (!isset($conf['templateFile'])) {
-			return $this->pi_wrapInBaseClass($this->pi_getLL('no_ts_template'));
-		}
-
-		$this->init();
-		return $this->pi_wrapInBaseClass($this->createPageBrowser());
-	}
-
-	/**
-	 * Initializes the plugin.
-	 *
-	 * @return	void
-	 */
-	function init() {
-		// Call pre-init hook
-		if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['preInit'])) {
-			foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['preInit'] as $userFunc) {
-				$params = array(
-					'pObj' => &$this,
-				);
-				GeneralUtility::callUserFunction($userFunc, $params, $this);
-			}
-		}
-
-		$this->numberOfPages = intval($this->cObj->stdWrap($this->conf['numberOfPages'], $this->conf['numberOfPages.']));
-		if (!($pageParameterName = trim($this->conf['pageParameterName']))) {
-			$this->pageParameterName = $this->prefixId . '[page]';
-			$this->currentPage = max(0, intval($this->piVars['page']));
-		}
-		else {
-			$parts = GeneralUtility::trimExplode('|', $pageParameterName, 2);
-			if (count($parts) == 2) {
-				$this->pageParameterName = $parts[0] . '[' . $parts[1] . ']';
-				$vars = GeneralUtility::_GP($parts[0]);
-				$this->currentPage = max(0, intval($vars[$parts[1]]));
-			}
-			else {
-				$this->pageParameterName = $pageParameterName;
-				$this->currentPage = max(0, intval(GeneralUtility::_GP($pageParameterName)));
-			}
-		}
-
-		if (self::testInt($this->conf['pagesBefore'])) {
-			$this->pagesBefore = intval($this->conf['pagesBefore']);
-		}
-		if (self::testInt($this->conf['pagesAfter'])) {
-			$this->pagesAfter = intval($this->conf['pagesAfter']);
-		}
-
-		$this->adjustForForcedNumberOfLinks();
-
-		$this->templateCode = $this->cObj->fileResource($this->conf['templateFile']);
-
-		// Call post-init hook
-		if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['postInit'])) {
-			foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['postInit'] as $userFunc) {
-				$params = array(
-					'pObj' => &$this,
-				);
-				GeneralUtility::callUserFunction($userFunc, $params, $this);
-			}
-		}
-
-		if ($this->conf['addHeaderParts']) {
-			$this->addHeaderParts();
-		}
-	}
-
-	/**
-	 * If a certain number of links should be displayed, adjust before and after
-	 * amounts accordingly.
-	 *
-	 * @return void
-	 */
-	protected function adjustForForcedNumberOfLinks() {
-		$forcedNumberOfLinks = intval($this->cObj->stdWrap($this->conf['numberOfLinks'], $this->conf['numberOfLinks.']));
-		if ($forcedNumberOfLinks > $this->numberOfPages) {
-			$forcedNumberOfLinks = $this->numberOfPages;
-		}
-		$totalNumberOfLinks = min($this->currentPage, $this->pagesBefore) +
-				min($this->pagesAfter, $this->numberOfPages - $this->currentPage) + 1;
-		if ($totalNumberOfLinks <= $forcedNumberOfLinks) {
-			$delta = intval(ceil(($forcedNumberOfLinks - $totalNumberOfLinks)/2));
-			$incr = ($forcedNumberOfLinks & 1) == 0 ? 1 : 0;
-			if ($this->currentPage - ($this->pagesBefore + $delta) < 1) {
-				// Too little from the right to adjust
-				$this->pagesAfter = $forcedNumberOfLinks - $this->currentPage - 1;
-				$this->pagesBefore = $forcedNumberOfLinks - $this->pagesAfter - 1;
-			}
-			elseif ($this->currentPage + ($this->pagesAfter + $delta) >= $this->numberOfPages) {
-				$this->pagesBefore = $forcedNumberOfLinks - ($this->numberOfPages - $this->currentPage);
-				$this->pagesAfter = $forcedNumberOfLinks - $this->pagesBefore - 1;
-			}
-			else {
-				$this->pagesBefore += $delta;
-				$this->pagesAfter += $delta - $incr;
-			}
-		}
-	}
-
-	/**
-	 * Adds header parts from the template to the TSFE.
-	 * It fetches subpart identified by ###HEADER_ADDITIONSS### and replaces ###SITE_REL_PATH### with site-relative part to the extension.
-	 *
-	 * @param	string		$ref	Reference
-	 * @param	string		$subpart	Subpart from template to add.
-	 * @param	array		$conf	Configuration
-	 * @return	void
-	 */
-	protected function addHeaderParts() {
-		$subPart = $this->cObj->getSubpart($this->templateCode, '###HEADER_ADDITIONS###');
-		$key = $this->prefixId . '_' . md5($subPart);
-		if (!isset($GLOBALS['TSFE']->additionalHeaderData[$key])) {
-			$GLOBALS['TSFE']->additionalHeaderData[$key] =
-				$this->cObj->substituteMarkerArray($subPart, array(
-					'###SITE_REL_PATH###' => $GLOBALS['TSFE']->config['config']['absRefPrefix'] .
-						\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($this->extKey),
-				));
-		}
-	}
-
-	/**
-	 * Produces the page browser HTML
-	 *
-	 * @return	string	Generated content
-	 */
-	protected function createPageBrowser() {
-		$out = '';
-		if ($this->numberOfPages > 1) {
-			// Set up
-			$markers = array(
-				'###TEXT_FIRST###' => htmlspecialchars($this->pi_getLL('text_first')),
-				'###TEXT_NEXT###' => htmlspecialchars($this->pi_getLL('text_next')),
-				'###TEXT_PREV###' => htmlspecialchars($this->pi_getLL('text_prev')),
-				'###TEXT_LAST###' => htmlspecialchars($this->pi_getLL('text_last')),
-			);
-			$subPartMarkers = array();
-			$subPart = $this->cObj->getSubpart($this->templateCode, '###PAGE_BROWSER###');
-
-			// First page link
-			if ($this->currentPage == 0) {
-				$subPartMarkers['###ACTIVE_FIRST###'] = '';
-			}
-			else {
-				$markers['###FIRST_LINK###'] = $this->getPageLink(0, self::PAGE_FIRST);
-				$subPartMarkers['###INACTIVE_FIRST###'] = '';
-			}
-			// Prev page link
-			if ($this->currentPage == 0) {
-				$subPartMarkers['###ACTIVE_PREV###'] = '';
-			}
-			else {
-				$markers['###PREV_LINK###'] = $this->getPageLink($this->currentPage - 1, self::PAGE_PREV);
-				$subPartMarkers['###INACTIVE_PREV###'] = '';
-			}
-			// Next link
-			if ($this->currentPage >= $this->numberOfPages - 1) {
-				$subPartMarkers['###ACTIVE_NEXT###'] = '';
-			}
-			else {
-				$markers['###NEXT_LINK###'] = $this->getPageLink($this->currentPage + 1, self::PAGE_NEXT);
-				$subPartMarkers['###INACTIVE_NEXT###'] = '';
-			}
-			// Last link
-			if ($this->currentPage == $this->numberOfPages - 1) {
-				$subPartMarkers['###ACTIVE_LAST###'] = '';
-			}
-			else {
-				$markers['###LAST_LINK###'] = $this->getPageLink($this->numberOfPages - 1, self::PAGE_LAST);
-				$subPartMarkers['###INACTIVE_LAST###'] = '';
-			}
-
-			// Page links
-			$actPageLinkSubPart = trim($this->cObj->getSubpart($subPart, '###CURRENT###'));
-			$inactPageLinkSubPart = trim($this->cObj->getSubpart($subPart, '###PAGE###'));
-			$pageLinks = '';
-			$start = max($this->currentPage - $this->pagesBefore, 0);
-			$end = min($this->numberOfPages, $this->currentPage + $this->pagesAfter + 1);
-			for ($i = $start; $i < $end; $i++) {
-				$template = ($i == $this->currentPage ? $actPageLinkSubPart : $inactPageLinkSubPart);
-				$pageType = ($i < $this->currentPage ? self::PAGE_BEFORE :
-					($i > $this->currentPage ? self::PAGE_AFTER : self::PAGE_CURRENT));
-				$localMarkers = array(
-					'###NUMBER###' => $i,
-					'###NUMBER_DISPLAY###' => $i + 1,
-					'###LINK###' => $this->getPageLink($i, $pageType),
-				);
-				if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['pageLinkMarkers'])) {
-					foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['pageLinkMarkers'] as $userFunc) {
-						$params = array(
-							'markers' => &$localMarkers,
-							'page' => $i,
-							'pObj' => &$this
-						);
-						GeneralUtility::callUserFunction($userFunc, $params, $this);
-					}
-				}
-				$pageLinks .= $this->cObj->substituteMarkerArray($template, $localMarkers);
-			}
-			$subPartMarkers['###PAGE###'] = $pageLinks;
-			$subPartMarkers['###CURRENT###'] = '';
-
-			// Less pages part
-			if ($start == 0 || !$this->conf['enableLessPages']) {
-				$subPartMarkers['###LESS_PAGES###'] = '';
-			}
-			// More pages part
-			if ($end == $this->numberOfPages || !$this->conf['enableMorePages']) {
-				// We have all pages covered. Remove this part.
-				$subPartMarkers['###MORE_PAGES###'] = '';
-			}
-
-			// Extra markers hook
-			if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['additionalMarkers'])) {
-				foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['additionalMarkers'] as $userFunc) {
-					$params = array(
-						'currentPage' => $this->currentPage,
-						'markers' => &$markers,
-						'numberOfPages' => $this->numberOfPages,
-						'pObj' => &$this,
-						'subparts' => &$subPartMarkers
-					);
-					GeneralUtility::callUserFunction($userFunc, $params, $this);
-				}
-			}
-
-			// Compile all together
-			$out = $this->cObj->substituteMarkerArrayCached($subPart, $markers, $subPartMarkers);
-			// Remove all comments
-			$out = preg_replace('/<!--\s*###.*?-->/', ' ', $out);
-			// Remove excessive spacing
-			$out = preg_replace('/\s{2,}/', ' ', $out);
-		}
-		return $out;
-	}
-
-	/**
-	 * Generates page link. Keeps all current URL parameters except for cHash and tx_pagebrowse_pi1[page].
-	 *
-	 * @param	int		$page	Page number starting from 1
-	 * @param	int		$pageType	One of PAGE_xxx constants
-	 * @return	string		Generated link
-	 */
-	protected function getPageLink($page, $pageType) {
-		// Prepare query string. We do both urlencoded and non-encoded version
-		// because older TYPO3 versions use unencoded parameter names
-		$queryConf = array(
-			'exclude' => $this->pageParameterName . ',' .
-							rawurlencode($this->pageParameterName) .
-							',cHash',
-		);
-		$additionalParams = urldecode($this->cObj->getQueryArguments($queryConf));
-
-		// Add page number
-		if ($page > 0) {
-			$additionalParams .= '&' . $this->pageParameterName . '=' . $page;
-		}
-
-		// Add extra query string from config
-		$extraQueryString = trim($this->conf['extraQueryString']);
-		if (is_array($this->conf['extraQueryString.'])) {
-			$extraQueryString = $this->cObj->stdWrap($extraQueryString, $this->conf['extraQueryString.']);
-		}
-		if (strlen($extraQueryString) > 2 && $extraQueryString{0} == '&') {
-			$additionalParams .= $extraQueryString;
-		}
-
-		// Call extra parameter hook
-		if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['additionalParameters'])) {
-			foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['additionalParameters'] as $userFunc) {
-				$params = array(
-					'pObj' => &$this,
-					'additionalParameters' => $additionalParams,
-					'pageType' => $pageType,
-					'pageNumber' => $page,
-				);
-				$additionalParams = GeneralUtility::callUserFunction($userFunc, $params, $this);
-			}
-		}
-		// Assemble typolink configuration
-		$conf = array(
-			'parameter' => $GLOBALS['TSFE']->id,
-			'additionalParams' => $additionalParams,
-			'useCacheHash' => (strlen($additionalParams) > 1) && !$this->conf['disableCacheHash'],
-		);
-
-		return htmlspecialchars($this->cObj->typoLink_URL($conf));
-	}
-
-	/**
-	 * Tests if the value can be interpreted as integer.
-	 *
-	 * @param mixed $value
-	 * @return bool
-	 */
-	static protected function testInt($value) {
-		return \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($value);
-	}
-}
diff --git a/Classes/ViewHelpers/PageBrowserViewHelper.php b/Classes/ViewHelpers/PageBrowserViewHelper.php
index ab7c502..c111c0f 100644
--- a/Classes/ViewHelpers/PageBrowserViewHelper.php
+++ b/Classes/ViewHelpers/PageBrowserViewHelper.php
@@ -41,23 +41,14 @@ class PageBrowserViewHelper extends AbstractViewHelper {
 	 * Render method of the view helper.
 	 *
 	 * @param integer $numberOfPages
-	 * @param boolean $enableMorePages
 	 * @return string
 	 */
-	public function render($numberOfPages, $enableMorePages = FALSE) {
-		// overwrite general configuration of pagebrowse
-		$additionalConfiguration = [
-			'numberOfPages' => (int) $numberOfPages,
-			'enableMorePages' => $enableMorePages,
-		];
-
-		$configuration = array_merge(
-			$GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_sgnews.']['pagebrowser.'],
-			$additionalConfiguration
-		);
+	public function render($numberOfPages) {
+		$configuration = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_sgnews.']['pagebrowser.'];
+		$configuration['settings.']['numberOfPages'] = (int) $numberOfPages;
 
 		/** @var ContentObjectRenderer $contentObject */
-		$contentObject = $this->objectManager->get('TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer');
+		$contentObject = $this->objectManager->get(ContentObjectRenderer::class);
 		$contentObject->start([], '');
 		return $contentObject->cObjGetSingle('USER', $configuration);
 	}
diff --git a/Configuration/TypoScript/Frontend/constants.txt b/Configuration/TypoScript/Frontend/constants.txt
index 2d8d67c..aa0fb67 100644
--- a/Configuration/TypoScript/Frontend/constants.txt
+++ b/Configuration/TypoScript/Frontend/constants.txt
@@ -14,7 +14,17 @@ plugin.tx_sgnews {
 		newsLimitPerPage = 12
 	}
 
-	pagebrowser {
-		templateFile = EXT:sg_news/Resources/Private/Partials/Pagebrowser/Pagebrowser.html
+	pagebrowser.settings {
+		# Number of page links to show before the current page
+		pagesBefore = 1
+
+		# Number of page links to show before the current page
+		pagesAfter = 1
+
+		# Enables section for "more" pages. This section is shown after links to next pages, normally like three dots (1 2 3 ...). Notice that you can also hide it by emptying corresponding template section.
+		enableMorePages = 1
+
+		# Enables section for "less" pages. This section is shown after links to next pages, normally like three dots (... 1 2 3) Notice that you can also hide it by emptying corresponding template section.
+		enableLessPages = 1
 	}
 }
diff --git a/Configuration/TypoScript/Frontend/setup.txt b/Configuration/TypoScript/Frontend/setup.txt
index efce6d2..bcd2112 100644
--- a/Configuration/TypoScript/Frontend/setup.txt
+++ b/Configuration/TypoScript/Frontend/setup.txt
@@ -60,32 +60,34 @@ plugin.tx_sgnews {
 
 	pagebrowser = USER
 	pagebrowser {
-		# USER_INT support
-		includeLibs = EXT:sg_news/Classes/UserFunc/class.tx_pagebrowse_pi1.php
-		userFunc = tx_pagebrowse_pi1->main
-
-		# Template file
-		templateFile = {$plugin.tx_sgnews.pagebrowser.templateFile}
-
-		# Extra parameters to the query string. Must start with & if not empty
-		extraQueryString =
-
-		# Number of page links to show before the current page
-		pagesBefore = 1
-
-		# Number of page links to show before the current page
-		pagesAfter = 1
-
-		# GET variable name for page pointer. Examples: "page" or "tx_exykey_pi1|page". Notice that array separator is pipe (one level only!)
-		pageParameterName = tx_pagebrowse_pi1|page
-
-		# Enables section for "more" pages. This section is shown after links to next pages, normally like three dots (1 2 3 ...). Notice that you can also hide it by emptying corresponding template section.
-		enableMorePages = 0
-
-		# Enables section for "less" pages. This section is shown after links to next pages, normally like three dots (1 2 3 ...) Notice that you can also hide it by emptying corresponding template section.
-		enableLessPages = 0
-
-		# Enables inclusion of the additional header parts (css)
-		addHeaderParts = 1
+		userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
+		extensionName = SgNews
+		pluginName = PageBrowser
+		vendorName = SGalinski
+		controller = PageBrowser
+		action = index
+		view < plugin.tx_sgnews.view
+		persistence < plugin.tx_sgnews.persistence
+		features < plugin.tx_sgnews.features
+		legacy < plugin.tx_sgnews.legacy
+		settings {
+			# Number of page links to show before the current page
+			pagesBefore = {$plugin.tx_sgnews.pagebrowser.settings.pagesBefore}
+
+			# Number of page links to show before the current page
+			pagesAfter = {$plugin.tx_sgnews.pagebrowser.settings.pagesAfter}
+
+			# Enables section for "more" pages. This section is shown after links to next pages, normally like three dots (1 2 3 ...). Notice that you can also hide it by emptying corresponding template section.
+			enableMorePages = {$plugin.tx_sgnews.pagebrowser.settings.enableMorePages}
+
+			# Enables section for "less" pages. This section is shown after links to next pages, normally like three dots (... 1 2 3) Notice that you can also hide it by emptying corresponding template section.
+			enableLessPages = {$plugin.tx_sgnews.pagebrowser.settings.enableLessPages}
+
+			# The number of the pages
+			numberOfPages = 0
+
+			# The current page
+			currentPage = 0
+		}
 	}
 }
diff --git a/Resources/Private/Language/de.locallang_backend.xlf b/Resources/Private/Language/de.locallang_backend.xlf
index 78d69e4..4bcac74 100644
--- a/Resources/Private/Language/de.locallang_backend.xlf
+++ b/Resources/Private/Language/de.locallang_backend.xlf
@@ -33,10 +33,14 @@
 			<source>News Overview</source>
 			<target>News-Ãœbersicht</target>
 		</trans-unit>
+		<trans-unit id="titlePageBrowserPlugin" approved="yes">
+			<source>Page Browser Plugin</source>
+			<target>Seitenbrowser-Plugin</target>
+		</trans-unit>
 		<trans-unit id="titleSingleViewPlugin" approved="yes">
 			<source>News Single View</source>
 			<target>News-Einzelansicht</target>
 		</trans-unit>
 		</body>
 	</file>
-</xliff>
\ No newline at end of file
+</xliff>
diff --git a/Resources/Private/Language/locallang_backend.xlf b/Resources/Private/Language/locallang_backend.xlf
index 194e483..3fcc666 100644
--- a/Resources/Private/Language/locallang_backend.xlf
+++ b/Resources/Private/Language/locallang_backend.xlf
@@ -27,9 +27,12 @@
 		<trans-unit id="titleOverviewPlugin">
 			<source>News Overview</source>
 		</trans-unit>
+		<trans-unit id="titlePageBrowserPlugin">
+			<source>Page Browser Plugin</source>
+		</trans-unit>
 		<trans-unit id="titleSingleViewPlugin">
 			<source>News Single View</source>
 		</trans-unit>
 		</body>
 	</file>
-</xliff>
\ No newline at end of file
+</xliff>
diff --git a/Resources/Private/Layouts/PageBrowser.html b/Resources/Private/Layouts/PageBrowser.html
new file mode 100644
index 0000000..ed9754c
--- /dev/null
+++ b/Resources/Private/Layouts/PageBrowser.html
@@ -0,0 +1,3 @@
+<div class="tx-sgnews-pagebrowser">
+	<f:render section="main" />
+</div>
diff --git a/Resources/Private/Partials/Pagebrowser/Pagebrowser.html b/Resources/Private/Partials/Pagebrowser/Pagebrowser.html
deleted file mode 100755
index d535280..0000000
--- a/Resources/Private/Partials/Pagebrowser/Pagebrowser.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>Page browser template</title>
-</head>
-<body>
-<!-- ###PAGE_BROWSER### begin -->
-<!--TYPO3SEARCH_end-->
-<nav>
-	<ul class="pagination">
-		<!-- ###ACTIVE_PREV### begin -->
-		<li class="tx-pagebrowse-prev"><a href="###PREV_LINK###" aria-label="Previous">&laquo;</a></li>
-		<!-- ###ACTIVE_PREV### end -->
-
-		<!-- ###INACTIVE_PREV### begin -->
-		<li class="tx-pagebrowse-prev disabled"><a aria-label="Previous"><span aria-hidden="true">&laquo;</a></li>
-		<!-- ###INACTIVE_PREV### end -->
-
-		<!-- ###PAGES### begin -->
-				<!--  ###LESS_PAGES### begin -->
-				<li>...</li>
-				<!--  ###LESS_PAGES### end -->
-				<!-- ###PAGE### begin -->
-				<li class="tx-pagebrowse-page"><a href="###LINK###">###NUMBER_DISPLAY###</a></li>
-				<!-- ###PAGE### end -->
-				<!-- ###CURRENT### begin -->
-				<li class="tx-pagebrowse-current active"><a href="#">###NUMBER_DISPLAY### <span class="sr-only">(current)</span></a></li>
-				<!-- ###CURRENT### end -->
-				<!--  ###MORE_PAGES### begin -->
-				<li>...</li>
-				<!--  ###MORE_PAGES### end -->
-		<!-- ###PAGES### end -->
-
-		<!-- ###ACTIVE_NEXT### begin -->
-		<li class="tx-pagebrowse-next"><a href="###NEXT_LINK###" aria-label="Next">&raquo;</a></li>
-		<!-- ###ACTIVE_NEXT### end -->
-
-		<!-- ###INACTIVE_NEXT### begin -->
-		<li class="tx-pagebrowse-next disabled"><a aria-label="Next"><span aria-hidden="true">&raquo;</a><</li>
-		<!-- ###INACTIVE_NEXT### end -->
-
-	</ul>
-</nav>
-<!--TYPO3SEARCH_begin-->
-<!-- ###PAGE_BROWSER### end -->
-
-</body>
-</html>
diff --git a/Resources/Private/Templates/PageBrowser/Index.html b/Resources/Private/Templates/PageBrowser/Index.html
new file mode 100644
index 0000000..2087a37
--- /dev/null
+++ b/Resources/Private/Templates/PageBrowser/Index.html
@@ -0,0 +1,85 @@
+{namespace sg=SGalinski\SgNews\ViewHelpers}
+
+<f:layout name="PageBrowser" />
+
+<f:section name="main">
+	<nav>
+		<ul class="pagination">
+			<f:if condition="{prevPageExist}">
+				<f:then>
+					<li class="tx-pagebrowse-prev">
+						<a href="{previousLink}" aria-label="Previous">
+							&laquo;
+						</a>
+					</li>
+				</f:then>
+				<f:else>
+					<li class="tx-pagebrowse-prev disabled">
+						<a aria-label="Previous">
+							<span aria-hidden="true">
+								&laquo;
+							</span>
+						</a>
+					</li>
+				</f:else>
+			</f:if>
+
+			<sg:extendedIf condition="{enableLessPages}" and="{showLessPages}">
+				<li>
+					<a href="{enableLessPagesLink}">
+						...
+					</a>
+				</li>
+			</sg:extendedIf>
+
+			<f:for each="{pageLinks}" as="pageLink">
+				<f:if condition="{pageLink.isCurrentPage}">
+					<f:then>
+						<li class="tx-pagebrowse-current active">
+							<a href="#">
+								{pageLink.number}
+								<span class="sr-only">
+									(current)
+								</span>
+							</a>
+						</li>
+					</f:then>
+					<f:else>
+						<li class="tx-pagebrowse-page">
+							<a href="{pageLink.link}">
+								{pageLink.number}
+							</a>
+						</li>
+					</f:else>
+				</f:if>
+			</f:for>
+
+			<sg:extendedIf condition="{enableMorePages}" and="{showNextPages}">
+				<li>
+					<a href="{enableMorePagesLink}">
+						...
+					</a>
+				</li>
+			</sg:extendedIf>
+
+			<f:if condition="{nextPageExist}">
+				<f:then>
+					<li class="tx-pagebrowse-next">
+						<a href="{nextLink}" aria-label="Next">
+							&raquo;
+						</a>
+					</li>
+				</f:then>
+				<f:else>
+					<li class="tx-pagebrowse-next disabled">
+						<a aria-label="Next">
+							<span aria-hidden="true">
+								&raquo;
+							</span>
+						</a>
+					</li>
+				</f:else>
+			</f:if>
+		</ul>
+	</nav>
+</f:section>
diff --git a/Resources/Public/Scripts/ScrollBrowser.js b/Resources/Public/Scripts/ScrollBrowser.js
index f574fad..49b3ab9 100644
--- a/Resources/Public/Scripts/ScrollBrowser.js
+++ b/Resources/Public/Scripts/ScrollBrowser.js
@@ -65,7 +65,7 @@ SG.ElementScrollBrowser.prototype = {
 	 * @return {void}
 	 */
 	initialize: function(resultList) {
-		$('.tx-pagebrowse-pi1').css('display', 'none');
+		$('.tx-sgnews-pagebrowser').css('display', 'none');
 		this.resultList = resultList;
 		this.loadIndicator = this.resultList.children(':last');
 		if (!this.loadIndicator.length) {
@@ -124,4 +124,4 @@ $(document).ready(
 		var resultList = $(this).find('.tx-sgnews-list');
 		(new SG.ElementScrollBrowser(resultList));
 	}
-);
\ No newline at end of file
+);
diff --git a/ext_localconf.php b/ext_localconf.php
index 4287c51..5ba6ec1 100644
--- a/ext_localconf.php
+++ b/ext_localconf.php
@@ -13,11 +13,6 @@ $extPath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('sg_news'
 $tsPath = $extPath . 'Configuration/TypoScript/Common/';
 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScriptSetup(file_get_contents($tsPath . 'setup.txt'));
 
-// @todo should be a extbase plugin, check the view helper
-\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPItoST43(
-	'sg_news', 'Classes/UserFunc/class.tx_pagebrowse_pi1.php', '_pi1', 'list_type', 1
-);
-
 // plugin configurations
 \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
 	'SGalinski.sg_news',
@@ -61,6 +56,13 @@ $tsPath = $extPath . 'Configuration/TypoScript/Common/';
 	['ListByCategory' => '',]
 );
 
+\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
+	'SGalinski.sg_news',
+	'PageBrowser',
+	['PageBrowser' => 'index',],
+	['PageBrowser' => '',]
+);
+
 // hook registration
 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][] =
 	'EXT:sg_news/Classes/TCA/TcaProvider.php:SGalinski\SgNews\TCA\TcaProvider';
diff --git a/ext_tables.php b/ext_tables.php
index 56d7ec3..cbb67cb 100644
--- a/ext_tables.php
+++ b/ext_tables.php
@@ -28,6 +28,11 @@ TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
 	'LLL:EXT:sg_news/Resources/Private/Language/locallang_backend.xlf:titleListByCategoryPlugin'
 );
 
+TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
+	'sg_news', 'PageBrowser',
+	'LLL:EXT:sg_news/Resources/Private/Language/locallang_backend.xlf:titlePageBrowserPlugin'
+);
+
 // Flex form assignment
 $pluginSignature = str_replace('_', '', 'sg_news') . '_overview';
 $TCA['tt_content']['types']['list']['subtypes_addlist'][$pluginSignature] = 'pi_flexform';
-- 
GitLab