Trường tùy chỉnh / meta được điền bằng cách thả xuống các bài đăng hiện có?


11

(Câu hỏi WP đầu tiên của tôi từng được hỏi! Hãy nhẹ nhàng!)

Tôi đang xây dựng một trang web chủ yếu là các trang (tức là tĩnh), sử dụng WP làm CMS. Ở dưới cùng của một số trang, sẽ xuất hiện 1, 2 hoặc 3 "hộp quảng cáo" - về cơ bản là các nút hình ảnh liên kết đến các phần khác của trang web. Mặc dù chỉ có tối đa 3 hộp quảng cáo sẽ xuất hiện trên bất kỳ trang nào, nhưng sẽ có ~ 30 hộp khác nhau để lựa chọn.

Khi khách hàng của tôi tạo một trang mới, tôi muốn anh ta có thể chọn các hộp quảng cáo từ một cái gì đó như danh sách thả xuống của tất cả các hộp quảng cáo có thể.

Dường như với tôi điều này sẽ làm việc như thế này:

  • Tạo một loại bài đăng tùy chỉnh được gọi là "hộp quảng cáo". (Mặc dù nó có thể dễ dàng trở thành một thẻ cho các bài đăng thông thường.)
  • Sử dụng một công cụ như Mẫu trường tùy chỉnh để tạo danh sách thả xuống trên trình chỉnh sửa trang, trong đó các giá trị của các tùy chọn thả xuống được tạo động từ danh sách tất cả các bài đăng hộp quảng cáo hiện có. ( Đây là phần tôi không biết làm thế nào. )
  • Truy cập siêu dữ liệu kết quả (số bài đăng thực sự là tất cả những gì tôi cần, sau đó tôi có thể lấy mọi thứ khác) trên mẫu trang.

Dựa trên các câu trả lời cho các câu hỏi khác ở đây, tôi đã xem xét ban đầu về WPAlchemy MetaBox, Bài viết-2-Bài viết và Trường tùy chỉnh SLT, nhưng tôi thú nhận tài liệu cho mỗi câu hỏi hơi khó hơn tôi, vì vậy tôi đã không hiểu quá sâu sắc

Lời khuyên? Là một trong những công cụ trên là giải pháp phù hợp với tôi, và tôi chỉ cần tìm ra nó? Am i thiếu cái gì ở đây?


Wow, cảm ơn vì tất cả sự hỗ trợ! Tôi hy vọng rằng dù sao tôi cũng không làm mất giá trị thời gian và sự hào phóng của MikeSchinkel, nhưng tôi đã chọn câu trả lời WPAlchemy làm câu trả lời "chính thức". Tôi vẫn còn đủ mới với PHP / Wordpress rằng tôi chưa thực sự thoải mái với các lớp và hook và các hàm tĩnh, v.v. Tôi hy vọng một ngày nào đó sẽ thành thạo như bạn!
Nic Warmenhoven

Câu trả lời:


7

tác giả của WPAlchemy , tôi hơi thiên vị, nhưng về cơ bản, bạn có một mô hình hoạt động tốt được vạch ra để tuân theo tùy thuộc vào tuyến đường bạn chọn.

