Links

Informationen zum Thema Links in TYPO3.

Erstellt: 10/2015| Geändert: 10/2015

Target

Um das Linkziel zu setzen entweder im Konstanten Editor leere Werte für die beiden Werte angeben:

Target for internal links    [PAGE_TARGET]
Pageframe object    [content.pageFrameObj]

- oder - in die Constants der Root Seite eintragen:

PAGE_TARGET =
content.pageFrameObj =

- oder - im Template:

# target for links
page.config.intTarget = _top
page.config.extTarget = _blank

Erstellt: 07/2010| Geändert: 10/2015

Links in eigenen Extensions

Einleitung

Das Feld mit enthaltenen Links ist wie folgt definiert:

'bodytext' => [
    'label' => 'LLL:EXT:rsystemplate_bootstrap/Resources/Private/Language/locallang_db.xlf:tab_item.bodytext',
    'l10n_mode' => 'prefixLangTitle',
    'l10n_cat' => 'text',
    'config' => [
        'type' => 'text',
        'cols' => '80',
        'rows' => '15',
        'softref' => 'typolink_tag,email[subst],url',
        'enableRichtext' => true,
        'richtextConfiguration' => 'default'
    ],
],

Im Quelltext des Editors bzw. in der Datenbank ist der Link dann wie folgt gespeichert:

 <a href="t3://page?uid=56">Rootsystem Responsive Template V7</a>

Bei der Ausgabe wird das dann wie folgt in den korrekten Link umgewandelt:

<f:format.html>{record.data.bodytext}</f:format.html>

In TYPO3 V8 war noch ein anderes Format hinterlegt:

<link 56 - internal-link>Rootsystem Responsive Template V7</link>

siehe im Archiv Links in eigenen Extensions mit RTE und RealURL

Erstellt: 07/2010| Geändert: 03/2023

Link Updates von alter Version

Wenn man ein altes TYPO3 auf die aktuelle Version bringt, kann es sein, dass in Tabellen von Extensions noch die alte Link Syntax steht (<link ...>). Um die Daten ins neue Format zu transformieren, braucht man einen Konverter. Ich habe mir einen geschrieben für eine meiner Extensions rsysreferences.

Die Klasse liegt in Classes/Updates:

<?php
declare(strict_types=1);

/*
 * This file is part of the package rsys/rsystemplate_bootstrap.
 *
 * For the full copyright and license information, please read the
 * LICENSE file that was distributed with this source code.
 */

namespace RSYS\RsystemplateBootstrap\Updates;

use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
use TYPO3\CMS\Install\Updates\RepeatableInterface;
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
use TYPO3\CMS\Frontend\Service\TypoLinkCodecService;
use TYPO3\CMS\Core\LinkHandling\LinkService;
use TYPO3\CMS\Core\LinkHandling\Exception\UnknownLinkHandlerException;
use TYPO3\CMS\Core\LinkHandling\Exception\UnknownUrnException;

/**
 * FrameClassUpdate
 */
class ReferencesUpdate implements UpgradeWizardInterface, RepeatableInterface
{

    /**
     * Table list with field list that may have links them
     *
     * @var array
     */
    protected $tableFieldListToConsider = [];

    /**
     * @var array Table names that should be ignored.
     */
    protected $blackListedTables = [
        'sys_log',
        'sys_history',
        'sys_template',
    ];

