¿Campo / meta personalizado rellenado por el menú desplegable de publicaciones existentes?

11

(Mi primera pregunta de WP: ¡se amable!)

Estoy creando un sitio que es en su mayoría páginas (es decir, estático), usando WP como CMS. En la parte inferior de varias de las páginas, aparecerán 1, 2 o 3 "cuadros de promoción", básicamente, imágenes de botones que enlazan con otras partes del sitio. Aunque solo aparecerán hasta 3 casillas de promociones en cualquier página, habrá alrededor de 30 diferentes para elegir.

Cuando mi cliente crea una nueva página, me gustaría que pueda elegir los cuadros de promoción de algo así como una lista desplegable de todos los posibles cuadros de promoción.

Me parece que esto debería funcionar así:

  • Crea un tipo de mensaje personalizado llamado "promo-box". (Aunque podría ser fácilmente una etiqueta para publicaciones regulares).
  • Use una herramienta como Plantilla de campo personalizado para crear un menú desplegable en el editor de páginas, donde los valores de las opciones desplegables se generan dinámicamente a partir de la lista de todas las publicaciones de promo-box existentes. ( Esta es la parte que no sé cómo hacer. )
  • Acceda a los metadatos resultantes (el número de publicación es realmente todo lo que necesito, luego puedo obtener todo lo demás) en la plantilla de la página.

Basándome en las respuestas a otras preguntas aquí, he echado un vistazo inicial a WPAlchemy MetaBox, Posts-2-Posts y SLT Custom Fields, pero confieso que la documentación de cada una de ellas es ligeramente más geek que yo, por lo que no profundizar demasiado.

¿Consejo? ¿Es una de las herramientas anteriores la solución adecuada para mí y solo tengo que descubrirla? ¿Me estoy perdiendo algo aquí?

    
pregunta Nic Warmenhoven 22.12.2010 - 01:00

2 respuestas

7

Como autor de WPAlchemy , soy un poco parcial, pero básicamente tienes un buen modelo de trabajo que debes seguir, dependiendo de la ruta que elijas.

Sin embargo, si usa WPAlchemy, básicamente haría algo como lo siguiente (paso # 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 puede contener estilos con los que puede aplicar estilo a su formulario y custom/meta.php es esencialmente un archivo HTML con el contenido del FORMULARIO del cuadro de meta, en este caso su menú desplegable, para generar su menú desplegable, haría un consulta wp personalizada para obtener todos sus tipos de correos personalizados. WPAlchemy tiene algunas funciones especiales de ayuda para ayudar a crear los elementos de tu formulario.

Hay documentación adicional para ayudarlo cuando trabaje en la plantilla.

El objetivo principal de WPAlchemy era mantener el control en manos del desarrollador, desde el estilo (look + feel) hasta la definición del contenido de la meta box.

Y yo y otros siempre estamos dispuestos a ayudar a quienes comentan y hacen preguntas.

    
respondido por el farinspace 22.12.2010 - 07:07
14

Jeje, eres un novato! ¡Te vamos a destrozar ...!

j / k :) Ofrecemos una cálida bienvenida a todos los novatos aquí, me alegro de contar con usted.

Esta es la tercera vez que escucho este requisito, dos veces de clientes y no de usted (y de su cliente). Eso me dice que es una necesidad bastante común.

Megustótuanálisis,asíquedecidíprogramarunaclaseparaabordartusegundopunto.LollaméLittlePromoBoxesporquenuncapuedosacar esta canción de mi cabeza, gracias a them . Básicamente, uso la clase para encapsular, para evitar posibles conflictos de nombres con las funciones que necesitaría escribir.

Puede poner esta clase en el archivo functions.php de su tema o en un archivo .PHP de un complemento que podría estar escribiendo (pero no se preocupe, parece mucho más complejo de lo que es).