Tuy nhiên, nếu sử dụng WPAlchemy, về cơ bản bạn sẽ làm một việc như sau (bước # 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.csscó thể chứa các kiểu mà bạn có thể tạo kiểu cho biểu mẫu của mình và custom/meta.phpvề cơ bản là tệp HTML có nội dung FORM của hộp meta, trong trường hợp này bạn thả xuống, để tạo trình đơn thả xuống của bạn, bạn sẽ thực hiện truy vấn wp tùy chỉnh để nhận tất cả bài đăng tùy chỉnh của bạn các loại. WPAlchemy có một số chức năng trợ giúp đặc biệt để hỗ trợ tạo các thành phần biểu mẫu của bạn.

tài liệu bổ sung để hỗ trợ bạn khi làm việc trong mẫu.

Mục tiêu chính của WPAlchemy là giữ quyền kiểm soát trong tay nhà phát triển, từ kiểu dáng (nhìn + cảm nhận) đến định nghĩa nội dung hộp meta.

Và bản thân tôi và những người khác luôn sẵn lòng giúp đỡ những người bình luận và đặt câu hỏi.


1
Câu trả lời hay, nhưng tôi có thể đề nghị móc thêm yêu cầu biểu định kiểu bổ sung cụ thể vào màn hình chỉnh sửa bài. Điều tương tự cũng có thể được nói cho việc tạo metabox, lý tưởng đó nên được nối do_meta_boxesvới một số logic có điều kiện hoặc thay vào đó add_meta_boxes_{%TYPE%}..
t31os

14

Hehe, bạn là người mới! Chúng ta sẽ xé ya thành những mảnh vụn ...!

j / k :) Chúng tôi chào đón nồng nhiệt cho tất cả những người mới ở đây, rất vui khi có bạn.

Vì vậy, đây là lần thứ 3 tôi nghe yêu cầu này, hai lần từ khách hàng và không phải lần nữa từ bạn (và khách hàng của bạn.) Điều đó cho tôi biết đó là một nhu cầu khá phổ biến.

Metabox tùy chỉnh WordPress hiển thị ba (3) lần thả xuống

Tôi thích phân tích của bạn vì vậy tôi quyết định viết mã một lớp để giải quyết điểm thứ 2 của bạn. Tôi gọi nó LittlePromoBoxesbởi vì tôi không bao giờ có thể lấy bài hát này ra khỏi đầu, nhờ họ . Về cơ bản, tôi sử dụng lớp để đóng gói để tránh xung đột đặt tên tiềm năng với các chức năng tôi cần viết.

Bạn có thể đặt lớp này trong functions.phptệp của chủ đề hoặc trong tệp .PHP của plugin bạn có thể đang viết (nhưng đừng lo, nó trông phức tạp hơn nhiều so với thực tế.)

Hàm đầu tiên on_load()là một hàm tĩnh mà tôi gọi ở cuối khai báo lớp để khởi tạo ba (3) hook bạn sẽ cần (các hàm tĩnh fyi về cơ bản là các hàm liên quan đến lớp , không phải là thể hiện) :

  1. Các initmóc để đăng ký promo-boxloại bưu điện,

  2. Các add_meta_boxes_postmóc để cho phép bạn xác định Metabox, và

  3. Các wp_insert_post_datamóc cho phép bạn chụp các hộp quảng chọn và lưu vào cơ sở dữ liệu.

Mỗi trong số các hook đó tham chiếu một hàm tĩnh khác trong lớp (đây là các hàm mà tôi đã gói gọn bằng cách tạo lớp.)

Tôi sẽ bỏ qua việc mô tả action_init()chức năng và chức năng make_labels()trợ giúp của tôi giả sử bạn biết cách đăng ký loại bài đăng dựa trên câu hỏi của bạn.

Các action_add_meta_boxes_post()chức năng đăng ký các Metabox sử dụng chức năng WordPress lõi add_meta_box()và tôi đã nhận xét các thông số của nó để giải thích lý do tại sao tôi đã thông qua những gì tôi truyền cho mỗi. Hàm gọi lại the_little_promo_boxes_metabox()dĩ nhiên là một hàm tĩnh khác của lớp và nó là thứ thực sự hiển thị nội dung trong metabox. Nó chủ yếu sử dụng chức năng cốt lõi của WordPress wp_dropdown_pages()để hiển thị danh sách các hộp quảng cáo (lưu ý rằng nó sẽ hiển thị các loại bài đăng khác ngoài 'trang' nhưng chỉ khi chúng được đánh dấu là đang 'hierarchical'=>trueđăng ký loại bài đăng của họ. Tại sao chỉ phân cấp? đã viết nó, đó là lý do tại sao! :)

