PHP-Klasse für den Austausch von HTML5 Tags in älteren Browsern


User Agents auswerten für valide und abwärtskompatible Seiten

HTML5 brachte eine Reihe von neuen Elementen mit sich, die jedoch von älteren Browsern nicht richtig interpretiert werden können, da die HTML-Rendering-Engine einstiger Browserversionen neue HTML5-Elemente, wie nav, article, aside und weitere, nicht kennt. Um dennoch abwärtskompatible Webseiten zu gestalten, ohne dabei auf neuere Elemente zu verzichten, setzen Webentwickler relativ häufig sogenannte Conditional Comments ein. Ein Beispiel:

<!-- [if lt IE 9]> Anweisungen<!--<![endif]-->

Ein Problem dabei, welche Browser nun was versteht, ist ohne Einarbeitung und eigene Test nicht einfach nachvollziehbar und neue HTML-Elemente werden der Rendering-Engine älterer Browser dadurch nicht unbedingt bekannter. Zumal die Frage im Raum stehen bleibt, wie valide ist eine Seite mit HTML5-Elementen eigentlich in älteren Browsern?
Eine nach unserer Auffassung bessere Lösung bietet die auf dieser Seite vorgestellte Klasse, die es ermöglicht, vor der Auslieferung neue HTML- Block-Elemente für ältere Browser einfach durch altbekannte Block-Elemente zu ersetzen. Möglich wird eine Erkennung älterer Browser durch die Auswertung der übermittelten User Agents.

Zum Code der Klasse gibt es nicht viel zu bemerken. Mit der PHP-Funktion stristr wird nach einer typischen Zeichenfolge gesucht, die im User Agent des jeweiligen Browsers vorkommen muss, um den Browser zu identifizieren. Zum Beispiel kommt im User Agent des Internet Explorers das Kürzel MSIE vor, gefolgt von einer Ziffer für die Version.
Wurde eine Übereinstimmung mit dem gesuchten String gefunden, wird mit der PHP-Funktion substr der gefundene String, welcher in der Eigenschaft $ausgewertet als Teilstring ab dem Fund gespeichert wird, soweit eingekürzt, bis nur noch eine Ziffernfolge übrig bleibt. Diese Ziffernfolge wird im Anschluss mit einer Switch-Case Fallunterscheidung ausgewertet.

Je nach Version des Browsers wird den Eigenschaften $html_…tag statt nav, article und aside einfach ein div zugwiesen. Die Eigenschaften und Tags lassen sich beinahe beliebig um weitere Tags ergänzen, falls Bedarf besteht.

<?php
/**---------------------------------------------------------------------------------
 * Klasse zur Ueberpruefung von User Agents auf alte und uralte Versionen und zur
 * Auslieferung von alten oder neuen HTML-Elemente-Tags.
 *
 * @author Horst Mueller
 * @license GPLv2
 * @link http://www.coder-welten.com/php-klasse-fuer-den-austausch-von-html5-tags/
 *
 * @version 1.0
 -----------------------------------------------------------------------------------
 */

class User_Agent_Pruefung {

    /**
     * Eingehende und ausgewertete User Agents
     *
     * @var string
     * @access private
     */
    private $eingehender;
    private $ausgewertet;

    /**
     * Ergebnis der Auswertung
     *
     * @var bool
     * @access private
     */
    private $uralt;

    /**
     * HTML5 Elemente-Tags
     *
     * @var string
     * @access public
     */
    public $html_navtag = "nav";
    public $html_arttag = "article";
    public $html_asitag = "aside";

    /**
     * Methode zur Pruefung und Auswertung
     */

