CSS styleswitcher
Op sites waar vooruitstrevend gewerkt wordt, wordt content van opmaak gescheiden door middel van CSS. Op deze manier kan, als men dit wil, een visuele updates snel doorvoeren over de gehele site. Ook kan met de site in verschillende visuele vormen aanbieden. Zo kan er een aparte stylesheet zijn voor slechtzienden, mensen speciaal van de phpvereniging of kunnen er gewoon voor de fun verschillende stylesheets aangeboden worden.
Voor mijn eigen site heb ik “gewoon voor de fun verschillende stylesheets gemaakt, een erg leuke extra feature. Wat ik in dit artikel wil beschrijven is het maken van een styleswitcher. Na het inladen van een standaard ingestelde stylesheet kan de bezoeker dmv een drop down select box de gewenste style te kiezen. Deze blijft bewaart in een cookie.
Omdat voor verschillende stylesheets verschillende files (css+plaatjes) nodig zijn
is het van belang dat we een overzichtelijke directory structuur hanteren.
Ik heb gekozen voor de volgende directory structuur op de server:
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 |
- [dir]style
- [dir]1
- [dir]css
css.php
index.css
archief.css
algemeen.css
hier alle plaatjes voor stylesheet 1
- [dir]2
- [dir]css
css.php
index.css
archief.css
algemeen.css
hier alle plaatjes voor stylesheet 2
- enz
|
Zoals je ziet zijn de bestandnamen hetzelfde, alleen het nummer van de directory is verschillend.
Ik ben er vanuit gegaan dat je meer dan één pagina op je website hebt en dat je per pagina dusdanige andere content hebt dat je daar een aparte stylesheet voor hebt. Voor de globale layout (kolomstructuur, uitlijning of header) hanteren we een algemeen bestand (algemeen.css) wat op alle pagina’s geldt.
Verschillende pagina’s, (deels) verschillende stylesheets dus. Ik ga even voor het gemak uit van 2 pagina’s, index.php en archief.php.
Deze delen een gezamelijke html-kop (<html><head></head><body>), opgeslagen in top.php.
Probleem: we gebruiken dezelfde <head> voor zowel archief.php als voor index.php, we moeten onderscheid maken in het aanroepen van de stylesheet (wat gebeurt in de <head>).
Hoe lossen we dit op:
In de <head> wordt standaard maar 1 stylesheet ingeladen, namelijk css.php. Aan de hand van een doorgegeven GET variabele bepalen we welke extra stylesheet we moeten includen in css.php.
In archief.php en index.php moeten we een variabele doorgeven, we gebruiken de filenaam:
archief.php en index.php
001 002 003 004 |
<?php
$thiscssfile=$_SERVER['PHP_SELF'];
include ('top.php');
?>
|
in top.php is nu de variabele $thiscssfile aanwezig en die geven we door aan css.php door middel van een GET variabele:
top.php
001 002 003 004 005 006 007 008 009 010 011 012 |
<body><head>
<?php
echo '<link href="style/'.$css_dir_nr.'/css/css.php';
if (isset ($thiscssfile)){
//$thiscssfile bevat bijvoorbeeld "/subdirectory/index.php"
$thiscssfile=str_replace('/subdirectory/','',$thiscssfile); //strip ‘/subdirectory/’
$thiscssfile=str_replace('.php','',$thiscssfile); //strip ‘.php’
echo '?file='.$thiscssfile;
}
echo '" rel="stylesheet" type="text/css" />';
?>
</head><body>
|
we roepen nu in de <head> dus aan:
<link href=”style/’.$css_dir_nr.’/css/css.php?file=index’ rel=”stylesheet” type=”text/css” />
We halen nu een php file aan als een css file, om aan de verwachtingen van de browser te voldoen, passen we de header aan in css.php
001 |
<?php header("Content-type: text/css"); ?>
|
In css.php gaan we nu aan de hand van de GET variabele de juiste stylesheet inladen:
css.php
001 002 003 004 005 006 007 008 009 010 011 012 013 014 |
<?php
header("Content-type: text/css");
if (isset ($_GET['file'])){
//eerst laden we het css bestand in wat de ‘algemene’ opmaak bevat, wat geldt voor alle pagina’s
readfile('algemeen.css');
//hierna kijken we welke pagina’s we extra moeten inladen
if ($_GET['file'] == 'index'){
readfile('index.css');
}
if ($_GET['file'] == 'archief'){
readfile('archief.css');
}
}
?>
|
Nu hebben we dus een systeem wat bij de juiste pagina de juiste stylesheet filenaam inlaadt. We hebben echter nog niet de juiste styledirectory geselecteerd.
Mensen die net goed opgelet hebben, hebben in top.php de variabele $css_dir_nr zien staan. Deze variabele bevat, zoals de naam zegt, het directorynummer van de geselecteerde stylesheet. Maar hoe wordt deze variabele gevuld? Aan de hand van de keuze van de bezoeker natuurlijk.
Deze keuze kan op 3 niveaus doorgegeven worden:
1. mensen die via de style-kiezer net een nieuwe stylesheet geselecteerd hebben
2. mensen die eerder hebben gekozen en een cookie hebben
3. mensen die ingelogd zijn en die in hun preferences een voorkeur hebben ingesteld (variabele $aUserinfo[‘stylesheetid’])
De stylekiezer
Stylenaam “1″ en “2″ zeggen niet veel, dus in de dropdown select box willen we zinnige namen kunnen geven aan de stylesheets.
Om de namen te koppelen aan de directory nummers gebruiken we een kleine mysql tabel:
`styleid` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`active` tinyint(1) DEFAULT ’0′,
PRIMARY KEY (`styleid`)
) TYPE=MyISAM;
Om de te kiezen stylesheets in de drop down selectbox weer te geven gebruiken we de volgende functie:
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 |
<?php
function printstylechooser($returnadress){
global $aUserInfo;
global $css_dir_nr;
if (isset ($css_dir_nr)){
$q="SELECT * FROM style WHERE active=1";
if (!$r=mysql_query($q))
echo 'failed to select styles'.mysql_error();
echo '<select name="style" onchange="location.href=this.options[this.selectedIndex].value">';
while ($a=mysql_fetch_assoc($r)){
echo '<option ';
if (isset ($_GET['stylesheetid'])){
if ($_GET['stylesheetid']==$a['styleid'])
echo ' selected="selected" ';
}elseif (isset ($_COOKIE['stylesheetid'])){
if ($_COOKIE['stylesheetid']==$a['styleid'])
echo ' selected="selected" ';
}elseif (isset ($aUserInfo)){
if ($aUserInfo['stylesheetid']==$a['styleid'])
echo ' selected="selected" ';
}elseif ($a['styleid']==1) //DEFAULT STYLESHEET IS NR 1
echo ' selected="selected" ';
echo 'value="'.$returnadress.'?stylesheetid='.$a['styleid'].'">'.$a['name'].'</option>';
}
echo '<option ';
if ((isset ($_GET['stylesheetid']) && $_GET['stylesheetid']==0) || (isset ($_COOKIE['stylesheetid']) && $_COOKIE['stylesheetid']==0) || (isset ($aUserInfo) && $aUserInfo['stylesheetid']==0))
echo ' selected="selected ';
echo 'value="'.$returnadress.'?stylesheetid=0">Random</option>';
echo '</select>';
}
}
?>
|
de laatste optie is optie 0: een random stylesheet. Het is een extratje wat waarschijnlijk niet gebruikt gaat worden, maar toch leuk voor de heb.
aan deze functie kun je een aantal dingen opmerken:
- we hebben een variabele $css_dir_nr nodig om hem te laten werken
- het gekozen style_dir_nr wordt voorgeselecteerd in de select box
- na een keuze van de gebruiker wordt de gekozen stylesheet doorgegeven als nummer in de url. Dus na het klikken in de style-kiezer wordt men doorverwezen naar bijvoorbeeld index.php?stylesheetid=1.
- de variabele $returnadress wordt gebruikt om de styleswitcher op verschillende pagina’s te kunnen weergeven en de gebruiker na keuze terug te laten keren naar deze specifieke pagina.
$css_dir_nr
De variabele $css_dir_nr is de door de user gekozen stylesheet, deze moet bekend zijn voordat de pagina geladen wordt en wordt gebruikt om
- in de stylesheet selector de huidige keuze te voorselecteren (zoals we net gezien hebben)
- de juiste stylesheet te laden (duh)
Voor het bepalen van het juiste directory nummer gebruiken we de volgende functie:
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 |
<?php
function stylesheetselector(){
global $cssnr;
global $aUserInfo;
//set new stylesheet
if (isset ($_GET['stylesheetid'])){
if (isset ($aUserInfo)){
$q="UPDATE account SET stylesheetid=".$_GET['stylesheetid']." WHERE account_id=".$aUserInfo['account_id'];
if (!$r=mysql_query($q))
die ('Failed to select stylesheet'.mysql_error().$q);
$aUserInfo['stylesheetid']=$_GET['stylesheetid'];
}
setcookie('stylesheetid',$_GET['stylesheetid'],time()+60*60*24*7);
}
//which one should be loaded?
if (isset ($_GET['stylesheetid']) && $_GET['stylesheetid']!=0)
$cssnr=$_GET['stylesheetid']; //this step is needed because the cookie is set but not available until next pageload
elseif (isset ($_COOKIE['stylesheetid']) && $_COOKIE['stylesheetid']!=0){
$cssnr=$_COOKIE['stylesheetid'];
}elseif (isset ($aUserInfo['stylesheetid']) && $aUserInfo['stylesheetid']!=0)
$cssnr=$aUserInfo['stylesheetid'];
elseif ((isset ($_GET['stylesheetid']) && $_GET['stylesheetid']==0) || (isset($_COOKIE['stylesheetid']) && $_COOKIE['stylesheetid']==0) || (isset ($aUserInfo['stylesheetid']) && $aUserInfo['stylesheetid']==0)){
//stylesheet is set to random
if (!$r=mysql_query("SELECT styleid FROM style WHERE active=1"))
enot ('Failed to select stylesheet'.mysql_error(),1);
else{
$max=mysql_num_rows($r);
$cssnr=rand(1,$max);
}
}else{
//set stylesheet to default
$cssnr=1;
}
}
?>
|
Beide hier besproken functies slaan we op in functions.php.
Actie
Om nu de zaak in actie te zien hoeven we eigenlijk maar 2 dingen te doen:
- verschillende stylesheets maken en deze in de bovenaan genoemde directorystructuur te zetten
- de mysql tabel te updaten met de aanwezige stylesheets (en ze hier ook benamen)
files
Hoe zien de files er nu uit na afloop.
index.php & archive.php
001 002 003 004 005 006 |
<?php
$thiscssfile=$_SERVER['PHP_SELF'];
include ('top.php');
printstyleselector('index.php');
?>
|
top.php
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 |
<?php
include_once ('functions.php');
stylesheetselector();
?>
<head>
<?php
echo '<link href="style/'.$css_dir_nr.'/css/1.php';
if (isset ($thiscssfile)){
$thiscssfile=str_replace('/moraalridder/','',$thiscssfile);
$thiscssfile=str_replace('.php','',$thiscssfile);
echo '?file='.$thiscssfile;
}
echo '" rel="stylesheet" type="text/css" />';
?>
</head>
<body>
|
Categories:
Tags: |