WordPress 的自訂欄位功能,也算是自訂定滿滿,前幾篇有文章內建與寫成外掛的方式的自訂欄位介紹,還有使用者帳號的自訂欄位,頁面的自訂欄位方式跟文章一樣就不說了,這次換選單頁來自訂欄位,這裡講的選單還是 Worepress 原來的選單系統,非區塊主題的選單。
自製外掛起手式
*一句老話,程式碼要放在佈景主題的 function 裡,還是要放在外掛裡,來使用這功能都可,外掛起手式這裡不再詳述,去看WordPress custom post type 如何自訂文章類型這篇😃
在本機建立伺服器環境
*要在本機建立 PHP、阿帕契網站環境可以看這篇如何使用 Python 爬取原價屋價目列表😜,別辛苦在遠端測試所寫的程式。
在 WordPress 後台的主題>選單頁面,選單項目已有一些內建好的欄位,如:href、Class、title、target=”_blank”、rel,只差沒有 ID 欄位,如果沒看到那麼多欄位,可以到選單頁面上”顯示項目設定”把欄位勾選出來,對應的 HTML 連結如下:

<li id="menu-item-19" class="dafatime menu-item menu-item-type-custom menu-item-object-custom menu-item-19"> <a title="打發時間" target="_blank" rel="ddd" href="https://dafatime.idv.tw">首頁</a> </li>
在選單項目增加 AID 自訂欄位
現在來添加一個 AID 欄位,其實也不一定要 AID 欄位,要添加 JS 的 html5 參數也是可以,這就要看個人需求,另外要注意的一點,就是所開出來的欄位需要佈景主題配合,撈取自訂欄位的參數,不然是不會在前台出現,開出來的欄位值,一樣是儲存在 _postmeta 資料表裡面,下面就添加自訂欄位的程式碼:
// 在選單項目中添加自訂欄位 function custom_menu_item_fields( $item_id, $item, $depth, $args ) { // 獲取已保存的自訂欄位值 $custom_field_value = get_post_meta( $item_id, '_menu_item_aid', true ); ?> <!-- 在選單編輯頁面中顯示自訂欄位 --> <p class="field-menu-item-aid description-thin"> <label for="edit-menu-item-aid-<?php echo esc_attr( $item_id ); ?>"> <?php esc_html_e( '連結ID', 'text-domain' ); ?><br /> <input type="text" id="edit-menu-item-aid-<?php echo esc_attr( $item_id ); ?>" class="widefat" name="menu-item-aid[<?php echo esc_attr( $item_id ); ?>]" value="<?php echo esc_attr( $custom_field_value ); ?>" /> </label> </p> <?php } add_action( 'wp_nav_menu_item_custom_fields', 'custom_menu_item_fields', 10, 4 ); // 更新選單項目時保存自訂欄位值 function save_custom_menu_item_fields( $menu_id, $menu_item_db_id, $args ) { if ( isset( $_REQUEST['menu-item-aid'][ $menu_item_db_id ] ) ) { $custom_field_value = sanitize_text_field( $_REQUEST['menu-item-aid'][ $menu_item_db_id ] ); update_post_meta( $menu_item_db_id, '_menu_item_aid', $custom_field_value ); } } add_action( 'wp_update_nav_menu_item', 'save_custom_menu_item_fields', 10, 3 );
上述程式碼就可以在後台選單項目中,看到連結 ID 的輸入框,輸入框的短可以使用 WordPress 內建樣式,省去再添加 CSS 的麻煩,差異在第 7 行 Class 最後字串,wide(長) 更 thin(短),如下圖:
<-- 長輸入框 --> <p class="field-menu-item-aid description-wide"> <-- 短輸入框 --> <p class="field-menu-item-aid description-thin">

自訂輸出選單結構 Walker
到這邊選單項目自訂欄就完成了,再來就是把自訂欄位顯示在前台的選單上,這裡有個問題是,要顯示選單項目自訂欄位,需要使用自訂選單 Walker,修改掉輸出選單的 HTML <li> 標籤部分,加入 AID 欄位顯示,下面是 Walker 程式碼入下:
class Custom_Menu_Walker extends Walker_Nav_Menu { // 修改選單項目的 HTML 輸出 function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { $output .= '<li id="menu-item-' . $item->ID . '" '; // 取得內建的 class 欄位的值 $classes = empty( $item->classes ) ? array() : (array) $item->classes; // 將內建的 class 加入到選單項目的 HTML 中 $output .= ' class="' . esc_attr( implode( ' ', $classes ) ) . '">'; // 取得內建的 title 欄位的值 $title = empty( $item->title ) ? '' : $item->title; // 檢查是否存在自訂欄位值 $custom_field_value = get_post_meta( $item->ID, '_menu_item_aid', true ); // 如果有自訂欄位值,則顯示 if ( ! empty( $custom_field_value ) ) { $item_aid = 'id ="' . esc_html( $custom_field_value ) . '"'; } $output .= '<a ' . $item_aid; $output .= 'title="' . esc_attr( $title ) . '" '; $output .= 'href="' . $item->url . '">' . $item->title . '</a>'; $output .= '</li>'; } }
在前台顯示 Walker
我把自訂 AID 欄位值添加調<a>標籤中,原本<a>標籤是沒有 ID 的,上述第 16 行取得自訂欄位值,檢查是否存在,第 18 行判斷不存在連 id=”” 都不顯示,第 22 行載入值,再來就是最後重頭戲,在前台顯示出自訂欄位,這裡一樣使用wp_nav_menu() 來掛上寫好的 Walker,將下面程式碼放到主題選單的位置。
wp_nav_menu(array( 'theme_location' => 'menu-1', 'container' => false, 'menu_class' => '', 'fallback_cb' => '__return_false', 'items_wrap' => '<ul id="%1$s" class="navbar-nav me-auto mb-2 mb-md-0 %2$s">%3$s</ul>', 'walker' => new Custom_Menu_Walker() ));
上面參數依需求自行修改,搭配自己的 CSS,第 7 行就載入剛剛寫的 Walker HTML 結構,顯示自訂欄位,下面就是輸出的 HTML 結構。
<li id="menu-item-48" class="rrrt455 menu-item menu-item-type-custom menu-item-object-custom menu-item-home"> <a id="ABC" title="首頁" href="http://localhost/edu">首頁</a> </li>
自訂欄位的值可以拿來呈現在選單 HTML 任何地方,也可以配合自己的 CSS 來使用,看個人需求,Wordpress 選單項目自訂欄位的教學範例到這裡進入尾聲,這篇文章拖了三個四個禮拜,中間發生真多事,中了新冠還要忙著找莉莉絲😄,文章上架後再去搞別的東西,掰掰~!
留言