Forum CMS Made Simple FR

Version complète : [Résolu]Mettre un menu sur 2 colonnes
Vous consultez actuellement la version basse qualité d’un document. Voir la version complète avec le bon formatage.
Pages : 1 2

Yvan

Citation :#~~~~~ NE PAS SUPPRIMER CE BLOC ~~~~~
#~ Version du CMS : 1.7.0
#~ Version du MLE si existante : Nope
#~ Informations Système :
#~ ----------------------------------------------
#~ Cms Version: 1.7
#~ Installed Modules:
#~ * CMSMailer: 1.73.14
#~ * FileManager: 1.0.2
#~ * MenuManager: 1.6.2
#~ * ModuleManager: 1.3.3
#~ * News: 2.10.4
#~ * nuSOAP: 1.0.1
#~ * Printing: 1.0.4
#~ * Search: 1.6.2
#~ * ThemeManager: 1.1.1
#~ * TinyMCE: 2.6.5
#~ * FrontEndUsers: 1.8.2
#~ * CustomContent: 1.5.3
#~ * CGExtensions: 1.18.3
#~ * CGCalendar: 1.5.2
#~ Config Information:
#~ * php_memory_limit:
#~ * process_whole_template: false
#~ * max_upload_size: 48000000
#~ * default_upload_permission: 664
#~ * assume_mod_rewrite: true
#~ * page_extension: /
#~ * internal_pretty_urls: false
#~ * use_hierarchy: true
#~ Php Information:
#~ * phpversion: 5.2.13
#~ * md5_function: On (Vrai)
#~ * gd_version: 2
#~ * tempnam_function: On (Vrai)
#~ * magic_quotes_runtime: Off (Faux)
#~ * E_STRICT: 0
#~ * memory_limit: 64M
#~ * max_execution_time: 10
#~ * safe_mode: Off (Faux)
#~ * session_save_path: Aucune vérification à cause de la restriction spécifiée par PHP open_basedir
#~ * session_use_cookies: On (Vrai)
#~ Server Information:
#~ * Server Api: apache2handler
#~ * Server Db Type: MySQL (mysql)
#~ * Server Db Version: 5.0.84
#~ ----------------------------------------------
#~~~~~ NE PAS SUPPRIMER CE BLOC ~~~~~
Bonjour,

J'avais écrit un code tout simple pour liste certaines pages de mon site (très similaire au minimal_menu.tpl) :

{if $count > 0}

{foreach from=$nodelist item=node}
{if $node->depth > $node->prevdepth}
{repeat string="<ul>" times=$node->depth-$node->prevdepth}
{elseif $node->depth < $node->prevdepth}
{repeat string="</li></ul>" times=$node->prevdepth-$node->depth}
</li>
{elseif $node->index > 0}</li>
{/if}

{if !isset($start_level)}
{assign var="start_level" value=$node->depth}
{/if}

{if $node->depth == $start_level and $node->type != 'sectionheader' and $node->type != 'separator'}
<h3 id="titre_membres">{$node->menutext}</h3>

{elseif $node->depth == $start_level+1 and $node->type != 'sectionheader' and $node->type != 'separator'}
<li><a href="{$node->url}"{if $node->target ne ""} target="{$node->target}"{/if}> {$node->menutext} </a>

{/if}

{/foreach}
</div>
{/if}

Mais comme le résultat est long et pas très large, j'aimerais maintenant faire 2 colonnes avec le résultat. Problème : ben... je vois pas comment faire.

Mon idée était de faire une 1ère itération et compter les entrées qui m'intéressaient pour prendre la moitié. Déjà, je ne suis pas sûr de la façon dont je peux compter. J'ai l'impression qu'incrémenter en Smarty est une très mauvaise idée. Je devrais alors utiliser une balise utilisateur, mais je ne vois pas comment.
Après je devrais recommencer l'itération et l'incrémentation dans la 1ère colonne et y mettre mes node. Au moment où je tombe sur un node avec $node->depth == $start_level et que l'incrémentation a dépassé le nombre de node qui m'intéresse, je devrais fermer la 1ère colonne et commencer la 2ème.

J'ai beau réfléchir, je ne vois pas comment faire. Quelqu'un aurait-il une idée ?
Tout dépend de l'affichage souhaité mais c'est réalisable en Css.

si tu souhaite avoir

menu1 menu5
menu2 menu6
menu3 menu7
menu4

ou

menu1 menu2
menu3 menu4
menu5 menu6
menu7

Le second est réalisable en CSS

Yvan

Je pensais plutôt à la 1ère...
donc pas le choix, tu passes par ta première solution : double looping

incrémenter en smarty n'est pas bien complexe, regarde un peu sa doc pour t'inspirer

Yvan

Merci. J'avais manqué le {counter}.
Par contre, quand j'écris ceci :

{assign var="tot" value='($numColl+2*$numCan)/2'}
{eval var=$tot}

J'obtiens comme résultat : ($numColl+2*$numCan)/2... or j'aimerais plutôt avoir un nombre.
Comment faire ?

Yvan

Ok, j'ai trouvé: {assign var=tot value=$numColl*0.5+$numCan}

Mais il est absurde, ce langage. Déjà dans la doc, ils mettent des guillemets ou des apostrophes autour des expressions au petit bonheur la chance. Ensuite, il faut écrire le calcul exactement comme je l'ai fait, sinon ça marche pas. Pas de parenthèses, ne pas commencer avec un chiffre... J'ai pas trouvé toutes ces règles dans la doc !

Bon, si ça intéresse quelqu'un, mon code ressemble à ça. Si tu as des remarques, Bess (ou autres), elles sont les bienvenues:

{* CSS classes used in this template:
.currentpage - The active/current page
.bullet_sectionheader - To style section header
hr.separator - To style the ruler for the separator *}

{if $count > 0}

{counter start=0 name=coll assign=numColl}
{counter start=0 name=can assign=numCan}

{foreach from=$nodelist item=node}

{if !isset($start_level)}
{assign var="start_level" value=$node->depth}
{/if}

{if $node->type != 'sectionheader' and $node->type != 'separator'}
{if $node->depth == $start_level}
{counter name=can}
{elseif $node->depth == $start_level+1}
{counter name=coll}
{/if}
{/if}

{/foreach}


À ce jour, il y a {eval var=$numColl} collectivités membres réparties dans {eval var=$numCan} cantons:

{assign var=tot value=$numColl*0.5+$numCan}

{assign var=change value=0}
{counter start=0 name=nod assign=numNode}
<div class="liste_membres">
<div class="liste_colonne1">

{foreach from=$nodelist item=node}

{if $node->depth > $node->prevdepth}
{repeat string="<ul>" times=$node->depth-$node->prevdepth}
{elseif $node->depth < $node->prevdepth}
{repeat string="</li></ul>" times=$node->prevdepth-$node->depth}
</li>
{elseif $node->index > 0}
</li>
{/if}

{if $node->depth == $start_level and $node->type != 'sectionheader' and $node->type != 'separator'}
{if $numNode>=$tot && $change==0}
</div>
<div class="liste_colonne2">
{assign var=change value=1}
{/if}
{counter name=nod}
{counter name=nod}
<h3 id="titre_membres">{$node->menutext}</h3>

{elseif $node->depth == $start_level+1 and $node->type != 'sectionheader' and $node->type != 'separator'}
{counter name=nod}
<li><a href="{$node->url}"{if $node->target ne ""} target="{$node->target}"{/if}> {$node->menutext} </a>
{/if}

{/foreach}

</div> {*2ème colonne*}
</div> {*liste_membres*}
</div>

{/if}

PS: apparemment, il faut fermer un <div> à la fin que je n'ai pas ouvert dans mon menu. Comment ça se fait ???
euuh aucune idée :/

Yvan

