Menus Xoops compatibles CSS
Catégorie : Thèmes et templates

Une premiêre approche fut l'intégration du menu DHTML TigraMenu. S'il la présentation est conforme à  nos attentes, cette solution comporte un nombre trop élevé d'améliorations possible .Un menu DHTML nécessite l'exécution de code Javascript. Les visiteurs ayant désactivés cette fontionnalité de leurs navigateurs ne peuvent exploiter les sous menus. Outre le contenu du menu, il est batît avec un volume de code important. L'utilisation de DHTML et donc le dessin dans le navigateur nécessite un positionnement fixe et donc difficile dans de l'entête. Un défaut d'affichage survient lorsque les options des sous menus recouvrent une image ou un fichier média.

Une seconde approche n'utilisait plus de DHTML et se rapprochait de notre objectif. Elle est décrite dans cet article

Ce menu utilise encore un peu de Javascript pour repositionner les éléments des listes. Mais le pods de la soluction a été sensiblement réduit. Le positionnement est plus précis mais le défaut d'affichage perdure.

Enfin, le troisiême opus est un aboutissement :

Etape 1 : préparer le thême

Nous visions un thême XHTML/CSS complet mais avons du renoncer. Par conséquent, pour l'organisation des colonnes nous contenuons à  utiliser une table comme le font la majorité des thêmes. Mais, pour l'organisation de l'entête, du conteneur et du pied nous avons utilisé la structure XHTML décrite dans cet article. Le menu comporte sa propre feuille de style (pour plus de clareté) et est intégré au thême par une balise Div « navcontainer ». De la même maniêre le contenu de cette balise est disposé dans un fichier HTML dédié importé dans le fichier principal.

Le fichier CSS

Dans notre feuille de style nous utilisons 100% de la largeur de la fenêtre via les balises #header et #conteneur.

#header contiendra le menu. Les dimensions du menu sont fonction de la hauteur de sa police fixée en 'em'. Cela lui permet de s'adapter aux utilisateurs utilisant l'accessibilité (agrandissement des polices par le navigateur). Par conséquent, #header ne comporte pas de hauteur fixe.

/* fixe les polices du thême */
body { 
background-color: #F4F4F4;
color: black;
font: 0.9em Verdana, "Trebuchet MS", "MS Sans Serif";
}
/* Bloc entête */
#header {
width:100%;
background-color: #F4F4F4;
}
/* Logo dans l'entête */
#logo {
background-image: url("images/logo.gif");
background-repeat: no-repeat;
padding-top: 10px;
margin-left: 10px;
width: 150px;
height: 80px;
float: left;
}
/* Banniêre dans l'entête */
#banniere {
float: right;
width: 468px;
height: 60px;
padding-right : 10px;
padding-top : 10px;
}
/* Bloc Conteneur */
#conteneur {
width:100%;
margin:0 auto;
background-color:white;
}
/* Bloc Centre*/
#centre {
}
/* Bloc Pied*/
#pied {
clear:both;
height: 30px;
color: #CC6666;
text-align:center;
font-size: 0.9em;
}
/* Bloc Contenu */
#content {
padding: 0; margin-top: 0;
}

/* suivent les définitions classiques issuées des thêmes 'en tables' */

Le fichier HTML :

On a séparé la feuille de style du menu de celle du thême. Il faut donc y faire appel dans le Head. Le menu est intégré à  la div Header.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<{$xoops_langcode}>" lang="<{$xoops_langcode}>">
<head>
<!-- ici le code habituel (meta xoops) -->
<title><{$xoops_sitename}> - <{$xoops_pagetitle}></title>
<link href="<{$xoops_url}>/favicon.gif" rel="SHORTCUT ICON" />
<link rel="stylesheet" type="text/css" media="screen" href="<{$xoops_url}>/xoops.css" />
<!-- inclue la feuille de style du thême -->
<link rel="stylesheet" type="text/css" media="screen" href="<{$xoops_themecss}>" />
<!-- inclue la feuille de style du menu -->
<link rel="stylesheet" type="text/css" media="all" href="<{$xoops_imageurl}>menu.css" />
<!-- RMV: added module header -->
<{$xoops_module_header}>
<script type="text/javascript">
<!--
<{$xoops_js}>
//-->
</script>
</head>
<body>
   <div id="conteneur">
<div id="header">
<div id="logo">&nbsp;</div>
<div id="banniere"><{$xoops_banner}></div>
<div id="navcontainer">
<{include file="wdforge4/menu.html"}>
</div>
</div>
<div id="centre">
<!-- Ici le code du contenu : colonnes -->
</div>
<div id="pied"><{$xoops_footer}></div>
</div>
</body>
</html>

Etape 2 : les onglets

Notre menu est réparti en deux parties : les onglets et le sous menu. Pour faciliter le positionnement respectif de ces éléments en deux lignes, nous utilisons deux divs successives et indépendantes. Cette partie est réservée à  la mise en place des onglets. Pour cela nous avons tout simplement suivit le travail d'Eric Meyer paru sur Litasmatic (http://css.maxdesign.com.au/listamatic/horizontal05.htm). Il existe beaucoup de méthodes pour construire une liste horizontale. L'ingrédient principal est "display: inline", appliqué à  une balise "LI".

1/ Créer une simple liste

Dans une liste non ordonnée, tous les éléments sont actifs, ce qui est essentiel à  son foncitonnement. Elle contient des liens <a href='#'> <a> pour lesquels des rêgles CSS édiées seront fixées.

<ul>
<li><a href="<{$xoops_url}>/">Accueil</a></li>
<li><a href="<{$xoops_url}>/modules/icontent/>Documents</a></li>
</ul>

2/ suppression des éléments graphique des listes

On utilise la définition LI de la balise identifiée « navlist »

#navlist li { list-style-type: none; }
<ul id="navlist">
<li><a href="<{$xoops_url}>/">Accueil</a></li>
<li><a href="<{$xoops_url}>/modules/icontent/>Documents</a></li>
</ul>

3/ réglage des marges (internes et externes)

La liste sera collé sur la gauche et le contenu sera décalé de 3px vers le bas.

#navlist {padding: 3px 0px; margin-left: 0;}

4/ Liste horizontale

Le dispay:inline va permettre un positionnement horizontal des options de la liste, on modifie le LI.

#navlist li { list-style-type: none; display: inline;}

5/ suppression des décorations du texte

Il s'agit du contenu des menus et donc des balises A à  l'intérieur des LI.

#navlist li a {text-decoration: none;}

6/ zones utiles des options (marges internes)

Pour créer un cadre autour de chaque lien des options du menu il faut lui créer un encadrement au moyen des marges internes (padding). Si la marge haute est fixe, on utilise une valeur proportionnelle pour la marge de droite afin d'adapter le cadre en fonciton de la taille de la police. Donner une valeur uniquement pour le haut et la droite équivaut à  fixer les 4 valeurs (raccourcis CSS). On crée aussi une marge interne fixe pour séparer les onglets.

#navlist li a {text-decoration: none; padding: 3px 0.5em;

7/ Ajout de la couleur et des bordures

Le trait en dessous des onglets pour #navlist et le contenu des options (les A)

#navlist {padding: 3px 0px; margin-left: 0; border-bottom: 1px solid #6667CC;}
#navlist li {margin: 0; list-style: none; display: inline; }
#navlist li a{ padding: 3px 0.5em; margin-left: 3px; border: 1px solid #6667CC; background: white; color:black; text-decoration: none;}

8/ Le rollover de la souris

La sous-classe hover des balises A

#navlist li a:hover {background: #F4F4F4;}

9/ centrer le texte

Cela concerne les balise UL génériques de notre feuille de style. On utilise alors l'héritage de la définition existante dans style.css de notre thême.