    public function pruefe_auf_uralt() {

        $this->eingehender = strip_tags( $_SERVER["HTTP_USER_AGENT"] );

        /*-- Beispiel IE '... MSIE 7.0 ...' --------------------------------------*/

        if ( stripos($this->eingehender, "MSIE") !== false ) {
            $this->ausgewertet = stristr( $this->eingehender, "MSIE" );
            $this->ausgewertet = substr( $this->ausgewertet, 5, 1 );

            switch ( $this->ausgewertet ) {
                case "5":
                case "6":
                case "7":
                case "8":
                    $this->uralt = true;
                    break;
                default:
                    $this->uralt = false;
            }
        }
        /*-- Beispiel Firefox '... Firefox/2.0.0.14' -----------------------------*/

        elseif ( stripos($this->eingehender, "Firefox") !== false ) {
            $this->ausgewertet = stristr( $this->eingehender, "Firefox" );
            $this->ausgewertet = substr( $this->ausgewertet, 8, 2 );

            switch ( $this->ausgewertet ) {
                case "1.":
                case "2.":
                case "3.":
                    $this->uralt = true;
                    break;
                default:
                    $this->uralt = false;
            }
        }
        /*-- Beispiel Safari vor Version 5 '... Version/4.1 Safari/533.16' -------*/

        elseif ( stripos($this->eingehender, "Safari/5") !== false
            and  stripos($this->eingehender, "Version")  !== false ) {
            $this->ausgewertet = stristr( $this->eingehender, "Version" );
            $this->ausgewertet = substr( $this->ausgewertet, 8, 2 );

            switch ( $this->ausgewertet ) {
                case "3.":
                case "4.":
                    $this->uralt = true;
                    break;
                default:
                    $this->uralt = false;
            }
        }
        /*-- Beispiel Safari kleiner Version 3 '... Safari/413' ------------------*/

        elseif ( stripos($this->eingehender, "Safari/4") !== false ) {
            $this->uralt = true;
        }
        /*-- Beispiel Opera kleiner Version 11 '... Presto/2.1.1 ...' (kein 2.3) -*/

        elseif ( stripos($this->eingehender, "Opera")  !== false
            and  stripos($this->eingehender, "Presto") !== false ) {
            $this->ausgewertet = stristr( $this->eingehender, "Presto" );
            $this->ausgewertet = substr( $this->ausgewertet, 7, 4 );

            switch ( $this->ausgewertet ) {
                case "2.1.":
                case "2.2.":
                case "2.4.":
                case "2.5.":
                case "2.6.":
                    $this->uralt = true;
                    break;
                default:
                    $this->uralt = false;
            }
        }
        else {
            $this->uralt = false;
        }
        if ( $this->uralt === true ) {
            $this->html_navtag = "div";
            $this->html_arttag = "div";
            $this->html_asitag = "div";
        }
        elseif ( $this->uralt === false ) {
            $this->html_navtag = "nav";
            $this->html_arttag = "article";
            $this->html_asitag = "aside";
        }
    }
}
?>

Die Datei wurde für die durchzuführenden Tests unter dem Namen class-user-agent-pruefung.php in einem neu angelegten Verzeichnisse /inc gespeichert, wobei dieses neue Verzeichnis innerhalb des Themes angelegt wurde. Der Name inc wurde gewählt, da die Extension inc im Allgemeinen für Include-Dateien steht.
Um innerhalb eines WordPress-Themes auf die Klasse zugreifen zu können, muss zuerst ein Objekt als Instanz dieser Klasse erzeugt werden. Eine Möglichkeit bestünde darin, in jeder Template-Datei, in welcher auf diese Klasse zugegriffen werden soll, eine neue Instanz der Klasse zu erstellen. Wesentlich eleganter ist es hingegen, eine Funktion zuschreiben, in der die Klasse eingebunden wird und in dieser Funktion ein Objekt der Klasse zu instanziieren. Die für diesen Zweck vorgesehene Funktion wird wie jede andere Funktion in der Datei functions.php vom Theme definiert.

<?php
/**
 * Einfuegen in die functions.php vom Theme exempel.
 */

function pruefe_neue_htmltags( $eingang = "div" ) {

    if ( isset($_SERVER["HTTP_USER_AGENT"]) and !empty($_SERVER["HTTP_USER_AGENT"]) ) {
        $class_uap = get_theme_root()."/exempel/inc/class-user-agent-pruefung.php";

        if ( file_exists($class_uap) ) require_once $class_uap;
        else exit( "Diese Datei existiert nicht!" );

        $tagausgabe = new User_Agent_Pruefung();
        $tagausgabe->pruefe_auf_uralt();

        if ( $eingang == "nav" )         return esc_html( $tagausgabe->html_navtag );
        elseif ( $eingang == "article" ) return esc_html( $tagausgabe->html_arttag );
        elseif ( $eingang == "aside" )   return esc_html( $tagausgabe->html_asitag );
        else return esc_html( $eingang );
    }
    else exit( "Kein UA!" );
}
?>

Nun kann in jeder Template-Datei vom Theme auf über diese Funktion auf die Klasse zugegriffen werden.

Beispiel vorher:

<nav id="navigation" class="navigation">
    <!-- Menue -->
</nav> 

<article id="artikel" class="artikel">
    <!-- Content -->
</article>

Beispiel nachher:

<<?php echo pruefe_neue_htmltags( 'nav' ); ?> id="navigation" class="navigation">
    <!-- Menue -->
</<?php echo pruefe_neue_htmltags( 'nav' ); ?>> 

<<?php echo pruefe_neue_htmltags( 'article' ); ?> id="artikel" class="artikel">
    <!-- Content -->
</<?php echo pruefe_neue_htmltags( 'article' ); ?>>

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *