[RESOLU] Barre de navigation récursive avec REQUEST_URI

Petit nouveau ! | 7 Messages

21 nov. 2014, 16:21

Bonjour à tous,

Depuis quelques jours je suis confronté à un petit soucis. J'essaye de générer dynamiquement une barre de navigation en fonction des paramètres passés dans l'url. De sorte que :

l'adresse racine/machin/truc/bidule/chouette

me retourne :

racine -> machin -> truc -> bidule -> chouette

Jusqu'ici pas de soucis, le soucis c'est pour les liens, je n'arrive pas à faire en sorte que les urls se fassent de cette façon :
  • racine -> ./
  • machin -> ./machin
  • truc => ./machin/truc
  • bidule -> ./machin/truc/bidule
  • etc
J'ai essayé plusieurs tentatives et actuellement je bloque pour les liens qui me ramènent tous sur la page d'avant (si je suis sur chouette tous les liens me renvoient sur bidule). Le truc qui me manque c'est la logique de l'algorythme à appliquer en fait, si quelqu'un voit une solution appropriée à mon problème, je prends avec plaisir :)

Voici mon code, pour information je travaille sous codeIgniter :
public function page_navigation($my_title = '')
    {
        //  Sur l'accueil, pas de navigation
        if( $this->CI->uri->total_segments() === 0 )
        {
            return NULL;
        }

        //  On récupère tous les segments de la barre d'adresse
        $count = 1;
        $segments = $this->CI->uri->segment_array();

        //  Début de la navigation
        $url = '<li><span class="glyphicon glyphicon-home"></span>&nbsp; <a href="' . site_url() . '">Accueil</a></li>';

        foreach( $segments as $segment )
        {
            if( $count === $this->CI->uri->total_segments() )
            {
                if( !empty($my_title) )
                {
                    $url .= '<li class="active">' . $my_title . '</li>';
                }
                else
                {
                    if( is_numeric($segment) )
                    {
                        $url .= '<li class="active">Elément n°' . $segment . '</li>';
                    }
                    else
                    {
                        $url .= '<li class="active">' . humanize_nav($segment) . '</li>';
                    }
                }
            }
            else
            {
                $href = base_url();
                for( $i = 1; $i < $this->CI->uri->total_segments(); $i ++ )
                {
                    $link .= $this->CI->uri->segment($i) . '/';
                }
                $url .= '<li><a href="' . $href . '">' . humanize_nav($segment) . '</a></li>';
            }

            $count++;
        }

        return '<div class="container">
                    <ol class="breadcrumb">
                        ' . $url . '
                    </ol>
                </div>';
    }
Merci par avance :)

Nestecha
Invité n'ayant pas de compte PHPfrance

21 nov. 2014, 18:40

Essaie avec ça, je l'ai commentée pour les explications :
<?php
error_reporting('E_ALL & ~E_NOTICE & ~E_DEPRECATED');

function createBreadCrumb($sSeparator = ' &raquo; ', $sHome = 'Home') {
    // On choppe le path entier et on supprime les valeurs vides
    $aPath = array_filter(explode('/', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)));

    // On cherche la clé associée à la dernière valeur dans tout le path
    $iLast = end(array_keys($aPath));

    // On crée une URL de base
    $sBaseURL = ('http') . '://' . $_SERVER['HTTP_HOST'] . '/';

    // On crée un breadcrumbs de base avec l'URL de base
    $aBreadCrumbs = array("<a href=\"$sBaseURL\">$sHome</a>");

    // Build the rest of the breadcrumbs
    // On construit le reste du breadcrumbs
    foreach ($aPath AS $iKey => $sSingleCrumb) {
        // $sTitle sera le titre qu'on inscrit dans la valeur du lien du breadcrumb, en enlevant .php et en changeant _ en espace
        $sTitle = ucwords(str_replace(array('.php', '_'), array('', ' '), $sSingleCrumb));

        // Si on n'a pas atteint la clé associée à la dernière valeur de $aPath (qui est $iLast) on crée un <a>
        if ($iKey != $iLast) {
            $aBreadCrumbs[] = "<a href=\"$sBaseURL$sSingleCrumb\">$sTitle</a>";
        } // Sinon on écrit simplement le $sTitle correspondant
        else {
            $aBreadCrumbs[] = $sTitle;
        }
    }

    // On rassemble tout le breadcrumbs en une chaîne qu'on pourra echo ensuite
    return implode($sSeparator, $aBreadCrumbs);
}
?>

<p><?= createBreadCrumb(); ?></p>
Faudra changer la ligne 12 si ton site est en HTTPS.

Petit nouveau ! | 7 Messages

21 nov. 2014, 19:25

J'ai du retirer la fonction end() à $iLast pour que cela fonctionne, autrement ça me retournait cette erreur :

Code : Tout sélectionner

Severity: Runtime Notice Message: Only variables should be passed by reference
Autrement ça me retourne exactement la même chose que ma fonction :/

Si ça peut aider certaines fonctions de base de Code Igniter peuvent être utiles. C'est à partir de ces fonctions que j'essayais d'obtenir quelque chose d'agréable :)

Nestecha
Invité n'ayant pas de compte PHPfrance

21 nov. 2014, 19:37

Tu n'as pas dû copier ça :
error_reporting('E_ALL & ~E_NOTICE & ~E_DEPRECATED');
End() est primordial pour que ça fonctionne (dans le code que j'ai copié).

Petit nouveau ! | 7 Messages

21 nov. 2014, 19:40

J'ai finalement réussi en me basant sur ta fonction :)

Voici le code corrigé si ça intéresse certains :)
/**
     *  Barre de navigation
     *
     * @param string $my_title
     * @return string
     */
    public function page_navigation($my_title = '')
    {
        //  Sur l'accueil, pas de navigation
        if( $this->CI->uri->total_segments() === 0 )
        {
            return NULL;
        }

        //  On récupère tous les segments de la barre d'adresse
        $count = 1;
        $segments = $this->CI->uri->segment_array();
        $last_segment = $this->CI->uri->segment($this->CI->uri->total_segments());

        //  Début de la navigation
        $links = ['<li><span class="glyphicon glyphicon-home"></span>&nbsp; <a href="' . site_url() . '">Accueil</a></li>'];

        foreach( $segments as $url => $title )
        {
            if( $count === $this->CI->uri->total_segments() )
            {
                if( !empty($my_title) )
                {
                    $links[] =  '<li class="active">' . $my_title . '</li>';
                }
                else
                {
                    if( is_numeric($title) )
                    {
                        $links[] = '<li class="active">Elément n°' . $title . '</li>';
                    }
                    else
                    {
                        $links[] = '<li class="active">' . humanize_nav($title) . '</li>';
                    }
                }
            }
            else
            {
                if( $url != $last_segment )
                {
                    $href = base_url();
                    for( $i = 1; $i <= $url; $i++ )
                    {
                        $href .= $this->CI->uri->segment($i) . '/';
                    }
                    $links[] = '<li><a href="' . $href . '">' . humanize_nav($title) . '</a></li>';
                }
                else
                {
                    $links[] = '<li class="active">' . humanize_nav($title) . '</li>';
                }
                //$url .= '<li><a href="' . site_url($title) . '">' . humanize_nav($title) . '</a></li>';
            }

            $count++;
        }

        $url = '';
        foreach( $links as $link )
        {
            $url .= $link;
        }

        return '<div class="container">
                    <ol class="breadcrumb">'
                    . $url .
                    '</ol>
                </div>';
    }
Dans tous les cas je te remercie pour ton aide, sans ton idée de base je n'y serais pas arrivé :)