Ich möchte hier den grundlegenden Aufbau einer mehrsprachigen Internetseite zeigen. Das Grundgerüst wird mit HTML, CSS und PHP realisiert.

Features

  • Browser-Spracherkennung
  • Sprachüberprüfung
  • Sprachspeicherung mit Cookies
  • Cookie-Löschfunktion
  • Anzeige der Cookie-Lebensdauer
  • Abfangen unbekannter Sprachen, Setzen einer Ausweichsprache
  • Debuginformationen in einer Box


Funktionsweise

  • Beim ersten Besuch der Zielseite startet die automatische Spracherkennung. Das System prüft den Browser auf mitgegebene Sprachinformationen im HTTP Header und nimmt die bevorzugte Sprache des Browsers als Seitensprache (falls Informationen mitgegeben und Sprache verfügbar).
  • Der Benutzer kann manuell durch Anklicken von Länderfahnen/Links eine andere verfügbare Sprache wählen.
  • Wird eine verfügbare Sprache vom Browser erkannt, vom Benutzer angeklickt oder anderweitig gewählt (z.B. manuelle URL Eingabe) so wird ein Cookie erstellt (falls möglich), in dem die Sprache gespeichert wird. Der Besucher wird bei seinem nächsten Webseitenbesuch also gleich die gewünschte Sprache sehen.
  • Die Cookielaufzeit beträgt 1 Jahr. Bei jeder Aktion auf der Zielseite wird die Lebensdauer wieder auf 1 Jahr gesetzt. Der Tod des Cookies wird in der Debugbox ausgegeben. Durch einen Klick des Benutzers auf einen Button/Link lässt sich das Cookie löschen.
  • Wird die Sprache (durch Browsererkennung, Wahl oder Eingabe) nicht erkannt oder ist für die erkannte Sprache kein übersetzter Inhalt vorhanden so wird eine Ausweichsprache (Standardsprache) gesetzt.
Code

Code anzeigenDen Code könnt ihr bequem mit den Links/Rechts Pfeiltasten horizontal bewegen.

<?php
/*
   ######################
    PHP Multilanguage
   ######################
   Desc: This page detects your browserlanguage, cookie or chosen language with PHP and displays the right content.
   Author: Hannes Schurig
   Date: 15.06.2011
   Edited: 16.06.2011 (v1.4)
   Changelog:
   1.1: komplett umgeschrieben... Funktion langanalyse geschrieben, gekürzt, optimiert
   1.2: + Debugmeldung (echo Ausgabe) bei unbekannter Sprache, mehr Kommentare
   1.3: + Cookie löschen Feature
   1.4: + Cookie Lebensdaueranzeige, Lebensdaueroptimierung (exakt 1 Jahr), besseres Deutsch in der Debugbox
   1.5: * Code minified
   1.6: + header(Location) URL correction, no more .php?lang=?? after choosing lang (only in minified version, link below)
   ###################
    minified version
   ###################
   !URL minified productive version: http://hannes-schurig.de/21/06/2011/php-mehrsprachigkeitssystem-minified/
 */

$lang = detectlang();
// Spracherkennung
// GET abfragen; wird geliefert wenn ein Sprachlink geklickt wird
if(isset($_GET["lang"])) { 
	$lang = langanalyse($_GET["lang"],"get");
}
// POST abfragen; wird in meinem Beispiel nicht benutzt
elseif(isset($_POST["lang"])) {
	$lang = langanalyse($_POST["lang"],"post");
}
// Cookie abfragen; ist ab dem 2. Besuch gesetzt (wenn Cookies aktiviert sind)
elseif(isset($_COOKIE["lang"])) {
	$lang = langanalyse($_COOKIE["lang"],"cookie");
}
// keine Sprache gefunden; Browsersprache erkennen, die Sprache mit der höchsten Priorität auswählen
else {
	$cutstring = explode("-", $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
	$detectlang = $cutstring[0];
	$lang = langanalyse($detectlang,"browser");
}
// Überprüfe ob für die Sprache verfügbar ist
function langanalyse($new_lang, $methode) {
	switch($new_lang) {
		// die erlaubten Sprachen hier hintereinander auflisten
		case ("de"): 
		case ("en"): 
			$lang = $new_lang; 
			setcookie("lang", $lang, time()+31536000);
			break;
		// Cookie löschen Funktion als Pseudo-Sprache
		case ("delete"):
			setcookie("lang", $lang, time()-3600); 
			break;
		// für die erkannte Sprache sind keine Übersetzungen vorhanden oder die Sprache ist gänzlich unbekannt
		default:
			$unknown_lang = 1;
			// die Standardsprache:
			$lang = "en"; 
			setcookie("lang", $lang, time()+31536000);
	}
	// Methode erkennen, Debugbox öffnen und Informationen ausgeben
	switch($methode) {
		case ("get"): echo('<div id="langdebug">Methode = get<br/>'); break;
		case ("post"): echo('<div id="langdebug">Methode = post<br/>'); break;
		case ("cookie"): echo('<div id="langdebug">Methode = cookie<br/>'); break;
		case ("browser"): echo('<div id="langdebug">Methode = browserdetect<br/>
	(kein GET, POST und COOKIE gefunden)<br/>
	Browserlang: '.$_SERVER["HTTP_ACCEPT_LANGUAGE"].'<br/>'); break;
		default: echo('<div id="langdebug">Methode = Unbekannt oder Fehler<br/>'); break;
	}
	// Hinweis im Debugbox wenn Sprache unbekannt
	if($unknown_lang == 1) {
		echo('!! Sprache "'.$new_lang.'" unbekannt. Auf "'.$lang.'" gesetzt<br/>');
		$unknown_lang = 0;
	}
	return $lang;
}
// ein paar zusätzliche Debuginformationen und die manuelle Sprachwahl
echo('aktuelle Sprache = '.$lang.'<br/>
Cookie Sprache = '.$_COOKIE["lang"].'<br/>
Cookie Tod = '. date("d.m.Y G:i",time()+31536000) .'<br/>
Sprache setzen:<br/>
<a href="'.$_SERVER['SCRIPT_NAME'].'?lang=de">Deutsch</a>   
<a href="'.$_SERVER['SCRIPT_NAME'].'?lang=en">Englisch</a><br/>  
<a href="'.$_SERVER['SCRIPT_NAME'].'?lang=delete">Cookie löschen</a>  
</div>');

// PHP Array mit den eigentlichen Inhalten der erlaubten Sprachen
$content["de"]["text"]="Hallo, dies ist nur ein Test";
$content["en"]["text"]="Hello, this is just a test";
$content["de"]["menu"]="
<ul>
 <li>Autos</li>
 <li>Frauen</li>
 <li>Alkohol</li>
</ul>";
$content["en"]["menu"]="
<ul>
 <li>Sex</li>
 <li>Drugs</li>
 <li>Rock'n'Roll</li>
</ul>";
$content["de"]["info"]="Zu Ihrer Information:<br/>
News 1: bla<br/>
News 2: bla<br/>
Test";
$content["en"]["info"]="For Your Information:<br/>
News 1: Foo<br/>
News 2: Bar<br/>
foobar";

?>
<html>
 <head>
  <title>Mehrsprachigkeit mit PHP, Array und COOKIES</title>
  <style type="text/css">
  div {
    margin: 20px;
	padding: 15px;
	float: left; }
  #langdebug {
    border: 1px solid black;
    font-size: 0.8em; }
  </style>
 </head>
<body>
 
 <div id="menu">
  <? echo($content[$lang]["menu"]); ?>
 </div>
 <div id="text">
  <? echo($content[$lang]["text"]); ?>
 </div>
 <div id="info">
  <? echo($content[$lang]["info"]); ?>
 </div>

</body>
</html>
Demo

Demo Link

Download

latest [.zip]

alte Versionen

Changelog


v1.1: komplett umgeschrieben… Funktion langanalyse geschrieben, gekürzt, optimiert
v1.2: + Debugmeldung (echo Ausgabe) bei unbekannter Sprache, mehr Kommentare
v1.3: + Cookie löschen Feature
v1.4: + Cookie Lebensdaueranzeige, Lebensdaueroptimierung (exakt 1 Jahr), besseres Deutsch in der Debugbox
*v1.5: minified/productive version available: Link
*v1.6: + header(Location) URL Korrektur nach Sprachwahl, keine lästigen .php?lang=?? Parameter mehr (nur in der Produktivversion verfügbar)

So heißt eine Komponente der neuen Google Anwendung „Google Correlate„.
Google Correlate kann die Aktivität von Suchanfragen grafisch darstellen. So kann man die Häufigkeit und Popularität einer Suchanfrage seit 2004 mit anderen Suchanfragen vergleichen oder kann Suchanfragen mit ähnlicher Aktivität von Google finden lassen.
Intelligente Menschen können aus diesen Zusammenhängen sicher eine Menge machen, für mich ist es erstmal nur grundlegend interessant 😀

Aber noch besser: „Search by Drawing“
Ihr braucht Suchbegriffe, Events oder andere Dinge mit einer ganz bestimmten zeitlichen Aktivität? Ein Suchbegriff, der Anfang 2005 aktiv war, dann erst Mitte 2009 wieder aufkam und nach 2010 nie wieder gesehen wurde? Google findet es 🙂
Malt selber eine Aktivitätskurve und Google ermittelt Suchbegriffe, die diese Kurve hatten, so gut es geht.

via

Ich bin ein Freund von bunten Statusmeldungen. „Speichern erfolgreich“, „Anmeldung fehlgeschlagen“, ein kleines Icon, schön farbig, user-friendly und ein bisschen Animations-Spielerei.

Das Coole ist: mit jQuery kann man eine solche Statusmeldung mit Style und Fading recht problemlos mit nur 1 Zeile realisieren!

Code
$.ajax({ type: 'POST', url: 'mailer.php', data:{'submit':'1','values':values}, success: function(data)
   {
	if($('#contact-wrapper .status').is(':hidden')) $('#contact-wrapper .status').html(data).addClass(data).fadeToggle().delay(3000).fadeToggle(function () { $(this).removeClass(data) }); /* 1 Zeile, ein Traum */
   } /* $.ajax success */
}); /* $.ajax */

(Update 1.1)

Die $.ajax Funktion liefert einen Rückgabewert der mailer.php. Dieser Rückgabewert ist entweder „success“ oder „error“. Das ließe sich natürlich ausbauen.
Die Statusmeldung ist mit CSS gestyled, wird eingeblendet, enthält einen bestimmten Text (in diesem Beispiel nur „success“ oder „error“), bleibt ein paar Sekunden stehen und wird dann ausgeblendet.

.status {
	display: none;
	border: 1px solid; 
}
.status.success {
	background: #DFF2BF url("img/10er-iconset.png") no-repeat 0px -38px;
	color: #4F8A10;
}
.status.error {
	background: #FFBABA url("img/10er-iconset.png") no-repeat 0px -58px;
	color: #D8000C;
}

Sehen wir uns die Codezeile im Detail an:

if($('#contact-wrapper .status').is(':hidden')) {
  $('#contact-wrapper .status').html(data)
    .addClass(data)
	  .fadeToggle()
	    .delay(3000)
		  .fadeToggle(function () { 
		    $(this).removeClass(data) 
		  });
}

(Update 1.1)

Zeile 1 überprüft, ob die Statusmeldung gerade angezeigt wird. Nur, wenn die Statusmeldung gerade nicht angezeigt wird, soll ein Klick (und damit das Einblenden der Statusmeldung) ausgelöst werden.
Zeile 2 setzt den Inhalt, also den Text, der Statusnachricht auf „error“ (

data

enthält den Rückgabewert der mailer.php). Hier sollte man vorher vielleicht eine aussagekräftigere Nachricht festlegen.
Zeile 3 fügt dem Zielelement die Klasse „error“ hinzu. Im CSS Dokument müssen die Klassen also so benannt sein wie die möglichen Rückgabewerte der mailer.php.
Zeile 4 blendet das Element ein, Zeile 5 wartet 3 Sekunden ab (lässt es also 3 Sekunden stehen),
Zeile 6 blendet das Element wieder aus, als callback Funktion (diese Funktion wird am Ende der Ausführung der fadeToggle Funktion ausgeführt) wird in
Zeile 7 die Klasse „error“ wieder entfernt.
(Update 1.1)

.fadeToggle(function(){}); mit callback muss sein, da sonst noch während der Ausblendeanimation (asynchron) die Styleklasse entfernt wird. Das führt zu Anzeigefehlern.

Dank jQuery ist das auch für den Internet Explorer kein Problem, kompatibel zu allen Versionen*.

Demo

Link

Download

jQuery-status-msg [.zip]
(Update 1.1)

Changelog

v1.1: Anzeigefehler bei mehrfachem Klick behoben (siehe Kommentar 1+2)

Mein letzter Post erklärte die spezielle Behandlung von Internet Explorer 6 (und jünger) in meinem Blog. Es wird statt dem eigentlich Inhalt ein bisschen Text und Links zu vernünftigen Browsern angezeigt.
Ich wollte dieses „Feature“ jetzt mit nur 1 Zeile realisieren. Den CSS und HTML Code in der tatsächlich index stehen zu haben ist unschön.
Daher präsentiere ich:

IE-Buster

a small jQuery Anti-IE Plugin

Frei nach dem Motto:
„If there’s something strange
in the internet.
Who ya gonna call?“

IE-Buster!!!
😉



Das Plugin ist nur 2,3KB groß und damit ein Leichtgewicht im Anti IE Geschäft. Es epfiehlt sich also wenn man keinen besonders hübschen und funktionsreichen Abgang beim IE sucht, sondern etwas kleines, schnelles und unkompliziertes.
Einzige Voraussetzung: jQuery muss eingebunden sein!

Code
$(document).ready(function() {
  $("head").append('<!--[if lte IE 6]><style type="text/css">#ie6-warning { display: block; width: 100%; height: 100%; background-color: white; position: absolute; z-index: 1111; top: 0px; left: 0px; color: black; padding: 10%; font-size: 17px; } #ie6-warning td { border: 1px solid #eee; padding: 4px; color: white; } #ie6-warning a { color: blue; }</style><![endif]--><!--[if gt IE 6]><style type="text/css">#ie6-warning { display: none!important; }</style><![endif]-->');
  $("body").append('<div id="ie6-warning">Ihr Browser ist zu alt um diese Internetseite korrekt darzustellen.<br/>Bitte aktualisieren Sie Ihren Browser oder installieren Sie einen anderen modernen Browser.<br/><br/>Your browser is too old to display this website correctly.<br/>Please update your browser or install another modern browser.<br/><br/><br/><table cellpadding="10"><tr><td></td><td>Google Chrome</td><td>Mozilla Firefox</td><td>Opera</td><td>Apple Safari</td><td>Microsoft Internet Explorer</td></tr><tr><td>Download (DE):</td><td><a href="http://www.google.de/chrome/">Link</a></td><td><a href="http://www.mozilla-europe.org/de/firefox/">Link</a></td><td><a href="http://de.opera.com/">Link</a></td><td><a href="http://www.apple.com/de/safari/">Link</a></td><td><a href="http://www.microsoft.com/germany/windows/internet-explorer/">Link</a></td></tr><tr><td>Download (EN):</td><td><a href="http://www.google.com/chrome/">Link</a></td><td><a href="http://www.mozilla-europe.org/en/firefox/">Link</a></td><td><a href="http://www.opera.com/">Link</a></td><td><a href="http://www.apple.com/safari/">Link</a></td><td><a href="http://www.microsoft.com/windows/internet-explorer/">Link</a></td></tr><tr><td>Suchen/Search for:</td><td><a href="http://www.google.com/search?q=chrome">Link</a></td><td><a href="http://www.google.com/search?q=firefox">Link</a></td><td><a href="http://www.google.com/search?q=opera">Link</a></td><td><a href="http://www.google.com/search?q=safari">Link</a></td><td><a href="http://www.google.com/search?q=internet+explorer">Link</a></td></tr></table><br/><br/><span>by <a href="http://it-stack.de">Hannes Schurig</a></span></div>');
});
Download

Download des Plugins v1.2

ie-buster-1.2 [.js] (Rechtsklick -> Speichern unter)
Nicht vergessen, regelmäßig nach Updates schauen.

oder

Einbinden der neuesten Version von meinem Server

<!-- <script type="text/javascript" src="jquery-min.js"></script> // (noch) Voraussetzung: jQuery! -->
<script type="text/javascript" src="http://public.hannes-schurig.de/IE-Buster/ie-buster-latest.js"></script>
Changelog


v1.2 – Anzeigefehler behoben
v1.1 – Anzeigefehler behoben

Gestern habe ich den IETester vorgestellt. Viele Versionen des Internet Explorer in einem Programm. Mir ist mal wieder aufgefallen, dass mein Blog im Internet Explorer 6 (und älter) nicht ansatzweise richtig dargestellt wird. Ich habe mich also (mal wieder) entschlossen, den IE 6 (und älter) aus meinem Blog zu entfernen.
Nachdem ich mehr oder weniger erfolgreich 2, 3 WordPress Plugins und 2, 3 andere Codeschnipsel ausprobiert hatte, was alles nicht so wirklich optimal lief, hab ich mich entschlossen meine eigene Anti-IE6 Warnung zu basteln.

Code
<!--[if lte IE 6]>
<style type="text/css">
.BGC { display: none!important; } 
#ie6-warning td { border: 1px solid #eee; padding: 4px; } 
#ie6-warning { display: block; 600px; height: 100%; color: white; margin: 10%; font-size: 17px; } 
</style>
<![endif]-->

<body>
<div id="ie6-warning">
  Ihr Browser ist zu alt um diese Internetseite korrekt darzustellen.<br/>
  Bitte aktualisieren Sie Ihren Browser oder installieren Sie einen anderen modernen Browser.<br/><br/>
  Your browser is too old to display this website correctly.<br/>
  Please update your browser or install another modern browser.<br/><br/><br/>
  <table cellpadding="10">
    <tr><td></td><td>Google Chrome</td><td>Mozilla Firefox</td><td>Opera</td><td>Apple Safari</td><td>Microsoft Internet Explorer</td></tr>
    <tr><td>Download (DE):</td><td><a href="http://www.google.de/chrome/">Link</a></td><td><a href="http://www.mozilla-europe.org/de/firefox/">Link</a></td><td><a href="http://de.opera.com/">Link</a></td><td><a href="http://www.apple.com/de/safari/">Link</a></td><td><a href="http://www.microsoft.com/germany/windows/internet-explorer/">Link</a></td></tr>
    <tr><td>Download (EN):</td><td><a href="http://www.google.com/chrome/">Link</a></td><td><a href="http://www.mozilla-europe.org/en/firefox/">Link</a></td><td><a href="http://www.opera.com/">Link</a></td><td><a href="http://www.apple.com/safari/">Link</a></td><td><a href="http://www.microsoft.com/windows/internet-explorer/">Link</a></td></tr>
    <tr><td>Suchen/Search for:</td><td><a href="http://www.google.com/search?q=chrome">Link</a></td><td><a href="http://www.google.com/search?q=firefox">Link</a></td><td><a href="http://www.google.com/search?q=opera">Link</a></td><td><a href="http://www.google.com/search?q=safari">Link</a></td><td><a href="http://www.google.com/search?q=internet+explorer">Link</a></td></tr>
  </table>
  <br/><br/><span>Liebe Grüße, best regards, Hannes Schurig</span>
</div>

Kurz, einfach, schmerzlos, schnell.
Es gibt eine IE < = 6 Weiche, die dann CSS Eigenschaften aktiviert. Diese blenden den Blog (.BGC ist der Blogcontainer) aus und blenden die IE 6 Warnung ein. Das wiederum ist einfach nur etwas Text und eine Tabelle. In der Tabelle biete ich die Downloadseiten der bekanntesten Browser auf deutsch und englisch an, zusätzlich dazu zu jedem Browser noch die Google Suchergebnisse. Leicht angepasst kann man diesen Codeschnipsel in jedem Webprojekt einbauen!

Webentwickler kennen das Leiden, Internet Explorer. Ein Graus, die Webseite auf diesen Browser abzustimmen. Zumal man meistens nur 1 Version davon installiert hat.
Mit IETester installiert man gleich 5 IE Versionen mit ihren jeweiligen Verhalten, Bugs und HTML Inkompatibilitäten.

Letzten Donnerstag kam Version 0.4.8 des Programms raus. Hier bekommt ihr den Download. Das Programm ist schnell installiert. Voll funktionsfähig in Windows 7 und 64bit, muss man dazu sagen.

Die Handhabung ist noch einfacher. Die Oberfläche verzichtet auf viel Schnickschnack und Features. Man kann einzelne Browserversionen starten und direkt die Internetseiten vergleichen.
Mehrere IE Ansichten nebeneinander? Kein Problem. Es lassen sich beliebig viele Tabs von verschiedenen IE Versionen öffnen und nebeneinander platzieren.

IETester liefert auch noch ein paar nützliche Tools mit. Dazu gehört neben der DebugBar (muss extra heruntergeladen werden) auch die Quellcodeanzeige, Schriftgrößenwahl und noch besser: aktivieren & deaktivieren von Cache, Medien (Videos, Bilder, Sound) und aktiven Inhalten (ActiveX, JS, Java).

Ein Top Tool wenn man vorher noch mit Multiple IEs oder anderen suboptimalen Lösungen gearbeitet hat!

Aufklappbare, verschachtelte Menüs mit gepunkteter Hierarchiehilfe
…das ist jetzt Thema 😀
Die Sache ist ziemlich simpel. Ich brauchte letztens ein aufklappbares Menü mit ebenfalls aufklappbaren Unterpunkten, möglichst unkomplizierter Aufbau, möglichst wenig Code. Irgendwann wird das Menü mit vielen aufgeklappten Untermenüs doch sehr übersichtlich, also habe ich „Hierarchielinien“ hinzugefügt. Keiner Ahnung ob es dafür auch einen normalen Namen gibt.

Verpackt in HTML/CSS und einfach animiert mit einem jQuery Zweizeiler, fertig.

Code

HTML:

<ul id="nav">
	<li class="expand">Über das IQB
		<ul>
			<li>Gründung</li>
			<li>Ziele</li>
			<li>Partner/Links</li>
		</ul>
	</li>
	<li>Personal</li>
	<li class="expand">Bildungsstandards
		<ul>
			<li>Aufgabenbeispiele</li>
			<li>EMSE</li>
			<li class="expand">Downloadserver
				<ul>
					<li>Audiofiles</li>
					<li>Videofiles</li>
				</ul>
			</li>
		</ul>
	</li>
	<li>VERA/Lernstandsvergleich</li>
	<li class="expand">Arbeitsbereiche
		<ul>
			<li>Testentwicklung</li>
			<li>Kompetenzerwerb</li>
			<li class="expand">Implementation
				<ul>
					<li>Was wird</li>
					<li>denn eigentlich</li>
					<li class="expand">so alles
						<ul>
							<li>test</li>
							<li>test2</li>
						</ul>
					</li>
					<li>implementiert??</li>
				</ul>
			</li>
			<li>Bildungsmonitoring</li>
			<li>Datenzentrum (FDZ)</li>
		</ul>
	</li>
</ul>

CSS:

body, html{
	height: 100%;
	width: 100%;
	font-family: "Trebuchet MS";
	margin: 0; padding: 0;
}
a {
	text-decoration:none;
	color: black;
}
ul, li {
	list-style: none;
}
#nav li {
	padding: 2px 2px 2px 15px;
	cursor: default;
}
#nav ul {
	display: none;
	background: url(img/dots.png) repeat-y scroll 10px 0 transparent;
}
#nav li.expand {
	background: url(img/arrow-down.gif) no-repeat scroll 0px 12px transparent;
}
.expanded {
	background: url(img/arrow-up.gif) no-repeat scroll 0px 12px transparent !important;
}

Das tatsächliche Design des Menüs muss jeder selbst basteln.

jQuery:

$(document).ready(function() {
   $(".expand").click(function(e) {
      $(this).toggleClass("expanded");
      $(this).children("ul:first").slideToggle("300");
      e.stopPropagation();
   });	
}); //$(document).ready
Demo:

Link

Download:

folding-nav.zip