Style.css : ul { list-style: decimal inside; text-align: left; margin: 0px 0px; } .Cet héritage est possible car la feuille style.css est invoquée avant menu.css dans la balise HEAD de theme.html :

<head>
..
<!-- inclue la feuille de style du thême -->
<link rel="stylesheet" type="text/css" media="screen" href="<{$xoops_themecss}>" />
<!-- inclue la feuille de style du menu -->
<link rel="stylesheet" type="text/css" media="all" href="<{$xoops_imageurl}>menu.css" />
...
</head>

10/ un petit plus les arrondis sous Mozilla

Un petit truc ajouté pour un effet onglet plus propre amis qui ne passe que sous mozilla : arrondir les angles des balise A. Là  aussi on travaille en dimension proportionnelle pour conserver 'accessibilité.

#navlist li a {padding: 3px 0.5em; margin-left: 3px; border: 1px solid #6667CC; background: white; color:black; text-decoration: none;
-moz-border-radius-topleft: 0.3em;
-moz-border-radius-topright: 0.3em;
}

11/ résultat une barre d'onglets propres et accessibles :

navlist
{ clear:both; padding: 3px 0px; margin-left: 0; border-bottom: 1px solid #6667CC; font-size: 0.9em;}
#navlist li { margin: 0; list-style: none; display: inline; }
#navlist li a { padding: 3px 0.5em; margin-left: 3px; border: 1px solid #6667CC; background: white; color:black; text-decoration: none; -moz-border-radius-topleft: 0.3em; -moz-border-radius-topright: 0.3em; }
#navlist li a:hover {background: #F4F4F4;}

<ul id="navlist">
<li><a href="<{$xoops_url}>/">Accueil</a></li>
<li><a href="<{$xoops_url}>/modules/icontent/>Documents</a></li>
...
</ul>
Image1

Etape 3 : le sous menu

Il s'agit d'une liste beaucoup moins élaborée que la précédente. Généralement le sous menu est défini au sein des options du menu principal. Ses options (LI) contiennent des balises UL. Il en résulte une dépendance de position entre l'option et le sous menu. Ce point pose une difficulté quand on veux un sous menu à  position fixe. En outre, pour pallier aux problêmes de chevauchement avec des images des menus précédents, j'ai pensé placer le sous menu horizontalement dans sedonde ligne. Il devient alors três simple de le réserver dans cet espace fixe.

J'ai donc inové en créant, pour le sous menu, une balise UL indépendante de la premiêre.

1/ Créer une simple liste.

Dans une liste non ordonnée, tous les éléments sont actifs, ce qui est essentiel à  son foncitonnement. Elle contient des liens <a href='#'> <a> pour lesquels des rêgles CSS dédiées seront fixées.

<ul>
   <li><a href="<{$xoops_url}>/modules/news/">Articles</a></li>
   <li><a href="<{$xoops_url}>/modules/mydownloads/">Téléchargements</a></li>
</ul>

2/ suppression des éléments graphiques des listes

On utilise la définition LI de la balise identifiée « navlist »

#nav2 li { list-style-type: none; }
<ul id="nav2">
<li><a href="<{$xoops_url}>/">Accueil</a></li>
<li><a href="<{$xoops_url}>/modules/icontent/>Documents</a></li>
</ul>

3/ réglage des marges (internes et externes)

La liste utilisera tout l'espace

#nav2 { margin: 0; padding: 0 0 0;}

4/ Liste horizontale

Le dispay:inline va permettre un positionnement horizontal des options de la liste, on modifie le LI.

#nav2 li { list-style-type: none; display: inline;}

5/ suppression des décorations du texte

Il s'agit du contenu des menus et donc des balises A à  l'interieur des LI.

#nav2 li a {text-decoration: none;}

6/ zones utiles des options (liens)

Le sous menu est une succession de liens qui ne surchargent pas la liste. On va donc laisser transparent leur zone utile

#nav2 li a {text-decoration: none; background-color: transparent;}

7/ Ajout de la couleur et des bordures

Le menu principal ayant un trait bas, on termine l'encadrement du sous menu.

#nav2 { margin: 0;      font-size: 0.9em; padding: 0 0 0; background-color: #69C; border-left: 1px solid #6667CC; border-right: 1px solid #6667CC; border-bottom: 1px solid #6667CC;}

8/ Le rollover de la souris

Pour les options on assure simplement un effet sur les liens par un changement de couleur via les sous-classes des balises A.

#nav2 a:link, #nav2 a:visited
#nav2 a:hover, {color: white;}

9/ Centrer le texte

De la même maniêre que pour le menu principal, on utilise l'héritage de la définition existante dans le fichier style.css de notre thême pour le centrage du texte des options.

10/ Résultat

#nav2 { margin: 0; padding: 0 0 0; background-color: #69C; border-left: 1px solid #6667CC;
border-right: 1px solid #6667CC; border-bottom: 1px solid #6667CC; font-size: 0.9em; 
#nav2 li { display: inline; list-style-type: none; padding-left: 1em;}
#nav2 a:link, #nav2 a:visited { color:white; background-color: transparent; text-decoration: none;}
#nav2 a:hover { color: black; }
<ul id="nav2">
<li><a href="<{$xoops_url}>/">Accueil</a></li>
<li><a href="<{$xoops_url}>/modules/icontent/>Documents</a></li>
Sous menus css

Etape4 : exploitation du contexte Xoops

Nous somme parti d'un template Xoops. Nous y avons invoqué les définitions CSS spécifiques du menu et y avons importé le code HTML de ses listes dans une DIV ajoutée à  l'entête : Image3

Surlignons les blocs :

Image4

Nous remarquons le padding des logo et banniêre. Le clear:both; et les marges de #navlist permettent un positionnement sous ses éléments. L'encadrement du menu par ses bordures délimitent bien la zone. Le menu s'adapte si on augmente la taille de la police du nagivateur. Tout est en place. Nous allons rendre ce menu plus vivant en tenant compte des choix de l'utilisateur. Il s'agit de mettre évidence l'onglet en cours, adapter le contenu du sous menu et y surligner l'option en cours.

Des styles pour les options courantes.

Pour chacune des listes, nous définitions un style qui identifie l'option en cours.

Les onglets

Pour surligner un onglet comme l'onglet en cours, nous changeons simplement sa couleur de fond. Un petit plus est assuré en donnant la couleur de fond du sous menu au cadre bas de l'onglet pour parfaire l'effet visuel. La mise en application est possible en utilisant une classe dédiée

#navlist li a#current {background: #69C; border-bottom: 1px solid #69C;}

Les sous menus

Dans le même esprit, nous allons cette fois simplement changer la couleur du lien dans la classe dédiée :

#nav2 a#current{color:black;}

Code HTML

Il s'agit de déterminer quel est le contexte Xoops courant pour appliquer la classe adéquate. Pour ce faire, on va exploiter les variables PHP et Smarty dans un script à  ajouter au thême avant l'invocation de menu.html. Ce script, en tout début de theme.html va interpréter déterminer le module courant en en récupérant le répertoire et l'envoyer dans une smarty 'xoops_cmod' :

<{php}>
$mod = $GLOBALS['xoopsModule'];
$dirname = (isset($mod) ? $mod->getVar('dirname') :'system');
$GLOBALS['xoopsTpl']->assign( 'xoops_cmod', $dirname );
<{/php}>
<!DOCTYPE ...

Ainsi, dans menu html, on peut travailler les styles. On va évaluer le contenu de la smarty pour affecter la classe 'current' à  l'option concernée dans la liste.

<ul id="navlist">
<{if $xoops_cmod == system or $xoops_cmod == news or $xoops_cmod == mydownloads ...}>
		<li ><a href="<{$xoops_url}>/" id="current">Accueil</a></li>
	<{else}>
		<li><a  href="<{$xoops_url}>/" >Accueil</a></li>
	<{/if}>
	<{if $xoops_cmod == icontent}>
		<li id="active"><a href="<{$xoops_url}>/modules/icontent/index.php?page=131" id="current">Documents</a></li>
	<{else}>
		<li><a href="<{$xoops_url}>/modules/icontent/index.php?page=131">Documents</a></li>
	<{/if}>
...

De la même maniêre pour le sous menu mais cette fois ci, avec le test dans la construction du lien

<ul id="nav2">
<{if $xoops_cmod == system or $xoops_cmod == news or $xoops_cmod == mydownloads ...}>
	<li><a href="<{$xoops_url}>/modules/news/" <{if $xoops_cmod == news}>id="current"<{/if}>>Articles</a></li>
	<{if $xoops_cmod == news}><li><a href="<{$xoops_url}>/modules/news/submit.php" class="new">&nbsp;</a></li><{/if}>
	<li><a href="<{$xoops_url}>/modules/mydownloads/" <{if $xoops_cmod == mydownloads}>id="current"<{/if}>>Téléchargements</a></li>

Un plus : le 'bouton' pour les soumission.s Il s'agit généralement de submit.php dans les modules. On va utiliser une image de 20 pixels de large en fond d'un lien et utiliser alors le padding.

Le css

#nav2 a.new {
	background-image: url(images/new.gif);
	background-repeat: no-repeat;
	padding-left: 10px;
	padding-right: 10px;
}

