Tutorial: PHP-Styleswitcher

Vornweg: Der PHP-Styleswitcher basiert auf dem Code von How do you make a website skinnable?. Ich hab’ dabei nur einige kleine Änderungen durchgeführt, damit das Script bei mir lauffähig wird.

Der Styleswitcher funktioniert per PHP und speichert beim User ein Cookie mit einer Lebensdauer von einem Jahr. Aktiviertes Javascript beim Besucher ist nicht nötig. Ich setze voraus, dass PHP auf dem Server installiert ist und ausserdem, dass man mindestens zwei verschiedene CSS-Styles hat, zwischen den man wechseln möchte. Mit diesem Switcher kann man jedoch auch ohne einen Wechsel der CSS-Dateien das Layout wechseln; wie erklär’ ich aber erst am Ende.

Als erstes läd man sich die Datei herunter und entpackt diese. Diese beinhaltet eine cookie.php und eine header.php. Dazu später mehr.

1. headerfiles – header(stylenummer).php

Angenommen man möchte zwischen 3 Styles wählen können, dann muss man 3 Dateien anlegen: header1.php, header2.php und header3.php. In diesen headerfiles stehen nun die zu wählenden CSS-Dateien. Z.B. könnte in der header1.php folgendes stehen:

<link rel="stylesheet" type="text/css" href="/link/zu/blau.css" title="Blau" media="screen" />
<link rel="alternate stylesheet" type="text/css" href="/link/zu/rot.css" title="Rot" media="screen" />
<link rel="alternate stylesheet" type="text/css" href="/link/zu/gelb.css" title="Gelb" media="screen" />

Der Link zur CSS-Datei muss von der index.php aus gesehen werden und nicht von dem jeweiligen headerfile. Die Angaben der zwei anderen alternativen CSS-Dateien macht insofern Sinn, dass im Opera und im Mozilla/Firefox die Styles auch im Browser gewechselt werden können ohne eine Cookie zu speichern (somit allerdings auch nur für die Zeit der Sitzung). Die header2.php müsste demnach etwa so aussehen:

<link rel="stylesheet" type="text/css"  href="/link/zu/rot.css" title="Rot" media="screen" />
<link rel="alternate stylesheet" type="text/css"  href="/link/zu/blau.css" title="Blau" media="screen" />
<link rel="alternate stylesheet" type="text/css"  href="/link/zu/gelb.css" title="Gelb" media="screen" />

2. header.php

Diese headerfiles (header1.php, header2.php usw.) speichert man am besten zusammen mit der heruntergeladenen header.php in einem Verzeichnis ab, muss man aber nicht.

<?php
$stylefile = "/verzeichnis/mit/der/header"; 
$stylefile .= $style;
$stylefile .= ".php";
//hier wird eine header(stylenummer).php angegeben
//also zum Beispiel /verzeichnis/mit/der/header1.php
//das Verzeichnis ist relativ zur header.php
include $stylefile;
//und hier wird dann die jeweilige headerNr.php 
//automatisch eingefügt
?>

Die header.php ist dafür da, die verschiedenen headerfiles an die Seite zu übermitteln. Ein headerfile hiesse z.B. header1.php für den Style Nr.1 und header2.php für den Style Nr.2. Am besten man legt die header.php mit den headerfiles, also header(stylnummer).php, in ein und dasselbe Verzeichnis. Dann würde die erste Zeile oben nur lauten:

$stylefile = "header";

3. cookie.php

Die cookie.php speichert man am besten im Hauptverzeichnis der Webseite, also dort, wo die index.php liegt.
Der Inhalt:

 <?php
$total_styles = 3;
//die Anzahl der vorhandenen Styles
$default_style = 1;
//der Standartstyle, wenn die Seite zum ersten mal besucht wird
if (isset($_REQUEST['newstyle'])) { 
  $newstyle=(int)$_REQUEST['newstyle'];
  if ( ($newstyle<1) OR ($newstyle>$total_styles) )
    $newstyle=$default_style;
} elseif (isset($_REQUEST['style'])) {
  $newstyle=(int)$style;
  if ( ($style<1) OR ($style>$total_styles) )
    $newstyle=$default_style;
  } else $newstyle=$default_style;
