web-dev-qa-db-fra.com

Afficher les balises de contenu h2 d'une page dans le sous-menu

Je pense que je suis en train d'essayer de faire quelque chose d'inhabituel parce que je ne peux le trouver nulle part.

Je souhaite avoir un sous-menu basé sur le contenu de la page associée.
par exemple. Dans mon menu, il y a un élément de menu appelé "TOP". Cet article a une sous-page appelée "chapitre 1".
Sur la page du "chapitre 1", il y a beaucoup de contenu qui contient des valeurs séparées dans les balises H1 ou H2.

Mon objectif est d’avoir les tags H1 et H2 (y compris leur valeur) chargés dans le sous-menu du "chapitre 1".

Je pensais faire cela avec la fonction wp_nav_menu et y ajouter un marcheur. Le problème est que je ne sais pas par où ni comment commencer (surtout avec le marcheur). Évidemment, j'ai créé la page et le sous-menu dans la feuille de style comme ci-dessous:

div class="nav">
    <?php wp_nav_menu( array( 'theme_location' => 'menu') );?>
</div>

Mais maintenant, je dois charger le contenu. J'espère que tout le monde pourra m'aider avec ce "problème" par où commencer.

  • MODIFIER -
    J'ai donc trouvé un moyen de ne récupérer que le contenu de toutes les balises "H1". cela ne concerne que la page en cours de visualisation.

    function getTextBetweenTags($tag, $html, $strict=0)
            {
                /*** a new dom object ***/
                $dom = new domDocument;
    
                /*** load the html into the object ***/
    
                $dom->loadHTML($html);
    
    
                /*** discard white space ***/
                $dom->preserveWhiteSpace = false;
    
                /*** the tag by its tag name ***/
                $content = $dom->getElementsByTagname($tag);
    
                /*** the array to return ***/
                $out = array();
                foreach ($content as $item)
                {
                    /*** add node value to the out array ***/
                    $out[] = $item->nodeValue;
                }
                /*** return the results ***/
                return $out;
            }
    
            global $post;
            $post_id = $post->ID;
            $html = get_post_field('post_content', $post_id);
            $content = getTextBetweenTags('h1', $html);
            $i=0;
            echo '<ul>';
            if($content[0]){ 
                foreach( $content as $item )
                {
                    echo '<li><a href="#'.$i++.'">'.utf8_decode($item).'</a></li>';
    
                }
            }else{
            echo'<li>'.get_the_title().'</li>'; 
            }
            echo '</ul>';
    
  • NEW EDIT - J'ai donc choisi des marcheurs personnalisés. J'ai maintenant pris un lecteur d'un tutoriel que j'ai trouvé en ligne. Ce marcheur prend la description du wp_nav_menu et la place sous le titre réel. Voici le promeneur:

    class custom_walker extends Walker_Nav_Menu{        
    //start of the sub menu wrap
    function start_lvl(&$output, $depth) {
    $output .= '<div class="drop">
                    <div class="holder">
                        <div class="container">
                            <ul class="list">';
    }
    
    //end of the sub menu wrap
    function end_lvl(&$output, $depth) {
    $output .= '
                </ul>
            </div>
        </div>
        <div class="bottom"></div>
    </div>';
    }
    
    //add the description to the menu item output
    function start_el(&$output, $item, $depth, $args) {
    global $wp_query;
    $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
    
    $class_names = $value = '';
    
    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    
    $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
    $class_names = ' class="' . esc_attr( $class_names ) . '"';
    
    $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        ) .'"' : '';
    
    $item_output = $args->before;
    $item_output .= '<a'. $attributes .'>';
    $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    $item_output .= '<br /><span class="sub">' . 
            $post_id = $post->ID;
            $html = get_post_field('post_content', $post_id);
            $content = getTextBetweenTags('h2', $html);
            $i=0;
            echo '<div style="background:#000000;"><ul>';
            if($content[0]){ 
                foreach( $content as $item )
                {
                    echo '<li><a href="#'.$i++.'">'.utf8_decode($item).'</a></li>';
                }
            }
            echo '<ul></div>'
    
     . '</span>';
    $item_output .= '</a>';
    $item_output .= $args->after;
    
    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );}}
    

J'ai remplacé la partie où le $description devrait être avec mon code personnalisé pour afficher le contenu entre les balises H2.

Cela fonctionne mais voici le problème. J'ai créé une div avec un fond noir pour que la partie chargée soit clairement indiquée. Les div-blocks sont au-dessus du menu et non en dessous. Je ne peux pas déterminer quel bloc est quel élément de sous-menu.

Le script en cours crée un contenu pour chaque élément de sous-menu. C’est génial, mais il n’affiche que le contenu de la page où il se trouve. J'ai donc changé le $post->ID en $item->ID, mais cela ne me donne que les identifiants des éléments de navigation. L'avantage de ceci est qu'il montre le contenu sous les éléments de menu.

Je pense que je suis sur la bonne voie ici, mais j'ai besoin de l'aide de mes amis :-)

M.

-edit- Ceci est la fonction start_el actuelle

function start_el(&$output, $item, $depth, $args) {
    global $wp_query;
    $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

    $class_names = $value = '';

    $classes = empty( $item->classes ) ? array() : (array) $item->classes;

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

    $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        ) .'"' : '';

    $current_post = get_post( $item->object_id );

    $item_output = $args->before;
    $item_output .= '<a'. $attributes .'>';
    $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    $item_output .= '<br /><span class="sub">'.
    $doc = new DOMDocument();
    $doc->LoadHTML( $post->post_content );
    $titles = $doc->getElementsByTagName('h1');
    foreach ($titles as $a_title) {
        $single_title = $doc->saveHTML( $a_title );
    }   
    '</span>';
    $item_output .= '</a>';
    $item_output .= $args->after;


    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
1
Interactive

En gros, vous ajoutez un lecteur personnalisé à wp_nav_menu. Chaque fois qu'un élément commence, vous pouvez vérifier le contenu de la page sous-jacente à l'élément de navigation.

Lorsqu'un contenu est disponible, lisez-le dans un nouvel objet DOMDocument- et filtrez tous les titres. Avec les titres, créez des sous-liens vers le lien actuel créé dans la fonction start_el-:

Exemple de travail:

class Custom_Walker extends Walker_Nav_Menu {
        function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
            $output .= '<li>';

            // link attributes for the "normal" link
            $attributes = '';
            $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        ) .'"' : '';

            $output .= sprintf( '%1$s<a%2$s>%3$s</a>%4$s',
                $args->before,
                $attributes,
                apply_filters( 'the_title', $item->title, $item->ID ),
                $args->after
            );

            // Check for titles in the content and add them as a sub-ul after the current a-element
            // but only on level 3
            if ( $depth == 3 ) {
                $current_post = get_post( $item->object_id );
                if ( $current_post->post_type == 'page' ) {
                    $doc = new DOMDocument;
                    $doc->LoadHTML( $current_post->post_content );
                    $titles = $doc->getElementsByTagName( 'h1' );
                    // begin the sub-list here
                    $output .= '<ul>';
                    foreach ( $titles as $a_title ) {
                        // clean up the title to use as a fragment in the href-attribute
                        $sanitized_title = sanitize_title( $doc->saveHTML( $a_title ) );
                        // and add the link to the output as a li-element
                        $output .= sprintf( '<li><a href="%s#%s">%s</a></li>', esc_attr( $item->url ), $sanitized_title, $doc->saveHTML( $a_title ) );
                    }
                    // end of sub-list
                    $output .= '</ul>';
                    $doc = null;
                }
            }
        }

        function end_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
            $output .= '</li>';
        }
    }
1
uruk