
什麼是自訂欄位?
所謂的自訂欄位(Custom Fields)是指WordPress內建的自訂欄位功能(見圖),它能讓每篇文章都附掛一些屬於該文章的自訂資料,例如你希望儲存每篇文章的英文標題,以便能在前端佈景中呈現出來,開發者就能設計一個自訂欄位來儲存該篇文章的英文標題。於是使用者就能在後台建立文章時,利用自訂欄位來設定英文標題,或進行更多其他資料的擴充。而且自訂欄位不受限於內容型別,也就是說除了內建的文章(Post)、網誌分頁(Page)…等,也能使用自訂的內容型別。
自訂欄位能讓開發人員可以預先自訂最多30組由「名稱」對應「值」的文字框欄位,提供給使用者或程式去存取,當然也不一定限於要在後台寫入,寫入的時間點可以是任何的Hook時間點,就看你想做出什麼樣的功能。常見的運用是在後台由使用者存好自訂資料後發佈,就能在前台輸出佈景時,隨著取出該文章的內容時,也取出其附掛的自訂資料來做出一些功能或特效。常見的應用像是計算每篇文章的瀏覽次數、存放縮圖路徑…等,都是自訂欄位的應用。
為何要使用自訂區塊(meta box)來包裝自訂欄位?
直接使用自訂欄位的相關Function,對開發人員來說快速又方便,如add_post_meta、update_post_meta及delete_post_meta等,缺點是使用者必須將就一點,使用預設的UI,而且還需要「聰明」一點,需要知道每個特定的自訂欄位有什麼特殊效果,何況要達成某些效果,有些還要設定多個自訂欄位。因此如果後台要提供給新手使用者操作,看到自訂欄位預設的UI,可能會覺得很醜或覺得難用。
要改善自訂欄位的使用性問題,我們可以透過建立自訂區塊(Meta Box)來「包裝」一下自訂欄位的UI。是的,Meta Box骨子裡還是用自訂欄位相關的操作Function來存取設定值。使用Meta Box可讓開發人員建立自訂的區塊,如此可達成包裝原本自訂欄位的UI,您可以放文字框、下拉方塊、勾選鈕…等,甚至是一個所見即所得的編輯介面(Editor)都行,讓後台能擁有更友善的操作介面。
實例應用說明
文章一開始提到的「英文選單標題」的例子,很適合當成範例說明,我們就來看看怎麼應用Meta Box吧,要試試看的話,首先打開您佈景中的functions.php,加入以下程式:
/* 小範例:建立英文選單標題 */add_action('admin_init', 'admin_init_fn'); // 指定後台初始化時要執行我們自訂的函式admin_init_fn
function admin_init_fn() { // 使用add_meta_box來增加一個「自訂區塊」,在callback的參數位置,放上我們自訂的函式 EnTitleCB_fn add_meta_box('EnTitle', '英文標題', 'EnTitleCB_fn', 'page', 'normal', 'high', null);}
function EnTitleCB_fn() { // 需要取得目前編輯的post資訊,如id global $post; // 如果是進入編輯模式,WP會POST資料進來 $entitle_cnt = get_post_meta( $post->ID, 'EnTitle', true ); ?> <th scope="row">主選單英文標題:</th> <td> <label for="EnTitle"> <input id="EnTitle" type="text" size="75" name="EnTitle" value="<?php echo $entitle_cnt;?>" /> <br /><em>說明:設定分頁出現在選單時的英文翻譯。</em> </label> </td></tr><?php}加入上述程式碼,WP會在後台初始化時呼叫我們寫的函式admin_init_fn,然後發現我們寫了一個add_meta_box,就為我們在後台加上一個自訂區塊叫「英文標題」,並且依照我們給的CallBack函式定義,輸出自訂區塊的外觀。
是的,目前只有「外觀」! 如果真的輸入值,按下「更新」,還是無法被儲存,因為我們還要在使用者儲存文章時,一併的把我們的值也存起來,所以還要在functions.php加上一些程式碼:
add_action('wp_insert_post', 'insert_post_fn', 10, 2); // 讓WP在新增文章內容時,也執行我們定義的insert_post_fn
function insert_post_fn($post_id, $post = null) { $meta_post_fields = array("EnTitle"); // EnTitle是我們定義的input的name $goloop = false;
// 如果是我們要處理的內容型別-page (讓自訂的meta box只出現在網誌分頁裡的文章) if ($post->post_type == "page") { $mfs = $meta_post_fields; $goloop = true; }
if ($goloop) { // 取得Post進來的欄位資料,針對我們自訂的欄位$meta_fields foreach ($mfs as $key) { // 如果有空值就不進行處理 $value = @$_POST[$key]; if (empty($value)) { delete_post_meta($post_id, $key); continue; }
// 如果丟過來的參數不是陣列 if (!is_array($value)) { // 更新資料,若無法更新,代表是要新增資料 if (!update_post_meta($post_id, $key, $value)) { add_post_meta($post_id, $key, $value); } }else{ // 如果丟過來的參數是陣列,先刪除之前的值,再一個個建進相同名稱的post meta delete_post_meta($post_id, $key);
// Loop through the array adding new values to the post meta as different entries with the same name foreach ($value as $entry) { add_post_meta($post_id, $key, $entry); } } } }}我們從meta box裡面的input所丟出來的值也可能是陣列,但這有機會再介紹。加入上述的程式碼,最後我們就能得到如下圖的結果,值也能存起來,不過因為我們使用了add_post_meta來幫助我們把值存在自訂欄位中,所以我們存的值也會自動出現在自訂欄位裡。
覺得自訂欄位區塊很多餘嗎?加入以下的程式碼,就可以移除它囉!
function remove_post_custom_fields() { remove_meta_box( 'postcustom' , 'post' , 'normal' );}add_action( 'admin_menu' , 'remove_post_custom_fields' );成功的使用add_post_meta儲存每篇文章的自訂資料後,我們就可以在前台使用get_post_meta把我們在每篇文章存的值取出來用,只要指定post id和欄位名稱就可以把對應的值取出來囉,是不是很方便呢?
如此您也能打造一個專業又好用的WP客製介面!
發佈留言