I often use the TYPO3 linkHandler to enable the possibility for editors to create direct links to records from within the CKEditor in TYPO3 backend. This is all well documented and easy to configure using the RecordLinkHandler, as long as the resulting link only contains one dynamic parameter. But sometimes it may be required to have multiple dynamic parameters for the resulting link. In this case you may need to create a userFunc for the typolink function in order to create a custom configuration which uses multiple dynamic parameters.
Requirement
Let us assume, you have an event which has multiple event registrations. Registrations are listed in the detail view of an event and each registration is shown as an accordion item with a unique ID in markup. Now you want to create a link to an event and set a link anchor to a specific registration. The resulting URL should be as shown below:
https://www.cool-events.tld/events/my-first-event#registration-1
Calling the URL will open the event detail page and scroll down the the HTML element with the ID "registration-1".
Note: This is just an example, which also can be achieved without a custom userFunc. Goal of this article is to demonstrate how to use a userFunc for typolink.
Solution
In order to archive the requirement, first a linkHandler Page TSConfig must be created as shown below:
TCEMAIN.linkHandler {
event {
handler = TYPO3\CMS\Recordlist\LinkHandler\RecordLinkHandler
label = Event Registration
configuration {
table = tx_sfeventmgt_domain_model_registration
}
}
}
Next, the TypoScript for the link generation is added.
config {
recordLinks {
registration {
typolink {
parameter = 1
userFunc = DERHANSEN\SfEventMgt\UserFunc\TypoLink->createEventLink
userFunc {
eventUid = TEXT
eventUid.data = field:event
registrationUid = TEXT
registrationUid.data = field:uid
}
}
}
}
}
Finally a custom userFunc needs to be created which renders the A-tag for the link.
<?php
declare(strict_types=1);
namespace DERHANSEN\SfEventMgt\UserFunc;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
class TypoLink
{
private const EVENT_DETAILPID = 22;
public ContentObjectRenderer $cObj;
public function createEventLink(array $content, array $config): string
{
$eventUid = $this->cObj->cObjGetSingle($config['eventUid'], $config['eventUid.']);
$registrationUid = $this->cObj->cObjGetSingle($config['registrationUid'], $config['registrationUid.']);
// Link parameters (can also contain multiple dynamic parameters)
$parameters = [
'tx_sfeventmgt_pieventdetail' => [
'controller' => 'Event',
'action' => 'detail',
'event' => $eventUid,
]
];
$link = $this->cObj->typoLink($this->cObj->lastTypoLinkResult->getLinkText(), [
'parameter' => self::EVENT_DETAILPID,
'additionalParams' => '&' . http_build_query($parameters),
'section' => 'registration-' . $registrationUid,
'returnLast' => 'url',
]);
return '<a href="' . $link . '">';
}
}
The most important part is, that the custom userFunc must only return the opening A-tag. In the userFunc, it is basically possible to construct the resulting link however you want. In the example above, 2 dynamic parameters are used in the function ($eventUid and $registrationUid). It is of course also possible to e.g. do dynamic database lookups in the function to fetch other dynamic parameters required for link construction.