it-swarm.com.de

Navigationsmenüelement abhängig von den Benutzerfunktionen anzeigen

Ich habe eine "Verzweigung" des Navigationsbaums meiner Hauptwebsite, die nur einer Reihe registrierter, angemeldeter Benutzer zugänglich sein sollte. Ich verstehe, wie man die Rolle und die Fähigkeiten eines Benutzers abfragt. In dieser Frage geht es speziell darum, wie Sie das integrierte Navigationsmenü am besten nutzen, ein Element jedoch nur unter bestimmten Bedingungen ausblenden können.

Muss ich die integrierte Standardnavigation überladen, eine benutzerdefinierte Abfrage schreiben und die Navigationsstruktur manuell erstellen? Ich würde das gerne vermeiden, wenn es möglich ist.

Ich benötige keine vollständigen Codebeispiele, nur Ihre Ideen und den allgemeinen Rahmen/Ansatz.

Schätzen Sie den Rat!

T

5
Tom Auger

Verwenden Sie Ihre eigene Gehhilfe und überprüfen Sie die Fähigkeit, bevor Sie einen Gegenstand erstellen.

4
fuxia

Jemand hat ein brillantes Plugin erstellt, um dies ohne Codierung zu tun. Hat sogar Kontrollkästchen in der Menü-Editor-Oberfläche zur Auswahl der genehmigten Rollen pro Menüpunkt.

http://wordpress.org/extend/plugins/nav-menu-roles/

4
somatic

Die Antwort toscho geschrieben ist richtig aber für die wenigen Leute, die wissen, was sie tun und wie es geht. :) Ich füge dies für den Rest der Welt als einfachere Lösung für die weniger fortgeschrittenen Benutzer hinzu. Die Idee wäre, verschiedene Menüs zu haben und sie nur basierend auf der Benutzerrolle anzuzeigen.

Angenommen, Sie haben 3 Menüs mit den Namen Editor, Autor und Standard:

if (current_user_can('Editor')){
    //menu for editor role
    wp_nav_menu( array('menu' => 'editor' ));

}elseif(current_user_can('Author')){
    //menu for author role
    wp_nav_menu( array('menu' => 'author' ));

}else{
    //default menu
    wp_nav_menu( array('menu' => 'default' ));
}
3
Bainternet

Das Problem beim Überschreiben von start_el und end_el besteht darin, dass dies nur die Anzeige des betreffenden Menüelements steuert - es hat keine Auswirkungen auf die Anzeige der untergeordneten Elemente. Ich denke, Sie müssen display_element überschreiben, um die Kinder ebenso zu verstecken.

Es ist auch möglich, das Beschreibungsfeld des Menüelements zu verwenden, um Informationen für jedes Menüelement zu speichern, ob es angezeigt werden soll oder nicht.

Dieser Code sucht in der Beschreibung der einzelnen Menüelemente nach einer durch Kommas getrennten Liste von Funktionen, z. B. [Funktion: this_one, next_one]. Wenn der aktuelle Benutzer über keine der Funktionen verfügt, wird das Element (oder eine seiner untergeordneten Funktionen) nicht angezeigt. Es ist ziemlich einfach, die Zeichenfolgen aus der Beschreibung zu entfernen, wenn Sie die Beschreibung tatsächlich für den beabsichtigten Zweck verwenden möchten.

/*
 * hide or display menus based on user capabilities
 *
 * Use the description field of the custom menu item. If it contains a string like [capability: xx, xx] 
 * display the menu item only if the user has at least one of the capabilities.
 * If a menu item is not displayed, nor are any of its sub items.
 */
/* Custom Walker */
class NASS_Nav_Walker extends Walker_Nav_Menu {

        // override parent method
        function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
            // we know the $element is a menu item  
            // we want to check its description field to see if it's OK to display it
            // in which case we just retreat to the parent method
            $desc = $element->description;
            if ( should_display_menu_item($desc) ) {
                parent::display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output );
            } else {
                return;
            }
        }    
}
/* should we display the menu item, if this is its description? */
function should_display_menu_item( $desc ) {
    // first see if the description contains a capability specification of the form
    // [capability: comma, delimited, list]
    // we assume all capability names consist only of lower case with underbars
    $prefix = "\[capability:";
    $postfix = "\]";
    $pattern = '@' . $prefix . '([a-z_, ]+)' . $postfix . '@';
    $answer = true;
    if ( preg_match($pattern, $desc, $matches) ) { // if we've got a match
        $found = $matches[1];   // the parenthesized bit of the regex
        $caps = array_map('trim', explode(",", $found));
        if ( count ($caps) > 0 ) { // there is at least one
            $answer = false;
            // now see if the user has any of them
            foreach ($caps as $cap) {
                if ( current_user_can ($cap) ) $answer = true;
            }
        }
    }
    return $answer;

}
2
lpryor

Ich habe versucht, das Beschreibungsfeld zu verwenden, um zu bestimmen, welche Rollen auf welche Menüelemente zugreifen können, und meine Änderungen basieren auf dem Code, den ich hier erhalten habe. - Pimp my WP Menu

Meine geänderte Version:

<?php

/***
* Menu WALKER - for restricting the menu items visibility
* Code modified by - Trupti Bhatt (http://3sided.co.in)
* using original code posted here - http://www.tisseur-de-toile.fr/wordpress-tricks/pimp-my-wordpress-menu-part-2-access-granted-to-authorized-personnel-only.html
***/
class description_walker extends Walker_Nav_Menu
{
        /*
                 *      Custom var to store current role
                 */
                private $current_user_role = "";

                /*
                 *      Get te current user role
                 */
                private function getCurrentUserRole()
                {
                                global $current_user;
                                if ( is_user_logged_in() )
                                {
                                        if ( $this->current_user_role == "" )
                                        {
                                                $this->current_user_role = $current_user->roles[0];
                                        }

                                        return $this->current_user_role;
                                }
                                else
                                {
                                        $this->current_user_role='visitor';
                                        return $this->current_user_role;
                                }
                }

                /*
                 *      Check if the user is an administrator
                 */
                private function isAdmin()
                {
                                $current_role = $this->getCurrentUserRole();

                if ( $current_role == "administrator" )
                                {
                                                return true;
                                }
                                else
                                {
                                                return false;
                                }
                }

                /*
                 *      Get all restrictions
                 */
                private function getAllRestrictions()
                {
                        global $menu_restricted_access_array;


                                $all_restrictions_array = array();

                                foreach ( $menu_restricted_access_array as $one_restriction )
                                {
                                        $all_restrictions_array = array_merge($all_restrictions_array, $one_restriction);
                                }
                                $all_restrictions_array = array_unique($all_restrictions_array);

                                return $all_restrictions_array;
                }

                /*
                 *      Check the access
                 */
                private function isAccessGranted( $id_menu_item )
                {
                                global $menu_restricted_access_array;

                if ( $this->isAdmin() )
                                {
                                                return true;
                                }
                else if ( isset($menu_restricted_access_array[$this->current_user_role]) )
                {
                    $restricted_access = $menu_restricted_access_array[$this->current_user_role];

                    if ( in_array($id_menu_item, $restricted_access) )
                                        {
                        return true;
                                        }
                                        else
                                        {
                        return false;
                                        }
                }
                else {
                        return true;
                                        }

                }

     /*
                 *      Element render
                 */
                function start_el(&$output, $item, $depth, $args)
        {

            global $wp_query, $menu_restricted_access_array;
            global $g_role,$g_pageid;
            $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
                        $g_role=strtolower((trim($item->description)));

                        $str = explode(',',$g_role);
                        for( $i=0; $i< count($str); $i++)
                                {                      

                                        if (strtolower(trim($str[$i]))==$this->current_user_role)
                                        {                      
                                                $restriction =$item->object_id;        
                                                $menu_restricted_access_array[$this->current_user_role] =array( $restriction);
                                        }


                                }


            $class_names = $value = '';

            $classes = empty( $item->classes ) ? array() : (array) $item->classes;
            $classes[] = 'menu-item-' . $item->ID;


            /*
             *  First test, add custom class to each menu item
             */
                $classes[] = 'my-custom-menu-class';

            /*
             *  Detect the menu item matching the unpublished page
             *  Detect the menu item matching the unpublished page
             */
                // -> FLag to display the output
                $item_to_display = true;
                $is_item_published = true;

                // -> Gather data of linked object
                $item_data = get_post($item->object_id);

                // --> If it's a page, act on the flag

                if ( !empty($item_data) && ($item->object == "page") )
                {
                    $is_item_published = ( $item_data->post_status == "publish" ) ? true : false;
                    $item_output = "";
                }

            /*
             *  Detect and display by user Role
             **/
                if ( _USE_RESTRICTED_ACCESS )
                {
                    $restrictions_array = $this->getAllRestrictions();
                    $this->isAccessGranted($item->object_id);

                }
                else
                {
                    $item_to_display = $is_item_published;
                }

            $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
            $class_names = ' class="' . esc_attr( $class_names ) . '"';



            $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
            $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

            $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

            $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
            $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
            $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
            $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';



                        if($depth != 0)
                        {
                    $description = $append = $prepend = "";
                        }

            // --> If the flag is true, when display the output

            if ( $item_to_display )
            {
                $item_output = $args->before;
                $item_output .= '<a'. $attributes .'>';
                $item_output .= $args->link_before .apply_filters( 'the_title', $item->title, $item->ID ).$append; // this is where the strong tags are prepend and append to the description

                                $item_output .= '</a>';
                $item_output .= $args->after;
            }

            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
        }
}
/*
 *      Restrictions configuration
* 2 is page id of Homepage
 **/
