Route enhancers 

This extension ships one ready made route enhancer in Configuration/Routes/Detail.yaml. TYPO3 does not read that file on its own — it is a fragment that has to be imported from the configuration of the site which shows the plugin.

What the file enhances 

The file declares a single enhancer of type Extbase named AcademicJobsDetailPlugin , bound to the plugin Detail of the extension AcademicJobs . That pair determines the argument namespace the enhancer works on — tx_academicjobs_detail .

It registers one route for the show action of \FGTCLB\AcademicJobs\Controller\JobController :

EXT:academic_jobs/Configuration/Routes/Detail.yaml
routes:
  - routePath: '/{job_title}'
    _controller: 'Job::show'
    _arguments:
      job_title: 'job'
Copied!

The path segment is resolved by a PersistedAliasMapper on tx_academicjobs_domain_model_job over the field slug , so the speaking part of the URL is the slug of the job record rather than its uid.

No enhancer is shipped for the other two plugins, and none is needed: the List plugin has neither pagination nor a filter, so its action takes no arguments at all, and the NewJobForm plugin submits its form by POST.

Importing it into a site configuration 

Add the resource to the imports of the site that contains the page with the job detail plugin:

config/sites/my_site/config.yaml
imports:
  - resource: 'EXT:academic_jobs/Configuration/Routes/Detail.yaml'
Copied!

Limiting the enhancer to its page 

TYPO3 offers every enhancer declared in a site configuration to every page of that site unless the enhancer says otherwise, and it takes the first candidate route whose path matches and whose aspects resolve. Distinct enhancer keys keep the entries apart in the YAML — they are not what keeps their routes apart while a URL is resolved.

The route of this extension is /{job_title} . Its path variable comes from an aspect and carries no requirements entry of its own, which makes it compile to .+ — a pattern that crosses slashes. What keeps it from answering a URL meant for another extension is only that its PersistedAliasMapper rejects a segment which is not a job slug, so the candidate is skipped and the next one is tried. That is a thin guarantee: a slug value that exists in both tables makes the two routes compete, and the enhancer imported first wins.

limitToPages settles it by naming the pages the enhancer applies to:

config/sites/my_site/config.yaml
imports:
  - resource: 'EXT:academic_jobs/Configuration/Routes/Detail.yaml'

routeEnhancers:
  AcademicJobsDetailPlugin:
    limitToPages: [17]
Copied!

The uid is the one of the page carrying the detail plugin, and it is the uid of the default language: matching derives the page as l10n_parent ?: uid , so a single entry covers every translation of that page. Plain page uids work on every TYPO3 version this extension supports.

In academic_persons the same mechanism is not a precaution but a requirement — that extension ships three enhancers whose routes overlap each other by construction. See its route enhancer documentation.

What the URLs look like 

Assuming the detail plugin sits on a page with the slug /jobs/detail, a link from the list to a job is built without the enhancer as:

/jobs/detail?tx_academicjobs_detail%5Bjob%5D=17
Copied!

and with the enhancer imported as:

/jobs/detail/research-assistant-biology
Copied!

Caveats 

  • The route needs a slug. PersistedAliasMapper resolves the path segment against the slug field of the job record, so a job whose slug is empty cannot be reached through the enhanced URL. A record saved in the backend gets one from the TCA slug field; a record created by the frontend form of the NewJobForm plugin does not go through the DataHandler at all and gets one from the event listener \FGTCLB\AcademicJobs\EventListener\GenerateJobSlug instead. Records that predate the slug field have to be updated once, for example by emptying the field in the backend form so it is generated again.
  • Jobs entered through the frontend form are created hidden, so they only become reachable — enhanced URL or not — once they were approved in the backend.
  • The list plugin renders its links with the detail plugin name and the page from the plugin setting detailPid . Enhancing the detail page therefore changes the links of an unmodified list template without any further configuration.