Router dans composant

Réduire
X
 
  • Filtrer
  • Heure
  • Afficher
Tout effacer
nouveaux messages

  • [RÉGLÉ] Router dans composant

    Bonjour,

    j'ai beaucoup cherché sur le net, essayé pas mal de "tuto" sur les routeurs joomla, mais je n'y arrive pas.
    J'ai créé un composant d'annonces, avec une vue en liste et une vue détail, donc la vue en liste redirige vers ma vue détail, avec l'ID de l'annonce pour charger les données, aucun souci de ce coté.
    Mon souci est que je souhaite bien sur avoir des URL SEF avec JRoute, mais je n'arrive pas à l'utiliser.
    Mon url absolue est tout simplement "JRoute::_('index.php?option=com_moncomposant& view =detail&ad=1')"
    Bien sur je souhaite avoir quelque chose comme "/annonces/alias"

    J'ai donc essayé de créer un fichier router selon certaines sources trouvées, mais certaines datent pas mal d'autres sont peu précises, même avec l'aide joomla (https://docs.joomla.org/J3.x:Support...r_component/fr) je n'ai pas réussi (sans rire)

    voici une ébauche de mon fichier router, mais je n'arrive pas à l'utiliser.
    Si quelqu'un peut éclairer un tout petit peu ma lanterne merci d'avance

    Code PHP:
    <?php

    defined
    ('_JEXEC') or die;

    class 
    ComposantRouter extends JComponentRouterBase
    {

    public function 
    build(&$query) {
    $segments = [];

    if (isset(
    $query['view'])) {
    $segments[] = $query['view'];
    unset(
    $query['view']);
    }

    if (isset(
    $query['id'])) {
    $segments[] = $query['id'];
    unset(
    $query['id']);
    }

    if (isset(
    $query['slug'])) {
    $segments[] = $query['slug'];
    unset(
    $query['slug']);
    }

    return 
    $segments;
    }

    public function 
    parse(&$segments) {
    $vars = [];

    $vars['view'] = $segments[0];
    $vars['id'] = $segments[1];
    $vars['slug'] = $segments[2];

    return 
    $vars;
    }
    }

    function 
    composantBuildRoute(&$query) {
    $router = new ComposantRouter;

    return 
    $router->build($query);
    }

    function 
    composantParseRoute($segments) {
    $router = new ComposantRouter;

    return 
    $router->parse($segments);
    }
    Dernière édition par Minie à 30/03/2020, 08h53

  • #2
    Hello.

    Code PHP:
    class ComposantRouter extends JComponentRouterBase 
    Il faut bien remplacer "Composant" par le nom de ton composant (sans le com_"), sinon la classe ne sera pas trouvée par Joomla\CMS\Component\Router\RouterBase et bien sûr rien ne sera fait.

    Ensuite tu est sûr d'avoir mis en place le SEO dans ton environnement de test, sinon ton router ne sera pas appelé (cela parait idiot, mais il faut y penser).

    Ensuite juste les 2 méthodes "build" et "parse", je ne vois pas l’intérêt des 2 autres (en tous cas moi je ne les défini pas dans mes routers).
    Mais cela va changer en J4, je n'ai pas encore regaré.
    Dernière édition par roland_d_alsace à 27/03/2020, 11h39
    Minie aime ceci.
    A tous les utilisateurs de Joomla du très Grand Est de la France et du Jura suisse
    Rejoignez le Joomla Users Groupe Alsace...
    roland_d_alsace va-t-il devenir roland_du_grand_est ?

    Commentaire


    • #3
      Merci pour ta réponse.
      en fait j'ai mis composant dans mon post, mais dans mon code c'est bien le nom de mon composant.

      Et la réécriture est bien activée dans la config.

      C'est juste que je n'arrive pas à l'utiliser, lorsque je créer mon lien, je ne vois pas où préciser par quoi je veux remplacer l'url absolue

      Actuellement, mon lien "JRoute::_('index.php?option=com_moncomposant& view =detail&ad=1')"
      Donne l'url suivante "lien_parent/detail?ad=1"

      Je voudrais "lien_parent/titre-annonce"

      Mais je ne vois nul part dans le router ou dans la construction du lien l'endroit où je dois dire "coupe cette partie et colle le titre"

      Commentaire


      • #4
        Normalement avec le routeur que tu as fait :
        ?view=toto&id=5&slug=10
        devient /toto/5/10

        Devant il y a soit :
        • La cascasque d''alias de menu que accède à la vue
        • /component/nomtoncomposant si tu ne passes pas par un lien de menu pour accéder à ta vue.
        Cela correspond avec que tu as fait sauf que tu traite id et slug, au lieu de traiter ad à la formation de ton url SEO

        view=detail a bien été remplacé par le segment /detail (le 2ème)

        Je ne sais pas à quoi correspond lien_parent dans ton composant, je suppose que c'est l'alias du lien de menu ?

        Mais si titre-annonce doit permettre de retrouver au retour d'une requête SEO la vue (variables view) et l'id de l'annonce, cela risque d'être un peu complexe.

        Le composant, tu ne peux pas jouer dessus, il faudra donc éventuellement jouer sur l'alias du lien de menu, ou alors se servir d'un alias de lien de menu (pas pareil).

        En tous cas 2 annonces ne pourront pas avoir le même titre, si tu ne mets pas l'id dans un segment de l'url SEO.

        Par exemple tu peux faut rajouter l'id au début ou à la fin du segement ou il y aura le titre.

        Si c'est devant, donc dans ton build il faudra faire $segment[1] = $query['id'].'-'.$query['titres-annonce']
        et dans ta méthode parse couper la chaine au 1er tiret pour "ressortir" l'id (le titre ne nous intéresse pas au niveau du retour de requete, c'est bien l'id qu'il nous faut).

        Il faut alors bien que tu ais &titre-annonce=xxxxxxxxx dans l'url a convertir SEO bien sûr.

        Ou alors à ta méthode build de retrouver l'information en session, par un requête dans la DB, etc.... pour construire le segment.

        Ou les 2 (si $query["titre-annonce'] n'existe pas alors on accède à la DB pour le retrouver et le mettre sans le segment SEO.

        Sinon tu peux rajouter éventuellement la date de l'annonce dans l'URL, et interdire 2 titres identiques le même jour par exemple.

        Dans Joomla/articles on met les catégories, mais dans un catégorie d'articles donnée on ne peux pas avoir 2x le même alias.

        A toit de voir comment tu peux cibler une annonce précise sans utiliser son id.
        Dernière édition par roland_d_alsace à 27/03/2020, 16h01
        Minie aime ceci.
        A tous les utilisateurs de Joomla du très Grand Est de la France et du Jura suisse
        Rejoignez le Joomla Users Groupe Alsace...
        roland_d_alsace va-t-il devenir roland_du_grand_est ?

        Commentaire


        • #5
          Pour info : discussion déplacée dans le forum Développement.
          A tous les utilisateurs de Joomla du très Grand Est de la France et du Jura suisse
          Rejoignez le Joomla Users Groupe Alsace...
          roland_d_alsace va-t-il devenir roland_du_grand_est ?

          Commentaire


          • #6
            Bonjour,

            merci c'est super !

            voici donc mon nouveau router :
            Code PHP:
            <?php

            defined
            ('_JEXEC') or die;

            class 
            GixadsRouter extends JComponentRouterBase
            {

            public function 
            build(&$query) {
            $segments = [];

            if (isset(
            $query['view'])) {
            $segments[] = $query['view'];
            unset(
            $query['view']);
            }

            if (isset(
            $query['ad'])) {

            $adInfos GixadsModelGixads::getAdInfos($query['ad']);
            $alias JFilterOutput::stringURLSafe($adInfos->ad_name);

            $segments[] = $alias;
            unset(
            $query['ad']);
            }


            return 
            $segments;
            }

            public function 
            parse(&$segments) {
            $vars = [];

            $vars['view'] = $segments[0];
            $vars['ad'] = $segments[1];

            return 
            $vars;
            }
            }
            la variable "ad" est bien remplacée par le nom de l'annonce transformé en alias (bien sur je ferais en sorte que la personne ne puisse pas créer deux annonces du même titre
            par contre lorsque je souhaite faire pareil pour la vue en remplaçant la ligne

            $segments[] = $query['view'];

            par

            $segments[] = 'detail-du-bien';

            le lien m’emmène sur la page d’accueil je ne comprends pas, le fonctionnement n'est pas sensé être le même pour la vue que pour l'id ?

            de plus, lorsque je rajoute dans l'url "&itemid=176", la page ne s'affiche pas dans le lien 176 (je précise que l'item id 176 est le lien de menu créé dans joomla qui correspond justement à la vue "detail", il devrait donc être le l'item id par défaut pour l'ouverture de mon lien)
            Au lieu de ca, ma page détail est ouverte dans l'item id parent (la vue en liste)

            structure :
            lien parent : vue en liste (index.php?option=com_gixads&view=list)
            lien enfant : vue détail (index.php?option=com_gixads&view=detail)

            les deux sont des liens de menu créé avec les vues de mon composant
            Dernière édition par Minie à 28/03/2020, 11h44

            Commentaire


            • #7
              Hello.

              Ce que tu défais dans ta méthode build, il faut le refaire dans la méthode parse (donc retrouver exactement ce que tu avais dans ton tableau $query à l'entrée du build, en sortant de la méthode parse).

              En l'état actuel lors du retour, (donc en sortant du parse) tu essaies d'afficher la vue "detail-du-bien" avec l'id = alias de ton annonce.

              Il faut faire le nécessaire pour transformer les serments en variable d'url.

              Il faut donc que dans le parse :
              • si segment[0] = "detail-du-bien" $vars['view'] = nom_de_ta_vue
              • rechercher l'id de l'annonce correspondant à l'alias et la placer en $vars['ad'] et éventuellement gérer un cache de lecture pour éviter un nouvel accès à la DB dans ton model, ou prévoir une variable $vars['ad'] indiquant à ton model de faire une recherche sur l'alias si l'ad n'est pas renseigné (par exemple par un $input->get('ad', null).
              Dernière édition par roland_d_alsace à 28/03/2020, 14h18
              Minie aime ceci.
              A tous les utilisateurs de Joomla du très Grand Est de la France et du Jura suisse
              Rejoignez le Joomla Users Groupe Alsace...
              roland_d_alsace va-t-il devenir roland_du_grand_est ?

              Commentaire


              • #8
                Merci beaucoup, j'y vois bien plus clair maintenant, tout fonctionne nickel, voici mon nouveau router :

                Code PHP:
                <?php

                defined
                ('_JEXEC') or die;

                class 
                GixadsRouter extends JComponentRouterBase
                {

                public function 
                build(&$query) {
                $segments = [];

                if (isset(
                $query['view'])) {
                if(
                $query['view'] == 'detail'){
                $segments[] = 'detail-du-bien';
                }
                else{
                $segments[] = $query['view'];
                }
                unset(
                $query['view']);
                }

                if (isset(
                $query['ad'])) {

                $adInfos GixadsModelGixads::getAdInfos($query['ad']);
                $segments[] = $adInfos->ad_alias;
                unset(
                $query['ad']);
                }

                return 
                $segments;
                }

                public function 
                parse(&$segments) {
                $vars = [];

                if(
                $segments[0] == 'detail-du-bien'){
                $vars['view'] = 'detail';
                }
                else{
                $vars['view'] = $segments[0];
                }

                $db JFactory::getDBO();
                $query 'SELECT * FROM #__gixads_ad WHERE ad_alias = "'.$segments[1].'"';
                $db->setQuery($query);
                $adInfos $db->loadObject();
                $vars['ad'] = $adInfos->ad_id;

                return 
                $vars;
                }

                }
                Ce que je ne comprends pas, c'est pourquoi l'itemid utilisé pour la vue détail reste celui de la vue en liste. Lorsque je cherche sur internet je ne trouve que des questions sur la suppression des ID dans les url. Du coup le fil d’Ariane reste sur la vue en liste, et les modules de la page détail ne s'affichent pas.

                Mes deux liens de menu sont comme suit : (nom / alias / itemid / url absolue)
                - Tous les biens / tous-les-biens / 112 / index.php?option=com_gixads&view=list
                -- Détail du bien / detail-bien / 176 / index.php?option=com_gixads&view=detail

                La vue en liste est le lien de menu parent de la vue détail. J'ai essayé plusieurs façons de tomber sur l'item id 176 avec ma vue détail :
                1. Dans mon router, j'ai essayé "$segments[] = 'detail-bien';" à la place de $segments[] = 'detail-du-bien';" puisque c'est l'url de l'itemid souhaité => Résultat : page blanche, plantage sans erreur annoncée
                2. Dans la construction de l'url j'ai rajouté "&itemid=176" ce qui donne : "JRoute::_('index.php?option=com_gixads&view=d etai l&ad='.$item['ad_id'].'&itemid=176')" => Résultat : aucune prise en compte, exemple d'url finale : "/tous-les-biens/detail-du-bien/plein-sud-maison-de-plain-pied-composee-de-3-chambres?itemid=176"

                Dois-je rajouter quelque chose dans mon router pour que l'itemid soit pris en charge et qu'il n'apparaisse plus dans l'url finale ?
                J'ai souvent modifié des composants existants, et ca fonctionnait comme ca, il doit donc manquer quelque chose dans le mien mais internet ne parle que de la suppression des chiffres dans l'url :'(

                En tout cas merci beaucoup pour toutes tes réponses, je n'avais pas encore osé m'attaquer à la réécriture d'url, le brouillard est levé ! (ou presque)
                Dernière édition par Minie à 29/03/2020, 10h12

                Commentaire


                • #9
                  Hello.

                  Rien ne t'interdit de forcer la variable d'url itemid dans ta méthode parse avec un
                  Code PHP:
                  $query['Itemid'] = $monitemid
                  Minie aime ceci.
                  A tous les utilisateurs de Joomla du très Grand Est de la France et du Jura suisse
                  Rejoignez le Joomla Users Groupe Alsace...
                  roland_d_alsace va-t-il devenir roland_du_grand_est ?

                  Commentaire


                  • #10
                    Salut,

                    je suis à l'ouest ... ca m'a fait tilté dans ton message, je n'ai rien à mettre dans mon router, c'est juste mon URL qui etait construite avec la clé "itemid" au lieu de "Itemid" ... je n'avais pas remarqué j'avais oublié la majuscule.

                    Tout est bon, merci beaucoup pour ton aide, je passe le sujet en réglé
                    Dernière édition par Minie à 30/03/2020, 08h53

                    Commentaire


                    • #11
                      Envoyé par Minie Voir le message
                      Salut,

                      je suis à l'ouest ... ca m'a fait tilté dans ton message, je n'ai rien à mettre dans mon router, c'est juste mon URL qui etait construite avec la clé "itemid" au lieu de "Itemid" ... je n'avais pas remarqué j'avais oublié la majuscule.

                      Tout est bon, merci beaucoup pour ton aide, je passe le sujet en réglé
                      Oui, le coup du I majuscule, cela m'est déjà arrivé aussi
                      Minie aime ceci.
                      A tous les utilisateurs de Joomla du très Grand Est de la France et du Jura suisse
                      Rejoignez le Joomla Users Groupe Alsace...
                      roland_d_alsace va-t-il devenir roland_du_grand_est ?

                      Commentaire

                      Annonce

                      Réduire
                      Aucune annonce pour le moment.

                      Partenaire de l'association

                      Réduire

                      Hébergeur Web PlanetHoster
                      Travaille ...
                      X