IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 PHP Discussion :

Système de menu [1.x]


Sujet :

PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert

    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2004
    Messages
    2 123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 123
    Par défaut Système de menu
    Bonjour,

    Afin de poursuivre mon auto-formation à symfony, j'ai tenté de créer un composant menu, l'objectif étant de bien comprendre le fonctionnement (l'utilisation d'un plugin pourrait facilité la chose mais ne m'aidera pas dans mon apprentissage )

    Voici ce que j'ai donc fait :

    Code schema.yml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Menu:
      connection: doctrine
      tableName: sfMenu
      columns:
        label:
          type: string(20)
        url:
          type: string(255)
        priority:
          type: integer
     
    # label : libellé du menu. ex: "accueil"
    # url : cible de l'item menu. ex: "http://localhost/frontend_dev.php/accueil"
    # priority : indice permettant d'ordonner les menus. ex: 1

    Code layout.php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    [...]
    <?php include_component("menu","index"); ?>
    [...]

    Le composant Menu et son template :
    Code components.class.php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class menuComponents extends sfComponents
    {
      public function executeIndex(sfWebRequest $request)
      {
        // getMenus renvoit la liste des menus ordonnés selon Priority (orderBy)
        $this->menus = Doctrine_Core::getTable('Menu')->getMenus();
     
        // affecte à currentMenu l'url demandé
        $this->currentMenu = $request->getUri();
      }
    }

    Code _index.php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <div id="menu" class="float-right">
        <ul>
          <?php
          $last = count($menus)-1;
     
          foreach ($menus as $key=>$menu) {
            echo "<li>";
            if ($menu->getUrl()==$currentMenu) {
                echo "<span class=\"menuonpage\">".$menu->getLabel()."</span>";
            } else {
                echo link_to($menu->getLabel(),$menu->getUrl());
            }
            if ($key < $last) { echo " | " ;}
            echo "</li>";
          }  
          ?>
        </ul>
    </div>

    Mon menu fonctionne bien pour un contexte donné. Cependant, je ne suis pas certain que ma méthode soit "symfony-friendly" et, comme elle tient compte d'urls absolues, elle ne fonctionne pas en dehors de son contexte (frontend_dev.php/prod/etc).

    Bref, je suis preneur de tout conseil

    Merci d'avance.

    PS: pour détailler le fonctionnement, mon menu se présente ainsi :
    accueil | blog | contact

    accueil est en gras car il s'agit de la page courante
    les autres liens (soulignés) représente les liens vers les autres pages

  2. #2
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Salut,

    J'ai cherché et abandonné...

    Le mieux serait de partir non pas sur des url mais sur des routes (et uniquement des routes).

    Tu peux récupérer la route utilisée par le parser depuis l'objet request et donc ne plus avoir le problèmes des paramètres.

    Mais il reste des difficultés au niveau des "sous" liens, imagine un lien user qui envoie sur une liste d'user, là, ça marche. Puis tu parts vers un user en particulier (pas de liens dans le menu) et ... plouf, plus de menu en évidence...

  3. #3
    Membre Expert

    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2004
    Messages
    2 123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 123
    Par défaut
    Salut,

    Merci pour ta réponse

    J'ai constaté que je pouvais récupérer la route dans le template via :
    $sf_context->getInstance()->getRouting()->getCurrentRouteName();
    ou dans actions/components :
    sfContext::getInstance()->getRouting()->getCurrentRouteName();

    Cela fonctionne bien pour les routes de type list mais je ne sais pas comment m'y prendre pour des routes de type show.

    Par exemple une des routes les plus utilisées est la suivante :
    Code routing.yml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    [...]
    pagecontent_view:
      url: /:slugname
      class: sfDoctrineRoute
      options:
        model: Content
        type: object
      param:
        module: pagecontent
        action: show
      requirements:
        sf_method: [GET]
    [...]

    Les commandes ci-dessus me renvoie bien pagecontent_view mais je ne sais pas comment récupérer le slugname correspondant, ce dernier permettant d'identifier le contenu et donc de comparer avec ceux stocker dans mon menu.

    Je me permets par la même occasion une question bonus. Si ma page d'accueil est sur la route pagecontent_view avec le slugname accueil (donc url : /accueil). Comment puis-je fais pour définir une nouvelle route qui permettrait d'afficher cette page à l'emplacement '/' (qui serait alors plus appropriée).

    J'avais imaginer configurer la route suivante mais je ne sais pas comment fournir l'information slugname à cette dernière.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    homepage:
      url:   /
      param: { module: pagecontent, action: show }
    Merci d'avance

  4. #4
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Récupérer le slug n'est pas plus difficile que le nom de la route.

    Le mieux serait dans le contrôleur de le mettre à disposition du template.

    Si non, par le même principe une fois que tu as l'instance, tu peux récupérer le sfRequest. De là, tu sais récupérer les paramètres et donc le slug.


    Pour la deuxième question, j'ai un peu l'impression que tu veux le beurre et l'argent du beurre... l'url / avec rien pour la racine (ce qui est logique).

    Et l'url /:slug pour d'autre choses, ce qui est dangereux.

    Tu fais quoi si tu as une route /login et un slug = login ?

    Bon, je ne suis pas sur d'avoir tout compris, mais si c'est ce que j'ai compris... faudrait envisager ce cas

  5. #5
    Membre Expert

    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2004
    Messages
    2 123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 123
    Par défaut
    Réponse un peu tardive mais vieux motard que jamais

    Pour la première question, voici comment j'ai fait pour passer par les routes. L'important étant de générer les routes au niveau de chaque item du menu afin d'obtenir les urls associées, l'url de la page courrante étant déjà connue.
    (suis pas sur que ce soit super optimisé mais faute de mieux...)

    Code schema.yml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Menu:
      connection: doctrine
      tableName: sfMenu
      columns:
        label:
          type: string(20)
        routename:
          type: string(255)
        paramarray:
          type: string(1024)
        priority:
          type: integer
     
    # routename est le nom de la route (cf routing.yml)
    # paramarray est le contenu du tableau de paramètre en chaine de caractèreq soit par exemple "mavar1"=>"toto"

    Code components.class.php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      public function executeIndex(sfWebRequest $request)
      {
        $this->menus = Doctrine_Core::getTable('Menu')->getMenus();
     
        $this->currentPage = $request->getUri();
    }

    Code _index.php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <div id="menu" class="float-right">
        <ul>
          <?php
          $last = count($menus)-1;
     
          foreach ($menus as $key=>$menu) {
            //cast de la chaine de caractère en array
            eval('$mymenuparam = array('.$menu->getParamarray(ESC_RAW).');');
     
            // génération de l'url en fonction de la route et des paramètres
            $mymenuurl = url_for($menu->getRoutename(),$mymenuparam,true);
     
            echo "<li>";
            if ($mymenuurl==$currentPage) {
                echo "<span class=\"menuonpage\">".$menu->getLabel()."</span>";
            } else {
                echo '<a href="'.$mymenuurl.'">'.$menu->getLabel().'</a>';
            }
            if ($key < $last) { echo " | " ;}
            echo "</li>";
          }  
          ?>
        </ul>
    </div>

    Maintenant, quelque soit le contexte, je suis capable d'identifier la page et donc son item dans le menu



    Citation Envoyé par Michel Rotta
    Pour la deuxième question, j'ai un peu l'impression que tu veux le beurre et l'argent du beurre... l'url / avec rien pour la racine (ce qui est logique).

    Et l'url /:slug pour d'autre choses, ce qui est dangereux.

    Tu fais quoi si tu as une route /login et un slug = login ?

    Bon, je ne suis pas sur d'avoir tout compris, mais si c'est ce que j'ai compris... faudrait envisager ce cas
    En fait, je pensais que les routes étaient analysées par ordre de priorité, c'est à dire que la première route qui répond aux critères sera celle utilisée.
    Après je fais peut être erreur.

    Par contre je suis conscient du problème pour le cas de la route /login
    le slug = login ne sera alors jamais pris en compte.

    Mais ce projet est avant tout le moyen de connaitre les diverses possibilités de symfony (en réalisant un espèce de CMS à usage unique ^^) et bien entendu, cela ne me viendrait jamais à l'idée de livrer ce genre de chose à un client (même en lui interdisant certains slugs, je trouverais cela dangereux au niveau maintenabilité et pas très carré au niveau fonctionnel).

    Concernant ma page d'accueil, en fait je cherche à savoir :
    - si on peut re-router la racine vers une page (exemple / redirige vers /accueil) ? (en dehors d'un pseudo module avec redirection dans le executeIndex du controleur)
    - si on peut charger une page avec le module en mode show pour un paramètre prédéfinit. par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    homepage:
      url:   /
      param: { module: pagecontent, action: show, slugname: accueil }
    Merci d'avance

  6. #6
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Concernant ma page d'accueil, en fait je cherche à savoir :
    - si on peut re-router la racine vers une page (exemple / redirige vers /accueil) ? (en dehors d'un pseudo module avec redirection dans le executeIndex du controleur)
    C'est la première idée qui m'est venue à l'esprit. Il n'y a pas de paramètres pour y arriver depuis les routes. Hors à trouver une astuce dans le .htaccess (et j'ai des doutes), il n'y a qu'une redirection qui pourrait marcher.

    - si on peut charger une page avec le module en mode show pour un paramètre prédéfinit. par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    homepage:
      url:   /
      param: { module: pagecontent, action: show, slugname: accueil }
    Merci d'avance
    Cette route ne peut marcher, pour que le paramètre slug soit passé il faudrait qu'il soit définit. Peut-être si on lui dit qu'il peut accepter des paramètres optionnels ?

    On avait fait un truc dans le genre pour passer des paramètres à une action unique, l'idée était d'avoir deux url simple qui retournait un paramètre par défaut. Mais pour cela, il faut qu'il y ait au moins un paramètre dans la route.

    J'ai inventé une machine à couper les cheveux en quatre, au cas où.

    Encore une chose, il y a un plugin intéressant, que j'ai déjà utilisé : pmSuperfishMenuPlugin, il y a peut-être des trucs à récupérer ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Système] Création menu dynamique
    Par delma dans le forum Langage
    Réponses: 1
    Dernier message: 20/10/2006, 19h44
  2. [système] Comment ajouter un item dans le context menu de Windows ?
    Par ddmicrolog dans le forum API, COM et SDKs
    Réponses: 8
    Dernier message: 29/06/2005, 17h03
  3. Réponses: 3
    Dernier message: 13/06/2005, 12h05
  4. [MFC] Menu système d'un dialog box
    Par tonyskn dans le forum MFC
    Réponses: 2
    Dernier message: 24/05/2004, 21h50
  5. Réponses: 3
    Dernier message: 11/06/2003, 00h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo