ฟิลด์ที่กำหนดเอง / เมตาบรรจุด้วยการเลื่อนลงของโพสต์ที่มีอยู่?


11

(คำถาม WP แรกของฉันเคยถาม!

ฉันกำลังสร้างเว็บไซต์ที่ส่วนใหญ่เป็นหน้าเว็บ (เช่นคงที่) โดยใช้ WP เป็น CMS ที่ด้านล่างของหลาย ๆ หน้าจะมี 1, 2, หรือ 3 "กล่องส่งเสริมการขาย" - โดยทั่วไปภาพปุ่มที่เชื่อมโยงไปยังส่วนอื่น ๆ ของเว็บไซต์ แม้ว่าจะมีเพียงกล่องโฆษณาถึง 3 กล่องเท่านั้นที่จะปรากฏในหน้าใดก็ตาม แต่จะมี ~ 30 กล่องให้เลือก

เมื่อลูกค้าของฉันสร้างหน้าใหม่ฉันต้องการให้เขาสามารถเลือกกล่องส่งเสริมการขายจากสิ่งที่ชอบรายการแบบหล่นลงของกล่องส่งเสริมการขายที่เป็นไปได้ทั้งหมด

ดูเหมือนว่าฉันนี้ควรทำงานเช่นนี้:

  • สร้างประเภทโพสต์ที่กำหนดเองที่เรียกว่า "กล่องส่งเสริมการขาย" (แม้ว่ามันจะเป็นเพียงแท็กสำหรับโพสต์ทั่วไปได้)
  • ใช้เครื่องมือเช่นCustom Field Templateเพื่อสร้างดรอปดาวน์ในตัวแก้ไขหน้าซึ่งค่าของตัวเลือกดรอปดาวน์จะถูกสร้างขึ้นแบบไดนามิกจากรายการโพสต์กล่องโปรโมชั่นที่มีอยู่ทั้งหมด ( นี่คือส่วนที่ฉันไม่รู้ว่าต้องทำอย่างไร )
  • เข้าถึงข้อมูลเมตาที่เกิดขึ้น (หมายเลขโพสต์เป็นสิ่งที่ฉันต้องการจริงๆแล้วฉันจะได้ทุกอย่างอื่น) บนเทมเพลตหน้า

จากคำตอบของคำถามอื่น ๆ ที่นี่ฉันได้เริ่มต้นดูที่ WPAlchemy MetaBox, Posts-2-Posts, และ SLT Custom Fields แต่ฉันยอมรับว่าเอกสารของพวกเขานั้นดูดีกว่าฉันเล็กน้อยดังนั้นฉันจึงไม่ได้ทำการแก้ไข ลึกเกินไป

แนะนำ? เป็นหนึ่งในเครื่องมือดังกล่าวเป็นทางออกที่เหมาะสมสำหรับฉันและฉันต้องคิดออก? ฉันทำอะไรบางอย่างหายไปหรือเปล่า


ว้าวขอบคุณสำหรับการสนับสนุนทั้งหมด! ฉันหวังว่าฉันไม่ได้ลดเวลาและความเอื้ออาทรของ MikeSchinkel แต่ฉันเลือกคำตอบ WPAlchemy เป็นคำตอบ "ทางการ" ฉันยังใหม่พอที่จะ PHP / Wordpress ว่าฉันยังไม่สะดวกสบายกับคลาสและ hooks และฟังก์ชั่นคงที่และเช่น ฉันหวังว่าสักวันหนึ่งจะมีความเชี่ยวชาญเท่ากับคุณทุกคน!
Nic Warmenhoven

คำตอบ:


7

ในฐานะที่เป็นผู้เขียนของ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 คือการควบคุมให้อยู่ในมือของนักพัฒนาตั้งแต่การจัดแต่งทรงผม (ลุค + ความรู้สึก) ไปจนถึงการกำหนดเนื้อหาเมตาบ็อกซ์

และตัวฉันและคนอื่น ๆ ก็เต็มใจที่จะช่วยเหลือผู้ที่แสดงความคิดเห็นและตั้งคำถาม


1
คำตอบที่ดี แต่ฉันขอแนะนำให้เชื่อมโยงคำขอสไตล์ชีทพิเศษเข้ากับหน้าจอการแก้ไขโพสต์โดยเฉพาะ เดียวกันยังอาจกล่าวได้ว่าการสร้าง metabox ที่ควรได้รับการติดยาเสพติดเข้าสู่do_meta_boxesกับตรรกะเงื่อนไขบางส่วนหรืออีกทางเลือกหนึ่งบนadd_meta_boxes_{%TYPE%}..
t31os

14

เฮ่คุณเป็นมือใหม่! เราจะฉีกยาเป็นชิ้นเล็กชิ้นน้อย ... !

j / k :) เราให้การต้อนรับอย่างอบอุ่นแก่มือใหม่ทุกคนที่นี่ยินดีที่ได้เป็นคุณ

ดังนั้นนี่เป็นครั้งที่ 3 ที่ฉันได้ยินข้อกำหนดนี้สองครั้งจากลูกค้าและไม่ใช่อีกครั้งจากคุณ (และลูกค้าของคุณ) นั่นบอกฉันว่ามันเป็นความต้องการทั่วไปที่สมเหตุสมผล

WordPress Metabox แบบกำหนดเองแสดงดรอปดาวน์สาม (3)

ฉันชอบการวิเคราะห์ของคุณดังนั้นฉันจึงตัดสินใจที่จะเขียนรหัสชั้นเรียนเพื่อระบุจุดที่ 2 ของคุณ ผมเรียกมันว่าLittlePromoBoxesเพราะผมไม่เคยได้รับเพลงนี้ออกจากหัวของฉันต้องขอบคุณพวกเขา โดยทั่วไปฉันใช้ชั้นเรียนเพื่อแค็ปซูลเพื่อหลีกเลี่ยงความขัดแย้งการตั้งชื่อที่อาจเกิดขึ้นกับฟังก์ชั่นที่ฉันต้องการจะเขียน

คุณสามารถใส่คลาสนี้ในfunctions.phpไฟล์ธีมของคุณหรือในไฟล์. PHP ของปลั๊กอินที่คุณอาจจะเขียน(แต่ไม่ต้องกังวลมันดูซับซ้อนกว่านี้มาก)

ฟังก์ชั่นแรกon_load()คือฟังก์ชั่นคงที่ซึ่งฉันเรียกท้ายประกาศคลาสเพื่อเริ่มต้นตะขอสาม (3) คุณจะต้อง(ฟังก์ชั่นคงที่ fyi เป็นฟังก์ชั่นหลักที่เกี่ยวข้องกับชั้นเรียนไม่อินสแตนซ์) :

  1. initเบ็ดลงทะเบียนpromo-boxประเภทโพสต์

  2. add_meta_boxes_postเบ็ดเพื่อให้คุณสามารถกำหนด metabox และ

  3. 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) เราต้องให้ ID ที่ไม่ซ้ำกันใน 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()เพื่อดึงข้อมูล ID ของกล่องโปรโมชั่นมากมายจากการใช้คีย์ฟิลด์แบบกำหนดเอง '_promo_boxes' ซึ่งฉันจะแสดงให้คุณเห็น เพื่อประหยัดต่อไป(หมายเหตุผมใช้ขีดก่อนหน้านี้ในชื่อ'_promo_boxes'ซึ่งเป็นสาเหตุของ WordPress เพื่อซ่อนตัวจากฟิลด์ที่กำหนดเอง UI มาตรฐานเมื่อผู้ใช้แก้ไขโพสต์.)

ฟังก์ชั่นสุดท้ายที่จะอธิบายก่อนที่คุณจะเห็นรหัส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ไฟล์ธีมของคุณ(โปรดทราบว่าคุณสามารถส่งโพสต์เป็นพารามิเตอร์ แต่คุณไม่จำเป็นต้องเว้นเสียแต่ว่าคุณจะใช้โพสต์อื่นใน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);
}

ตอนนี้คุณสามารถเรียกใช้หนึ่งหรือทั้งสองฟังก์ชั่นเหล่านี้ใน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>';
?>

1
คุณไม่เคยทำให้ฉันประหลาดใจกับคำตอบของคุณความพยายามในการสร้างรหัสและอธิบายแต่ละขั้นตอน .. สุดยอด! .. (การเอ่ยถึงกล่องเล็ก ๆ ของฉันก็ทำให้ฉันคิดถึงหนึ่งในซีรีย์ทีวีที่ฉันโปรดปราน) ..
t31os

1
@ t31os - ขอบคุณ! เมื่อฉันเริ่มตอบฉันไม่สามารถหยุดตัวเองได้ ฉันคิดว่าครอบงำ / ครอบงำ แต่อย่างน้อยฉันก็ใช้ประโยชน์ได้ดี!
MikeSchinkel

@toscho - ขอบคุณ ใช่ฉันมักจะเพิ่มอารมณ์ขันบ่อยๆเมื่อฉันไม่สามารถต้านทานได้ :-)
MikeSchinkel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.