Zum Inhalt springen

RealURL, Mehrsprachigkeit und 404-Behandlung

Erstellt am 13. August 2007 · 9 Antworten · letzte Antwort am 6. August 2009

Tags: RealURL, Weiterleitungen & 404, Frage

Unbekannter Benutzer ·

Moin!

Ich würd' hier gerne mal was zur Diskussion stellen:

Wenn man mit RealURL eine mehrsprachige Site aufbauen will, steht man irgendwann vor ein paar Problemen.

Je nach Konfiguration ist der Inhalt der Standardsprache sowohl über die URL mit Sprachkürzel als auch ohne erhältlich, also sowohl über

http://www.bla.com/blubb.html

als auch über

http://www.bla.com/en/blubb.html

Das macht Suchmaschinen natürlich nicht froh, weil es Content doppelt gibt.

Die Variante, für die Standardsprache nur die Adresse ohne Sprachkürzel anzubieten, ist ziemlich inkonsistent.

Dem kann man Abhilfe schaffen, indem man einen Standardwert definiert und keinen Bypass zuläßt:

'preVars' => array(
	array(
		'GETvar' => 'L',
		'valueMap' => array(
			'en' => '0',
			'de' => '1',
			'fr' => '2',
			'nl' => '3',
		),
		'valueDefault' => 'en',
	),
),

Im Hinblick auf die Behandlung von Aufrufen nicht vorhandener Seiten gibt's nun aber ein Problem:

Gibt man eine Adresse ohne Sprachkürzel ein, wird sie auf eine mit dem Standardkürzel "en" umgeschrieben. Wenn es die Seite gibt, ist das in Ordnung.

Gibt es sie jedoch nicht, wird unabhängig von den Einstellungen für pageNotFoundHandling im Install-Tool und der Einstellung postVarSet_failureMode keine Fehlerseite aufgerufen und - noch schlimmer - es wird kein 404 Not Found im Header zurückgegeben. Im Hinblick auf Suchmaschinen ist das tödlich, weil doppelter Content auftaucht und alte Seiten nicht aus deren Datenbank gelöscht werden.

Nach viel Herumprobieren ist mir folgende Umgehungslösung eingefallen:

Es wird einfach alles, was ohne Sprachkürzel eingegeben wird, direkt auf das Sprachkürzel der Standardsprache umgeleitet. Damit greift dieser Mechanismus auch für nicht vorhandene Adressen und es wird wieder eine Fehlerseite angezeigt.

Das geht so:

'redirects_regex' => array(
	'(^..[^/].*)' => 'en/\1'
),

Im Klartext wird allen Adressen, die keinen Slash enthalten, der String "en/" vorangestellt.

Dann läßt sich auch noch die Fehlerseite für die jeweilige Sprache anpassen. Klar, bei Adressen ohne anfängliches Sprachkürzel kennt man die Sprache nicht, aber wenn jemand z.B. im deutschen Bereich eine nicht vorhandene Adresse aufruft, sollte er schon eine deutsche Fehlermeldung bekommen. Das kann man folgendermaßen tun:

Im Install-Tool unter pageNotFoundHandling eintragen:

USER_FUNCTION:fileadmin/scripts/pageNotFoundHandling.php:user_pageNotFound->pageNotFound

pageNotFoundHandling.php sieht so aus:

<?php 
class user_pagenotfound { 
    function pagenotfound($param, $conf) { 
        $host = $_SERVER['SERVER_NAME']; 
        $lang = substr($param['currentUrl'], 1, 2); 
        $errorpage = "404.html"; 
        header("HTTP/1.0 404 Not Found"); 
        header("Location: http://".$host."/".$lang."/".$errorpage); 
    } 
} 
?>

Auf der obersten Ebene des TYPO3-Seitenbaums legt man dann eine Seite mit dem Titel 404 an und kann sie auch übersetzen.

Nun würde mich mal interessieren, ob es dafür eine bessere Lösung gibt. Irgendwelche Tips?

Mopps ·

Servus,

Deine redirects_regex ist denke ich nicht ganz richtig. Damit der ganze URL-Schwanz nicht verloren geht muss noch \1 hinten dran.
-> hab grad gemerkt, dass das vom Forum verschluckt wird. Also es muss lauten:
'(^..[^/].*)' => 'en/\1'

Bei mir gab es noch Probleme mit Verweisen, die auf die Startseite linken. Die Links sehen so aus:

http://www.meine-Domain.de/de.html

Das funktioniert nicht richtig. Bei Links von anderen Sprachen landet man trotzdem auf der deutschen Startseite oder bekommt ein 404 (hatte beim rumfriemeln grad beides).

Deswegen habe ich noch folgendes der RealUrl-Konfiguration hinzugefügt:

'redirects' => array(
     'de.html'=>'de/',
     'en.html'=>'en/',
     'it.html'=>'it/',
),

So: Damit funktioniert die Sprachumschaltung oberflächig gesehen zufriedenstellend und nach dem Muster wie du es beschrieben hast:
1) Rufe ich http://www.meine-Domain.de/folder/datei.html auf, wird daraus http://www.meine-Domain.de/de/folder/datei.html gebaut
2) Aus http://www.meine-Domain.de/en.html wird richtig http://www.meine-Domain.de/en/
3) Rufe ich http://www.meine-Domain.de/en/seite-nich-da.html auf, dann bekomme ich http://www.meine-Domain.de/en/404.html (also 404 sprachabhängig). Schön.

ABER: Was ich überhaupt nicht verstehe und was mal gar nicht geht ist der korrekte bzw. falsche HTTP-StatusHeader (404-Header).

Ich benutze folgende Einstellungen:
1) Das Script pageNotFoundHandling.php von oben
2) Install-Tool [pageNotFound_handling]: wie beschrieben pageNotFoundHandling.php eingebunden
3) Install-Tool [pageNotFound_handling_statheader]: HTTP/1.0 404 Not Found
4) RealUrl Konfig: 'postVarSet_failureMode' => '',

Rufe ich eine existierende Seite auf kommt:

URL=http://www.meine-Domain.de/seite-gibts.html
Result code: 302 (Found / Moved Temporarily)
New location: http://www.meine-Domain.de/de/404.html

URL=http://www.meine-Domain.de/de/404.html
Result code: 200 (OK / OK)

Nochmal: Es wird immer ein "302 (Found / Moved Temporarily)" produziert. Bei Nicht existierenden Seiten ebenfalls. Ich bekomme nie einen 404

Wieso denn das bitte? #angry#

Mopps ·

Ich habe jetzt die pagenotfoundhandling.php geändert in:

<?php
class user_pagenotfound {
	function pagenotfound($param, $conf) {
		$host = 'meine-Domain.de';
		$lang = substr($param['currentUrl'], 1, 2);
		$errorpage = "404.html";

		$filename = "http://". $host ."/". $lang ."/". $errorpage;
		$filecontent = file_get_contents($filename);
                echo $filecontent;
    }
}
?>

funktioniert soweit auch. Dadurch sind die permanenten "302 (Found / Moved Temporarily)" weg. Jetzt ist es wie folgt:

Rufe ich http://www.meine-Domain.de/de/seite.html auf bekomme ich einen 404, obwohl die Seite existiert!

Rufe ich http://www.meine-Domain.de/seite.html bekomme ich einen 302, da die Seite ja unter http://www.meine-Domain.de/de/seite.html liegt (wird also richtig angezeigt).

Ich blick gar nichts mehr! Hier mal meine Einstellungen von RealUrl:

'init' => array (
            'enableCHashCache' => '1',
            'appendMissingSlash' => 'ifNotFile',
            'enableUrlDecodeCache' => '1',
            'enableUrlEncodeCache' => '1',
            'postVarSet_failureMode' => '',
        ),
        
       	'redirects' => array(
       		'de.html'=>'de/',
       		'en.html'=>'en/',
       		'it.html'=>'it/',
	),
       		
	'redirects_regex' => array(
        	'(^..[^/].*)' => 'de/\1'
	),
        
        'preVars' => array(
		array(
			'GETvar' => 'L',
			'valueMap' => array(
				'de' => '0',
				'en' => '1',
				'it' => '2',
			),
		'valueDefault' => 'de',
		),
	),
	
        'pagePath' => array (
            'type' => 'user',
            'userFunc' => 'EXT:realurl/class.tx_realurl_advanced.php:&tx_realurl_advanced->main',
            'spaceCharacter' => '-',
            'languageGetVar' => 'L',
            'expireDays' => '7',
            'rootpage_id' => '1',
            'segTitleFieldList'=>'alias,nav_title,title,subtitle',
        ),

Hat jemand ne Ahnung, wo der Hund sich in den Schwanz beißt?

Mopps ·

Ich hab die ganze Zeit in einem Login-geschützten Bereich gearbeitet. Seiten, die sich darin befinden, können natürlich nicht geprüft werden. Deswegen immer der 404.

Leider funktioniert die Umleitung auf die Login-Seite nicht mehr, wenn man versucht eine Seite aufzurufen, die sich innerhalb des geschützten Bereichs befindet (wenn man nicht angemeldet ist). Da kommt jetzt die 404.html

Unbekannter Benutzer ·

Interessant! Die 302er habe ich hier nur bei nicht vorhandenen Seiten bekommen, aber dank Deiner Änderung funktioniert nun auch das.

Zugriffe auf geschützte Bereiche kannst Du so abfangen:

<?php
class user_pageNotFound {
    function pageNotFound($param, $conf) {
        $host = $_SERVER['SERVER_NAME'];
        $lang = substr($param['currentUrl'], 1, 2);
        // hier die geschützten Verzeichnisse abfragen
        if ((strripos($param['currentUrl'],'geschuetztes_verzeichnis_1')) || (strripos($param['currentUrl'],'geschuetztes_verzeichnis_2')) || (strripos($param['currentUrl'],'geschuetztes_verzeichnis_3'))) {
          // hier den Pfad zur Login-Seite eintragen, z.B. anmeldung/login.html
          $errorPage = "anmeldung/login.html?redirect_url=".$param['currentUrl'];
          $errorHeader = "HTTP/1.0 401 Unauthorized";
        } else {
          $errorPage = "404.html";
          $errorHeader = "HTTP/1.0 404 Not Found";
        }
        header($errorHeader);
        $filecontent = file_get_contents("http://".$host."/".$lang."/".$errorPage);
        echo $filecontent;
    }
}
?>

Das ist zwar nicht wirklich elegant, aber eine bessere Lösung habe ich nicht gefunden.

Mopps ·

vielen Dank für deine Verbesserung. Das ist auf jeden Fall besser. Die Header werden richtig ausgegeben.

Wenn ich nicht angemeldet bin und eine geschützte Seite aufrufen will, dann werde ich zur Login-Seite geleitet. Bei mir funktioniert allerdings der redirect nach der Anmeldung nicht.

Im Formular steht richtig

<input type="hidden" name="redirect_url" value="/de/typo3/extensions/ext-testbereich.html" />

Nach der Anmeldung geschieht aber keine Weiterleitung. (Hab auch schon absoluten Pfad probiert)

Eine Idee?

Unbekannter Benutzer ·

Oh jeh, das ist schon wieder so lange her... Wenn ich mich recht erinnere, muß die Weiterleitung erst aktiviert werden:

config {
  typolinkLinkAccessRestrictedPages = 10
  typolinkLinkAccessRestrictedPages_addParams = &redirect_url=###RETURN_URL###
}
Mopps ·

Danke. Leider ist das nicht die Lösung.

config.typolinkLinkAccessRestrictedPages

Erklärung: Links auf geschlossene Bereiche werden angezeit, redirecten jedoch zB. zu einer zentralen Login-Page.

Irgendwie muss das anders gehen. Im redirect_url Feld der newloginbox steht ja der richtige Wert. Er bewirkt nur nichts.

Unbekannter Benutzer ·

Es hat sich leider herausgestellt, daß das externe PHP-Skript ziemlich hohe Server-Last verursacht. Von daher sollte ein anderer weg gesucht werden.

An dieser Stelle vielen Dank an Herrn Clemens vom Mittwald-Support.