Sélecteur de style dans un thème

Depuis peu j'ai mis en place un petit système qui permet de faire varier le style du thème utilisé ici en fonction de la saison actuelle ou au libre choix de l'utilisateur. Pour obtenir ceci je suis parti du thème de base (FallSeason), et j'ai choisi de faire varier uniquement les images utilisées pour l'entête, les fonds de menu et les puces. Voyons comment implémenter un tel fonctionnement[1].

Préparation des styles

Première étape, identification des images et création des variations saisonnières. Dans le répertoire du thème nous avons un répertoire images qui contient les images originales. Dans ce répertoire nous allons créer autant de répertoires que de saison avec les noms suivants : autumn, spring, summer et winter. Dans le premier nous allons y placer les images spécifiques de la saison (entête, fonds de menu, …) déjà présentes dans ce thème — je rappelle que le thème actuel a pour objet l'automne, puis dans les autres y créer à partir d'images nouvelles ou en modifiant les images originales[2] tout en s'assurant qu'elles portent le même nom que dans le premier répertoire. Voilà à terme ce que nous devons avoir :

/themes/fallseason/images/autumn/ :
 - header.jpg
 - menu.jpg
 - currentmenu.jpg
 - puce.jpg  
/themes/fallseason/images/spring/ :
 - header.jpg
 - menu.jpg
 - currentmenu.jpg
 - puce.jpg  
/themes/fallseason/images/summer/ :
 - header.jpg
 - menu.jpg
 - currentmenu.jpg
 - puce.jpg  
/themes/fallseason/images/winter/ :
 - header.jpg
 - menu.jpg
 - currentmenu.jpg
 - puce.jpg

Ensuite il faut identifier dans le thème le ou les styles faisant appel à une des images en question et les extraires pour en faire quatre petits fichiers de style complémentaire, un par saison, soit autumn.css, spring.css, summer.css et winter.css. Ces quatre fichiers seront créés dans le répertoire principal du thème. Exemple pour l'entête. Dans le fichier style.css nous avions ceci :

#headerpic
{
    position: relative;
    height: 149px;
    background: #fff url(images/header.jpg) repeat-x bottom left;
    margin-bottom: 2px;
}

Nous allons supprimer la ligne background:…left; pour la placer dans le fichier autumn.css. Voilà ce qu'il reste dans le fichier style.css :

#headerpic
{
    position: relative;
    height: 149px;
    margin-bottom: 2px;
}

Et voilà ce que nous avons maintenant dans le fichier autumn.css :

#headerpic
{
    background: #fff url(images/autumn/header.jpg) repeat-x bottom left;
}

Cette opération est à faire pour tous les styles utilisant une des images placées dans les répertoires des saisons. Une fois terminé, il suffit de dupliquer le fichier autumn.css pour créer les fichiers spring.css, summer.css et winter.css en prenant soin au passage de modifier le nom du répertoire où se trouvent les images (voir l'exemple mis en emphase dans l'exemple ci-dessus).

Sélection du style désiré

Ensuite, il va falloir indiquer dans le fichier template.php qu'une feuille de style additionnelle doit être utilisée (celle de la saison en cours). Pour cela, dans la section <head>, juste après l'appel de la feuille de style standard, nous allons rajouter ceci :

<link rel="stylesheet" type="text/css" href="<?php dcInfo('theme'); ?>/<?php echo dcGetSeason(); ?>.css" media="screen" />

La fonction dcGetSeason(), dont vous avez remarqué la présence dans la ligne précédente, va se charger de déterminer la saison courante en fonction de la date du jour ou de fournir la saison explicitement choisie par l'utilisateur.

Le principe retenu ici est de proposer à l'utilisateur les choix suivants :

  • utiliser une saison précise et conserver ce choix pendant 3 mois dans un cookie,
  • laisser le serveur déterminer la saison actuelle et l'utiliser, choix enregistré comme tel dans un cookie pendant un an,
  • idem que précédent à la nuance près que l'utilisateur se trouve sur l'autre hémisphère (les saisons sont inversées).

Pour déterminer le choix de l'utilisateur nous allons utiliser un paramètre passé via l'URL. Ce paramètre, nommé style pourra avoir une des valeurs suivantes :

  • autumn
  • winter
  • spring
  • summer
  • default
  • antipodes

Les quatre premières permettent de forcer la saison désirée, les cinquièmes et sixièmes permettent de laisser au serveur le soin de la déterminer en fonction de la date courante, la dernière provoquant l'inversion de la saison retenue (hiver pour été, …).

La fonction qui fait (quasiment) tout

Cette fonction est créée dans le fichier prepend.php du thème (à créer s'il n'existe pas). Voilà son code :

# Gestion du style

function dcGetSeason($record = false)
{
	$styles = array('autumn','winter','spring','summer','default','antipodes');
	$dates = array(320, 621, 923, 1221);

	$today = getdate();
	$serial = $today['mon'] * 100 + $today['mday'];

	if (($serial >= $dates[0]) && ($serial < $dates[1])) { $season = 'spring'; $index = 2; }
	elseif (($serial >= $dates[1]) && ($serial < $dates[2])) { $season = 'summer'; $index = 3; }
	elseif (($serial >= $dates[2]) && ($serial < $dates[3])) { $season = 'autumn'; $index = 0; }
	else { $season = 'winter'; $index = 1; }

	if (isset($_GET['style']) && in_array($_GET['style'], $styles, true))
	{
		if ($record) {
			if ($_GET['style'] == 'default') { $period = 365; }
			elseif ($_GET['style'] == 'antipodes') { $period = 365; }
			else { $period = 92; }
			setcookie('style', $_GET['style'], time() + ($period * 24 * 3600));
			if (dc_http_cache == 1) files::touch(DC_UPDATE_FILE);
			header('Location: '.(!empty($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'],$_SERVER['HTTP_HOST']) !== false ? $_SERVER['HTTP_REFERER'] : dc_blog_url));
			exit;
		}
		if ($_GET['style'] == 'antipodes') $season = $styles[($index + 2) % 4];
		elseif ($_GET['style'] != 'default') $season = $_GET['style'];
	}
	elseif (isset($_COOKIE['style']) && in_array($_COOKIE['style'], $styles, true))
	{
		if ($_COOKIE['style'] == 'antipodes') $season = $styles[($index + 2) % 4];
		elseif ($_COOKIE['style'] != 'default') $season = $_COOKIE['style'];
	}

	return $season;
}

Que fait cette fonction ?

Elle détermine tout d'abord la saison actuelle en fonction de la date du jour[3]. Puis si un paramètre style=… est présent dans l'URL, l'extrait — et l'enregistre dans un cookie nommé style si l'argument $record de la fonction est positionné à true.

Dans le cas contraire, pas de style positionné dans l'URL, elle récupèrera le choix enregistré par l'utilisateur et en déterminera la saison correspondante. Si aucun cookie n'existe ou que celui-ci est arrivé à expiration, elle retournera la saison calculée au préalable.

Toujours dans le fichier prepend.php, à la suite de cette fonction nous rajoutons la ligne suivante :

dcGetSeason(true);

Ce qui permet d'enregistrer le choix effectué dans un cookie avant l'affichage de la page et de forcer le retour à la page d'accueil en ayant indiqué au passage que le cache est obsolète[4]. Prenez soin de placer cette ligne en dehors de toute fonction pour qu'elle soit appelée explicitement dès le début[5].

Voilà terminés les modifications et ajouts à faire dans le thème.

Donner le choix au visiteur

Dernière chose à faire préciser à l'utilisateur les différents choix qu'il a avec à chaque fois l'URL correspondante. Exemple pour un blog ayant comme URL http://www.domain.tld/ :

  • http://www.domain.tld/index.php?style=autumn pour l'automne
  • http://www.domain.tld/index.php?style=winter pour l'hiver
  • http://www.domain.tld/index.php?style=spring pour le printemps
  • http://www.domain.tld/index.php?style=summer pour l'été
  • http://www.domain.tld/index.php?style=default pour la saison courante
  • http://www.domain.tld/index.php?style=antipodes pour la saison inverse

Ces URL peuvent être indiquées dans un billet, dans une liste de la sidebar, là où vous voudrez.

Conclusion

Vous voilà doté d'un changement de style saisonnier automatique et positionnable à volonté par l'utilisateur. Vous pouvez bien sûr utiliser d'autres critères pour le changement, qu'il soit basé sur le temps (nuit/jour, mensuel, …) ou pas (catégorie d'appartenance du dernier billet, …). Les possibilités n'ont de limite que votre imagination.

Je précise que je n'ai rien inventé du tout, simplement repris des codes existants à droite et à gauche, en particulier pour la gestion et l'enregistrement du cookie qui vient en droite ligne des plugins switcher de thème disponibles pour Dotclear 1 et 2.

Notes

[1] Ce système est différent des plugins switcher de thème disponibles pour Dotclear 1 et 2 dans la mesure ou il n'est question ici que de faire varier uniquement quelques aspects de certains styles.

[2] Par exemple en faisant varier la teinte d'une image sans toucher à la saturation et à la luminosité, ce qui permet de changer uniquement la couleur dominante.

[3] J'ai choisi, par soucis de simplification, d'utiliser la même date pour chaque saison, quelque soit l'année en cours. D'après ce que j'ai pu récupérer comme informations à ce sujet, les dates retenues — 20 mars, 21 juin, 23 septembre et 21 décembre — sont celles qui reviendront le plus fréquemment dans les dix ans qui viennent.

[4] Dans le cas contraire l'utilisateur devrait attendre une mise à jour du contenu de la page pour voir son choix effectivement pris en compte.

[5] Les instructions présentes dans ce fichier (prepend.php) et non incluses dans une fonction sont exécutées avant l'affichage de la page. Si vous voulez en savoir un peu plus sur le déroulement des opérations, consultez ce billet.

Ajouter un commentaire

Les commentaires peuvent être formatés en utilisant la syntaxe Markdown Extra.

Ajouter un rétrolien

URL de rétrolien : https://open-time.net/trackback/3147

Haut de page