En fait le </div>, c'était faux: j'ai remarqué un bug d'affichage dans le cadre du contenu... Si je l'enlève, le menu s'affiche où il faut, mais dépasse du cadre du contenu, comme si ce dernier était vide.
En fait, pour afficher comme je voulais, j'ai dû mettre un float:right; pour le div.liste_membres. Mais je ne suis pas sûr de comprendre la logique, ni si c'est une solution très robuste.
(J'ai mis ça, pour être exact:
div.liste_membres {
margin: 2em 0em;
float:right;
width:96%;
} )

Si je mets un minimal_menu, par exemple, le cadre du contenu est nickel.

Dans mon code, qu'est-ce qui fait que mon menu dépasse du contenu sans un float:right ?
avec une url à tester je saurais mieux te répondre.

retire le [résolu] si tu n'es pas encore satisfait

Yvan

www.coord21.ch/test_cmsms

Sur l'accueil, il y a un lien pour la liste des membres.

Mis à part ça, je me rends compte que ma solution est pas terroche... je vais regarder s'il y a pas moyen de faire un tableau de counter pour mettre faire deux colonnes pour chaque canton (ou catégorie). ça donnera mieux, surtout quand il y aura plus de monde dans la liste.
bha il est beau ton tableau ? sous FF en tout cas aucun pb d'écart quelconque
Pourquoi ne pas faire dans la boucle smarty de base un test de pair/impair avec « is [not] even » ?

Ton HTML :
Code :
<ul>
<li class="left"><a href="#">Lien 1</a></li>
<li class="right"><a href="#">Lien 2</a></li>
<li class="left"><a href="#">Lien 3</a></li>
<li class="right"><a href="#">Lien 4</a></li>
</ul>
Ton CSS :
Code :
ul {
display : block ;
overflow : auto ;
width : 200px ;
}

ul li {
display : block ;
width : 100px ;
height : 35px ;
}

ul li.left {
float : left ;
}

ul li.right {
float : right ;
}
Ton menu Smarty :
Code :
{if $count > 0}
<ul>
{assign var="num" value=1}
{foreach from=$nodelist item=node}

{if $node->type != 'sectionheader' and $node->type != 'separator'}
<li class="{if $num is even}right{else}left{/if}"><a href="{$node->url}"{if $node->target ne ""} target="{$node->target}"{/if}>{$node->title}</a></li>
{/if}
{assign var="num" value=$num+1}
{/foreach}
</ul>
{/if}
Dis moi si ça fonctionne. Ca permet d'alterner le style (left/right) et donc positionner le li à droite ou à gauche.
Enfin j'ai fais ça de tête, je n'ai pas testé.

Yvan

bess a écrit :bha il est beau ton tableau ? sous FF en tout cas aucun pb d'écart quelconque
Avec le float:right, ça donne bien. Mais ce que je sais pas, c'est si c'est robuste, si ça va pas changer avec une autre résolution ou autre...

Yvan

kraygoon a écrit :Dis moi si ça fonctionne. Ca permet d'alterner le style (left/right) et donc positionner le li à droite ou à gauche.
Enfin j'ai fais ça de tête, je n'ai pas testé.
Cool, je vais regarder. J'ai pas pensé à toucher aux <li>. mais si ça peut m'éviter de construire un tableau de compteur, c'est pas plus mal ! Merci

Yvan

Alors, le truc des li alignés à gauche ou à droite, ça fonctionne pas, puis qu'ils passent à la ligne de toute façon.

Je vais donc essayer la chose suivante:
- créer un tableau avec la longueur désirée pour mes tableaux (la moitié de page fille pour chaque page)
- après chaque page, faire deux listes en float left qui contiendront chacun la moitié des pages filles

C'est drôlement compliqué, mais ça devrait marcher.

Juste une question sur les arrays en Smarty, pour voir si j'ai bien compris:
Pour rajouter une entrée, je fais $array->append($i,$numNode) et pour récupérer la valeur je peux utiliser simplement $array[$i]. J'ai bien compris ? Est-ce que je dois déclarer $array avant ?

