WordPress 的自訂欄位功能,也算是自訂定滿滿,前幾篇有文章內建與寫成外掛的方式的自訂欄位介紹,還有使用者帳號的自訂欄位,頁面的自訂欄位方式跟文章一樣就不說了,這次換選單頁來自訂欄位,這裡講的選單還是 Worepress 原來的選單系統,非區塊主題的選單。

自製外掛起手式

*一句老話,程式碼要放在佈景主題的 function 裡,還是要放在外掛裡,來使用這功能都可,外掛起手式這裡不再詳述,去看WordPress custom post type 如何自訂文章類型這篇😃

在本機建立伺服器環境

*要在本機建立 PHP、阿帕契網站環境可以看這篇如何使用 Python 爬取原價屋價目列表😜,別辛苦在遠端測試所寫的程式。

在 WordPress 後台的主題>選單頁面,選單項目已有一些內建好的欄位,如:href、Class、title、target=”_blank”、rel,只差沒有 ID 欄位,如果沒看到那麼多欄位,可以到選單頁面上”顯示項目設定”把欄位勾選出來,對應的 HTML 連結如下:

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 資料表裡面,下面就添加自訂欄位的程式碼:

PHP
// 在選單項目中添加自訂欄位
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(短),如下圖:

HTML
<-- 長輸入框 -->
<p class="field-menu-item-aid description-wide">
<-- 短輸入框 -->
<p class="field-menu-item-aid description-thin">

自訂輸出選單結構 Walker

到這邊選單項目自訂欄就完成了,再來就是把自訂欄位顯示在前台的選單上,這裡有個問題是,要顯示選單項目自訂欄位,需要使用自訂選單 Walker,修改掉輸出選單的 HTML <li> 標籤部分,加入 AID 欄位顯示,下面是 Walker 程式碼入下:

PHP
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,將下面程式碼放到主題選單的位置。

PHP
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 結構。

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

最後修改日期: 2024 年 4 月 5 日

留言

撰寫回覆或留言

發佈留言必須填寫的電子郵件地址不會公開。