Encapsuler la navigation BP dans un wp_nav_menu (reloaded!)

Crédits Photo Menu on the streets of Canterbury by Mskadu, on Flickr

Derni√®rement, je suis tomb√© sur ce billet int√©ressant de WP First Aid. Il y est question de wp_nav_menu et de se raccrocher √† un filter (wp_nav_menu_items) afin d’ajouter des items √† un menu existant. Rappelez-vous j’avais propos√© une premi√®re m√©thode pour int√©grer la navigation BuddyPress √† un wp_nav_menu en f√©vrier dernier. Or via l’utilisation de ce fameux filter c’est encore plus simple !!

Rappel: activation du support des wp_nav_menu

Pour activer le support des menus dans votre thème, il suffit de commencer par écrire quelques lignes de code dans le script functions.php

<?php

function register_my_menu() {
  register_nav_menu( array(
    'primary' => 'Menu 1',
    'secondary' => 'Menu 2',
  ) );
}
add_action( 'init', 'register_my_menu' );

Depuis l’administration WordPress, il est d√©sormais possible de param√©trer les menus (primary et secondary).

Application du filter

Juste pour le fun, on va l√©g√®rement corser l’histoire en d√©cidant de n’afficher la navigation BuddyPress qu’√† partir du moment o√Ļ l’utilisateur est logg√©. Dans votre functions.php, ajoutez ces quelques lignes de code :

function imath_bp_nav_menu_items($items, $args) {
   //on ne veut ajouter la navigation que sur le premier menu
   if ( $args->theme_location == "primary" ){
     $buddypress_menu = '<li class="menu-item">
<a href="'.get_bloginfo('url') .'/'. BP_ACTIVITY_SLUG.'">Communauté</a>     <ul class="sub-menu">
       <li class="menu-item"><a href="'.get_bloginfo('url') .'/'. BP_ACTIVITY_SLUG.'">'.__( 'Activity', 'buddypress' ).'</a></li>
       <li class="menu-item"><a href="'.get_bloginfo('url') .'/'. BP_MEMBERS_SLUG.'">'.__( 'Members', 'buddypress' ).'</a></li>
       <li class="menu-item"><a href="'.get_bloginfo('url') .'/'. BP_GROUPS_SLUG.'">'.__( 'Groups', 'buddypress' ).'</a></li>
       <li class="menu-item"><a href="'.get_bloginfo('url') .'/'. BP_FORUMS_SLUG.'">'.__( 'Forums', 'buddypress' ).'</a></li>
     </ul>
     </li>';
     // vous pouvez si vous le souhaitez sur le même modèle ajouter les blogs du réseaux...
     // si l'utilisateur est loggé, on affiche les items BuddyPress
   if ( is_user_logged_in() ) {
     $items = $items . $buddypress_menu ;
   }

   return $items;
   } else {
     return $items;
   }
}
add_filter( 'wp_nav_menu_items', 'imath_bp_nav_menu_items', 9, 2 );

Et voil√†, le tour est jou√© ūüėČ

Bonus

Si vous voulez √™tre certain que les visiteurs non logg√©s ne puissent pas atteindre la zone BuddyPress…

function imath_is_user_loggedout_die( $located_template ){
   if ( is_user_logged_in() ){
     return $located_template;
   }

   // sinon la page n'existe pas !!!
   return locate_template( array( '404.php' ) );
}
add_filter('bp_load_template', 'imath_is_user_loggedout_die', 1, 1);

A+

