Хе-хе, ты новичок! Мы разорвем тебя в клочья ...!
j / k :) Мы предлагаем теплый прием всем новичкам здесь, рад, что вы.
Поэтому я слышу это требование в третий раз, дважды от клиентов, а не от вас (и вашего клиента). Это говорит о том, что это достаточно распространенная потребность.
Мне понравился твой анализ, поэтому я решил написать код для твоего второго пункта. Я назвал это, LittlePromoBoxes
потому что я никогда не могу выкинуть эту песню из головы, благодаря им . В основном я использую класс для инкапсуляции, чтобы избежать возможных конфликтов имен с функциями, которые мне нужно написать.
Вы можете поместить этот класс в functions.php
файл вашей темы или в файл .PHP плагина, который вы, возможно, пишете (но не волнуйтесь, он выглядит намного сложнее, чем он есть).
Первая функция on_load()
- это статическая функция, которую я вызываю в конце объявления класса для инициализации трех (3) хуков, которые вам понадобятся (например, статические функции - это функции, связанные с классом , а не с экземпляром) :
init
Крюк , чтобы зарегистрировать promo-box
тип записи,
add_meta_boxes_post
Крюк , чтобы позволить вам определить METABOX, и
wp_insert_post_data
Крюк , чтобы позволить вам захватить выбранные промо коробки и сохранить в базе данных.
Каждый из этих хуков ссылается на другую статическую функцию в классе (это были функции, которые я инкапсулировал, создавая класс.)
Я пропущу описание action_init()
функции и моей make_labels()
вспомогательной функции, предполагая, что вы знаете, как зарегистрировать тип сообщения на основе вашего вопроса.
action_add_meta_boxes_post()
Функция регистрирует METABOX с помощью функции ядра WordPress , add_meta_box()
и я заметил , что это параметры , чтобы объяснить , почему я прошел , что я проходил мимо каждого из них . Функция обратного вызова, the_little_promo_boxes_metabox()
конечно, является другой статической функцией класса, и именно она отображает содержимое в метабоксе. В основном он использует основную функцию WordPress wp_dropdown_pages()
для отображения списка рекламных блоков (обратите внимание, что он будет отображать другие типы записей, кроме «страницы», но только в том случае, если они помечены как находящиеся 'hierarchical'=>true
в их регистрации типов записей. Почему только иерархические? написал это, вот почему! :)
Поскольку мы показываем три (3) выпадающих списка, нам нужно дать каждому уникальный идентификатор в HTML ( "promo_box_{$i}"
), но одно и то же имя в квадратных скобках ( 'promo_boxes[]'
), чтобы PHP собирал их в массив внутри $_POST
переменной (к которой WordPress обращается к нам; Вы увидите, как через минуту) . И, конечно, нам нужно установить выбранное значение ( (empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i])
), если действительно одно из значений было выбрано ранее.
Я также использовал основную функцию WordPress, get_post_type_object()
чтобы показать, как получать метки от типа записи, а также использовал основную функцию WordPress, get_post_meta()
чтобы получить массив идентификаторов промо-боксов, используя ключ настраиваемого поля '_promo_boxes', который я покажу вам чтобы сохранить следующее (обратите внимание, что в названии я использовал предыдущее подчеркивание, '_promo_boxes'
которое заставляет WordPress скрываться от стандартного пользовательского интерфейса настраиваемого поля, когда пользователь редактирует сообщение.) .
Последняя функция, которую нужно описать перед тем, как вы увидите код, - filter_wp_insert_post_data()
получает существующие данные поста в первом параметре ( $data
) и содержимое $_POST
массива благодаря WordPress в качестве второго параметра ( $postarr
). Внутри этой функции мы вызываем основную функцию WordPress update_post_meta()
и извлекаем массив промо-боксов ( $postarr['promo_boxes']
), чтобы сохранить значение пользовательского поля для ключа '_promo_boxes'
для поста, указанного в $_POST
массиве (то есть $postarr['ID']
).
Тем не менее, вот код для 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'
по их порядковым номерам 1..3. Но чтобы сделать их более похожими на WordPress, вот две функции-обертки, которые нужно добавить в functions.php
файл вашей темы (обратите внимание, что вы можете передавать сообщение в качестве параметра, но вам это не нужно, если вы не используете сообщение, отличное от того, что в 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>';
?>