web-dev-qa-db-fra.com

Marcheur personnalisé avec hachages en lieu de liens

Je développe actuellement une mise en page basée sur une page avec WordPress dans laquelle le contenu réel est divisé en pages distinctes dans le backend, qui sont toutes reliées pour former une mise en page d'une page dans mon fichier de modèle de page d'accueil.

Les menus WordPress autorisent des URL personnalisées, ce qui est probablement le moyen le plus simple de gérer un document d'une page en faisant référence à des liens basés sur un hachage menant aux div correspondants.

Cependant, je suis à la recherche de la solution probablement la plus propre pour organiser le menu et ses ancres, de sorte que les éditeurs/administrateurs réels d'un site puissent simplement créer un lien vers une page réelle et le faire traduire par un programme personnalisé en un hachage qui mène à la bonne section. sur le frontend.

Jusqu’à présent, j’allais avec le slug des pages simples, laissais le wp_query le ramasser et l’ajouter comme identifiant à la division d’emballage, par exemple.

La page 1 intitulée 'La page à propos' a un slug 'à propos de la page', la div ressemble alors à

<div class="section_wrapper" id="about-page"></div>

et tapez ce slug comme URL de hachage dans l'éditeur de menu.

Existe-t-il un simple lecteur ou une autre solution qui aide dans ce cas, c’est-à-dire, qui convertit les liens vers les pages en hachages simples? Ou une pratique encore meilleure?

1
physalis

Après des recherches plus approfondies, j’ai finalement trouvé une solution viable, propre et simple, qui fonctionne jusqu’à présent sans faille.

Il suffit de placer ceci dans votre functions.php pour créer un programme personnalisé qui transforme les permaliens classiques en hachages (par exemple, page.com/mypage en page.com/#mypage):

/* Custom nav walker */

class Single_Page_Walker extends Walker_Nav_Menu{
    function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
       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        ) .'"' : '';
       if($item->object == 'page')
       {
            $varpost = get_post($item->object_id);
            if(is_home()){
              $attributes .= ' href="#' . $varpost->post_name . '"';
            }else{
              $attributes .= ' href="'.home_url().'/#' . $varpost->post_name . '"';
            }
       }
       else
            $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 );
        $item_output .= $args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;
        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args, $id );
    }
}

Ensuite, là où vous voulez que votre menu apparaisse, insérez le code suivant pour appeler votre menu (que vous auriez dû définir auparavant comme une position de menu dans votre functions.php), et ajustez les options à votre guise, en dehors du "lecteur" partie:

<?php 
    wp_nav_menu(array(
    'theme_location' => 'onepage',
    'echo' => true,
    'container' => false,
    'walker'=> new Single_Page_Walker,
    'depth' => 1) );
?>

- c’est déjà ça. Maintenant, vous pouvez remplir votre menu dans le backend sans plus vous soucier des hash :).

2
physalis

Je le fais actuellement sur un projet.

Tout d'abord, j'utilise le slug pour créer l'ancre sur le template onepage:

<article id="post-<?= get_slug(get_the_ID()); ?>" class="container">

Ensuite. J'utilise le code suivant dans une classe de menu personnalisé pour remplacer l'URL de l'attribut href de l'élément de menu.

/**
* Figure out if the current item is on the page - replace anchor
*/
if (is_page_template('template-forside.php')) {
    $onepageID = get_the_ID();
} else {
    $onepageID = get_option('page_on_front');
}


// Build array of IDs that are on the page
$onepageids = array($onepageID);
$pages = get_pages('child_of='.$onepageID);
foreach($pages as $child) {
    array_Push($onepageids, $child->ID);
}

if( in_array($item->object_id,$onepageids) ) {
    if ( is_page_template('template-forside.php') ) {
        // The menu item links to the current page
        $atts['href']   = '#post-'.get_slug($item->object_id);
    } else {
        $atts['href'] = get_home_url().'#post-'.get_slug($item->object_id);
    }


} else {
    $atts['href']   = ! empty( $item->url )        ? $item->url        : '';
}

Notez que je fais trois choses:

  1. Déterminez s'il s'agit réellement d'un modèle à une page (template-forside.php) ou non. Sinon, la page de couverture du site est la page de garde.
  2. Construire un tableau d'id de page qui se trouvent sur la première page
  3. Utilisez ce tableau pour vérifier si l'ID de menu-objects est sur le modèle d'une page.
  4. Si tel est le cas, je modifie href en ancre slug (si la page en cours est la page en cours). Ou ajoutez l'URL de la maison avant l'ancre de la limace (ou pas sur la page dès maintenant)

NOTE - Ce code est assez erroné car il suppose que le modèle d’une page est la page de couverture, il ne peut donc pas être complètement généralisé.

0
Kristoffer