9 commentaires sur “Encapsuler la navigation BP dans un wp_nav_menu (reloaded!)

  1. Merci pour cet article que j’ai appliqu√© sans souci √† mon site Buddypress de test (v 1.5.1).
    Juste une petite chose, il faut modifier √† la ligne 5 du script de ta premi√®re fonction ¬ę¬†Communaut√©¬†¬Ľ par ¬ę¬†Communaut鬆¬Ľ pour √©viter un probl√®me d’encodage … je chipote ! On pourrai √©galement am√©liorer la s√©mantique avec les css pour rendre actif l’onglet ¬ę¬†Communaut√©¬†¬Ľ lorsque l’utilisateur a cliqu√© sur un des items enfants…

    J’ai combin√© ce filtre avec les slugs francis√©s, d√©finis dans mon fichier : plugins/bp-custom.php en indiquant par exemple ¬ę¬†define( ‘BP_MEMBERS_SLUG’, ‘membres’ );¬†¬Ľ
    J’ai √©galement retir√© mon ¬ę¬†Admin bar¬†¬Ľ en indiquant :
    ¬ę¬†define(‘BP_DISABLE_ADMIN_BAR’, true);¬†¬Ľ
    En tout cas, c’est le genre de petits ¬ę¬†tricks¬†¬Ľ √† conna√ģtre pour optimiser l’exp√©rience utilisateur avec Buddypress !

  2. Dois-je ajouter que ce plugin (compatible BP 1.5.1) fait également le job, mais il demande de modifier directement le fichier header.php du thème Buddypress par défaut bp-default :

    http://wordpress.org/extend/plugins/buddypress-profile-menu/

    Donc √©tant donn√© que tu utilises le fichier function.php, ta m√©thode est davantage p√©renne ūüėČ

    Je cogite pour ma part sur la refonte du menu de r√©glage de la page de profil utilisateur, pour le placer (comme Widget?) dans la sidebar par exemple… Ou en utilisant le m√™me principe que pour ton menu ¬ę¬†Communaut√©¬†¬Ľ (sous forme de menu d√©roulant) et s’intitulerait ¬ę¬†Mon profil¬†¬Ľ. Ce menu fonctionnerait avec comme principe :
    1 lien -> 1 page
    Par exemple :
    Settings (lien plac√© dans la sidebar) -> Page ¬ę¬†Settings¬†¬Ľ

    Cela √©viterait le syst√®me de ¬ę¬†Tabs¬†¬Ľ actuel sur plusieurs lignes. A mon avis, actuellement, un nouvel utilisateur inscrit ne comprend pas grand chose √† la gestion de son compte Buddypress ! le probl√®me principal qui se pose est : Comment subdiviser Activity – Groups – Forums – Settings en plusieurs pages ?

    1. Salut @Mecanographik,

      J’ai retir√© comme demand√©, tes 2 derniers commentaires ūüôā A l’occase, je regarderai le code..
      Autrement pour ton projet de menu profil. Pour la partie d√©roulante c’est du css et du js.
      Je pense qu’il y a un moyen assez simple de le faire. Il s’agit de s’accocher au hook ‘bp_after_sidebar_me’ pour automatiquement le mettre sous l’avatar de l’utilisateur de la sidebar. L’avantage est que si pas logg√© pas de hook et donc pas de menu ūüėČ
      Voici ce que j’ai test√© et qui semble fonctionner :

      function imath_user_menu(){
        global $bp;
        ?>
        <br style="clear:both"/>
        <div id="user-menu" class="widget widget_nav_menu">
          <ul>
            <li class="<?php if(BP_XPROFILE_SLUG == $bp->current_component && 'edit' != $bp->current_action && 'change-avatar' != $bp->current_action) echo 'current-menu-item';?>"><a href="<?php echo $bp->loggedin_user->domain . BP_XPROFILE_SLUG;?>">Mon Profil</a></li>
            <li class="<?php if(BP_XPROFILE_SLUG == $bp->current_component && 'edit' == $bp->current_action ) echo 'current-menu-item';?>"><a href="<?php echo $bp->loggedin_user->domain . BP_XPROFILE_SLUG;?>/edit/">Editer Mon Profil</a></li>
            <li class="<?php if(BP_XPROFILE_SLUG == $bp->current_component && 'change-avatar' == $bp->current_action) echo 'current-menu-item';?>"><a href="<?php echo $bp->loggedin_user->domain . BP_XPROFILE_SLUG;?>/change-avatar/">Editer Mon Avatar</a></li>
            <li class="<?php if(BP_SETTINGS_SLUG == $bp->current_component ) echo 'current-menu-item';?>"><a href="<?php echo $bp->loggedin_user->domain . BP_SETTINGS_SLUG;?>">Mes r√©glages</a></li>
            <li class="<?php if(BP_ACTIVITY_SLUG == $bp->current_component ) echo 'current-menu-item';?>"><a href="<?php echo $bp->loggedin_user->domain . BP_ACTIVITY_SLUG;?>">Mon activit√©</a></li>
            <li class="<?php if(BP_BLOGS_SLUG == $bp->current_component ) echo 'current-menu-item';?>"><a href="<?php echo $bp->loggedin_user->domain . BP_BLOGS_SLUG;?>">Mes Blogs</a></li>
            <li class="<?php if(BP_GROUPS_SLUG == $bp->current_component ) echo 'current-menu-item';?>"><a href="<?php echo $bp->loggedin_user->domain . BP_GROUPS_SLUG;?>">Mes Groupes</a></li>
            <li class="<?php if(BP_FRIENDS_SLUG == $bp->current_component ) echo 'current-menu-item';?>"><a href="<?php echo $bp->loggedin_user->domain . BP_FRIENDS_SLUG;?>">Mes amis</a></li>
            <li class="<?php if(BP_MESSAGES_SLUG == $bp->current_component ) echo 'current-menu-item';?>"><a href="<?php echo $bp->loggedin_user->domain . BP_MESSAGES_SLUG;?>">Mes messages</a></li>
          </ul>
        </div>
        <br style="clear:both"/>
        <?php
      }

      add_action('bp_after_sidebar_me', 'imath_user_menu');

      Voici ce que ça peut donner :
      lien vers illustration

  3. ok, merci pour le test ! c’est tout √† fait √ßa dans l’id√©e,
    c’est clair que je n’aurai pas pens√© √† bp_after_sidebar_me. Finalement je me suis attaqu√© √† la fonction bp_get_displayed_user_nav()
    Je l’ai copi√©e, ajout√© √† function.php de mon th√®me enfant et l’ai utilis√© dans members/single/settings/general.php
    Mais ta technique permet de ne pas √† devoir red√©ployer le menu d√©roulant d√®s qu’on veut changer de tab dans le profil…

    voici le résultat :
    http://i1081.photobucket.com/albums/j360/mecanographik/snap/profile-tabs.png

    Je ne suis pas parvenu √† faire un hook sur la fonction bp_get_displayed_user_nav() pour ne pas √† devoir recopier les fichiers du th√®me par d√©faut, dans lesquels elel est pr√©sente… Ma modification force √† n’afficher que le Tab ¬ę¬†courant¬†¬Ľ (current component)

    1. Intéressant !!
      En fait si tu veux ajouter un item à la navigation, tu peux utiliser
      add_action('bp_member_options_nav', 'tafonction');

      Mais dans ton cas et vu la fonction en question (bp_get_displayed_user_nav), tu pourras t’apercevoir qu’elle permet de filtrer ce qu’elle retourne (apply_filters(‘bp_get_displayed_user_nav_[cssid]’,…)). Donc tu peux √©ventuellement √©galement utiliser un autre moyen en bouclant sur le tableau de la global $bp->bp_nav pour √™tre s√Ľr de ne pas manquer un menu (cas des plugins qui ajoutent des menus par exemple…). Voici ce que √ßa pourrait donner :

      add_action('template_redirect', 'imath_user_nav_filters', 1);

      function imath_user_nav_filters(){
        global $bp;
        foreach((array)$bp->bp_nav as $nav){
          add_filter('bp_get_displayed_user_nav_'.$nav['slug'], 'imath_hide_or_show_user_nav', 9, 2);
        }  
      }

      function imath_hide_or_show_user_nav($li, $user_nav_item){
        global $bp;
        if($bp->current_component == $user_nav_item['slug']){
          return $li;
        }
        else return false;
      }

      Bonne nuit ūüėČ

  4. J’ai impl√©ment√© ta derni√®re proposition dans functions.php, mais sans succ√®s ! Merci pour le coup de pouce car tu m’as permis de trouver une solution allant dans ton sens, et plus simple encore gr√Ęce √† la fonction bp_core_remove_nav_item, la voici :

    http://chopapp.com/#bvueknrg

    Merci pour ton aide en tout cas, il me reste un petit probl√®me que tu as √©voqu√© pr√©c√©demment, le slug ¬ę¬†√©v√®nements¬†¬Ľ n’est pas identifi√© donc appra√ģt dans le menu du profil(cas des plugins qui ajoutent des menus). La solution serait peut-√™tre de d√©clarer ce slug dans bp-custom.php, je regarde cela de plus pr√®s…
    Voici le résultat actuel :
    http://i1081.photobucket.com/albums/j360/mecanographik/profile-tabs-v2.png

  5. Je suis finalement parvenu à mes fins en reprenant mon dernier exemple et en réutilisant ta fonction imath_hide_or_show_user_nav
    Le d√©faut de ma fonction est que je dois g√©rer un cas d’exception pour l’item nomm√© ¬ę¬†Ev√®nements¬†¬Ľ qui a comme slug ¬ę¬†events¬†¬Ľ… mais √ßa marche ūüėČ
    Voici le code complet sur CHO :

    http://chopapp.com/#913z34bd

Les commentaires sont fermés.