最近發現我的 WordPress 主題在手機上觀看,發現選單列消失,最後才想到有可能是我開啟 AMP 功能,導致版型的 JS 無法載入而發生錯誤。為了讓手機提升網頁的觀看速度,我不想因此關掉 AMP 功能,所以就自己研究如何在板型上新增 AMP 的選單列。

使用程式關鍵

此篇需要一點 CSS 與 PHP 的程式觀念,才比較好理解, 使用到的兩個主要程式代碼:

建立子主題

因為會修改到主題版面的程式碼,建議建立一個子主題,才不會影響到原本主題的功能,網路上的建立子主題的分享很多,這邊分享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 – 指示側邊欄應從頁面的哪一側打開,leftright,默認為 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 樣板上,再來就可以進一步看各位讀者如何將選單改得更美觀了!

如果有任何問題都可以在底下留言喔。

參考文件:

rHuei

一個喜歡亂玩亂弄的工程師。

Join the Conversation

2 Comments

Leave a comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *