T3PO3 v10: How to use RouteEnhancer with ArrayPaginator? - typo3

I'm using the ArrayPaginator for my Extbase list view, since Fluid widget functionality will no longer be available in TYPO3 v11.
And I'm currently trying to use the RouteEnhancer with this.
My list action just receives the argument for the current page as integer.
And the code for the RouteEnhancer looks like this:
RefList:
type: Extbase
limitToPages:
- 142
extension: Ref
plugin: Pi2
routes:
-
routePath: /seite-{page}
_controller: 'Ref::list'
_arguments:
page: currentPage
defaultController: 'Ref::list'
requirements:
page: \d+
aspects:
page:
type: StaticRangeMapper
start: '1'
end: '1000'
I've seen a lot examples for the Fluid pagination widget that contained the value #widget_0/currentPage for the argument page.
The URL is generated correctly if I switch to another page but the content displayed from the list view is still the same as on page 1.
What am I missing here?

You can us a QueryResultPaginator instead of a ArrayPaginator.
Route
routeEnhancers:
RefList:
type: Extbase
extension: Ref
plugin: Pi2
routes:
- routePath: '/'
_controller: 'Ref::list'
- routePath: '/{page}'
_controller: 'Ref::list'
_arguments:
page: current-page
defaultController: 'Ref::list'
aspects:
current-page:
type: StaticRangeMapper
start: '1'
end: '100'
RefController.php Get current-page from request
public function listAction()
{
$refs = $this->refRepository->findAll();
$currentPage = $this->request->hasArgument('current-page') ? $this->request->getArgument('current-page') : 1;
$paginatedRefs = new QueryResultPaginator($refs, $currentPage, $this->itemsPerPage);
$simplePagination = new SimplePagination($paginatedRefs);
$pagination = $this->buildSimplePagination($simplePagination, $paginatedRefs);
$this->view->assignMultiple([
'refs' => $paginatedRefs,
'pagination' => $pagination,
]);
}
/**
* Build simple pagination
*
* #param SimplePagination $simplePagination
* #param QueryResultPaginator $paginator
* #return array
*/
protected function buildSimplePagination(SimplePagination $simplePagination, QueryResultPaginator $paginator): array
{
$firstPage = $simplePagination->getFirstPageNumber();
$lastPage = $simplePagination->getLastPageNumber();
return [
'lastPageNumber' => $lastPage,
'firstPageNumber' => $firstPage,
'nextPageNumber' => $simplePagination->getNextPageNumber(),
'previousPageNumber' => $simplePagination->getPreviousPageNumber(),
'startRecordNumber' => $simplePagination->getStartRecordNumber(),
'endRecordNumber' => $simplePagination->getEndRecordNumber(),
'currentPageNumber' => $paginator->getCurrentPageNumber(),
'pages' => range($firstPage, $lastPage)
];
}
List.html add pagination template
<f:for each="{refs.paginatedItems}" as="ref">
<f:render partial="List/ListItem" arguments="{ref: ref}" />
</f:for>
<f:render partial="List/Pagination" arguments="{pagination:pagination, action:'list'}" />
Partial List/Pagination.html
add links for pagination: previous
<f:link.action action="{action}" arguments="{current-page:pagination.previousPageNumber}">previous</f:link.action>
add links for pagination: pages
<f:link.action action="{action}" arguments="{current-page:page}">{page}</f:link.action>
add links for pagination: next
<f:link.action action="{action}" arguments="{current-page: pagination.nextPageNumber}">next</f:link.action>

I've found a workaround.
Inside the controller list action: $currentPage = (int) ($_GET['tx_ref_pi2']['currentPage'] ?? 1);

Related

typo3 : Routing config for my own extension

I'm using typo3 v9.5 and have my own extension.
Actually I'm trying to get a clean URL with route Enhancers, it's my first time with it
I need an url like this :
https://www.mywebsite.com/{my-category}
and actually I have this :
https://www.mywebsite.com/{my-category}?tx_plugin_plugin%5BpageId%5D=102
&cHash=d6374a0e73ca3fde9c60edf88cfdf7cf
I have a second argument pageId, but it is possible to hide it on the url ?
this is my config.yaml :
Myext:
type: Extbase
extension: Myext
plugin: Myext
routes:
- { routePath:
'/{categorie-name}',
_controller: 'Categorie::list',
_arguments: {
categorie-name: 'parentCategoryId'
}
}
defaultController: 'Categorie::list'
defaults:
page: '0'
aspects:
categorie-name:
type: PersistedAliasMapper
tableName: 'sys_category'
routeFieldName: 'title'
page:
type: StaticRangeMapper
start: '1'
end: '100'
I have another question, I saw some config about routing, and they have this settings :
tableName: 'sys_category'
routeFieldName: 'slug'
I tried to put slug to instead of 'title' but I got an error because I don't have this field on my sys_category table, it is possible to add this field on a core table of Typo3 ?
Error my table sys_category doesn't have slug field :
You can exclude parameter you don't need in /typo3conf/LocalConfiguration.php,
'FE' => [
'cacheHash' => [
'excludedParameters' => [
'pageId',
],
],
],
may be this will work for you.