EDIT: dans le sujet des menus, j'aimerais savoir quelque chose d'autre:
Comment peut-on spécifier pour un lien externe qu'on veut qu'il s'ouvre dans un autre onglet ?

xX WeI Xx

"Comment peut-on spécifier pour un lien externe qu'on veut qu'il s'ouvre dans un autre onglet ?"

Il me semble que c'est au souhait de l'utilisateur vis à vis de son navigateur.
le point qui concerne le menu sort du context initial Yvan. fait en un autre sujet si besoin. (pour info la balise<a target="_blank"> fait ce que tu recherche mais elle n'est pas compilante Xhtml 1.0 strict)

Yvan

Est-ce que quelqu'un pourrait me dire comment on fait pour créer un tableau et ajouter des entrées ??? J'en peux plus de cette doc Smarty, elle est franchement foireuse ! J'y comprends rien !

Dans une boucle foreach, j'aimerais ajouter des entrées dans un nouveau tableau. Je pourrais ajouter des chiffres les uns après les autres, mais je pourrais aussi ajouter des couples (clé, chiffre) si c'est nécessaire.
Est-ce que je dois initialiser le tableau avant la boucle ? Comment faire simplement ajouter une valeur à la fin ? Comment faire pour appeler la xème entrée du tableau ? Je voulais utiliser 'append' mais j'y arrive pas.

Quelqu'un pourrait m'aider ?

EDIT: j'arrive à rien avec Smarty. C'est juste incompréhensible. Mais pour mettre des opérations mathématiques et jouer avec des tableaux, j'ai meilleur temps de le faire en PHP, non ? Comment puis-je ajouter du code PHP dans mon gabarit de menu ?

Yvan

Bon, j'imagine que je suis tellement à la ramasse que personne ne voit vraiment où je veux en venir. Alors, voilà ce que j'ai mis dans un gabarit de menu (au début) pour récupérer le nombre de pages et de leurs pages filles :

{if $count > 0}

<?php
$total_coll=0;
$numCan=0;
$numColl=0;
$tableau = array();
?>
{foreach from=$nodelist item=node}

{if !isset($start_level)}
{assign var="start_level" value=$node->depth}
{/if}

{if $node->type != 'sectionheader' and $node->type != 'separator'}
{if $node->depth == $start_level}
<?php
$total_coll += $numColl;
$numCan++;
$array[$numCan] = $numColl/2;
$numColl=0;
?>
{elseif $node->depth == $start_level+1}
<?php
$numColl++;
?>
{/if}
{/if}

{/foreach}

{assign var="total_coll" value=$total_coll+$numColl}

<p>À ce jour, il y a {eval var=$total_coll} collectivités membres réparties dans {eval var=$numCan} cantons:</p>

ça me semblait bien, sauf que c'est pas le cas. Est-ce qu'il me faut mettre des balises utilisateurs à la places des balises php ? Y a pas moyen de tout mettre dans ce gabarit ? Parce que ça risque d'être vraiment pas clair si j'ai treize petites balises utilisateurs à gauche à droite. Et difficile à modifier...

Quelqu'un aurait-il un conseil ?

Yvan

Up. J'ai beau persévérer, Smarty reste tjs aussi mystérieux. Comment faire créer un tableau et le remplir ? Je suis quand même pas le seul qui essaye de faire ce genre de truc !?
Je pensais utiliser quelque chose du genre :
{assign var="tableau[$numCan]" value=$numColl*0.5}
Mais bien sûr, ça marche pas du tout. Quelqu'un pourrait-il m'aiguiller ?
re,

>Smarty reste tjs aussi mystérieux
la doc !!! http://www.smarty.net/manual/fr/

Yvan

Mais je sais !!!
Seulement, j'y ai pas trouvé mes réponses. Y avait bien la méthode 'append', mais j'en suis venu à la conclusion qu'il faudrait me contenter des fonctions utilisateurs et natives.
Ajouter un élément dans un tableau: aucune idée ! Et pourtant, c'est la base. ça devrait se trouver au début, en gras, mais non.
Est-ce qu'il faut que j'utilise des balises {php} pour créer un tableau ? Si non, comment faire ?
smarty dans son utilisation des tag est destiné principalement a l'affichage dans un template (gabarit chez cmsms) et non a remplir le rôle premier du PHP.

pour remplir un tableau, faire un algo, fouiller les fichiers, lire un flux de donnée : faire une balise utilisateur en PHP pur

pour préparer les variables du gabarits : utilise comme ce que j'ai expliqué dans ton autre sujet les solutions de smarty : $smarty->assign()

pour afficher une valeur, pour afficher une itération de valeur d'un tableau, pour colorier une ligne sur deux, .... dans ton gabarit : utilise les tag smarty


voilà.

Yvan

Re bonjour !

Merci bcp pour ce petit topo. J'ai écouté tes conseils et j'ai repris mon code. Côté php et smarty, tout roule, mais maintenant, je suis perdu avec le css...

Depuis mon gabarit de menu, je construit une série de <div> avec à l'intérieur un titre, suivi de deux listes <ul> de classes différentes. J'aimerais qu'elles s'affichent l'une à côté de l'autre, depuis la gauche. Mais je n'y arrive pas !

Je pensais utiliser des float:left sur les <ul> afin qu'ils se mettent l'un à côté de l'autre, mais ça ne fonctionne pas parfaitement, car les titres suivants se décalent sur la droite, tandis qu'ils ne passent pas à la ligne s'il y a encore de la place (pas de 2ème colonne).

Voyez par vous-mêmes:
http://www.coord21.ch/test_cmsms/liste-d...e-coord21/

Je suis vraiment navré de vous embêter avec ça, mais j'ai passé l'après-midi à essayer de comprendre la raison de ces problèmes, mais je ne vois définitivement pas. En plus, j'ai un bug d'affichage en bas qui vient de je-ne-sais-où !

Voici le code de mon menu, au cas où:

{if $count > 0}

{menu_count start_level=$start_level nodelist=$nodelist}

À ce jour, il y a {eval var=$total_coll} collectivités membres réparties dans {eval var=$numCan} cantons:

{assign var=open value=0}
{assign var=droite value=0}
{counter start=0 name=canton assign=numCan}
{counter start=0 name=collec assign=numColl}
<div class="liste_membres">

{foreach from=$nodelist item=node}

{if !isset($start_level)}
{assign var="start_level" value=$node->depth}
{/if}

{if $node->depth == $start_level and $node->type != 'sectionheader' and $node->type != 'separator'}
{if $open==1}
{assign var=droite value=0}
{counter start=0 name=collec assign=numColl}
</ul> </div>
</div>
{/if}

<div class="canton">
{assign var=open value=1}
{counter name=canton}
<h3 id="titre_membres">{$node->menutext}</h3>
<div>
<div class="liste_gauche"> <ul>

{elseif $node->depth == $start_level+1 and $node->type != 'sectionheader' and $node->type != 'separator'}

{counter name=collec}

{if $numColl > $tableau_coll.$numCan && $droite==0}
</ul> </div>
<div class="liste_droite"> <ul>
{assign var=droite value=1}
{/if}

<li><a href="{$node->url}"{if $node->target ne ""} target="{$node->target}"{/if}>{$node->menutext}</a></li>

{/if}

{/foreach}

</ul> </div> </div> {*dernière liste, dernier div classe gauche ou droite, dernier div}

</div> {*dernier canton*}
</div> {*liste_membres*}

{/if}

Et un bout de mon CSS:

div.liste_gauche,
div.list_droite {
float:left;
width: 320px;
}

Quelqu'un aurait-il une intuition salutaire ?
revérifie ton algo, moi j'ai en résultat

div 1
- liste gauche
- liste droite
- div 2
- liste gauche
- liste droite
- div 3
- liste gauche
- ...

déjà une première erreur avant de corriger la suite
Pages : 1 2