Champ personnalisé / méta renseigné par liste déroulante des publications existantes?

11

(Ma première question WP jamais posée! Soyez gentil!)

Je construis un site composé principalement de pages (statique), en utilisant WP comme système de gestion de contenu. Au bas de plusieurs pages, apparaissent 1, 2 ou 3 "boîtes de promotion" - essentiellement des images de boutons qui renvoient vers d'autres parties du site. Bien que seules 3 boîtes promotionnelles apparaissent sur une page donnée, il en existe environ 30 différentes.

Lorsque mon client crée une nouvelle page, j'aimerais qu'il puisse choisir des boîtes de promotion dans une liste déroulante, par exemple une liste déroulante de toutes les boîtes de promotion possibles.

Il me semble que cela devrait fonctionner comme ceci:

  • Créez un type de message personnalisé appelé "boîte de promotion". (Bien que cela puisse tout aussi bien être une balise pour les messages normaux.)
  • Utilisez un outil tel que Modèle de champ personnalisé pour créer un menu déroulant dans l'éditeur de page, où les valeurs des options de liste déroulante sont générées dynamiquement à partir de la liste de tous les articles de la boîte de promotion existants. ( C’est la partie que je ne sais pas faire. )
  • Accédez aux métadonnées obtenues (le numéro de message est tout ce dont j'ai besoin, puis je peux obtenir tout le reste) sur le modèle de page.

Sur la base des réponses aux autres questions ici, j’ai jeté un coup d’œil initial à WPAlchemy MetaBox, Posts-2-Posts et SLT Custom Fields, mais j’avoue que la documentation de chacune d’elles est un peu plus geek que moi. pas trop approfondi.

Un conseil? Est-ce que l'un des outils ci-dessus est la bonne solution pour moi, et je dois juste le comprendre? Est-ce que je manque quelque chose ici?

    
posée Nic Warmenhoven 22.12.2010 - 01:00

2 réponses

7

En tant que auteur de WPAlchemy , je suis un peu partial, mais vous avez essentiellement un bon modèle de travail à suivre en fonction de la route que vous choisissez.

Cependant, si vous utilisez WPAlchemy, vous feriez essentiellement quelque chose comme ceci (étape 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 peut contenir des styles avec lesquels vous pouvez styler votre formulaire et custom/meta.php est essentiellement un fichier HTML avec le contenu FORM de la boîte méta, dans ce cas, votre liste déroulante, pour générer votre liste déroulante requête wp personnalisée pour obtenir tous vos types de publication personnalisés. WPAlchemy dispose de fonctions d’aide spéciales pour vous aider à créer vos éléments de formulaire.

Il existe une documentation supplémentaire pour vous aider à utiliser le modèle.

L'objectif principal de WPAlchemy était de garder le contrôle entre les mains du développeur, du style (look + feel) à la définition du contenu de la boîte méta.

Et moi-même et les autres sommes toujours disposés à aider ceux qui commentent et posent des questions.

    
réponse donnée farinspace 22.12.2010 - 07:07
14

Hehe, vous êtes un novice! Nous allons vous déchirer en lambeaux ...!

j / k:) Nous souhaitons la bienvenue à tous les débutants, ravis de vous accueillir.

C’est donc la troisième fois que je suis confronté à cette exigence, deux fois de la part de clients et non plus de vous (et de votre client). Cela m’indique que c’est un besoin assez courant.

J'aiaimévotreanalyseetj'aidoncdécidédecoderuneclassepourrépondreàvotredeuxièmepoint.Jel’aiappeléeLittlePromoBoxesparcequejenepourraisjamaisobtenir cette chanson dans ma tête, grâce à eux . Fondamentalement, j'utilise la classe pour encapsuler afin d'éviter les conflits de noms potentiels avec les fonctions que j'aurais besoin d'écrire.

Vous pouvez mettre cette classe dans le fichier functions.php de votre thème ou dans le fichier .PHP d'un plug-in que vous écrivez peut-être (mais ne vous inquiétez pas, cela semble beaucoup plus complexe qu'il ne l'est réellement.)

La première fonction on_load() est une fonction statique que j'appelle à la fin de la déclaration de classe pour initialiser les trois (3) points d'ancrage dont vous aurez besoin (les fonctions statiques fyi sont essentiellement fonctions liées à la classe , pas à l'instance) :

  1. Le crochet init pour enregistrer le type de message promo-box ,

  2. Le crochet add_meta_boxes_post pour vous permettre de définir le metabox, et

  3. Le crochet wp_insert_post_data pour vous permettre de capturer les boîtes de promotion sélectionnées et de les enregistrer dans la base de données.

Chacun de ces crochets fait référence à une autre fonction statique de la classe (il s’agissait des fonctions que j’encapsulais en créant la classe.)

Je vais ignorer la description de la fonction action_init() et de ma fonction d'assistance make_labels() en supposant que vous sachiez comment enregistrer un type de publication en fonction de votre question.

La fonction action_add_meta_boxes_post() enregistre la métabox à l'aide de la fonction principale WordPress add_meta_box() et j'ai commenté ses paramètres pour expliquer pourquoi j'ai passé ce que j'ai passé pour chacun. La fonction de rappel the_little_promo_boxes_metabox() est bien sûr une autre fonction statique de la classe et c'est ce qui affiche réellement le contenu de la metabox. Il utilise principalement la fonction principale de WordPress wp_dropdown_pages() pour afficher une liste de boîtes de promotion (notez qu'il affichera d'autres types de publication en plus de 'page', mais uniquement si elles sont marquées comme étant 'hierarchical'=>true dans leur enregistrement de type de publication. Pourquoi seulement hiérarchique? Parce que c'est comme ça qu'ils l'ont écrit, voilà pourquoi!:)

Puisque nous affichons trois (3) menus déroulants, nous devons attribuer à chacun un identifiant unique dans le code HTML ( "promo_box_{$i}" ) mais le même nom avec des crochets ( 'promo_boxes[]' ) pour que PHP les rassemble dans un tableau. dans $_POST variable (auquel WordPress a accès pour nous; vous verrez comment dans une minute) . Et bien sûr, nous devons définir la valeur sélectionnée ( (empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i]) ) si l’une des valeurs avait déjà été sélectionnée.

J'ai également utilisé la fonction principale WordPress get_post_type_object() pour montrer comment obtenir les libellés d'un type de publication, ainsi que l'utilisation de la fonction principale WordPress get_post_meta() pour récupérer un tableau d'ID de boîtes promotionnelles à l'aide de la clé de champ personnalisée ' _promo_boxes 'que je vais vous montrer, vous devez enregistrer le prochain (note: j’avais utilisé un trait de soulignement précédent dans le nom '_promo_boxes' , ce qui a pour effet de masquer WordPress de l’interface utilisateur de champ personnalisée standard lorsque l'utilisateur modifie le message.) .

La dernière fonction à décrire avant de voir le code est filter_wp_insert_post_data() qui reçoit les données de publication existantes dans le premier paramètre ( $data ) et le contenu du tableau $_POST grâce à WordPress en tant que second paramètre (% code%). Dans cette fonction, nous appelons la fonction principale WordPress $postarr et extrayons le tableau de boîtes promotionnelles ( update_post_meta() ) pour enregistrer la valeur de champ personnalisé de la clé $postarr['promo_boxes'] de la publication spécifiée par le tableau '_promo_boxes' (c.-à-d. $_POST ).

Cela dit, voici le code de la classe $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();

Il reste encore deux (2) fonctions statiques non encore mentionnées: LittlePromoBoxes et get_promo_boxes() ; ce sont des fonctions auxiliaires qui vous aideront à récupérer les publications de get_promo_box() par leurs nombres ordinaux 1..3. Mais pour leur donner plus de contenu WordPress, voici deux fonctions d’emballage à ajouter au post_type='promo-box' file de votre thème (notez que vous pouvez passer un message en tant que paramètre, mais vous n’êtes pas obligé de le faire, sauf si vous utilisez un message différent. celle 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);
}

Vous pouvez maintenant appeler une ou les deux fonctions de votre fichier de thème functions.php avec un code qui pourrait ressembler à ceci (ce code aurait pu être écrit en boucle, mais la plupart des développeurs WordPress semblent aimer dupliquer le code afin qu’ils puissent le lire au lieu d’éliminer la redondance, alors, quand à Rome ...):

<?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>';
?>
    
réponse donnée MikeSchinkel 22.12.2010 - 11:54

Lire d'autres questions sur les étiquettes