Le html

<ul id="nav2">
<{if $xoops_cmod == system or $xoops_cmod == news or $xoops_cmod == mydownloads ...}>
	<li><a href="<{$xoops_url}>/modules/news/" <{if $xoops_cmod == news}>id="current"<{/if}>>Articles</a></li>
	<{if $xoops_cmod == news}><li><a href="<{$xoops_url}>/modules/news/submit.php" class="new">&nbsp;</a></li><{/if}>
	<li><a href="<{$xoops_url}>/modules/mydownloads/" <{if $xoops_cmod == mydownloads}>id="current"<{/if}>>Téléchargements</a></li>

Etape 5 (et finale) : Le menu utilisateur

Grand classique de nos réalisations, le menu utilisateur est inclus au menu général sous la forme d'un onglet indiquant le pseudo et d'un sous menu des options adaptées à  son profil. Ilne fonctionne qu'avec le hack du nombre de message dans header.php à  la ligne 90 :

if ($xoopsUser != '') {
// début modification 
	$pm_handler =& xoops_gethandler('privmessage');
	$criteria = new CriteriaCompo(new Criteria('read_msg', 0));
	$criteria->add(new Criteria('to_userid', $xoopsUser->getVar('uid')));
	$xoopsTpl->assign('nbrepm', $pm_handler->getCount($criteria));
//fin modification
	$xoopsTpl->assign(array('xoops_isuser' 

Le menu utilisateur est résumé dans par l'utilisation de quelques scripts du module 'system'. Pour les identifier nous devons alors utiliser, en plus de $dirname construite dans le script en début de theme.html, la smarty xoops $SCRIPT_NAME. Elle contient le nom du script en cours en partant de la racide du site. S'il est déposé à  la racine du domaine, la variable ne contiendra que le seul nom du script php. Sinon, elle contient aussi le nom du répertoire dans lequel est déposé xoops.

Exemples
accueil (index.php) d'un xoops déposé en racine :

<{$SCRIPT_NAME}> => index.php
accueil (index.php) d'un xoops déposé dans le répertoire racine/rep1/rep2/ :
<{$SCRIPT_NAME}> => rep1/rep2/index.php

Il faut impérativement tenir compte de cette notion lors de l'envois du thême.html sur le serveur. En effet, le chemin de la copie de test peut différer de cette de la version réelle de votre site. Les scripts du menu utilisateur sont : readpmsg.php, viewpmsg.php, user.php, edituser.php, userinfo.php et register.php. Si nous sommes sur l'un de ces scripts, nous allons donc, dans theme.html affecter la valeur 'user' à  la smarty <{$xoops_cmod }> :

<{php}>
$mod = $GLOBALS['xoopsModule'];
$dirname = (isset($mod) ? $mod->getVar('dirname') :'system');
$GLOBALS['xoopsTpl']->assign( 'xoops_cmod', $dirname );
<{/php}>
<{if ($xoops_cmod==system)}>
	<{if ($SCRIPT_NAME == "/readpmsg.php" or $SCRIPT_NAME == "/viewpmsg.php" or $SCRIPT_NAME == "/user.php" or $SCRIPT_NAME == "/edituser.php" or $SCRIPT_NAME == "/userinfo.php" or $SCRIPT_NAME == "/register.php")}>
	<{php}>
	$GLOBALS['xoopsTpl']->assign( 'xoops_cmod', 'user' );
	<{/php}>
	<{else}>
	<{/if}>
<{/if}>
<!DOCTYPE...

Pour finir, le code html dédié au menu utilisateur. Il affiche le nombre de messages privés en attente de lecture et transforme donc le lien

Onglets

<ul id="navlist">
...
<{if $xoops_cmod == user}>
		<{if $xoops_isuser}>
			<{if $nbrepm>0}>
				<li ><a href="<{$xoops_url}>/viewpmsg.php" id="current"><{$xoops_uname}>:<{$nbrepm}></a></li>
			<{else}>
			<li><a href="<{$xoops_url}>/viewpmsg.php" id="current"><{$xoops_uname}></a></li>
			<{/if}>
		<{else}>
			<li><a href="<{$xoops_url}>/register.php" id="current">S'enregistrer</a></li>
		<{/if}>
	<{else}>
		<{if $xoops_isuser}>
			<{if $nbrepm>0}>
				<li><a href="<{$xoops_url}>/viewpmsg.php" ><{$xoops_uname}>:<{$nbrepm}></a></li>
			<{else}>
			<li><a href="<{$xoops_url}>/viewpmsg.php" ><{$xoops_uname}></a></li>
			<{/if}>
		<{else}>
			<li><a href="<{$xoops_url}>/register.php" >S'enregistrer</a></li>
		<{/if}>
	<{/if}>
</ul>

Sous menus

<ul id="nav2">
...
<{if $xoops_cmod == user}>
	<{if $xoops_isuser}>
		<{if $xoops_isadmin}>
			<li><a href="<{$xoops_url}>/admin.php">Administration</a></li>
		<{/if}>
		<li><a href="<{$xoops_url}>/user.php">Votre compte</a></li>
		<{if $nbrepm>0}>
			<li><a href="<{$xoops_url}>/viewpmsg.php">Messagerie:<{$nbrepm}></a></li>
		<{else}>
			<li><a href="<{$xoops_url}>/viewpmsg.php">Messagerie</a></li>
		<{/if}>
		<li><a href="<{$xoops_url}>/user.php?op=logout">Deconnexion</a></li>
	<{else}>
		&nbsp;
	<{/if}>
<{/if}>
</ul>

Conclusion

Nous remercions les xoopsiens Christian, TheCat, DenisDlu pour leurs participations diverses à  la réalisation de ce menu. Pour information, nous vous indiquons qu'il est possible de décliner le format des onglet à  l'aide des três bons guides disponibles (en anglais) à  l'adresse suivante Listamatic de maxdesign
Pour vos remerciements, nous vous laissons le soins de référencer notre site sur les votres : Image5

<a href="http://creativecommons.org/licenses/by-nc-sa/2.0/fr/" title="Licence, certains droits réservés"><img src="http://www.frxoops.org/images/cdr_bouton.gif" alt="Licence, certains droits réservés" /></a>