Routeenhancer typo3 extension with 2 plugin

I develop a Typo3 extension with 2 plugin
This is my ext_localconf.php
call_user_func(
function()
{
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Didattica',
'Lauree',
[
\Polimi\Didattica\Controller\ElencocdsController::class => 'lauree,detail',
],
// non-cacheable actions
[
\Polimi\Didattica\Controller\ElencocdsController::class => 'lauree,detail',
]
);
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Didattica',
'Laureemagistrali',
[
\Polimi\Didattica\Controller\ElencocdsmagController::class => 'laureemagistrali,detail',
],
// non-cacheable actions
[
\Polimi\Didattica\Controller\ElencocdsmagController::class => 'laureemagistrali,detail',
]
);
I tried to add a routeenhancer for my extension
routeEnhancers:
Elencocds:
type: Extbase
extension: Didattica
plugin: Lauree
routes:
- routePath: '{name}'
_controller: 'Elencocds::detail'
_arguments:
name: elencocds
defaultController: 'Elencocds::detail'
defaults:
page: '1'
requirements:
page: \d+
aspects:
name:
type: PersistedPatternMapper
tableName: tx_didattica_domain_model_elencocds
routeFieldPattern: ^(?<slug>.+)$
routeFieldResult: '{slug}'
Elencocdsmag:
type: Extbase
extension: Didattica
plugin: Laureemagistrali
routes:
- routePath: '{name}'
_controller: 'Elencocdsmag::detail'
_arguments:
name: elencocds
defaultController: 'Elencocdsmag::detail'
defaults:
page: '1'
requirements:
page: \d+
aspects:
name:
type: PersistedPatternMapper
tableName: tx_didattica_domain_model_elencocds
routeFieldPattern: ^(?<slug>.+)$
routeFieldResult: '{slug}'
the first plugin works fine.
the second plugin correctly displays the "converted" url, but remains stationary in the "laureemagistrali" action, and does not apply the "detail" action.
Seems it does not nothing.
What am I doing wrong?

Typo3 - ReDirect and RouteEnhancer

I am having trouble with my Extbase-Plugin, redirects and route enhancers:
I have a plugin that gets job offers via an API and displays as a list on a Typo3-page. I have written a route enhancer to make the URLs for the single job offers pretty.
If a user clicks on a link, the method "showJob" from the controller is called. This method redirects the user to a different page (I do need two distinct pages for this) and calls the method "showSingleJob".
I have written this redirect like this:
{
$currentPid = $GLOBALS['TSFE']->id;
$jobID = $this->request->getArgument('jobID');
$jobTitle = $this->request->getArgument('jobTitle');
$pageID = $this->request->getArgument('pageID');
$args = [
'jobID' => $jobID,
'jobTitle' => $jobTitle,
"pageID" => $pageID
];
$response = json_decode($this->curl_get_contents('https://api.jobsAPI.com/job/' . $jobID));
if ($pageID != $currentPid) {
$uriBuilder = $this->uriBuilder;
$uri = $uriBuilder
->reset()
->setTargetPageUid(intval($pageID))
->setAddQueryString(TRUE)
->uriFor('showSingleJob', $args, 'UmJobs', 'UmJobs', 'jobliste');
$this->redirectToUri($uri, 0, 404);
}
$this->view->assign('apiJob', $response);
}
The method "showSingleJob" simply gets the data for the desired job and displays it. This works just fine.
But I need pretty urls for the redirected page. At the moment I get my typo3-Url plus all the parameters I am passing. So I tried my hand at a route enhancer:
routeEnhancers:
UmJobs:
type: Extbase
limitToPages:
- 1
- 3
extension: UmJobs
plugin: jobliste
routes:
- routePath: '/karriere/'
_controller: 'UmJobs::list'
- routePath: '/karriere/{jobTitle}/{jobID}/{pageID}'
_controller: 'UmJobs::showJob'
_arguments:
jobTitle: jobTitle
jobID: jobID
pageID: pageID
defaultController: 'UmJobs::showJob'
- routePath: '/karriere/job/{jobTitle}/{jobID}/{pageID}'
_controller: 'UmJobs::showSingleJob'
_arguments:
jobTitle: jobTitle
jobID: jobID
pageID: pageID
defaultController: 'UmJobs::showSingleJob'
requirements:
jobID: '^[0-9].*$'
pageID: '^[0-9].*$'
jobTitle: '^[a-zA-Z0-9].*$'
Again this works fine for "showJobs" but It doens't work at all for "showSingleJobs". It seems as if the enhancer is completely ingored by $uribuilder.
Anyone have an idea what I am doing wrong?
Thanks a lot in advance!
Seems to me as if your URIs are not unique...
'UmJobs::showJob
routePath: '/karriere/{jobTitle}/{jobID}/{pageID}'
Now lets the values be:
jobTitle = job // Matching the requirement '^[a-zA-Z0-9].*$'
jobID = 123 // Matching the requirement '^[0-9].*$'
pageID = 987 // Matching the requirement '^[0-9].*$'
The path would be: /karriere/job/123/987
'UmJobs::showSingleJob
routePath: '/karriere/job/{jobTitle}/{jobID}/{pageID}'
Now lets the values be:
jobTitle = 123 // Matching the requirement '^[a-zA-Z0-9].*$'
jobID = 987 // Matching the requirement '^[0-9].*$'
pageID = '' // Matching the requirement '^[0-9].*$'
The path would be: /karriere/job/123/987
Conclusion
You can have the same URI for different actions - which can not be served.

