TYPO3 Logo
TypoScript Explained
Options
Give feedback View source How to edit Edit on GitHub Full documentation (single file)

TypoScript Explained

About TypoScript

  • Introduction
  • Getting started
    • Quick overview
    • First steps
    • Page
    • Content records
    • Create a menu with TypoScript
    • fluid_styled_content
    • TypoScript objects
      • Objects executing database queries
      • Objects rendering content
      • Further objects
    • TypoScript functions
      • stdWrap
      • getText / data
      • imgResource
      • select
      • split
      • if
      • typolink
      • parseFunc
    • Next steps
  • Usage
    • TypoScript in Sites
    • TypoScript in Extensions
    • Backend Module
    • Access TypoScript in an extension
    • Constants
    • Register
    • Debugging / analyzing
  • Using and setting TSconfig
    • Setting page TSconfig
    • Setting user TSconfig
    • Conditions
    • PHP API
  • Syntax
    • Identifiers
    • Code blocks
    • Operators
    • Comments
    • Conditions
    • File imports
    • String formats
    • TSconfig differences

Frontend TypoScript

  • Page
    • PAGE Examples
  • Content Objects (cObject)
    • Content objects (general information)
    • CASE
    • Content object array - COA, COA_INT
    • CONTENT
    • EXTBASEPLUGIN
    • FILES
    • FLUIDTEMPLATE
    • HMENU
      • TMENU
        • TMENUITEM
    • IMAGE
      • GIFBUILDER
        • Examples
        • Colors in TypoScript GIFBUILDER
        • Note on (+calc)
        • Properties
        • GIFBUILDER objects
          • ADJUST
          • BOX
          • CROP
          • EFFECT
          • ELLIPSE
          • EMBOSS
          • IMAGE
          • OUTLINE
          • SCALE
          • SHADOW
          • TEXT
          • WORKAREA
    • IMG_RESOURCE
    • LOAD_REGISTER
    • PAGEVIEW
    • RECORDS
    • RESTORE_REGISTER
    • SVG
    • TEXT
    • USER and USER_INT
  • Data processors
    • comma-separated-value
    • database-query
    • files
    • flex-form
    • gallery
    • language-menu
    • menu
      • Browse
      • Categories
      • Directory
      • Keywords
      • Language
      • List
      • Rootline / Breadcrumb
      • Updated
      • Userfunction
    • page-content
    • record-transformation
    • site
    • site-language
    • split
    • Custom data processors
  • Config
  • Top-level objects
    • page & config
    • module
    • plugin
    • Reserved top-level objects
  • Functions
    • cache
    • Calc
    • Data / getText
    • encapsLines
    • getEnv
    • HTMLparser
    • HTMLparser_tags
    • if
    • imageLinkWrap
    • imgResource
    • makelinks
    • numberFormat
    • numRows
    • optionSplit
    • parseFunc
    • replacement
    • round
    • select
    • split
    • stdWrap
    • strPad
    • tags
    • typolink
    • Wrap
  • Conditions

Backend TypoScript

  • Page TSconfig Reference
    • colorPalettes
    • mod
      • SHARED
      • web_info
      • web_layout
        • Backend layouts
      • web_list
      • web_view
      • wizards
    • options
    • RTE
    • TCAdefaults
    • TCEFORM
    • TCEMAIN
    • templates
    • tx_*
  • User TSconfig reference
    • admPanel (EXT:adminpanel)
    • auth
    • options
    • page
    • permissions
    • setup
    • TCAdefaults
    • tx_*

Appendix

  • PHP and TypoScript
  • Glossary
  • Sitemap
  1. TypoScript Explained
  2. Examples for typolink.userFunc
Give feedback Edit on GitHub

Examples for typolink.userFunc

Given this TypoScript example:

EXT:site_package/Configuration/TypoScript/setup.typoscript
registration {
    value = My Link Title
    typolink {
        parameter = 4711
        additionalParams = &someKey=someValue
        language = 3
        ATagParams = rel="noreferrer"
        title = My Link Title
        userFunc = MyVendor\MySitePackage\UserFunctions\TypoLinkUserFunc->createUserFuncLink
        userFunc {
            eventUid = TEXT
            eventUid.data = field:eventUid
            someFuncParam = someFuncValue
        }
    }
}
Copied!

This would first create a TypoLink LinkResultInterface that would resolve to something like <a href="/en/pages/4711?someKey=someValue" rel="noreferrer">My Link Text</a>.

But because userFunc = MyVendor\SitePackage\UserFunctions\TypoLinkUserFunc->createUserFuncLink is defined you can now manipulate the generated link to your liking.

The usual case would be to enrich the link with any kind of attributes, or also to change existing ones:

EXT:site_package/Classes/UserFunctions/TypoLinkUserFunc.php
<?php

declare(strict_types=1);

namespace MyVendor\MySitePackage\UserFunctions;

use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\LinkHandling\LinkService;
use TYPO3\CMS\Frontend\Typolink\LinkResultInterface;

class TypoLinkUserFunc
{
    public function createUserFuncLink(
        LinkResultInterface $content,
        array $conf,
        ServerRequestInterface $request,
    ): LinkResultInterface {
        // First check what kind of link this is.
        // This example only operates on TYPE_PAGE for internal
        // links; the userFunc can of course also react to
        // types like TYPE_URL (external pages)
        if ($content->getType() === LinkService::TYPE_PAGE) {
            // Add (or replace) a custom "title" link attribute and
            // add "target=_blank" to it, and adjust the link text:

            return $content
                ->withTarget('_blank')
                ->withAttribute('title', 'Custom Title')
                ->withLinkText('A replaced link');
        }

        // If the condition does not match, return the unmodified
        // link.
        return $content;
    }
}
Copied!

This class would take the LinkResultInterface object, enrich it with attributes, pass it to a new immutable object and return that. Then this is what finally gets emitted after full processing:

<a href="/en/pages/4711"
   target="_blank"
   title="Custom Title"
   rel="noreferrer">A replaced link</a>
Copied!

Here is another example which uses more complex operations and also operates on the linked URL:

EXT:site_package/Classes/UserFunctions/TypoLinkUserFunc.php
<?php

declare(strict_types=1);

namespace MyVendor\MySitePackage\UserFunctions;

use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\LinkHandling\LinkService;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\Typolink\LinkResult;
use TYPO3\CMS\Frontend\Typolink\LinkResultInterface;

class TypoLinkUserFunc
{
    public function createUserFuncLink(
        LinkResultInterface $content,
        array $conf,
        ServerRequestInterface $request,
    ): LinkResultInterface {

        // First check what kind of link this is.
        // This example only operates on TYPE_PAGE for internal
        // links; the userFunc can of course also react to
        // types like TYPE_URL (external pages)
        if ($content->getType() === LinkService::TYPE_PAGE) {
            $cObj = $this->getContentObjectRenderer($request);

            // Check if typolink.userFunc additional data is set
            // and act on it
            if ($conf['eventUid.']['data'] ?? null) {
                $url = $content->getAttribute('href')
                       . '/event/' . (int)$conf['eventUid.']['data'];
                // Here you could do database lookups for example
                // to add extbase routing URIs and retrieve
                // fields. This is just an example, proper link building
                // needs to be performed here, also considering cHash.
                $linkText = 'Event Title #18';
            } else {
                // Use currently defined URL
                $url = $content->getUrl();
                // Example how to utilize the cObj and it's wrapping so
                // that `<a href=...><strong>(TITLE!)</strong></a>`
                // would be returned.
                $linkText = $cObj->stdWrap_dataWrap('<strong>{FIELD:title}</strong');
            }

            return $content
                ->withTarget('_blank')
                ->withAttribute('href', $url)
                ->withAttribute('title', 'Custom: ' . $cObj->data['title'])
                ->withLinkText($linkText);
        }

        if ($conf['freshExternalLink'] ?? false) {
            // Depending on conditions, you could also return a completely new object
            // for an external link:
            return (new LinkResult(LinkService::TYPE_URL, 'https://example.com'))
                    ->withLinkText('I am an external link');
        }

        if ($conf['freshInternalLink'] ?? false) {
            // ... or an internal link (UID in $conf['freshInternalPageUid']):
            // NOTE: You might want to use the PageLinkBuilder to achieve this;
            //       (this is not yet documented)
            $cObj = $this->getContentObjectRenderer($request);
            $frontendUrl = $cObj->typoLink_URL(['parameter' => $conf['freshInternalPageUid'] ?? 1]);
            return (new LinkResult(LinkService::TYPE_PAGE, $frontendUrl))
                ->withLinkText('I am an internal link');
        }

        // If the condition does not match, return the unmodified link.
        return $content;
    }

    protected function getContentObjectRenderer(ServerRequestInterface $request): ContentObjectRenderer
    {
        return $request->getAttribute('currentContentObject');
    }
}
Copied!

This class would take the LinkResultInterface object, retrieve some data from it, alter it, pass it to a new immutable object and return that. Then this is what finally gets emitted after full processing:

<a href="/en/pages/4711/event/18"
   target="_blank"
   title="Custom: My Link Text"
   rel="noreferrer">Event Title #18</a>
Copied!

You can also apply a custom userFunc to vital objects like the lib.parseFunc_RTE.userFunc routine. This would allow you to modify any kind of link generated from the parsing of the Rich-Text-Editor (RTE), usually by adding CSS classes to it, adjusting rel attributes or attaching data-XXX attributes.

  • Previous
Reference to the headline

Copy and freely share the link

This link target has no permanent anchor assigned. You can make a pull request on GitHub to suggest an anchor. The link below can be used, but is prone to change if the page gets moved.

Copy this link into your TYPO3 manual.

  • Home
  • Contact
  • Issues
  • Repository

Last rendered: Jun 13, 2025 06:36

© since 2012 by the TYPO3 contributors
  • Legal Notice
  • Privacy Policy