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 選單項目自訂欄位的教學範例到這裡進入尾聲,這篇文章拖了三個四個禮拜,中間發生真多事,中了新冠還要忙著找莉莉絲😄,文章上架後再去搞別的東西,掰掰~!
留言