La primera función on_load() es una función estática a la que llamo al final de la declaración de clase para inicializar los tres (3) ganchos que necesitará (las funciones estáticas de fyi son esencialmente funciones relacionadas con la clase , no con la instancia) :

  1. El gancho init para registrar el tipo de publicación promo-box ,

  2. El gancho add_meta_boxes_post para permitirte definir el metabox, y

  3. El gancho wp_insert_post_data le permite capturar los cuadros de promoción seleccionados y guardar en la base de datos.

Cada uno de esos enlaces hace referencia a otra función estática en la clase (estas fueron las funciones que estaba encapsulando al crear la clase).

Saltaré describiendo la función action_init() y mi función make_labels() helper asumiendo que sabes cómo registrar un tipo de publicación según tu pregunta.

La función action_add_meta_boxes_post() registra el metabox usando la función central de WordPress add_meta_box() y he comentado sus parámetros para explicar por qué pasé lo que pasé por cada uno. La función de devolución de llamada the_little_promo_boxes_metabox() es, por supuesto, otra función estática de la clase y es lo que realmente muestra el contenido en el metabox. Utiliza principalmente la función de núcleo de WordPress wp_dropdown_pages() para mostrar una lista de cuadros de promoción (tenga en cuenta que mostrará otros tipos de publicaciones además de "página", pero solo si están marcados como 'hierarchical'=>true en su registro de tipo de publicación. ¿Por qué solo jerárquico? Porque así lo escribieron, por eso! :)

Ya que estamos mostrando tres (3) menús desplegables, necesitamos dar a cada uno un ID único en el HTML ( "promo_box_{$i}" ) pero el mismo nombre entre corchetes ( 'promo_boxes[]' ) para que PHP los recopile en una matriz dentro de $_POST variable (al que WordPress accede por nosotros; verás cómo en un minuto) . Y, por supuesto, debemos establecer el valor seleccionado ( (empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i]) ) si de hecho uno de los valores se había seleccionado previamente.

También utilicé la función de núcleo de WordPress get_post_type_object() para mostrar cómo obtener las etiquetas de un tipo de publicación, y también usé la función de núcleo de WordPress get_post_meta() para recuperar una serie de ID de recuadros de promoción utilizando la clave del campo personalizado ' _promo_boxes 'que te mostraré que debes guardar el siguiente (nota que usé un guión bajo en el nombre '_promo_boxes' que hace que WordPress se oculte de la IU del campo personalizado estándar cuando el usuario está editando la publicación). .

La última función que se describe antes de ver el código es filter_wp_insert_post_data() , que recibe los datos de publicación existentes en el primer parámetro ( $data ) y el contenido de la matriz $_POST gracias a WordPress como segundo parámetro (% código%). Dentro de esta función, llamamos a la función principal de WordPress $postarr y extraemos la matriz de cuadros de promoción ( update_post_meta() ) para guardar en el valor del campo personalizado para la clave $postarr['promo_boxes'] para la publicación especificada por la matriz '_promo_boxes' (es decir, $_POST ).

Dicho esto, aquí está el código para la clase $postarr['ID'] :

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();

Todavía hay dos (2) funciones estáticas aún no mencionadas: LittlePromoBoxes y get_promo_boxes() ; estas son funciones de ayuda para ayudarlo a recuperar las publicaciones de get_promo_box() por sus números ordinales 1..3. Pero para hacerlos más como WordPress, aquí hay dos funciones de envoltorio para agregar al archivo post_type='promo-box' file de su tema (tenga en cuenta que puede pasar una publicación como parámetro, pero no tiene que hacerlo a menos que esté usando una publicación diferente que el de 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);
}

Ahora puede llamar a una o ambas de estas funciones en su archivo de tema functions.php con un código que podría parecerse a esto (este código podría haberse escrito en un bucle pero a la mayoría de los usuarios de WordPress les gusta duplicar el código para que puedan leerlo en lugar de eliminar la redundancia. Entonces, cuando estén en 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>';
?>
    
respondido por el MikeSchinkel 22.12.2010 - 11:54

Lea otras preguntas en las etiquetas