文章與頁面自訂欄位功能
WordPress 的文章(posts)或頁面(pages)都有一個叫做自訂欄位功能面版,這個功能可以增加文章或頁面的欄位,內建功能在新區塊編輯器(gutenberg)沒有顯示出來,可以到設定裡把它打開,點下左上角設定按鈕➜偏好設定➜區塊➜其他項目-開啟自訂欄位,這時區塊編輯器下面就會出現自訂欄位的面板,就可以開始自訂欄位啦!
頁面與文章的基本可輸入的欄位只有標題、內容、精選圖片,文章多了內容摘要,如果要額外增加欄位,就可以自訂欄位功能,網路上有些使用者,把文章功能當作員工資料使用,舉例我增加了員工資料所需要的欄位,如電話、住址欄位,而後面所有新增文章都會有這些自訂欄位,無法關閉會一直跟這所有後續新增文章,這種增加欄位方式方便,但有個缺點!對 MySQL 資料庫結構來說,開欄位是不太佔容量,因為沒有內容,屬橫向式欄位,而 WordPress 自訂欄位方式是會佔容量的,把欄位當成內容的方式存儲欄位標籤(key_meta),就算欄位沒有內容一樣會佔容量,所以欄位就是內容,屬縱向式欄位,雖然佔不了多少容量,積沙成塔量一多也是很嚇人的。
換個方式解釋,在 MySQL 下橫向式欄位不管有幾個欄位對於儲存一篇文章來說都是屬於一筆資料,縱向式欄位假設自訂定兩個自訂欄位,每篇文章則會存下兩筆資料,如果是使用自訂欄位外掛的話,有可能會變成是四筆資料,所以使用 wordpress 的自訂欄位時請想清楚資料量再開欄位。
Metabox 自訂欄位
當然這篇文章自定欄位沒這麼初階,要寫 code 來把它完成,這樣欄位的功能跟版面可以做自己想要的,寫完就會顯示編輯頁面右邊面版與下方面版,至於程式碼要放在哪裡,對於剛接觸 wordpress 不久的人來說會覺得有點不清楚,這樣區分~!只要是需要跟 wordpress 核心需要 hook 的一定是寫在 functions 裡,這時一定有人會問,到底在哪裡,就是佈景主題或外掛裡的 functions.php,其它大多是寫在範本(template)裡面,也有例外的如短碼[code],寫在佈景主題裡換主題功能就沒的有點不方便,最好還是寫在外掛裡,比較好搬家。
來寫支外掛吧!
外掛起手勢在這裡就不再詳述,想知道的可以看 WordPress custom post type 如何自訂文章類型 這篇,這裡直接 functions 環節,以上一篇自訂文章類型,這篇接續 books 文章類型添加文章自訂欄位,在外掛裡添加下列程式碼:
//metabox hook
function box_admin() {
add_meta_box(
'meta_box', //UIID
'書籍資料', //面板標題
'display_book_meta_box', //html 內容
'books', //對應的文章類型(post_type),只會在對應的文章類型顯示 metabox 與自訂欄位
'side', //顯示位置 normal 編輯區域下方、side 側邊
'default', //顯示框優先等級 'high', 'core', 'default', 或'low'
);
}
add_action( 'add_meta_boxes', 'box_admin' );
//面板輸入欄位
function display_book_meta_box( $post ) {
echo "這裡準備要設置輸入欄位";
}
一開始先 hook metabox 面板,設定值以需要為主,上面說明就自己品吧!圖解部份如圖下。
上圖就可以知道設定值在做什麼了,再來就是自訂欄位的輸入框,放進 metabox 裡面,如過要做自訂面板樣式,面板 ID 就可以哪來運用,這裡就不而外做樣式了,就用後台的基本樣式,來增加兩個欄位 ISBN 與 出版日期,使用 table 來做排版,加入程式碼如下:
//metabox hook
function box_admin() {
add_meta_box(
'meta_box', //UIID
'書籍資料', //面板標題
'display_book_meta_box', //html 內容
'books', //對應的文章類型(post_type),只會在對應的文章類型顯示 metabox 與自訂欄位
'side', //顯示位置 normal 編輯區域下方、side 側邊
'default', //顯示框優先等級 'high', 'core', 'default', 或'low'
);
}
add_action( 'add_meta_boxes', 'box_admin' );
//面板輸入欄位
function display_book_meta_box( $post ) {
?>
<table style="width: 40%;">
<tr>
<td style="width: 40%">ISBN:</td>
<td><input type="text" style="width: 100%;" name="isbn" value="" /> </td>
</tr>
<tr>
<td style="width: 40%">出版日期</td>
<td><input type="text" style="width: 100%;" name="publish_date" value="" /></td>
</tr>
</table>
<?php
}
加入輸入框後,重新載入頁面就可以在書籍資料的 metabox 面板下面添加多了兩個輸入框如下圖。
再來就是要把 mrtabox 新增加的兩個欄位儲存到資料庫,添加下面程式碼:
//metabox hook
function box_admin() {
add_meta_box(
'meta_box', //UIID
'書籍資料', //面板標題
'display_book_meta_box', //html 內容
'books', //對應的文章類型(post_type),只會在對應的文章類型顯示 metabox 與自訂欄位
'side', //顯示位置 normal 編輯區域下方、side 側邊
'default', //顯示框優先等級 'high', 'core', 'default', 或'low'
);
}
add_action( 'add_meta_boxes', 'box_admin' );
//面板輸入欄位
function display_book_meta_box( $post ) {
?>
<table style="width: 100%;">
<tr>
<td style="width: 40%">ISBN:</td>
<td><input type="text" style="width: 100%;" name="isbn" value="" /> </td>
</tr>
<tr>
<td style="width: 40%">出版日期</td>
<td><input type="text" style="width: 100%;" name="publish_date" value="" /></td>
</tr>
</table>
<?php
}
//儲存 metabox 欄位資料
function books_save_data( $post_id ) {
//ISBN欄位
if ( array_key_exists( 'isbn', $_POST ) ) {
update_post_meta( $post_id, 'isbn', $_POST['isbn']);
}
//出版日期欄位
if ( array_key_exists( 'publish_date', $_POST ) ) {
update_post_meta( $post_id, 'publish_date', $_POST['publish_date']);
}
}
add_action( 'save_post', 'books_save_data' );
到這裡欄位輸入資料後按下編輯畫面的發佈按鈕,兩個欄位的資料就會寫入資料庫,但再次進入編輯頁面兩個欄位未被載入,需添加 get_post_meta() 提取存入的資料,如下面程式碼,重新載入頁面就會看到剛剛輸入的資料已載入輸入框內。
//metabox hook
function box_admin() {
add_meta_box(
'meta_box', //UIID
'書籍資料', //面板標題
'display_book_meta_box', //html 內容
'books', //對應的文章類型(post_type),只會在對應的文章類型顯示 metabox 與自訂欄位
'side', //顯示位置 normal 編輯區域下方、side 側邊
'default', //顯示框優先等級 'high', 'core', 'default', 或'low'
);
}
add_action( 'add_meta_boxes', 'box_admin' );
//面板輸入欄位
function display_book_meta_box( $post ) {
$isbn = get_post_meta( $post->ID, 'isbn', true );
$publish_date = get_post_meta( $post->ID, 'publish_date', true );
?>
<table style="width: 100%;">
<tr>
<td style="width: 40%">ISBN:</td>
<td><input type="text" style="width: 100%;" name="isbn" value="<?php echo $isbn; ?>" /> </td>
</tr>
<tr>
<td style="width: 40%">出版日期</td>
<td><input type="text" style="width: 100%;" name="publish_date" value="<?php echo $publish_date; ?>" /></td>
</tr>
</table>
<?php
}
//儲存 metabox 欄位資料
function books_save_data( $post_id ) {
//ISBN欄位
if ( array_key_exists( 'isbn', $_POST ) ) {
update_post_meta( $post_id, 'isbn', $_POST['isbn']);
}
//出版日期欄位
if ( array_key_exists( 'publish_date', $_POST ) ) {
update_post_meta( $post_id, 'publish_date', $_POST['publish_date']);
}
}
add_action( 'save_post', 'books_save_data' );
應該有注意到欄位名稱與 meta_key 欄位名稱是一樣的,可以到資料庫查看 _postmeta 資料表,內的 meta_key 欄位就可以看到,如下圖。
好啦~!這支 metabox 自訂欄位外掛就完成程,如過想要把兩支外掛合併為一支,只要這邊的 code 複製起來,貼到自訂文章類型外掛後面就可以變成一支了,那就這樣啦~!掰掰~!
留言