
WordPressのメニューにページ内リンクを混入
明示的に除外しない限りだいたい全ページについてくる共通メニューのカスタマイズメモ。
使っているテンプレートが縦スクロールでセクションを並べるタイプだったので、トップページだけはページを読み直しせずにページ内リンクの移動になるようにしたかったのです。
だけど他のページからは、アンカー付きでトップページへリンクしてくれないと困ります。
メニューを書き出しているのは、Walker_Nav_Menuクラス。
wp-includes/class-walker-nav-menu.php にあります。
少し前のWPだと、wp-includes/nav-menu-template.phpにありました。
このクラスを継承してメニューを作って、必要なところだけ書き換えます。
いつもの、functions.phpに、Walker_Nav_Menuを継承したクラスを追加しました。
1 2 3 4 5 6 |
# #メニューのリンクをカスタマイズ class My_Walker_Nav_Menu extends Walker_Nav_Menu { } |
元のWalker_Nav_Menuクラスにはいくつか要素がありますが、star_el関数に、リンクのhtmlタグの内容があります。カスタマイズすべきはここだけなので、とりあえず、まずはstar_el関数を、丸ごとMy_Walker_Nav_Menuに持ってきました。
1 2 3 4 5 6 7 8 9 10 11 12 |
# #メニューのリンクをカスタマイズ class My_Walker_Nav_Menu extends Walker_Nav_Menu { public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { $indent = ( $depth ) ? str_repeat( "t", $depth ) : ''; ###コピペにつき、中略### $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); } } |
ソースの中に、それっぽい一行が。
$atts[‘href’] = ! empty( $item->url ) ? $item->url : ”;
どうやら $item->url に入った値がそのまま、リンクURLになるようです。
というわけで、その手前に追記。
リンクのURLが#ではじまるときに、Wordpressのホームページではそのままアンカーへ(ページ内リンク)、他の時はトップページへのリンクにアンカーをつけたものにします。
1 2 3 4 5 6 7 |
# # トップページのページ内リンクを、他ページでは通常リンクにする if ( !is_home()){ if(strpos($item -> url,"#")===0){ $item -> url="/".$item -> url; } } |
最終的には、こうなりました。
黄色いところ以外は元のWalker_Nav_Menuクラスからのコピペなので、実際に使っているWPのものを使ってください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# #メニューのリンクをカスタマイズ class My_Walker_Nav_Menu extends Walker_Nav_Menu { function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { $indent = ( $depth ) ? str_repeat( "t", $depth ) : ''; $classes = empty( $item->classes ) ? array() : (array) $item->classes; $classes[] = 'menu-item-' . $item->ID; /** * Filter the arguments for a single nav menu item. * * @since 4.4.0 * * @param array $args An array of arguments. * @param object $item Menu item data object. * @param int $depth Depth of menu item. Used for padding. */ $args = apply_filters( 'nav_menu_item_args', $args, $item, $depth ); /** * Filter the CSS class(es) applied to a menu item's list item element. * * @since 3.0.0 * @since 4.1.0 The `$depth` parameter was added. * * @param array $classes The CSS classes that are applied to the menu item's `<li>` element. * @param object $item The current menu item. * @param array $args An array of {@see wp_nav_menu()} arguments. * @param int $depth Depth of menu item. Used for padding. */ $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) ); $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : ''; /** * Filter the ID applied to a menu item's list item element. * * @since 3.0.1 * @since 4.1.0 The `$depth` parameter was added. * * @param string $menu_id The ID that is applied to the menu item's `<li>` element. * @param object $item The current menu item. * @param array $args An array of {@see wp_nav_menu()} arguments. * @param int $depth Depth of menu item. Used for padding. */ $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args, $depth ); $id = $id ? ' id="' . esc_attr( $id ) . '"' : ''; $output .= $indent . '<li' . $id . $class_names .'>'; # トップページのページ内リンクを、他ページでは通常リンクにする if ( !is_home()){ if(strpos($item -> url,"#")===0){ $item -> url="/".$item -> url; } } $atts = array(); $atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : ''; $atts['target'] = ! empty( $item->target ) ? $item->target : ''; $atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : ''; $atts['href'] = ! empty( $item->url ) ? $item->url : ''; /** * Filter the HTML attributes applied to a menu item's anchor element. * * @since 3.6.0 * @since 4.1.0 The `$depth` parameter was added. * * @param array $atts { * The HTML attributes applied to the menu item's `<a>` element, empty strings are ignored. * * @type string $title Title attribute. * @type string $target Target attribute. * @type string $rel The rel attribute. * @type string $href The href attribute. * } * @param object $item The current menu item. * @param array $args An array of {@see wp_nav_menu()} arguments. * @param int $depth Depth of menu item. Used for padding. */ $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth ); $attributes = ''; foreach ( $atts as $attr => $value ) { if ( ! empty( $value ) ) { $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } } /** This filter is documented in wp-includes/post-template.php */ $title = apply_filters( 'the_title', $item->title, $item->ID ); /** * Filter a menu item's title. * * @since 4.4.0 * * @param string $title The menu item's title. * @param object $item The current menu item. * @param array $args An array of {@see wp_nav_menu()} arguments. * @param int $depth Depth of menu item. Used for padding. */ $title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth ); $item_output = $args->before; $item_output .= '<a'. $attributes .'>'; $item_output .= $args->link_before . $title . $args->link_after; $item_output .= '</a>'; $item_output .= $args->after; /** * Filter a menu item's starting output. * * The menu item's starting output only includes `$args->before`, the opening `<a>`, * the menu item's title, the closing `</a>`, and `$args->after`. Currently, there is * no filter for modifying the opening and closing `<li>` for a menu item. * * @since 3.0.0 * * @param string $item_output The menu item's starting HTML output. * @param object $item Menu item data object. * @param int $depth Depth of menu item. Used for padding. * @param array $args An array of {@see wp_nav_menu()} arguments. */ $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); } } |
Wordpress管理画面 > 外観 > メニューは、ページ内リンクはカスタムリンクで#で始まるものにします。
#の内容は、トップページのソースコードから、各セクションのタイトルあたりに<a href=”#latestnews”>などアンカーが埋め込まれてあればそれを。
もしくは、<a href=”#アンカー”>で自分で作成したものを。とにかく、#で始まるようにします。
そして、テンプレート内のWalker_Nav_Menuを表示している場所を、作成したMy_Walker_Nav_Menuに置き換えます。
おそらく、header.phpです。ソースコードを「Walker_Nav_Menu」でテキスト検索して、「My_Walker_Nav_Menu」に置き換えます。
使ってるテンプレートだと、こんな感じです。
1 2 3 |
<?php wp_nav_menu(array('theme_location' => 'primary', 引数・略,'walker' => new My_Walker_Nav_Menu)); ?> |
「My_Walker_Nav_Menu」になっていますが、元は「Walker_Nav_Menu」でした。
実際に動いているサイトが、こちらです。
(サンドイッチを食べて、野菜を買って家で野菜を食べてね!)
ところで、トップページがとうとうブログだけになりました。
ボスはエネリークスに旅立ちました。 http://eneleaks.com/
Satokoが、弊社本体のスタッフブログで紹介されていたので、本人に内緒でこっそりリンクを貼ります。
新しい仲間が増えました!〜その6〜 – ・゚・発電屋ブログ・゚・