Настраиваемое поле/мета, заполненное выпадающим списком существующих сообщений?
(Мой первый вопрос WP, когда-либо заданный! Будь нежен!)
Я создаю сайт, который в основном состоит из страниц (т.Е. статических), используя WP в качестве CMS. В нижней части нескольких страниц появятся 1, 2 или 3 "промо-поля" - в основном изображения кнопок, которые ссылаются на другие части сайта. Хотя на любой странице будет отображаться только до 3 промо-боксов, на выбор будет ~30 различных.
Когда мой клиент создает новую страницу, я бы хотел, чтобы он мог выберите промо-боксы из чего-то вроде выпадающего списка всех возможных промо-боксов.
Мне кажется, это должно работать так:
- Создайте пользовательский тип публикации под названием "промо-бокс". (Хотя с таким же успехом это может быть тег для обычных сообщений.)
- Используйте такой инструмент, как Пользовательский шаблон поля , чтобы создать раскрывающийся список в редакторе страниц, где значения параметров раскрывающегося списка динамически генерируются из списка всех существующих сообщений в промо-боксе. (Это это та часть, которую я не знаю, как сделать.)
- Получите доступ к полученным метаданным (номер записи - это действительно все, что мне нужно, тогда я смогу получить все остальное) в шаблоне страницы.
Основываясь на ответах на другие вопросы здесь, я сначала взглянул на метабокс WPAlchemy, Сообщения-2-Сообщения и пользовательские поля SLT, но, признаюсь, документация для каждого из них немного сложнее, чем я, поэтому я не слишком углублялся.
Совет? Является ли один из вышеперечисленных инструментов правильным решение для меня, и я просто должен это выяснить? Я что-то здесь упускаю?
2 answers
Как автор WPAlchemy, я немного предвзят, но у вас, по сути, есть хорошая рабочая модель, которой нужно следовать в зависимости от того, какой маршрут вы выберете.
Однако, если вы используете 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
по сути представляет собой HTML-файл с содержимым ФОРМЫ в мета-поле, в данном случае вашего выпадающего списка, для создания вашего выпадающего списка вы должны выполнить пользовательский запрос wp, чтобы получить все ваши пользовательские типы записей. В WPAlchemy есть некоторые специальные вспомогательные функции, помогающие создавать элементы формы.
Существует дополнительная документация , которая поможет вам при работе с шаблоном.
Основной целью WPAlchemy было сохранить контроль в руках разработчика, от стиля (внешний вид + ощущения) до определения содержимого мета-бокса.
И я, и другие всегда готовы помочь тем, кто комментирует и задает вопросы.
Хе-хе, ты новичок! Мы разорвем тебя в клочья...!
J/k:) Мы тепло приветствуем всех новичков здесь, рады видеть вас.
Итак, я уже в 3-й раз слышу это требование, дважды от клиентов, а не снова от вас (и вашего клиента). Это говорит мне о том, что это достаточно распространенная потребность.
Мне понравился ваш анализ, поэтому я решил закодировать класс, чтобы ответить на ваш 2-й пункт. Я назвал это LittlePromoBoxes
, потому что я никогда не смогу выкинь эту песню из моей головы, спасибо им. В основном я использую класс для инкапсуляции, чтобы в противном случае избежать потенциальных конфликтов имен с функциями, которые мне нужно было бы написать.
Вы можете поместить этот класс в файл вашей темы functions.php
или в.PHP-файл плагина, который вы, возможно, пишете (но не волнуйтесь, он выглядит намного сложнее, чем есть на самом деле.)
Первая функция on_load()
- это статическая функция, которую я вызываю в конце объявления класса, чтобы инициализируйте три (3) крючка, которые вам понадобятся (к вашему сведению, статические функции по сути являются функциями , относящимися к классу, а не к экземпляру) :
Крючок
init
для регистрации типа записиpromo-box
,Крючок
add_meta_boxes_post
, позволяющий определить метабокс, иКрючок
wp_insert_post_data
, позволяющий вам захватывать выбранные рекламные коробки и сохранять их в базе данных.
Каждый из этих крючков ссылается на другой статический функция в классе (это были функции, которые я инкапсулировал, создавая класс.)
Я пропущу описание функции action_init()
и моей вспомогательной функции make_labels()
, предполагая, что вы знаете, как зарегистрировать тип сообщения на основе вашего вопроса.
Функция action_add_meta_boxes_post()
регистрирует метабокс, используя основную функцию 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()
, которая получает существующие данные post в первом параметре ($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
(обратите внимание, что вы можете передать сообщение в качестве параметра, но вам не нужно этого делать, если вы не используете другой пост, который находится в Цикле):
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>';
?>