最近發現我的 WordPress 主題在手機上觀看,發現選單列消失,最後才想到有可能是我開啟 AMP 功能,導致版型的 JS 無法載入而發生錯誤。為了讓手機提升網頁的觀看速度,我不想因此關掉 AMP 功能,所以就自己研究如何在板型上新增 AMP 的選單列。
使用程式關鍵
此篇需要一點 CSS 與 PHP 的程式觀念,才比較好理解, 使用到的兩個主要程式代碼:
- amp-sidebar – amp 提供的側邊欄,顯示選單列的區塊
- wp_get_nav_menu_items – WordPress 提供的抓取選單內容的 Function
建立子主題
因為會修改到主題版面的程式碼,建議建立一個子主題,才不會影響到原本主題的功能,網路上的建立子主題的分享很多,這邊分享Haway大大的文章(點此前往),版主的內容很詳細,應該可以輕鬆學習。
通常 WordPress 主題的選單列都是在 header.php 裡面,記得將該檔案複製到子主題裡面,之後的程式碼也都會寫在裡面。
amp-sidebar 側邊攔
新增選單按鈕
首先先建立開啟選單列的按鈕,而每個主題的選單位置不同,因此讀者需要先找到自己的版型位置喔,這邊用 <button> 建立按鈕,並且用 on 元素指定觸法 amp-sidebar 的 id。
<!-- sidebar 為 id --> <button class="hamburger" on="tap:sidebar.toggle"></button> <!-- 切換側邊欄 --> <button on="tap:sidebar">Open</button> <!-- 打開側邊欄,默認為open --> <button on="tap:sidebar.open">Open</button> <!-- 打開側邊欄 --> <button on="tap:sidebar.close">x</button> <!-- 關閉側邊欄 -->
因為是手機版面才需要顯示,可以寫 CSS 設定未超過指定寬度時顯示按鈕出來,底下為範例。
.sidebar_btn { display: none; } @media (max-width: 767px) { .sidebar_btn { display: block; } }
選單樣式
再來就是將選單的內容顯示出來,透過 <amp-sidebar> 可以簡單製作出側邊欄的樣式,底下介紹用到的元素。
- side – 指示側邊欄應從頁面的哪一側打開,left 或 right,默認為 left
- layout – 指定側邊欄的顯示佈局,必須為 nodisplay
將底下的程式放到 <body> 底下,這樣就不會被主題的版型影響,選單的樣式可以寫 class 自訂樣式。
<amp-sidebar class="sample-sidebar" id="sidebar" layout="nodisplay" side="right"> <button on="tap:sidebar.close">x</button> <ul> <li>Nav item 1</li> <li><a href="#">Nav item 2</a></li> <li>Nav item 3</li> </ul> </amp-sidebar>
再寫一個簡單的 css ,讓選單好看一些。
.sample-sidebar { width: 250px; padding: 10px; } .sample-sidebar li, nav[toolbar] li { margin: 16px; margin-left: 16px; list-style: none; }
如果有多層的選單的話,需要再用到 <amp-nested-menu> 來達到切換子選單,以下是動作指令解釋。
- amp-nested-submenu – 宣告子目錄
- amp-nested-submenu-open – 進入子目錄
- amp-nested-submenu-close – 返回父目錄
可以參考底下範例程式,就可以來切換選單了
<amp-sidebar class="sample-sidebar" id="sidebar" layout="nodisplay" side="right"> <amp-nested-menu layout="fill"> <button on="tap:sidebar.close">x</button> <ul> <li amp-nested-submenu-open> <span amp-nested-submenu-open>Nav item 1 >></span> <div amp-nested-submenu> <ul> <li> <button amp-nested-submenu-close>Go back</button> </li> <li>Nav item 1</li> </ul> </div> </li> <li><a href="#">Nav item 2</a></li> <li>Nav item 3</li> </ul> </amp-nested-menu> </amp-sidebar>
wp_get_nav_menu_items 抓取清單
上面將模板建立好之後,需要將 WordPress 的選單內容抓取出來,將資料放到選單中,因此需要使用到 wp_get_nav_menu_items 的 function ,可以參考底下的範例使用。
要注意的是需要將 $theme_location 變數值更改成原本主題的選單 ID,這個 ID 可以從 wp_nav_menu function 裡面的 theme_location 屬性取得 ID。
<amp-sidebar class="sample-sidebar" id="sidebar" layout="nodisplay" side="right"> <amp-nested-menu layout="fill"> <button on="tap:sidebar.close">x</button> <?php $theme_location = 'main-menu'; // 這邊需要更改為主題的 theme_location ID if ( ($theme_location) && ($locations = get_nav_menu_locations()) && isset($locations[$theme_location]) ) { $menu_list = '<ul>' ."\n"; $menu = get_term( $locations[$theme_location], 'nav_menu' ); $menu_items = wp_get_nav_menu_items($menu->term_id); foreach( $menu_items as $menu_item ) { if( $menu_item->menu_item_parent == 0 ) { $parent = $menu_item->ID; $menu_array = array(); foreach( $menu_items as $submenu ) { if( $submenu->menu_item_parent == $parent ) { $bool = true; $menu_array[] = '<li><a href="' . $submenu->url . '">' . $submenu->title . '</a></li>' ."\n"; } } if( $bool == true && count( $menu_array ) > 0 ) { $menu_list .= '<li amp-nested-submenu-open>' ."\n"; $menu_list .= '<span amp-nested-submenu-open>' . $menu_item->title . ' >></span>' ."\n"; $menu_list .= '<div amp-nested-submenu>' ."\n"; $menu_list .= '<ul>' ."\n"; $menu_list .= '<li><button amp-nested-submenu-close>Go back</button></li>' ."\n"; $menu_list .= implode( "\n", $menu_array ); $menu_list .= '</ul>' ."\n"; $menu_list .= '</div>' ."\n"; $menu_list .= '</li>' ."\n"; } else { $menu_list .= '<li><a href="' . $menu_item->url . '">' . $menu_item->title . '</a></li>' ."\n"; } } } $menu_list .= '</ul>' ."\n"; } echo $menu_list; ?> </amp-nested-menu> </amp-sidebar>
透過上面的程式碼,就能夠自動抓取原本的選單內容,並且套用到 amp-sidebar 樣板上,再來就可以進一步看各位讀者如何將選單改得更美觀了!
如果有任何問題都可以在底下留言喔。
參考文件:
教學很實用,步驟寫的蠻清楚。
謝謝你的支持!