Hehe, você é um novato! Vamos rasgar você em pedaços ...!
j / k :) Oferecemos boas-vindas a todos os novatos aqui, prazer em tê-lo.
Portanto, é a terceira vez que ouvi esse requisito, duas vezes de clientes e não novamente de você (e de seu cliente.) Isso me diz que é uma necessidade razoavelmente comum.
Gostei da sua análise, então decidi codificar uma classe para abordar seu segundo ponto. Liguei LittlePromoBoxes
porque nunca consigo tirar essa música da minha cabeça, graças a eles . Basicamente, uso a classe para encapsular para evitar possíveis conflitos de nomes com as funções que eu precisaria escrever.
Você pode colocar essa classe no functions.php
arquivo do seu tema ou no arquivo .PHP de um plug-in que possa estar escrevendo (mas não se preocupe, parece muito mais complexo do que é).
A primeira função on_load()
é uma função estática que eu chamo no final da declaração de classe para inicializar os três (3) ganchos necessários (as funções estáticas da fyi são essencialmente funções relacionadas à classe , não à instância) :
O init
gancho para registrar o promo-box
tipo de postagem,
O add_meta_boxes_post
gancho para permitir que você defina o metabox e
O wp_insert_post_data
gancho para permitir que você capture as caixas promocionais selecionadas e salve no banco de dados.
Cada um desses ganchos faz referência a outra função estática da classe (essas eram as funções que eu estava encapsulando ao criar a classe).
Vou pular a descrição da action_init()
função e minha make_labels()
função auxiliar, assumindo que você saiba como registrar um tipo de postagem com base na sua pergunta.
A action_add_meta_boxes_post()
função registra a metabox usando a função principal do WordPress add_meta_box()
e eu comentei seus parâmetros para explicar por que passei no que passei para cada um. A função de retorno de chamada the_little_promo_boxes_metabox()
é obviamente outra função estática da classe e é o que realmente exibe o conteúdo no metabox. Ele usa principalmente a função principal do WordPress wp_dropdown_pages()
para exibir uma lista de caixas promocionais (observe que ele exibirá outros tipos de postagem além da 'página', mas apenas se eles estiverem marcados como estando 'hierarchical'=>true
em seu registro de tipo de postagem. Por que apenas hierárquico? Porque é dessa maneira que eles escreveu, é por isso! :)
Como mostramos três (3) listas suspensas, precisamos fornecer a cada um um ID exclusivo no HTML ( "promo_box_{$i}"
), mas o mesmo nome entre colchetes ( 'promo_boxes[]'
), para que o PHP os colete em uma matriz dentro da $_POST
variável (que o WordPress acessa para nós; você verá como em um minuto) . E é claro que precisamos definir o valor selecionado ( (empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i])
) se um dos valores já tiver sido selecionado anteriormente.
Também usei a função principal do WordPress get_post_type_object()
para mostrar como obter os rótulos de um tipo de postagem, e também usando a função principal do WordPress get_post_meta()
para recuperar uma matriz de IDs de caixas promocionais usando a chave de campo personalizada '_promo_boxes', que mostrarei que você tem para salvar em seguida (observe que usei um sublinhado anterior no nome '_promo_boxes'
que faz com que o WordPress oculte da interface do usuário do campo personalizado padrão quando o usuário estiver editando a postagem.) .
A última função a ser descrita antes de você ver o código é o filter_wp_insert_post_data()
que recebe os dados de postagem existentes no primeiro parâmetro ( $data
) e o conteúdo da $_POST
matriz, graças ao WordPress como o segundo parâmetro ( $postarr
). Dentro dessa função, chamamos a função principal do WordPress update_post_meta()
e extraímos o array das caixas promocionais ( $postarr['promo_boxes']
) para salvar no valor do campo personalizado da chave '_promo_boxes'
da postagem especificada pelo $_POST
array (por exemplo $postarr['ID']
).
Dito isto, aqui está o código para a LittlePromoBoxes
classe:
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();
Ainda existem duas (2) funções estáticas ainda não mencionadas: get_promo_boxes()
e get_promo_box()
; essas são funções auxiliares para ajudá-lo a recuperar as postagens post_type='promo-box'
pelos seus números ordinais 1..3. Mas para torná-los mais WordPress, como aqui estão duas funções de wrapper para adicionar ao functions.php
arquivo do seu tema (observe que você pode passar uma postagem como um parâmetro, mas não é necessário, a menos que esteja usando uma postagem diferente da do 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);
}
Agora você pode chamar uma ou ambas as funções no seu single.php
arquivo de tema com um código que se parece com isso (esse código pode ter sido escrito em um loop, mas a maioria dos temáticos do WordPress parece gostar de duplicar o código para que possa lê-lo em vez de eliminar a redundância Então, quando em Roma ...):
<?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>';
?>