define("_USE_RESTRICTED_ACCESS", true);
$menu_restricted_access_array['subscriber'] = array('2');

?>

Es ist noch nicht die sauberste Version, aber es funktioniert. Ich hoffe, jemand anderes kann das auch gut gebrauchen.

1
tejas

Ich werde meine Lösung für andere posten, die möglicherweise auf diesen Thread stoßen. Ich bin nicht 100% zufrieden damit, weil Sie eine Vorlage nicht mit der Menüfunktionalität koppeln sollten (Toschos Ansatz, Metadaten oder eine benutzerdefinierte Taxonomie zu verwenden, ist wahrscheinlich korrekter). Es ist jedoch schnell und schmutzig. Ich habe versucht, die enge Kopplung zu mildern, indem ich einige Konstanten in der oberen Hälfte von functions.php bereitgestellt habe, um zukünftigen Entwicklern bei der Pflege des Codes zu helfen:

// define the custom password-protected template that is used to determine whether this item is protected or not in the menus
define ('ZG_PROTECTED_PAGE_TEMPLATE', 'page-membersonly.php');
// define the custom capability name for protected pages
define ('ZG_PROTECTED_PAGE_CAPABILITY', 'view_member_pages');

Die geschützte Seitenvorlage ist also nur eine Variante von single.php, überprüft jedoch aus Sicherheitsgründen, ob current_user_can (ZG_PROTECTED_PAGE_CAPABILITY) vorhanden ist, bevor Inhalte angezeigt werden.

Als nächstes implementiere ich einen benutzerdefinierten Walker gemäß Toschos Vorschlag. Der Walker ist in diesem Fall äußerst einfach: Wir überschreiben die öffentlichen start_el- und end_el-Methoden von Walker_Nav_Menu und fangen sie nur so lange ab, bis wir die Frage stellen: Haben wir Zugriff auf das Menüelement?

Die Regel ist einfach: Wenn es sich bei der Seite nicht um eine "private" Seite handelt (die in diesem Fall von dieser Seite mithilfe einer bestimmten Seitenvorlage bestimmt wird), wird sie angezeigt. Wenn es sich bei IS um eine "private" Seite handelt und der Benutzer für eine Rolle authentifiziert ist, die über die von uns gesuchte benutzerdefinierte Funktion verfügt, wird sie angezeigt. Ansonsten ist es nicht sichtbar.

Wenn wir Zugriff haben, müssen wir nur die integrierten Methoden von Walker_Nav_Menu verwenden, ohne sie zu ändern. Daher rufen wir die parent :: -Methode mit demselben Namen auf.

/* Custom Walker to prevent password-protected pages from appearing in the list */
    class HALCO_Nav_Walker extends Walker_Nav_Menu {

        protected $is_private = false;
        protected $page_is_visible = false;

        // override parent method
        function start_el(&$output, $item, $depth, $args) {
            // does this menu item refer to a page that is using our protected template?
            $is_private = get_post_meta($item->object_id, '_wp_page_template', true) == ZG_PROTECTED_PAGE_TEMPLATE;
            $page_is_visible = !$is_private || ($is_private && current_user_can(ZG_PROTECTED_PAGE_CAPABILITY));

            if ($page_is_visible){
                parent::start_el(&$output, $item, $depth, $args);
            }
        }

        // override parent method
        function end_el(&$output, $item, $depth) {
            if ($page_is_visible){
                parent::end_el(&$output, $item, $depth);
            }
        }
    }
0
Tom Auger