    /**
     * Regular expressions to match the <link ...>content</link> inside
     * @var array
     */
    protected $regularExpressions = [
        'default' => '#
            (?\'tag\'<link\\s++(?\'typolink\'[^>]+)>)
            (?\'content\'(?:[^<]++|<(?!/link>))*+)
            </link>
            #xumsi',
        'flex' => '#
            (?\'tag\'&lt;link\\s++(?\'typolink\'(?:[^&]++|&(?!gt;))++)&gt;)
            (?\'content\'(?:[^&]++|&(?!lt;/link&gt;))*+)
            &lt;/link&gt;
            #xumsi'
    ];

    /**
     * @return string
     */
    public function getIdentifier(): string
    {
        return self::class;
    }

    /**
     * @return string
     */
    public function getTitle(): string
    {
        return '[Rsystemplate Bootstrap] Migrate the field "<link" for all content elements to "t3page?id="';
    }

    /**
     * @return string
     */
    public function getDescription(): string
    {
        return '';
    }

    /**
     * @return array
     */
    public function getPrerequisites(): array
    {
        return [
            DatabaseUpdatedPrerequisite::class
        ];
    }

    /**
     * @return bool
     */
    public function updateNecessary(): bool
    {
        $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tx_rsysreference_domain_model_reference');
        $tableColumns = $connection->getSchemaManager()->listTableColumns('tx_rsysreference_domain_model_reference');
        // Only proceed if section_frame field still exists
        if (!isset($tableColumns['description'])) {
            return false;
        }
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_rsysreference_domain_model_reference');
        $queryBuilder->getRestrictions()->removeAll();
        $elementCount = $queryBuilder->count('uid')
            ->from('tx_rsysreference_domain_model_reference')
            ->where(
                $queryBuilder->expr()->like('description', "'%<link%'")
            )
            ->execute()
            ->fetchColumn(0);
        return (bool)$elementCount;
    }

     /**
     * Finds all <link> tags and calls the typolink codec service and the link service (twice) to get a string
     * representation of the href part, and then builds an anchor tag.
     *
     * @param string $tableName
     * @param string $fieldName
     * @param array $row
     * @param bool $isFlexformField If true the content is htmlspecialchar()'d and must be treated as such
     * @return mixed the modified content
     */
    protected function transformLinkTagsIfFound(string $tableName, string $fieldName, array $row, bool $isFlexformField)
    {
        $content = $row[$fieldName];
        if (is_string($content)
            && !empty($content)
            && (stripos($content, '<link') !== false || stripos($content, '&lt;link') !== false)
        ) {
            $result = preg_replace_callback(
                $this->regularExpressions[$isFlexformField ? 'flex' : 'default'],
                function ($matches) use ($isFlexformField) {
                    $typoLink = $isFlexformField ? htmlspecialchars_decode($matches['typolink']) : $matches['typolink'];
                    $typoLinkParts = GeneralUtility::makeInstance(TypoLinkCodecService::class)->decode($typoLink);
                    $anchorTagAttributes = [
                        'target' => $typoLinkParts['target'],
                        'class' => $typoLinkParts['class'],
                        'title' => $typoLinkParts['title'],
                    ];

                    $link = $typoLinkParts['url'];
                    if (!empty($typoLinkParts['additionalParams'])) {
                        $link .= (strpos($link, '?') === false ? '?' : '&') . ltrim($typoLinkParts['additionalParams'], '&');
                    }

                    try {
                        $linkService = GeneralUtility::makeInstance(LinkService::class);
                        // Ensure the old syntax is converted to the new t3:// syntax, if necessary
                        $linkParts = $linkService->resolve($link);
                        $anchorTagAttributes['href'] = $linkService->asString($linkParts);
                        $newLink = '<a ' . GeneralUtility::implodeAttributes($anchorTagAttributes, true) . '>' .
                            ($isFlexformField ? htmlspecialchars_decode($matches['content']) : $matches['content']) .
                            '</a>';
                        if ($isFlexformField) {
                            $newLink = htmlspecialchars($newLink);
                        }
                    } catch (UnknownLinkHandlerException $e) {
                        $newLink = $matches[0];
                    } catch (UnknownUrnException $e) {
                        $newLink = $matches[0];
                    }
                    return $newLink;
                },
                $content
            );
            if ($result !== null) {
                $content = $result;
            } else {
                $this->logger->error('Converting links failed due to PCRE error', [
                    'table' => $tableName,
                    'field' => $fieldName,
                    'uid' => $row['uid'] ?? null,
                    'errorCode' => preg_last_error()
                ]);
            }
        }
        return $content;
    }

    /**
     * @return bool
     */
    public function executeUpdate(): bool
    {
        $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tx_rsysreference_domain_model_reference');
        $queryBuilder = $connection->createQueryBuilder();
        $queryBuilder->getRestrictions()->removeAll();
        $statement = $queryBuilder->select('uid', 'description')
            ->from('tx_rsysreference_domain_model_reference')
            ->where(
                $queryBuilder->expr()->like('description', "'%<link%'")
            )
            ->execute();
        while ($record = $statement->fetch()) {
            $row['description'] = $this->transformLinkTagsIfFound(
                'tx_rsysreference_domain_model_reference',
                'description',
                $record,
                false
            );
            $queryBuilder->update('tx_rsysreference_domain_model_reference')
                ->where(
                    $queryBuilder->expr()->eq(
                        'uid',
                        $queryBuilder->createNamedParameter($record['uid'], \PDO::PARAM_INT)
                    )
                )
                ->set('description', $row['description']);
            $queryBuilder->execute();
        }
        return true;
    }
}

Dann noch Registrieren der Klasse in der ext_localcont.php und den Update Wizard starten.

$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][\RSYS\RsystemplateBootstrap\Updates\ReferencesUpdate::class] = \RSYS\RsystemplateBootstrap\Updates\ReferencesUpdate::class;

 

Erstellt: 03/2023| Geändert: 03/2023

Link title und alt Text ändern

Um für die <title> und <alt> Tags von Links den Text zu ändern folgendes in die Seiten "Options" der Root Seite (und die Texte eben eintragen, die man wünscht):

RTE {
   classesAnchor {
     externalLink {
       altText =
       titleText =
     }
     externalLinkInNewWindow {
       altText =
       titleText =
     }
     internalLink {
       altText =
       titleText =
     }
     internalLinkInNewWindow {
       altText =
       titleText =
     }
     download {
       altText =
       titleText =
     }
     mail {
       altText =
       titleText =
     }
   }
}

Tut man das nicht, hat man den "Opens internal link in current window" Text und andere englische Texte. Dann lieber leer lassen und dem Redakteur die Wahl lassen, ob er etwas einträgt.

Erstellt: 07/2010| Geändert: 10/2015