RouteEnhancer with aspects throws InvalidParameterException

I used the example verbatim from the Changelog:
The only thing I changed was the limitToPages.
routeEnhancers:
NewsPlugin:
type: Extbase
limitToPages: [82]
extension: News
plugin: Pi1
routes:
- { routePath: '/{news_title}', _controller: 'News::detail', _arguments: {'news_title': 'news'} }
defaultController: 'News::detail'
aspects:
news_title:
type: PersistedAliasMapper
tableName: 'tx_news_domain_model_news'
routeFieldName: 'path_segment'
routeValuePrefix: '/'
This throws an exception in 9.5.4:
Symfony\Component\Routing\Exception\InvalidParameterException
Parameter "tx_news_pi1__news" for route "tx_news_pi1_0" must match "[^/]++" ("" given) to generate a corresponding URL.
in /var/www/example/htdocs/typo3_src-9.5.4/vendor/symfony/routing/Generator/UrlGenerator.php line 155
at Symfony\Component\Routing\Generator\UrlGenerator->doGenerate(array('tx_news_pi1__news' => 0), array('_controller' => 'News::detail'), array(), array(array('variable', '/', '[^/]++', 'tx_news_pi1__news', true), array('text', '/aktuelles/artikel')), array('tx_news_pi1__news' => ''), 'tx_news_pi1_0', 1, array(), array())
in /var/www/example/htdocs/typo3_src-9.5.4/vendor/symfony/routing/Generator/UrlGenerator.php line 128
Currently, no other route enhancers exist. But I successfully used a simpler configuration on that exact same page and that worked:
NewsDetail:
type: Extbase
limitToPages: [82]
extension: News
plugin: Pi1
routes:
- { routePath: '/{news_id}', _controller: 'News::detail', _arguments: {'news_id': 'news'} }
Not sure where to look and how best to troubleshoot. I was hoping someone had similar problem or could point me in the right direction.
Check if empty path_segment is the problem here:
select count(*) from tx_news_domain_model_news where path_segment='';
Fix
If there are news entry with empty titles, you may want to remove these or update the title first.
Run update wizard: "Updates slug field "path_segment" of EXT:news records" (you may have to mark it as "undone" in Upgrade Wizard first (BE: Upgrade > Upgrade Wizard > Run Upgrade Wizard)
Or manually set tx_news_domain_model_news.path_segment
Same problem for me, the problem was because 'path_segment' generated with Install Tool Wizard had a slash, like : "the-path/another-segment"
The solution is to check for slash in 'path_segment' and replace them with another symbol, request like this :
SELECT uid, pid, path_segment, title FROM tx_news_domain_model_news WHERE path_segment LIKE "%/%";
and change path_segment like that : "the-path_another-segment"

TYPO3 Ext. Custom Routes: Reverse Resolution not working

I am struggling with the URL generation of TYPO3 in my own extension.
Site Config:
routeEnhancers:
JobsPlugin:
type: Extbase
limitToPages: [11]
extension: Company
plugin: Jobs
routes:
- { routePath: '/{job_title}', _controller: 'Jobs::job', _arguments: {'job_title': 'id'} }
defaultController: 'Jobs::job'
requirements:
job_title: '[0-9]{1..6}'
aspects:
job_title:
type: PersistedAliasMapper
tableName: 'tx_company_domain_model_job'
routeFieldName: 'path_segment'
routeValuePrefix: '/'
Controller:
/**
* #param int $id
*/
public function jobAction(int $id) { }
Problem
The generated URL looks fine: /de/karriere/technischen-verkaufsberaterin-aussendienst
But when you want to access the page a PageNotFoundException is thrown.
Do I need to make any additional configurations or did I configure anything wrong?
Thanks in advance!
The problem was routeValuePrefix.
After I removed it, the URL could be resolved.
I assume, that this leads to a double slash when resolving: /de/karriere//technischen-verkaufsberaterin-aussendienst