問題描述
(我的第一個 WP 問題曾經問過!溫柔!)
我正在構建一個主要是頁面 (即靜態) 的網站,使用 WP 作為 CMS 。在幾頁的底部,將出現 1,2 或 3 個”promo boxes” – 基本上 button-images 連結到站點的其他部分。雖然在任何給定的頁面上只能出現 3 個促銷框,但可以選擇 30 個不同的促銷框。
當我的客戶建立一個新頁面時,我希望他能夠從所有可能的促銷框的下拉式清單中選擇促銷框。
看來我應該這樣工作:
-
建立名為”promo-box” 的自定義帖子型別。 (儘管它可以很容易地成為常規帖子的標籤。)
-
使用類似 Custom Field Template 的工具在頁面編輯器上建立一個下拉式清單,其中從所有現有的 promo-box 帖子的列表中動態生成下拉選項的值。 (這是我不知道該怎麼做的部分)
-
訪問生成的後設資料 (釋出號真的是我需要的,然後我可以得到所有其他) 在頁面模板上。
根據對其他問題的回應,我已經初步看過 WPAlchemy MetaBox,Post-2-Posts 和 SLT Custom Fields,但是我承認每個檔案的檔案比我都微乎其微,所以我還沒有被挖掘出來太深了
建議嗎?上面的工具之一是我正確的解決方案,我只需要弄清楚?我在這裡遺漏了什麼嗎?
最佳解決方案
作為 WPAlchemy 的 author,我有點偏見,但您基本上有一個很好的工作模式概述遵循,根據你選擇的路線。
但是,如果使用 WPAlchemy,您將基本上執行以下操作 (步驟#2):
// functions.php
include_once 'WPAlchemy/MetaBox.php';
if (is_admin())
{
// a custom style sheet if you want to do some fancy styling for your form
wp_enqueue_style('custom_meta_css', TEMPLATEPATH . '/custom/meta.css');
}
// define the meta box
$custom_metabox = new WPAlchemy_MetaBox(array
(
'id' => '_custom_meta',
'title' => 'My Custom Meta',
'template' => TEMPLATEPATH . '/custom/meta.php'
));
custom/meta.css
可以包含樣式,您可以使用 custom/meta.php
樣式,custom/meta.php
本質上是一個具有後設資料框的 FORM 內容的 HTML 檔案,在這種情況下,您的下拉選單將生成您的下拉選單,您將執行一個自定義 wp 查詢來獲取所有的自定義帖子型別。 WPAlchemy 有一些特殊的幫助函式來幫助建立表單元素。
另外還有一個 documentation 來幫助你在模板中工作。
WPAlchemy 的主要目標是將開發者掌握控制權,從造型 (外觀+感覺) 到元框內容定義。
我和他人總是樂意幫助那些發表評論和提問的人。
次佳解決方案
呵呵,你是個新手!我們要撕裂你的碎片…!
j /k :) 我們熱烈歡迎這裡的所有新手,很高興有你。
所以這是我第三次聽到這個要求,兩次來自客戶,不再來自你 (和你的客戶) 。這告訴我這是一個很常見的需要。
我喜歡你的分析,所以我決定編寫一個類來解決你的第二點。我呼叫 LittlePromoBoxes
,因為我不能讓 this song 出來,感謝 them 。基本上我使用類來封裝,以避免與我需要編寫的函式發生潛在的命名衝突。
您可以將此類放在主題的 functions.php
檔案中,或者在您可能正在編寫的外掛的.PHP 檔案中 (但不要擔心,它看起來比它複雜得多) 。
第一個函式 on_load()
是一個靜態函式,我在類宣告的末尾呼叫初始化你需要的三 (3) 個鉤子 (fyi 靜態函式本質上是 functions related to the class,而不是例項):
-
init
掛鉤註冊promo-box
帖子型別, -
add_meta_boxes_post
鉤子允許您定義 metabox,和 -
wp_insert_post_data
鉤子允許您捕獲所選的促銷框並儲存到資料庫。
這些鉤子中的每一個引用了類中的另一個靜態函式 (這些是我透過建立類封裝的函式) 。
我將跳過描述 action_init()
函式和 make_labels()
幫助函式,假設您知道如何根據您的問題註冊一個帖子型別。
action_add_meta_boxes_post()
功能使用 WordPress 核心函式 add_meta_box()
註冊 metabox,我已經評論過它的引數,以解釋為什麼我透過了我為每個透過了。回撥函式 the_little_promo_boxes_metabox()
當然是該類的另一個靜態函式,它實際上是在 metabox 中顯示的內容。它主要使用 WordPress 核心函式 wp_dropdown_pages()
來顯示一個促銷框列表 (注意它將顯示除了’page’ 之外的其他帖子型別,但只有在他們的帖子型別註冊中被標記為'hierarchical'=>true
,為什麼只有層次結構?因為這樣寫了,這就是為什麼!:)
由於我們顯示了三 (3) 個下拉式清單,所以我們需要在 HTML("promo_box_{$i}"
) 中給出每個唯一的 ID,但是使用方括號 ('promo_boxes[]'
) 賦予相同的名稱,以便 PHP 將它們收集到 $_POST
變數中的陣列 (WordPress 訪問對我們來說,你會看到如何在一分鐘內) 。當然,我們需要設定選擇的值 ((empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i])
),如果其中一個值以前被選中。
我還使用 WordPress 核心函式 get_post_type_object()
來顯示如何從帖子型別獲取標籤,並且還使用 WordPress 核心函式 get_post_meta()
從使用自定義欄位鍵’_promo_boxes’ 來檢索一個促銷框 ID 陣列,我會顯示你有儲存下一個 (注意我使用名稱'_promo_boxes'
中的一個前面的下劃線,導致 WordPress 在使用者編輯帖子時從標準自定義欄位 UI 隱藏) 。
在您看到程式碼之前,描述的最後一個功能是 filter_wp_insert_post_data()
,它接收第一個引數 ($data
) 中的現有帖子資料以及 $_POST
陣列的內容,這得益於 WordPress 作為第二個引數 ($postarr
) 。在這個功能裡面,我們稱之為 WordPress 核心函式 update_post_meta()
,並提取促銷框陣列 ($postarr['promo_boxes']
),以儲存 $_POST
陣列 (即 $postarr['ID']
) 指定的帖子'_promo_boxes'
的自定義欄位值。
也就是說,這是 LittlePromoBoxes
類的程式碼:
class LittlePromoBoxes {
static function on_load() {
add_action('init',array(__CLASS__,'action_init'));
add_action('add_meta_boxes_post',array(__CLASS__,'action_add_meta_boxes_post'));
add_filter('wp_insert_post_data',array(__CLASS__,'filter_wp_insert_post_data'),10,2);
}
static function action_init() {
register_post_type('promo-box',array(
'labels' => self::make_labels('Promo Box','Promo Boxes'),
'public_queryable'=> false,
'hierarchical' => true, // IMPORTANT!!! wp_dropdown_pages() requires 'hierarchical'=>true
'show_ui' => true,
'query_var' => false,
'supports' => array('title','editor','thumbnail','custom-fields'),
'show_in_nav_menus'=>true,
'exclude_from_search'=>true,
));
}
static function make_labels($singular,$plural=false,$args=array()) {
if ($plural===false)
$plural = $singular . 's';
elseif ($plural===true)
$plural = $singular;
$defaults = array(
'name' =>_x($plural,'post type general name'),
'singular_name' =>_x($singular,'post type singular name'),
'add_new' =>_x('Add New',$singular),
'add_new_item' =>__("Add New $singular"),
'edit_item' =>__("Edit $singular"),
'new_item' =>__("New $singular"),
'view_item' =>__("View $singular"),
'search_items' =>__("Search $plural"),
'not_found' =>__("No $plural Found"),
'not_found_in_trash'=>__("No $plural Found in Trash"),
'parent_item_colon' =>'',
);
return wp_parse_args($args,$defaults);
}
static function action_add_meta_boxes_post($post) {
add_meta_box(
'little-promo-boxes', // Metabox Name, used as the "id" for a wrapping div
'Little Promo Boxes', // Metabox Title, visible to the user
array(__CLASS__,'the_little_promo_boxes_metabox'), // Callback function
'post', // Add to the Edit screen for Post Types of 'post'
'side', // Show it in the sidebar (if center then it would be 'normal'
'low' // Show it below metaboxes that specify 'high'
);
}
static function the_little_promo_boxes_metabox($post) {
$pto = get_post_type_object('promo-box');
$default_options = array(
'post_type' => 'promo-box',
'show_option_none' => "Select a {$pto->labels->singular_name}",
);
$promo_boxes = get_post_meta($post->ID,'_promo_boxes',true);
for($i=0; $i<=2; $i++) {
wp_dropdown_pages(array_merge($default_options,array(
'id' => "promo_box_{$i}",
'name' => 'promo_boxes[]',
'selected' => (empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i]),
)));
}
}
static function filter_wp_insert_post_data($data, $postarr) {
update_post_meta($postarr['ID'],'_promo_boxes',$postarr['promo_boxes']);
return $data;
}
static function get_promo_boxes($post=false) {
static $promo_boxes=array();
if (!$post)
$post = $GLOBALS['post'];
if (!isset($promo_boxes[$post->ID])) {
$promo_boxes[$post->ID] = get_post_meta($post->ID,'_promo_boxes',true);
$index = 0;
foreach($promo_boxes[$post->ID] as $promo_box_id) {
$promo_boxes[$post->ID][$index++] = (is_numeric($promo_box_id) ? get_post($promo_box_id) : false);
}
}
return $promo_boxes[$post->ID];
}
static function get_promo_box($number,$post=false) {
$promo_boxes = self::get_promo_boxes($post);
return $promo_boxes[$number-1];
}
}
LittlePromoBoxes::on_load();
還沒有提到兩個 (2) 靜態功能:get_promo_boxes()
和 get_promo_box()
; 這些是幫助函式,幫助您透過其序號查詢 post_type='promo-box'
的帖子。但是要讓他們更多的 WordPress 像這裡是兩個包裝函式新增到您的主題的 functions.php
檔案 (注意,你可以傳遞一個引數,但你不必,除非你使用不同的帖子,一個在 The Loop) :
function get_little_promo_boxes($post=false) {
return LittlePromoBoxes::get_promo_boxes($post);
}
function get_little_promo_box($number,$post=false) {
return LittlePromoBoxes::get_promo_box($number,$post);
}
現在您可以在 single.php
主題檔案中呼叫這些函式中的一個或兩個,其程式碼可能類似於此 (此程式碼可能已經被寫入迴圈中,但大多數 WordPress 主體似乎喜歡重複程式碼,以便他們可以讀取它而不是消除冗餘,所以,當在羅馬…):
<?php
$promo_boxes = get_little_promo_boxes();
if (isset($promo_boxes[1]))
echo '<div id="promo-box1" class="promo-box">' . get_the_title($promo_boxes[1]->ID) . '</div>';
if (isset($promo_boxes[2]))
echo '<div id="promo-box2" class="promo-box">' . get_the_title($promo_boxes[2]->ID) . '</div>';
if (isset($promo_boxes[3]))
echo '<div id="promo-box3" class="promo-box">' . get_the_title($promo_boxes[3]->ID) . '</div>';
?>
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。