TYPO3: Mehrsprachige 404 Fehlerseite bei realurl

Dies ist out-of-the-box nicht möglich, da TYPO3 zu einer ungültigen URL nicht die Sprach-ID (den Sprachparameter L) geliefert bekommt und die URL auch nicht über realurl aufgelöst werden kann, da keine entsprechende Seite im System existiert.
Ein Beispiel: Es wird die URL domain.com/de/veraltete-url/ aufgerufen. Da realurl zu dieser URL keine Seite findet, steigt realurl aus und obwohl die URL den Sprachkey „de“ enthält, wird die 404 Fehlerseite anschließend in der Default-Sprache angezeigt.

Mit Ext. realurl_force404lang

Edit Nov. 2015: Leider gab es für diese Erweiterung schon lange kein Update mehr, daher funktioniert sie in neueren TYPO3- und realurl-Versionen nicht mehr.

Die Erweiterung realurl_force404lang korrigiert diesen Umstand: Sie erkennt die Sprach-ID anhand der realurl-Konfiguration aus der sprechenden URL und schreibt diesen in die GET-Superglobale. Damit wird aber noch nicht automatisch die definierte Fehlerseite (z.B. $TYPO3_CONF_VARS[‚FE‘][‚pageNotFound_handling‘] = ‚/index.php?id=71‘) in der richtigen Sprache aufgerufen, daher muss man für das 404-Handling eine User-Funktion schreiben:

LocalConfiguration.php

$TYPO3_CONF_VARS['FE']['pageNotFound_handling'] = 'USER_FUNCTION:fileadmin/php/pageNotFoundHandling.php:user_pageNotFound->pageNotFound';
$TYPO3_CONF_VARS['FE']['pageNotFound_handling_redirectPageID'] = 71; // Attention: this parameter is not provided by TYPO3, but needed for page-not-found-userfunction

pageNotFoundHandling.php

class user_pageNotFound {
  /**
   * Redirect to 404 error page with language-ID provided by ext. "realurl_force404lang"
   *
   * @param array $params: "currentUrl", "reasonText" and "pageAccessFailureReasons"
   * @param object $tsfeObj: object type "tslib_fe"
   */
  function pageNotFound(&$params, &$tsfeObj) {
    // handle default language
    $tsfeObj->pageErrorHandler('/index.php?id=' . $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_redirectPageID'] . (array_key_exists('L', $_GET) ? '&L=' . $_GET['L'] : ''));
  }
}

Ohne Erweiterung

Ohne die Erweiterung realurl_force404lang geht es auch, so könnte die Funktion aussehen:

class user_pageNotFound {
  /**
   * Detect language and redirect to 404 error page
   *
   * @param array $params: "currentUrl", "reasonText" and "pageAccessFailureReasons"
   * @param object $tsfeObj: object type "tslib_fe"
   */
  function pageNotFound($params, $tsfeObj) {
    // get first realurl configuration array (important for multidomain)
    $realurlConf = array_shift($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']);
    // look for language configuration
    foreach($realurlConf['preVars'] as $conf) {
      if($conf['GETvar'] == 'L') {
        foreach($conf['valueMap'] as $k => $v) {
          // we expect a part like "/de/" in requested url
          if(strpos($params['currentUrl'], '/' . $k . '/') !== false) {
            $tsfeObj->pageErrorHandler('/index.php?id=' . $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_redirectPageID'] . '&L=' . $v);
          }
        }
      }
    }
    // handle default language
    $tsfeObj->pageErrorHandler('/index.php?id=' . $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_redirectPageID']);
  }
}

Edit Mai 2016: An der obigen Lösung gefällt mir nicht, dass TYPO3 auf die 404 Fehlerseite redirected, anstatt unter der aufgerufenen URL die Inhalte der 404 Fehlerseite mit Statuscode „404 Not Found“ anzuzeigen. Daher habe ich den PHP Code überarbeitet:

use TYPO3\CMS\Core\Utility\GeneralUtility;
 
class user_pageNotFound {
 
    /**
     * Redirect to 404 error page with language-ID
     *
     * @param array $params: "currentUrl", "reasonText" and "pageAccessFailureReasons"
     * @param object $tsfeObj: object type "tslib_fe"
     */
    function pageNotFound(&$params, &$tsfeObj) {
        // Get first realurl configuration array (important for multidomain)
        $realurlConf = array_shift($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']);
        // Look for language configuration
        $language = false;
        foreach($realurlConf['preVars'] as $conf) {
            if($conf['GETvar'] == 'L') {
                if(is_array($conf['valueMap'])) {
                    foreach($conf['valueMap'] as $k => $v) {
                        // We expect a part like "/de/" in requested url
                        if(strpos($params['currentUrl'], '/' . $k . '/') !== false) {
                            $language = $v;
                            break;
                        }
                    }
                }
            }
        }
        // Get contents of 404 page
        $contentUrl = GeneralUtility::locationHeaderUrl(sprintf(
            '/index.php?id=%u%s',
            $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_redirectPageID'],
            $language ? sprintf('&L=%u', $language) : ''
        ));
        $content = GeneralUtility::getUrl($contentUrl);
        // Output 404 page
        if($content) {
            echo $content;
        // No 404 page found: Display TYPO3 error page
        } else {
            $params['reasonText'] .= sprintf(
                ' Additionally, %s was not found while trying to retrieve the error document.',
                $contentUrl
            );
            if(strpos($contentUrl, 'https://') === 0) {
                $params['reasonText'] .= ' It seems, your SSL certificate seems not to be accepted.';
            }
            $tsfeObj->pageErrorHandler('', '', $params['reasonText']);
        }
    }
}

Autor:
Geändert: Dienstag, 31. Mai 2016 13:05 Uhr
Erstellt: Montag, 23. Dezember 2013 13:21 Uhr
Tags: , , , , ,
Themengebiet: Web Entwicklung, TYPO3, TYPO3 Extensions

Trackback: Trackback-URL LoadingZu Favoriten hinzufügen

5 Kommentare

  1. 1

    Danke, nach langer Suche endlich etwas, das tut.
    Habe die Version ohne Erweiterung verwendet.

  2. 2

    Danke! Endlich ein Tool für dieses Problem (ohne force404-Ext).
    Leider kriege ich es nicht hin, dass er mir im „handle default language“-Fall, trotzdem die Fehlerbehandlung durchführt … er springt immer auf die Startseite der Default-Sprache (so wie es auf der eingesetzten Seite vor Einführung der 404-Version war). Hat jemand ne Idee dazu?
    Viele Grüße
    Joachim

  3. 3

    Ich vergaß mitzuteilen, dass ich brutal bin und im GETvar=L – fehlt-Fall &L=1 übergebe:

    // handle default language
    $tsfeObj->pageErrorHandler(‚/index.php?id=‘ . $GLOBALS[‚TYPO3_CONF_VARS‘][‚FE‘][‚pageNotFound_handling_redirectPageID‘] . ‚&L=1‘);

  4. 4

    Es lag wie immer am Problem vor dem Computer … realurl muss auch richtig konfiguriert sein:

    array(
    ‚GETvar’=>’L‘,
    ‚valueDefault‘ => ‚de‘,
    ‚valueMap’=>array(
    ‚en’=>’0‘,
    ‚de’=>’1′,
    ’noMatch’=>’bypass‘,
    ),
    ),

    Ich habe das noMatch-Verhalten vergessen …

  5. 5

    @Sven Burkert: eine super Lösung, die Du ausgetüftelt hast! Funktioniert wunderbar. Danke!

Kommentar abgeben