Vì chúng tôi hiển thị ba (3) danh sách thả xuống, chúng tôi cần cung cấp cho mỗi ID duy nhất trong HTML ( "promo_box_{$i}") nhưng cùng tên với dấu ngoặc vuông ( 'promo_boxes[]') để PHP sẽ thu thập chúng thành một mảng bên trong $_POSTbiến (mà WordPress truy cập cho chúng tôi; bạn sẽ thấy như thế nào trong một phút) . Và tất nhiên chúng ta cần đặt giá trị đã chọn ( (empty($promo_boxes[$i]) ? 0 : $promo_boxes[$i])) nếu thực sự một trong các giá trị đã được chọn trước đó.

Tôi cũng đã sử dụng chức năng lõi WordPress get_post_type_object()để hiển thị cách lấy nhãn từ loại bài đăng và cũng sử dụng chức năng lõi WordPress get_post_meta()để truy xuất một mảng ID hộp quảng cáo bằng cách sử dụng khóa trường tùy chỉnh '_promo_boxes' mà tôi sẽ cho bạn thấy để lưu tiếp theo (lưu ý tôi đã sử dụng dấu gạch dưới trước trong tên '_promo_boxes'khiến WordPress ẩn khỏi giao diện người dùng trường tùy chỉnh tiêu chuẩn khi người dùng đang chỉnh sửa bài đăng.) .

Hàm cuối cùng để mô tả trước khi bạn thấy mã là filter_wp_insert_post_data()nhận dữ liệu bài đăng hiện có trong tham số đầu tiên ( $data) và nội dung của $_POSTmảng nhờ WordPress làm tham số thứ hai ( $postarr). Bên trong hàm này, chúng ta gọi hàm WordPress lõi update_post_meta()và trích xuất mảng hộp quảng cáo ( $postarr['promo_boxes']) để lưu vào giá trị trường tùy chỉnh cho khóa '_promo_boxes'cho bài đăng được chỉ định bởi $_POSTmảng (tức là $postarr['ID']).

Điều đó nói rằng, đây là mã cho LittlePromoBoxeslớp:

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

Vẫn còn hai (2) hàm tĩnh chưa được đề cập: get_promo_boxes()get_promo_box(); đây là các hàm trợ giúp để giúp bạn truy xuất các bài đăng của post_type='promo-box'số thứ tự 1..3. Nhưng để làm cho chúng có nhiều WordPress hơn như ở đây là hai hàm bao bọc để thêm vào functions.phptệp chủ đề của bạn (lưu ý rằng bạn có thể chuyển một bài đăng dưới dạng tham số nhưng bạn không phải sử dụng trừ khi bạn đang sử dụng một bài đăng khác trong bài đó trong Vòng lặp ) :

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

Bây giờ bạn có thể gọi một hoặc cả hai hàm này trong single.phptệp chủ đề của mình bằng mã có thể trông như thế này (mã này có thể được viết trong một vòng lặp nhưng hầu hết các chủ đề WordPress dường như muốn sao chép mã để họ có thể đọc nó thay vì loại bỏ sự dư thừa Vì vậy, khi ở 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>';
?>

1
Bạn không bao giờ hết ngạc nhiên với câu trả lời của bạn, công sức bạn bỏ ra để tạo mã và giải thích từng bước .. tuyệt vời! .. (việc bạn nhắc đến những chiếc hộp nhỏ cũng khiến tôi nghĩ về một trong những phim truyền hình yêu thích của tôi) ..
t31os

1
@ t31os - Cảm ơn! Khi tôi bắt đầu trả lời, tôi không thể dừng lại. Tôi ám ảnh / bắt buộc tôi đoán. Nhưng ít nhất tôi đang sử dụng tốt!
MikeSchinkel

@toscho - Cảm ơn. Vâng, tôi rất hiếm khi thêm vào sự hài hước mà khi nói đến tôi, tôi không thể cưỡng lại. :-)
MikeSchinkel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.