//hier wird ein evtl. gesetztes Cookie
//ausgelesen und ueberprueft,
//ob einer und wenn, welcher Style gewaehlt wurde 
$style=$newstyle;
setcookie ('style', "", time() - 3600);
setcookie('style',$newstyle,time()+(86400*365),'/');
setcookie('style', $newstyle,time()+(86400*365),'/','.www.deineseite.de');
$style=$newstyle;
//ein Cookie namens "style" mit einer Lebensdauer von
//einem Jahr und dem gewaehlten Style wird gesetzt
?>

In dieser Datei muss die Anzahl der vorhanden und zu wechselnden Styles, sowie der Standartstyle eingestellt werden. Der Standartstyle ist jener welcher, den der Besucher sieht, wenn er das erste mal die Seite besucht oder seine Cookies gelöscht hat. Ebenso sollte in der Datei auch die Domain (www.deineseite.de) eingetragen werden, von der das Cookie stammt.

4. index.php

Wie bindet man das alles nun in die Seite ein?
Ganz einfach:
als erstes noch vor der DOCTYPE-Angabe also in die allererste Zeile wird die cookie.php includiert mit:

<?php include('cookie.php'); ?>

Diese muss deswegen in die erste Zeile, weil das sonst mit den Cookies nicht klappt.
Die header.php muss aber auch noch irgendwo hin. Diese fügt man einfach da ein, wo sonst die Angabe für die CSS-Datei war (weil dort wird es ja auch wieder durch die header.php reingeschrieben):

<?php include('/link/zur/header.php'); ?>

Um zwischen den Styles nun zu switchen, fügt man solche Links auf der Seite ein:

<a href="index.php?newstyle=1">verdammt cooler Style</a><br />
<a href="index.php?newstyle=2">boa, noch geilerer Style</a><br />
<a href="index.php?newstyle=3">Isch krieg 'ne Krise, best style ever seen on this world</a>

Fertig.

5. Beispiel

Hier auf yablo.de sieht das ganze so aus.
Meine Datein in der Verzeichnisstruktur ist in etwa so angelegt:

/ein/paar/server/pfade/www.yablo.de/public_html/
Hier liegen die index.php und die cookie.php.

/ein/paar/server/pfade/www.yablo.de/public_html/headerfiles/
Hier liegen header.php, header1.php, header2.php und header3.php.

/ein/paar/server/pfade/www.yablo.de/public_html/css/parzifal/parzifal.css
/ein/paar/server/pfade/www.yablo.de/public_html/css/gruen/gruen.css
/ein/paar/server/pfade/www.yablo.de/public_html/css/einfach/einfach.css

Hier befinden die einzelnen CSS-Dateien.

Meine index.php oder das template:

<?php include('cookie.php'); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
xml:lang="de" lang="de">
<head>
<meta name="generator" content="XE/3 0.6" />
<title>YaBlo</title>
<meta http-equiv="Content-Type" content="text/html; 
charset='iso-8859-1'" />
<meta name="title" content="YaBlo" />
<meta name="author" content="Trencavel" />
<meta name="publisher" content="Trencavel" />
<meta name="copyright" content="YaBlo" />
<meta name="revisit" content="after 3 days" />
<meta name="description" content="YaBlo" />
<meta name="abstract" content="Weblog von Trencavel" />
<meta name="page-topic" content="Weblog" />
<meta name="audience" content="all" />
<meta name="robots" content="index,follow" />
<?php include('./headerfiles/header.php'); ?>
<div id="header">
<!-- end of 'header' --></div>
...

Meine headerfiles liegen im Verzeichnis (von der index.php aus gesehen) /headerfiles.
Meine header.php zeigt nun auch, das meine headerfiles (z.B. header1.php) im gleichen Verzeichnis wie die header.php liegen:

<?php
$stylefile = "header"; 
$stylefile .= $style;
$stylefile .= ".php";
include $stylefile;
?>

Meine cookie.php sieht so aus:

<?
$total_styles = 3;
$default_style = 3;
if (isset($_REQUEST['newstyle'])) { 
  $newstyle=(int)$_REQUEST['newstyle'];
  if ( ($newstyle<1) OR ($newstyle>$total_styles) ) 
    $newstyle=$default_style;
  } elseif (isset($_REQUEST['style'])) {
    $newstyle=(int)$style;
  if ( ($style<1) OR ($style>$total_styles) ) 
    $newstyle=$default_style;
} else $newstyle=$default_style;
//hier wird ein evtl. gesetztes Cookie ausgelesen und ueberprueft,
//ob einer und wenn, welcher Style gewaehlt wurde 
$style=$newstyle;
setcookie ('style', "", time() - 3600);
setcookie('style',$newstyle,time()+(86400*365),'/');
setcookie('style',$newstyle,time()+(86400*365),'/','.www.yablo.de');
$style=$newstyle;
?>

Meine header1.php:

<link rel="stylesheet" type="text/css" href="./css/einfach/einfach.css" title="Einfach" media="screen, projection" />
<link rel="alternate stylesheet" type="text/css" href="./css/parzifal/parzifal.css" title="Parzifal"  media="screen, projection" />
<link rel="alternate stylesheet" type="text/css" href="./css/gruen/gruen.css" title="Gruen" media="screen, projection" />
</head>
<body>

header2.php:

<link rel="stylesheet" type="text/css"  href="./css/gruen/gruen.css" title="Gruen"  media="screen, projection" />
<link rel="alternate stylesheet" type="text/css"  href="./css/parzifal/parzifal.css" title="Parzifal" media="screen, projection" />
<link rel="alternate stylesheet" type="text/css" href="./css/einfach/einfach.css" title="Einfach" media="screen, projection" />
</head>
<body>

und die header3.php:

<link rel="stylesheet" type="text/css" href="./css/parzifal/parzifal.css" title="Parzifal" media="screen, projection" />
<link rel="alternate stylesheet" type="text/css" href="./css/gruen/gruen.css" title="Grün" media="screen, projection" />
<link rel="alternate stylesheet" type="text/css" href="./css/einfach/einfach.css" title="Einfach" media="screen, projection" />
</head>
<body>

Änderungen die evtl. angepasst werden müssen, hab ich fett geschrieben. Wie man sieht hab ich in den headerfiles nicht nur auf die CSS-Dateien verwiesen, sondern auch gleich den End-head- und den Anfang-body-Tag mit eingefügt und aus der index.php herausgenommen. Warum steht im nächsten Kapitel.

Da ich mir überlegt habe, dass es auf meiner Seite wohl nicht nur bei 3 Styles bleiben wird, hab ich mich für eine Auswahlliste entschieden. Die sieht so aus:

<form action="">
<select name="menu" size="1" onchange="javascript:parent.location=this.form.menu.options[this.form.menu.selectedIndex].value;">
<option>Style</option>
<option></option>
<option value="index.php?newstyle=3">Parzifal</option>
<option value="index.php?newstyle=2">Gruen</option>
<option value="index.php?newstyle=1">Einfach</option>
</select></form>

6. Komplette Layoutänderungen

Der Vorteil dieser Styleswitch-Variante: Man kann hier nun das komplette Layout oder sogar den Inhahlt der Seite wechseln. Das einzige was man machen muss: Alles, was bis jetzt unterhalb des

<?php include(header.php) ?>stand, löschen und in ein headerfile (header1.php) eintragen. Nun könnte ich eine anderes headerfile (header2.php) anlegen mit dem neuen Inhalt. Und schon kann man zwischen beiden Inhalten oder Layouts wechseln. Man könnte es aber auch nicht nur bei den headerfiles belassen, sondern auch noch footerfiles, navifiles, menufiles oder sturzbetrunkenfiles anlegen und nach oben beschriebener Weise einfügen. Je nach dem!

Viel Spass!

Ach ja, ich weiss nicht, ob und wieviel ich Support geben kann, da ich von dem Zeug so gut wie keine Ahnung habe.:-/

Kommentar

  1. # - Guido schrieb am 8. Oktober 2004, 17:17:

    wei krieg ich das hin, dass auch iframes mit geändert werden?

    cu
    guido
  2. # - trenc schrieb am 8. Oktober 2004, 20:17:

    Hi,

    ich hab zwar noch nie mit Frames gearbeitet (nicht jeder Browser mag die). Sollte jedoch auch nicht viel anders wie oben bei Punkt 6 beschrieben funktionieren. Aber wenn www.guidohaeni.de Deine Seite ist, würd’ ich vorschlagen:
    a) Komplett auf Frames zu verzichten
    und ganz wichtig
    b) die Musik rausnehmen, weil nach zweimal nacheinander um die 3.5 MB zu laden ist selbst für DSL einfach zu heftig. Ich hab den Seitenaufbau dann einfach abgebrochen. User mit Modem werden wohl Deine Seite nie besuchen.
    Am einfachsten wäre es in Deinem Fall ein CMS zu benutzen. Dann sind auch Layoutänderungen einfacher zu handhaben.
  3. # - Thomas schrieb am 4. November 2004, 13:18:

    Danke für die tolle erklärung dazu. Mal ein tutorial was auf anhieb funktioniert.
  4. # - broetchen schrieb am 3. Februar 2005, 12:49:

    thx thx thx :)

    echt dicke freu über deine geniale anleitung, weil :) klingt so fett verständlich ….werde gleich mal schauen ob ich das nachbauen kann

    ach ja nett anmerk über deinen letzten satz
    mom ich quote :
    ... da ich von dem Zeug so gut wie keine Ahnung habe.:-/

    mußte ich echt grinsen janzbreit weil dafür ist es RICHTIG FETT :))

    greetz vom broetchen
  5. # - Andrea schrieb am 12. Mai 2005, 19:40:

    Hallo, dein Styleswitcher gefällt mir gut, habe ich gleich ausprobiert. Ich schaffe es aber nicht, dass das Stylesheet auf den Seiten gefunden wird, die in Unterordnern liegen. Es klappt nur auf den Seiten, die im Stammordner sind. Was mache ich da falsch?
  6. # - trenc schrieb am 13. Mai 2005, 10:50:

    Hm,

    leider kenne ich Deine Verzeichnisstruktur nicht und weiß auch noch nicht ganz genau, was Du meinst.
    Aber ich vermute, dass der Fehler in den Pfadangaben liegt. Die Pfadangaben zur CSS-Datei in den headerfiles muss man immer von der Datei aus sehen, von welcher aus die headerfiles includiert werden. Wenn Du jetzt von Seiten aus einem Unterordner anstatt vom Stammordner die headerfiles includierst, benötigst Du in diesen headerfiles andere Pfadangaben zur CSS-Datei, nämlich Angaben vom Unterordner aus gesehen.
    Einfacher gesagt: Für jeden Unterordner bräuchtest Du also extra headerfiles.
    Oder:
    Du kannst natürlich, da Du ja mit PHP arbeitest, auch die Seiten aus den Unterverzeichnissen in Deiner index.php aus dem Stammordner heraus aufrufen, so dass das ganze Webseitenprojekt über die index.php abgerufen werden kann.
  7. # - Gabi schrieb am 18. Mai 2005, 22:51:

    Das Einbinden der Headerfiles hat soweit gut geklappt, lediglich der Cookie funktioniert nicht.
    Die cookie.php liegt in dem Verzeichnis, wo meine php-Dateien liegen und ist genau nach Anleitung über dem doctype eingebunden.

    Hier mal ein Link zu meiner Site, die ich gerade in Arbeit habe. Das Untermenü auf der rechten Seite funktioniert. Immer wenn ich einen neuen Untermenüpunkt anklicke, erscheint das Standardstyle.
    Bei den Styles funktionieren zur Zeit Standard, Sommer und Herbst, wobei Standard und Herbst (noch) gleich aussehen, also nicht irritieren lassen.

    http://www.beautycolors.de/php/knigge.php

    Hat jemand eine Idee?
    Ich habe meinen Webspace übrigens bei Strato, falls das eine Rolle spielt.

    Viele Grüße,
    Gabi
  8. # - trenc schrieb am 20. Mai 2005, 17:09:

    Ferndiagnose ist immer bisschen schlecht, ich kann Dir da auf Anhieb leider auch nicht helfen, aber schreib mal in Deine knigge.php ein
    error_reporting(E_ALL);
    und schau mal, ob Dir die Fehlermeldung weiterhilft.
  9. # - pfeilchen schrieb am 12. Juni 2005, 18:59:

    hi, geniales Tut!

    funktioniert auch alles wunderprächtig. jetzt möchte ich das script gerne erweitern in dem ich nen link zu einer subdomain lege, die den zuvor ausgewählten style beinhaltet. hab nur leider kein plan wie man das gesetzte cookie über domaingrenzen hinweg auslesen kann?

    hat das schon mal jemand versucht?

    danke!
  10. # - pfeilchen schrieb am 12. Juni 2005, 19:12:

    noch mal ich :-)

    habe es gerade selbst herausgefunden!

    hier:

    http://www.php-center.de/de-html-manual/function.setcookie.html

    “domain” – “Um das Cookie für all Sub-Domains von example.com verfügbar zu machen, setzen Sie es auf ’.example.com’. Der . ist zwar nicht erforderlich, erhöht aber die Kompatibilität zu mehr Browsern. Eine Setzen auf www.example.com macht das Cookie nur in der www Sub-Domain verfügbar…”

    nix für ungut!
  11. # - isabella schrieb am 27. November 2005, 17:11:

    Funzt soweit – auch das Cookie wird gesetzt. Aber sobald ich auf eine andere Seite wechsle (gleiches Verzeichnis, ebenfalls das Styleswitcher-Skript eingebunden), ist’s auch schon vorbei. Der gewählte Stil wird einfach nicht beibehalten. Woran liegt das wohl? Ich habe alles haargenau so gemacht wie in der Anleitung. Und es hat geklappt. Dann habe ich nochmal eine identische Testdatei erstellt im gleichen Verzeichnis. Somit haben diese beiden Testdateien jeweils das Skript eingebunden. Danach habe ich diese beiden Dateien miteinander verlinkt. Wenn ich nun einen Stil wähle, wird dieser gewechselt. Wenn ich danach aber per Link auf die andere Seite gehe, verliert er den Stil wieder und nimmer default.
  12. # - Adam schrieb am 4. Juli 2006, 16:20:

    XSS (Cross Site Scripting)

    http://www.beautycolors.de/php/knigge.php?style=’; alert(String.fromCharCode(88,83,83))//\’; alert(String.fromCharCode(88,83,83))//”; alert(String.fromCharCode(88,83,83))//\”; alert(String.fromCharCode(88,83,83))//>!—alert(String.fromCharCode(88,83,83))=&{}

  13. # - Ingolf schrieb am 31. Oktober 2006, 13:35:

    vielleicht schaut ja noch jemand in dieses tutorial da der letzte eintrag recht alt ist. ich habe das gleiche problem wie isabella: beim wechsel auf eine andere seite bleibt der gewählte style nicht erhalten
    das komische: auf meinem rechner mit xampp funktioniert es

  14. # - trenc schrieb am 31. Oktober 2006, 17:21:

    Hm, seltsamer Weise werden auf Deiner Seite auch zwei Cookies anstatt nur eines gesetzt. Sind denn die Skripte auch identisch?

  15. # - Maja schrieb am 29. Januar 2007, 17:33:

    Ich habe, nachdem erstmal alles hervorragend geklappt hat – großes Lob für die Anleitung – das gleiche Problem mit den Cookies. Und zwar nicht nur, wenn ich auf eine andere Seite wechsle, sondern, wenn ich die Seite einfach neu hereinlade und dabei das “?newstyle=2” in der URL wieder entferne. Es wird sofort ein neues Cookie mit Default-Einstellungen gesetzt.
    Hier meine Testseite: http://www.elomaran.de/index-test.php
    Offenbar wird das vorhandene Cookie nicht gelesen, woran kann es liegen?

    Liebe Grüße
    Maja

  16. # - slaym schrieb am 8. März 2007, 13:44:

    Hi,
    ich weis nich was ich falsch mache.
    aber ich mach es genauso wie du es beschrieben hast und nichts funzt, naja gut die cookies werden gesetzt … sogar die richtigen!aber die css styles funktionieren einfach nicht, ich habe schon tausend Pfadangaben ausprobiert!langsam weis ich echt nich mehr weiter!
    für ne hilfe wäre ich echt super dankbar!

    mfg
    slaym

  17. # - trenc schrieb am 9. März 2007, 19:42:

    @ slaym:
    Kannst Du genauere Angaben machen?

    Meine Glaskugel ist gerade zur Reparatur …

    @Maja:
    Auf Deiner Testseite werden immer zwei Cookies gesetzt, einer davon ohne Domainzuordnung. Beim wechsel auf die Standardseite – ohne Styleauswahl – werden beide Cookies gelöscht und zwei neue mit dem Standardstyle gesetzt. Aber ohne Einsicht in den Code kann ich da leider auch nichts Genaueres sagen.

  18. # - Stryder schrieb am 12. Juli 2007, 10:44:

    Gibt es schon eine Lösung für das Cookie Problem?

    Bei mir wird auch bei jedem neuladen oder Seitenwechsel die Standard CSS-Datei geladen.

  19. # - trenc schrieb am 25. Juli 2007, 18:56:

    Hm,
    da Ferndiagnose immer schlecht ist und es auch kein Cookie-Problem gibt, werde ich, wenn ich mal wieder etwas Zeit habe, ein paar Beispieldateien hochladen. An diesen wird man dann Live sehen können, wie das funktioniert.

    Aber wie gesagt: Ich muss leider erstmal paar Minuten Zeit freischaufeln; bin g’rad etwas stark eingespannt.

  20. # - Rainbow schrieb am 27. November 2007, 13:42:

    Hallo!

    die Anleitung ist super, der code ist bei mir zumindestens etwas schlecht zu lesen, – da er etwas blass ist.

    Es hat bei mir nicht wirklich funktioniert. Er hat den Cookie einfach nicht speichern wollen. Ich habe die cookie.php meinem Verständnis/Logik nach umgebaut und dann hat es super geklappt:

    if (isset($_REQUEST['newstyle']))
            {
                    setcookie("style", $_REQUEST['newstyle']);
                    setcookie("style", $_REQUEST['newstyle'], time()+3600);  /* verfällt in 1 Stunde */
                    setcookie("style", $_REQUEST['newstyle'], time()+3600, "/~/", ".debian-server/", 1);
                    $style = $_COOKIE['style'];
            }
            elseif (isset($_COOKIE['style']))
            {
                    $style=$_COOKIE['style'];
            }
            else
            {
                    $style=1;
            }

    Achso, du fragtes nach Unzulänglichkeiten, ich kann keinen Kommentar absenden. ( Hab skripte nun auch aktiv, geht nicht )

  21. # - trenc schrieb am 27. November 2007, 22:58:

    Hi Rainbow,

    danke für die Hinweise. Hab die Code-Snippets nun lesbarer gestaltet. Den Code und das Tutorial müsste ich bei Gelegenheit mal überarbeiten. Was ich mir schon mal im Juli vorgenommen hatte. ;)

  22. # - Yoko schrieb am 5. März 2008, 18:28:

    Schönes Tut, nur funktioniert es bei mir leider gar nicht. Hab alles so gemacht, wie es hier steht, aber die der Include für die header.php wird nicht gelesen. =(

  23. # - jan schrieb am 4. Juni 2008, 13:22:

    Sehr schönes tutorial, vielen dank!
    Für alle die probleme haben, die cookies zu übergeben: hier ein evtl. Lösungsansatz der beim ein oder anderen hoffentlich hilft:

    Das Problem ist, dass einige Serverbetreiber ihre register_globals (zu denen auf $_REQUEST) gehört leider unterbinden. Lösung:

    <?php $total_styles=2; $default_style=1; if (isset($_GET[‘newstyle’])){ $newstyle=(int)$_GET[‘newstyle’]; if ( ($newstyle<1) OR ($newstyle>$total_styles)) $newstyle=$default_style; }elseif (isset($_COOKIE[‘style’])){ $newstyle=(int)$_COOKIE[‘style’]; if(($_COOKIE[‘style’]<1) OR ($_COOKIE[‘style’]>$total_styles)) $newstyle=$default_style; }else $newstyle=$default_style; $style=$newstyle; setcookie(‘style’,”“,time()-3600); setcookie(‘style’,$newstyle,time()+(86400*365),’/’); setcookie(‘style’,$newstyle,time()+(86400*365),’/’,’.12345.de’); $style=$newstyle; ?>





Textile-Hilfe