Thêm Bộ lọc phân loại vào danh sách quản trị cho loại bài đăng tùy chỉnh?


129

Tôi đã tạo Loại bài đăng tùy chỉnh được gọi 'listing'và thêm Phân loại tùy chỉnh được gọi 'businesses'. Tôi muốn thêm danh sách Doanh nghiệp thả xuống vào danh sách quản trị viên cho Danh sách.

Đây là chức năng này trông như thế nào trong danh sách quản trị viên cho Bài viết (Tôi cũng muốn như vậy đối với Loại bài đăng tùy chỉnh của mình):

Danh mục thả xuống trong bài viết

Đây là mã hiện tại của tôi ( Và đây là mã tương tự trên Gist. ):

<?php
/*
Plugin Name: Listing Content Item
Plugin URI:
Description: 
Author: 
Version: 1.0
Author URI: 
*/

class Listing {
  var $meta_fields = array("list-address1","list-address2","list-country","list-province","list-city","list-postcode","list-firstname","list-lastname","list-website","list-mobile","list-phone","list-fax","list-email", "list-profile", "list-distributionrange", "list-distributionarea");

  public function loadStyleScripts() {
    $eventsURL = trailingslashit( WP_PLUGIN_URL ) . trailingslashit( plugin_basename( dirname( __FILE__ ) ) ) . 'css/';
    wp_enqueue_style('listing-style', $eventsURL.'listing.css');
  }

  function Listing() {
    // Register custom post types
    register_post_type('listing', array(
      'labels' => array(
        'name' => __('Listings'), 'singular_name' => __( 'Listing' ),
        'add_new' => __( 'Add Listing' ),
        'add_new_item' => __( 'Add New Listing' ),
        'edit' => __( 'Edit' ),
        'edit_item' => __( 'Edit Listing' ),
        'new_item' => __( 'New Listing' ),
        'view' => __( 'View Listing' ),
        'view_item' => __( 'View Listing' ),
        'search_items' => __( 'Search Listings' ),
        'not_found' => __( 'No listings found' ),
        'not_found_in_trash' => __( 'No listings found in Trash' ),
        'parent' => __( 'Parent Listing' ),
      ),
      'singular_label' => __('Listing'),
      'public' => true,
      'show_ui' => true, // UI in admin panel
      '_builtin' => false, // It's a custom post type, not built in
      '_edit_link' => 'post.php?post=%d',
      'capability_type' => 'post',
      'hierarchical' => false,
      'rewrite' => array("slug" => "listings"), // Permalinks
      'query_var' => "listings", // This goes to the WP_Query schema
      'supports' => array('title','editor')
    ));

    add_filter("manage_edit-listing_columns", array(&$this, "edit_columns"));
    add_action("manage_posts_custom_column", array(&$this, "custom_columns"));

    // Register custom taxonomy

    #Businesses
    register_taxonomy("businesses", array("listing"), array(
      "hierarchical" => true, 
      "label" => "Listing Categories", 
      "singular_label" => "Listing Categorie", 
      "rewrite" => true,
    ));

    # Region
    register_taxonomy("regions", array("listing"), array(
      'labels' => array(
        'search_items' =>  __( 'Search Regions' ),
        'popular_items' => __( 'Popular Regions' ),
        'all_items' => __( 'All Regions' ),
        'parent_item' => null,
        'parent_item_colon' => null,
        'edit_item' => __( 'Edit Region' ), 
        'update_item' => __( 'Update Region' ),
        'add_new_item' => __( 'Add New Region' ),
        'new_item_name' => __( 'New Region Name' ),
        'separate_items_with_commas' => __( 'Separate regions with commas' ),
        'add_or_remove_items' => __( 'Add or remove regions' ),
        'choose_from_most_used' => __( 'Choose from the most used regions' ),
      ),
      "hierarchical" => false, 
      "label" => "Listing Regions", 
      "singular_label" => "Listing Region", 
      "rewrite" => true,
    ));

    # Member Organizations
    register_taxonomy("organizations", array("listing"), array(
      'labels' => array(
        'search_items' =>  __( 'Search Member Organizations' ),
        'popular_items' => __( 'Popular Member Organizations' ),
        'all_items' => __( 'All Member Organizations' ),
        'parent_item' => null,
        'parent_item_colon' => null,
        'edit_item' => __( 'Edit Member Organization' ), 
        'update_item' => __( 'Update Member Organization' ),
        'add_new_item' => __( 'Add New Member Organization' ),
        'new_item_name' => __( 'New Member Organization Name' ),
        'separate_items_with_commas' => __( 'Separate member organizations with commas' ),
        'add_or_remove_items' => __( 'Add or remove member organizations' ),
        'choose_from_most_used' => __( 'Choose from the most used member organizations' ),
      ),
      "hierarchical" => false, 
      "label" => "Member Organizations", 
      "singular_label" => "Member Organization", 
      "rewrite" => true,
    ));

    # Retail Products
    register_taxonomy("retails", array("listing"), array(
      'labels' => array(
        'search_items' =>  __( 'Search Retail Products' ),
        'popular_items' => __( 'Popular Retail Products' ),
        'all_items' => __( 'All Retail Products' ),
        'parent_item' => null,
        'parent_item_colon' => null,
        'edit_item' => __( 'Edit Retail Product' ), 
        'update_item' => __( 'Update Retail Product' ),
        'add_new_item' => __( 'Add New Retail Product' ),
        'new_item_name' => __( 'New Retail Product Name' ),
        'separate_items_with_commas' => __( 'Separate retail products with commas' ),
        'add_or_remove_items' => __( 'Add or remove retail products' ),
        'choose_from_most_used' => __( 'Choose from the most used retail products' ),
      ),
      "hierarchical" => false, 
      "label" => "Retail Products", 
      "singular_label" => "Retail Product", 
      "rewrite" => true,
    ));

    # Farming Practices
    register_taxonomy("practices", array("listing"), array(
      'labels' => array(
        'search_items' =>  __( 'Search Farming Practices' ),
        'popular_items' => __( 'Popular Farming Practices' ),
        'all_items' => __( 'All Farming Practices' ),
        'parent_item' => null,
        'parent_item_colon' => null,
        'edit_item' => __( 'Edit Farming Practice' ), 
        'update_item' => __( 'Update Farming Practice' ),
        'add_new_item' => __( 'Add New Farming Practice' ),
        'new_item_name' => __( 'New Farming Practice Name' ),
        'separate_items_with_commas' => __( 'Separate farming practices with commas' ),
        'add_or_remove_items' => __( 'Add or remove farming practices' ),
        'choose_from_most_used' => __( 'Choose from the most used farming practices' ),
      ),
      "hierarchical" => false, 
      "label" => "Farming Practices", 
      "singular_label" => "Farming Practice", 
      "rewrite" => true,
     ));

    # Products 
    register_taxonomy("products", array("listing"), array(
      'labels' => array(
        'search_items' =>  __( 'Search Products' ),
        'popular_items' => __( 'Popular Products' ),
        'all_items' => __( 'All Products' ),
        'parent_item' => null,
        'parent_item_colon' => null,
        'edit_item' => __( 'Edit Product' ), 
        'update_item' => __( 'Update Product' ),
        'add_new_item' => __( 'Add New Product' ),
        'new_item_name' => __( 'New Product Name' ),
        'separate_items_with_commas' => __( 'Separate products with commas' ),
        'add_or_remove_items' => __( 'Add or remove products' ),
        'choose_from_most_used' => __( 'Choose from the most used products' ),
      ),
      "hierarchical" => false, 
      "label" => "Products", 
      "singular_label" => "Product", 
      "rewrite" => true,
    ));


    // Admin interface init
    add_action("admin_init", array(&$this, "admin_init"));
    add_action("template_redirect", array(&$this, 'template_redirect'));

    // Insert post hook
    add_action("wp_insert_post", array(&$this, "wp_insert_post"), 10, 2);
  }

  function edit_columns($columns) {
    $columns = array(
      "cb" => "<input type=\"checkbox\" />",
      "title" => "Business Name",
      "description" => "Description",
      "list-personal" => "Personal Information",
      "list-location" => "Location",
      "list-categorie" => "Categorie",
    );

    return $columns;
  }

  function custom_columns($column) {
    global $post;
    switch ($column) {
      case "description":
        the_excerpt();
        break;
      case "list-personal":
        $custom = get_post_custom();
        if(isset($custom["list-firstname"][0])) echo $custom["list-firstname"][0]."<br />";
        if(isset($custom["list-lastname"][0])) echo $custom["list-lastname"][0]."<br />";
        if(isset($custom["list-email"][0])) echo $custom["list-email"][0]."<br />";
        if(isset($custom["list-website"][0])) echo $custom["list-website"][0]."<br />";
        if(isset($custom["list-phone"][0])) echo $custom["list-phone"][0]."<br />";
        if(isset($custom["list-mobile"][0])) echo $custom["list-mobile"][0]."<br />";
        if(isset($custom["list-fax"][0])) echo $custom["list-fax"][0];
        break;
      case "list-location":
        $custom = get_post_custom();
        if(isset($custom["list-address1"][0])) echo $custom["list-address1"][0]."<br />";
        if(isset($custom["list-address2"][0])) echo $custom["list-address2"][0]."<br />";
        if(isset($custom["list-city"][0])) echo $custom["list-city"][0]."<br />";
        if(isset($custom["list-province"][0])) echo $custom["list-province"][0]."<br />";
        if(isset($custom["list-postcode"][0])) echo $custom["list-postcode"][0]."<br />";
        if(isset($custom["list-country"][0])) echo $custom["list-country"][0]."<br />";
        if(isset($custom["list-profile"][0])) echo $custom["list-profile"][0]."<br />";
        if(isset($custom["list-distributionrange"][0])) echo $custom["list-distributionrange"][0]."<br />";
        if(isset($custom["list-distributionarea"][0])) echo $custom["list-distributionarea"][0];
        break;
      case "list-categorie":
        $speakers = get_the_terms(0, "businesses");
        $speakers_html = array();
        if(is_array($speakers)) {
          foreach ($speakers as $speaker)
          array_push($speakers_html, '<a href="' . get_term_link($speaker->slug, 'businesses') . '">' . $speaker->name . '</a>');
          echo implode($speakers_html, ", ");
        }
        break;
    }
  }

  // Template selection
  function template_redirect() {
    global $wp;
    if (isset($wp->query_vars["post_type"]) && ($wp->query_vars["post_type"] == "listing")) {
      include(STYLESHEETPATH . "/listing.php");
      die();
    }
  }

  // When a post is inserted or updated
  function wp_insert_post($post_id, $post = null) {
    if ($post->post_type == "listing") {
      // Loop through the POST data
      foreach ($this->meta_fields as $key) {
        $value = @$_POST[$key];
        if (empty($value)) {
          delete_post_meta($post_id, $key);
          continue;
        }

        // If value is a string it should be unique
        if (!is_array($value)) {
          // Update meta
          if (!update_post_meta($post_id, $key, $value)) {
            // Or add the meta data
            add_post_meta($post_id, $key, $value);
          }
        }
        else
        {
          // If passed along is an array, we should remove all previous data
          delete_post_meta($post_id, $key);

          // Loop through the array adding new values to the post meta as different entries with the same name
          foreach ($value as $entry)
            add_post_meta($post_id, $key, $entry);
        }
      }
    }
  }

  function admin_init() {
    // Custom meta boxes for the edit listing screen
    add_meta_box("list-pers-meta", "Personal Information", array(&$this, "meta_personal"), "listing", "normal", "low");
    add_meta_box("list-meta", "Location", array(&$this, "meta_location"), "listing", "normal", "low");
  }

  function meta_personal() {
    global $post;
    $custom = get_post_custom($post->ID);
    if(isset($custom["list-firstname"][0])) $first_name = $custom["list-firstname"][0];else $first_name = '';
    if(isset($custom["list-lastname"][0])) $last_name = $custom["list-lastname"][0];else $last_name = '';
    if(isset($custom["list-website"][0])) $website = $custom["list-website"][0];else $website = '';
    if(isset($custom["list-phone"][0])) $phone = $custom["list-phone"][0];else $phone = '';
    if(isset($custom["list-mobile"][0])) $mobile = $custom["list-mobile"][0];else $mobile = '';
    if(isset($custom["list-fax"][0])) $fax = $custom["list-fax"][0];else $fax = '';
    if(isset($custom["list-email"][0])) $email = $custom["list-email"][0];else $email = '';
?>
<div class="personal">
<table border="0" id="personal">
<tr><td class="personal_field"><label>Firstname:</label></td><td class="personal_input"><input name="list-firstname" value="<?php echo $first_name; ?>" /></td></tr>
<tr><td class="personal_field"><label>Lastname:</label></td><td class="personal_input"><input name="list-lastname" value="<?php echo $last_name; ?>" /></td></tr>
<tr><td class="personal_field"><label>Email:</label></td><td class="personal_input"><input name="list-email" value="<?php echo $email; ?>" size="40"/></td></tr>
<tr><td class="personal_field"><label>Website:</label></td><td class="personal_input"><input name="list-website" value="<?php echo $website; ?>" size="40"/></td></tr>
<tr><td class="personal_field"><label>Phone:</label></td><td class="personal_input"><input name="list-phone" value="<?php echo $phone; ?>" /></td></tr>
<tr><td class="personal_field"><label>Mobile:</label></td><td class="personal_input"><input name="list-mobile" value="<?php echo $mobile; ?>" /></td></tr>
<tr><td class="personal_field"><label>Fax:</label></td><td class="personal_input"><input name="list-fax" value="<?php echo $fax; ?>" /></td></tr>
</table>
</div>
     <?php
  }

  // Admin post meta contents
  function meta_location() {
    global $post;
    $custom = get_post_custom($post->ID);
    if(isset($custom["list-address1"])) $address1 = $custom["list-address1"][0];else $address1 = '';
    if(isset($custom["list-address2"])) $address2 = $custom["list-address2"][0];else $address2 = '';
    if(isset($custom["list-country"])) $country = $custom["list-country"][0];else $country = '';
    if(isset($custom["list-province"])) $province = $custom["list-province"][0];else $province = '';
    if(isset($custom["list-city"])) $city = $custom["list-city"][0];else $city = '';
    if(isset($custom["list-postcode"])) $post_code = $custom["list-postcode"][0];else $post_code = '';
    if(isset($custom["list-profile"])) $profile = $custom["list-profile"][0];else $profile = '';
    if(isset($custom["list-distributionrange"])) $distribution_range = $custom["list-distributionrange"][0];else $distribution_range = '';
    if(isset($custom["list-distributionarea"])) $distribution_area = $custom["list-distributionarea"][0];else $ddistribution_area = '';
  ?>
<div class="location">
<table border="0" id="location">
<tr><td class="location_field"><label>Address 1:</label></td><td class="location_input"><input name="list-address1" value="<?php echo $address1; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>Address 2:</label></td><td class="location_input"><input name="list-address2" value="<?php echo $address2; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>City:</label></td><td class="location_input"><input name="list-city" value="<?php echo $city; ?>" /></td></tr>
<tr><td class="location_field"><label>Province:</label></td><td class="location_input"><input name="list-province" value="Ontario" readonly /></td></tr>
<tr><td class="location_field"><label>Postal Code:</label></td><td class="location_input"><input name="list-postcode" value="<?php echo $post_code; ?>" /></td></tr>
<tr><td class="location_field"><label>Country:</label></td><td class="location_input"><input name="list-country" value="Canada" readonly /></td></tr>
<tr><td class="location_field"><label>Profile:</label></td><td class="location_input"><input name="list-profile" value="<?php echo $profile; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>Distribution Range:</label></td><td class="location_input"><input name="list-distributionrange" value="<?php echo $distribution_range; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>Distribution Area:</label></td><td class="location_input"><input name="list-distributionarea" value="<?php echo $distribution_area; ?>" size="60" /></td></tr>
</table>
</div>
   <?php
  }
}

// Initiate the plugin
add_action("init", "ListingInit");
function ListingInit() { 
  global $listing;
  $listing = new Listing();
  $add_css = $listing->loadStyleScripts();
}

Làm cách nào tôi có thể thêm danh sách Doanh nghiệp thả xuống vào danh sách quản trị viên cho Danh sách?


8
Cảm ơn cho ảnh chụp màn hình, nó thực sự giúp có những cái đó.
MikeSchinkel

Có một plugin Bộ lọc phân loại quản trị viên có thể thực hiện công việc chính xác.
Anh Trần

Câu trả lời:


140

CẬP NHẬT: Tôi đã bao gồm một câu trả lời hoàn chỉnh mới nhưng ngay cả vậy tôi đã để lại phản hồi ban đầu của mình ở phía dưới mà một vài bình luận đầu tiên tham khảo.


Xin chào @tarasm :

Mặc dù tôi đã nói nó không khó nhưng nó có một chút liên quan. Nhưng trước khi chúng ta đào sâu vào mã ...

Ảnh chụp màn hình:

... Hãy xem một số ảnh chụp màn hình cho thành phẩm:

Trang danh sách danh sách không có Lọc:

Trang danh sách danh sách không có bộ lọc
(nguồn: mikechinkel.com )

Trang danh sách danh sách với Lọc:

Trang danh sách danh sách với Lọc
(nguồn: mikechinkel.com )

Mật mã

Vì vậy, ở đây chúng tôi đi ... ( Lưu ý: Tôi đã sử dụng một hình thức số ít cho tên phân loại business; Tôi hy vọng nó phù hợp với bạn. Từ nhiều kinh nghiệm với cả WordPress và phát triển cơ sở dữ liệu trong quá khứ, tôi tin rằng tốt nhất là làm theo cách này .)

Bước # 1: restrict_manage_postsMóc hành động.

Điều đầu tiên bạn cần làm là móc restrict_manage_postshành động không có tham số và được gọi từ /wp-admin/edit.php(trong v3.0.1, cuộc gọi đó nằm trên dòng 378.) Điều này sẽ cho phép bạn tạo trình đơn thả xuống chọn tại vị trí thích hợp phía trên danh sách Danh sách bài viết.

<?php
add_action('restrict_manage_posts','restrict_listings_by_business');
function restrict_listings_by_business() {
    global $typenow;
    global $wp_query;
    if ($typenow=='listing') {
        $taxonomy = 'business';
        $business_taxonomy = get_taxonomy($taxonomy);
        wp_dropdown_categories(array(
            'show_option_all' =>  __("Show All {$business_taxonomy->label}"),
            'taxonomy'        =>  $taxonomy,
            'name'            =>  'business',
            'orderby'         =>  'name',
            'selected'        =>  $wp_query->query['term'],
            'hierarchical'    =>  true,
            'depth'           =>  3,
            'show_count'      =>  true, // Show # listings in parens
            'hide_empty'      =>  true, // Don't show businesses w/o listings
        ));
    }
}

Chúng ta bắt đầu bằng cách kiểm tra các $typenowbiến để đảm bảo chúng tôi đang trong thực tế trên post_typecủa listing. Nếu bạn không nhận được thả xuống này cho tất cả các loại bài đăng, trong một số trường hợp là những gì bạn muốn, nhưng không phải trường hợp này.

Tiếp theo chúng tôi tải thông tin về phân loại kinh doanh bằng cách sử dụng get_taxonomy(). Chúng tôi cần nó để lấy nhãn cho phân loại (tức là " Doanh nghiệp "; chúng tôi có thể đã được mã hóa cứng, nhưng điều đó không tốt lắm nếu bạn cần quốc tế hóa sau này.) Sau đó, chúng tôi gọi wp_dropdown_categories()với tất cả các đối số thích hợp trong $argsmảng để tạo ra thả xuống

<?php
return wp_dropdown_categories(array(
    'show_option_all' =>  __("Show All {$business_taxonomy->label}"),
    'taxonomy'        =>  $taxonomy,
    'name'            =>  'business',
    'orderby'         =>  'name',
    'selected'        =>  $wp_query->query['term'],
    'hierarchical'    =>  true,
    'depth'           =>  3,
    'show_count'      =>  true, // Show # listings in parens
    'hide_empty'      =>  true, // Don't show businesses w/o listings
));

Nhưng những lý lẽ thích hợp là gì? Chúng ta hãy xem xét từng cái riêng lẻ:

  • show_optional_all- Khá đơn giản, đó là những gì được hiển thị trong trình đơn thả xuống lúc đầu và khi không có bộ lọc nào được áp dụng. Trong trường hợp của chúng tôi, nó sẽ là "Hiển thị tất cả các doanh nghiệp " nhưng chúng tôi có thể gọi nó là "Danh sách cho tất cả các doanh nghiệp" hoặc bất cứ điều gì bạn thích.

  • taxonomy- Đối số này cho hàm biết phân loại gì để lấy các thuật ngữ từ mặc dù hàm có categoriestên của nó. Trong phiên bản.8 và trước đó, WordPress không có phân loại tùy chỉnh nhưng khi chúng được thêm vào, nhóm đã quyết định việc thêm một đối số phân loại vào chức năng này sẽ dễ dàng hơn là tạo một chức năng khác với tên khác.

  • name- Đối số này cho phép bạn chỉ định giá trị mà WordPress sử dụng cho namethuộc tính của phần tử <select> được tạo cho trình đơn thả xuống. Chỉ trong trường hợp không rõ ràng thì đây cũng là giá trị sẽ được sử dụng trong URL khi lọc.

  • orderby- Đối số này cho WordPress biết cách sắp xếp các kết quả theo thứ tự abc. Trong trường hợp của chúng tôi, chúng tôi đã chỉ định đặt mua namecác điều khoản trong phân loại, tức là tên doanh nghiệp trong trường hợp này.

  • selected- Đối số này là cần thiết để trình đơn thả xuống có thể hiển thị bộ lọc hiện tại trong trình đơn thả xuống. Nó phải là term_idtừ thuật ngữ phân loại đã chọn. Trong trường hợp của chúng tôi, nó có thể là term_idtừ "Doanh nghiệp số 2" . Chúng ta lấy giá trị này ở đâu? Từ biến toàn cầu của WordPress $wp_query; querydĩ nhiên, nó có một thuộc tính chứa một mảng gồm tất cả các tham số URL và các giá trị của chúng (trừ khi một số plugin bướng bỉnh đã sửa đổi nó.) Với cách xử lý WordPress, mọi thứ sẽ có một termtham số URL được truyền vào URL khi người dùng nhấp vào bộ lọc nếu người dùng chọn một thuật ngữ hợp lệ (nghĩa là một trong những doanh nghiệp được liệt kê).

  • hierarchical- Bằng cách đặt điều này cho truebạn, hãy nói với chức năng tôn trọng bản chất phân cấp của phân loại và hiển thị chúng trong chế độ xem dạng cây nếu các điều khoản (doanh nghiệp) trên thực tế có con. Để chụp ảnh màn hình để xem nó trông như thế nào, xem bên dưới.

  • depth- Đối số này phối hợp với hierarchicalđối số để xác định hàm có bao nhiêu cấp độ sâu trong việc hiển thị con.

  • show_count- Nếu trueđối số này sẽ hiển thị một số bài đăng trong ngoặc đơn ở bên trái của tên hạn trong danh sách thả xuống. Trong trường hợp này, nó sẽ hiển thị một số danh sách liên quan đến một doanh nghiệp. Để chụp ảnh màn hình để xem nó trông như thế nào, xem bên dưới.

  • hide_empty- Cuối cùng, nếu có các điều khoản trong phân loại không liên quan đến bài đăng (nghĩa là các doanh nghiệp không liên quan đến danh sách) thì đặt điều này truesẽ bỏ qua việc đưa chúng vào danh sách thả xuống.

Phân loại học thả xuống nên phân cấp và đếm
(nguồn: mikechinkel.com )

Bước # 2: parse_queryMóc lọc.

Tiếp theo, chúng tôi gọi sự chú ý của chúng tôi đến parse_queryhook bộ lọc có một tham số ( $query) và được gọi từ /wp-includes/query.php(trong v3.0.1, cuộc gọi đó nằm trên dòng 1549.) Nó được gọi khi WordPress hoàn thành việc kiểm tra URL và đặt tất cả các giá trị phù hợp trong hiện tại hoạt động $wp_querybao gồm những thứ như $wp_query->is_home$wp_query->is_author, vv

Sau khi parse_queryhook bộ lọc chạy, WordPress sẽ gọi get_posts()và tải lên một danh sách các bài đăng dựa trên những gì được chỉ định trong hoạt động hiện tại $wp_query. Vì vậy, parse_querythường là một nơi tuyệt vời để khiến WordPress thay đổi ý định về những bài đăng mà nó sẽ tải.

Trong trường hợp sử dụng của bạn, chúng tôi muốn đưa WordPress vào bộ lọc dựa trên các doanh nghiệp đã chọn; tức là để chỉ hiển thị những bảng liệt kê đã được gắn liền với hoạt động kinh doanh được lựa chọn (tôi muốn nói "... chỉ những bảng liệt kê đã được 'phân loại' bởi các doanh nghiệp đã chọn" nhưng điều đó không đúng kỹ thuật; categorylà nó phân loại riêng trên peer với businessngoại trừ việc categoryđược xây dựng vào WordPress và businesslà tùy chỉnh. Nhưng đối với những người quen thuộc với bài viết phân loại này có thể giúp bạn hiểu khi họ làm việc gần như giống hệt. Nhưng tôi lạc đề ...)

Vào mã. Điều đầu tiên chúng tôi làm là lấy một tham chiếu đến hiện đang hoạt động $wp_query's query_varsđể nó thuận tiện hơn để làm việc với, giống như cách làm của nó trong WordPress' riêng parse_query()chức năng. Không giống như $wp_query->queryđược sử dụng để phản chiếu các tham số được truyền trên URL, $wp_query->query_varsmảng được sử dụng để kiểm soát truy vấn mà WordPress chạy và dự kiến ​​sẽ được sửa đổi. Vì vậy, nếu bạn cần sửa đổi một, đó sẽ là một (ít nhất tôi nghĩ đó là sự khác biệt giữa hai người; nếu có ai biết cách khác xin vui lòng cho tôi biết để tôi có thể cập nhật điều này!)

<?php
add_filter('parse_query','convert_business_id_to_taxonomy_term_in_query');
function convert_business_id_to_taxonomy_term_in_query($query) {
    global $pagenow;
    $qv = &$query->query_vars;
    if ($pagenow=='edit.php' &&
            isset($qv['taxonomy']) && $qv['taxonomy']=='business' &&
            isset($qv['term']) && is_numeric($qv['term'])) {
        $term = get_term_by('id',$qv['term'],'business');
        $qv['term'] = $term->slug;
    }
}

Tiếp theo, chúng tôi kiểm tra $pagenowđể đảm bảo rằng chúng tôi thực sự đang tải WordPress từ đường dẫn URL /wp-admin/edit.php. Chúng tôi làm điều này để tránh vô tình làm hỏng các truy vấn trên các trang khác. Chúng tôi cũng kiểm tra để chắc chắn rằng chúng tôi có cả hai businessnhư một taxonomyphần tử và một termyếu tố quá. (Lưu ý taxonomytermlà một cặp; chúng được sử dụng cùng nhau để cho phép truy vấn thuật ngữ phân loại; phải có cả hai hoặc WordPress không biết nên phân loại phân loại nào.)

Bạn có thể tự hỏi làm thế nào businessbật lên trong taxonomyphần tử của query_varsmảng. Những gì chúng tôi đã viết trong parse_queryhook của chúng tôi đã kích hoạt ma thuật nội bộ của WordPress đang chờ đợi khi bạn đăng ký businessphân loại "" bằng cách đặt query_varthành đúng ( register_taxonomy()sao chép tên của phân loại như nó query_var; tất nhiên bạn có thể thay đổi nó trừ khi bạn có xung đột tốt nhất là gắn bó với cùng):

<?php
add_action('init','register_business_taxonomy');
    function register_business_taxonomy() {
        register_taxonomy('business',array('listing'),array(
        'label' => 'Businesses',
        'public'=>true,
        'hierarchical'=>true,
        'show_ui'=>true,
        'query_var'=>true
    ));
}

Bây giờ $ wp_query của WordPress đã được viết để sử dụng sên cho các truy vấn được lọc phân loại tiêu chuẩn, không phải ID thuật ngữ phân loại. Đối với trường hợp sử dụng này, những gì chúng ta thực sự cần để làm cho truy vấn lọc của chúng tôi hoạt động là:

taxonomy: kinh doanh

term: business-1 (tức là slug)

Không phải những thứ này:

taxonomy: kinh doanh

term: 27 (tức là term_id)

Thật thú vị và không may là trình đơn thả xuống được tạo bằng cách wp_dropdown_categories()đặt thuộc tính <option>'thành valuethuật ngữ (/ business') term_id, chứ không phải thuật ngữ slug. Vì vậy, chúng tôi cần chuyển đổi $wp_query->query_vars['term']từ một số term_idthành chuỗi slugnhư sau trong đoạn trích được trích từ bên trên (Lưu ý đây không phải là cách hiệu quả nhất để truy vấn cơ sở dữ liệu nhưng cho đến khi WordPress thêm hỗ trợ cho term_ids vào truy vấn của nó, đó là cách tốt nhất chúng tôi có thể làm!) :

<?php
$term = get_term_by('id',$qv['term'],'business');
$qv['term'] = $term->slug;

Và đó là nó! Với hai chức năng đó, bạn có được bộ lọc mà bạn mong muốn.

NHƯNG XIN CHỜ CHÚT NỮA! :-)

Tôi đã tiếp tục và thêm một cột "Doanh nghiệp" vào danh sách Danh sách của bạn bởi vì, tôi biết đó sẽ là câu hỏi tiếp theo của bạn. Không có một cột cho những gì bạn lọc, nó có thể rất khó hiểu cho người dùng cuối. (Tôi đã vật lộn với chính nó và tôi là lập trình viên!) Tất nhiên bạn có thể đã thấy cột "Doanh nghiệp" trong các ảnh chụp màn hình trước ở trên.

Bước # 3: manage_posts_columnsMóc lọc.

Để thêm một cột vào danh sách bài đăng, hãy gọi thêm hai (2) hook. Cái đầu tiên là manage_posts_columnshoặc phiên bản dành riêng cho loại bài đăng manage_listing_posts_columnsmà tôi đã gọi thay thế. Nó chấp nhận một tham số ( posts_columns) và được gọi từ /wp-admin/includes/template.php(trong v3.0.1, cuộc gọi đó nằm trên dòng 623):

<?php
add_action('manage_listing_posts_columns', 'add_businesses_column_to_listing_list');
function add_businesses_column_to_listing_list( $posts_columns ) {
    if (!isset($posts_columns['author'])) {
        $new_posts_columns = $posts_columns;
    } else {
        $new_posts_columns = array();
        $index = 0;
        foreach($posts_columns as $key => $posts_column) {
            if ($key=='author')
                $new_posts_columns['businesses'] = null;
            $new_posts_columns[$key] = $posts_column;
        }
    }
    $new_posts_columns['businesses'] = 'Businesses';
    return $new_posts_columns;
}

manage_posts_columnsHàm hook của bạn được truyền qua một mảng các cột trong đó giá trị là tiêu đề cột được hiển thị và khóa là định danh cột bên trong. Các định danh cột tiêu chuẩn có thể bao gồm những thứ này và hơn thế nữa : 'cb', 'title' 'author',, ``' date'`, v.v.

'cb', là checkboxcột và cả hai 'title'và tương ứng 'date'tham chiếu post_titlepost_datetừ wp_postsbảng. 'author'tất nhiên là post_authortrường sau khi tên tác giả được lấy từ wp_usersbảng.

Ảnh chụp màn hình của cột bài viết 'cb' dưới dạng hộp kiểm.
(nguồn: mikechinkel.com )

Đối với manage_posts_columnshook, chúng tôi chỉ đơn giản muốn chèn cột của chúng tôi businessesvào $posts_columnsmảng trước đó 'author', giả sử một số plugin khác chưa bị xóa authorkhỏi danh sách!

$new_posts_columns['businesses'] = 'Businesses';

( Lưu ý khi tôi viết add_businesses_column_to_listing_list()nó đã xảy ra với tôi rằng PHP phải có cách dễ dàng hơn để chèn giá trị vào một mảng kết hợp theo đúng thứ tự?!? Hoặc ít nhất phải có một chức năng trong lõi WordPress để làm điều đó? Nhưng vì Google làm tôi thất vọng vì vậy tôi đã đi với những gì hiệu quả. Nếu có ai có bất kỳ giải pháp thay thế được đề xuất nào, tôi sẽ được mọi người biết ơn và đánh giá cao trước!)

Điều cuối cùng đưa chúng ta đến ...

Bước # 4: manage_posts_custom_columnMóc hành động

Điều thứ hai của hai (2) chúng ta cần làm để làm cho các doanh nghiệp của chúng ta hiển thị trong cột là thực sự xuất tên của từng doanh nghiệp được liên kết bằng cách sử dụng manage_posts_custom_columnhook hành động. Móc này chấp nhận hai (2) tham số ( column_idpost_id) và cũng được gọi từ /wp-admin/includes/template.php(trong v3.0.1, cuộc gọi đó nằm trên dòng 1459.):

<?php
add_action('manage_posts_custom_column', 'show_businesses_column_for_listing_list',10,2);
function show_businesses_column_for_listing_list( $column_id,$post_id ) {
    global $typenow;
    if ($typenow=='listing') {
        $taxonomy = 'business';
        switch ($column_name) {
        case 'businesses':
            $businesses = get_the_terms($post_id,$taxonomy);
            if (is_array($businesses)) {
                foreach($businesses as $key => $business) {
                    $edit_link = get_term_link($business,$taxonomy);
                    $businesses[$key] = '<a href="'.$edit_link.'">' . $business->name . '</a>';
                }
                //echo implode("<br/>",$businesses);
                echo implode(' | ',$businesses);
            }
            break;
        }
    }
}

Móc này được gọi cho mỗi cột cho mỗi hàng (/ doanh nghiệp). Trước tiên, chúng tôi xác minh rằng chúng tôi thực sự chỉ làm việc với listingloại bài đăng tùy chỉnh và sau đó chúng tôi sử dụng một switchtuyên bố để kiểm tra đối với column_id. Tôi đã chọn switchvì hook này thường được sử dụng để tạo đầu ra cho nhiều cột khác nhau, đặc biệt nếu chúng tôi sử dụng một hàm cho nhiều loại bài đăng khác nhau có thể trông giống như thế này:

<?php
add_action('manage_posts_custom_column', 'my_manage_posts_custom_column',10,2);
function my_manage_posts_custom_column( $column_id,$post_id ) {
    global $typenow;
    switch ("{$typenow}:{$column_id}") {
    case 'listing:business':
        echo '...whatever...';
        break;
    case 'listing:property':
        echo '...whatever...';
        break;
    case 'agent:listing':
        echo '...whatever...';
        break;
    }
}

Kiểm tra trường hợp sử dụng của chúng tôi chỉ gần hơn một chút, bạn sẽ thấy get_the_terms()hàm chỉ đơn giản trả về danh sách các thuật ngữ cho phân loại này (tức là các doanh nghiệp cho danh sách này.) Ở đây có permalink cho trang web mặt trước của thuật ngữ thường liệt kê các bài đăng được liên kết với thuật ngữ nhưng tất nhiên có thể khác nhau tùy thuộc vào chủ đề và / hoặc plugin được cài đặt.

Chúng tôi sử dụng permalink để siêu liên kết thuật ngữ chỉ vì tôi thích siêu liên kết mọi thứ. Sau đó, chúng tôi hợp nhất tất cả các thuật ngữ siêu liên kết (/ doanh nghiệp) với nhau được phân tách bằng |ký tự ống dẫn (' ') và xuất ra bộ đệm PHP gửi nó đến trình duyệt / máy khách HTTP của người dùng:

<?php
$businesses = get_the_terms($post_id,$taxonomy);
if (is_array($businesses)) {
    foreach($businesses as $key => $business) {
        $edit_link = get_term_link($business,$taxonomy);
        $businesses[$key] = '<a href="'.$edit_link.'">' . $business->name . '</a>';
    }
    //echo implode("<br/>",$businesses);
    echo implode(' | ',$businesses);
}

BÂY GIỜ chúng tôi cuối cùng đã hoàn thành.

Tóm lược

Vì vậy, tóm lại, bạn cần sử dụng bốn (4) móc sau đây để có được cả bộ lọc và cột liên quan trong trang danh sách bài đăng tùy chỉnh (Ồ, nó cũng sẽ hoạt động với Bài đăng và Trang.) Chúng là:

  • Bước # 1: restrict_manage_postsMóc hành động.
  • Bước # 2: parse_queryMóc lọc.
  • Bước # 3: manage_posts_columnsMóc lọc.
  • Bước # 4: manage_posts_custom_columnMóc hành động

Tải mã ở đâu

Nhưng nếu tôi buộc bạn phải đọc qua tất cả những điều trên thì tôi chắc chắn sẽ không phải là một người rất tốt nếu tôi cũng bắt bạn đào mã chỉ để có thể dùng thử! Nhưng trái với những gì một số người nói, tôi tốt. Vì vậy, ở đây ya đi:

LƯU Ý cho @tarasm : Tôi đã bao gồm các hook cho aregister_post_type()register_taxonomy()để những người khác có thể thử điều này mà không phải tạo lại chúng. Có lẽ bạn sẽ muốn xóa hai cuộc gọi chức năng đó trước khi bạn kiểm tra điều này.

KẾT THÚC


Phản hồi ban đầu:

Xin chào @tarasm :

Bạn đang tìm kiếm một lần thả xuống ở trên cùng như màn hình này hay bạn đang tìm kiếm một lần thả xuống trên mỗi bản ghi bài đăng và nếu vậy bạn sẽ mong đợi cái sau hoạt động như thế nào?

Cách tạo Sắp xếp theo chức năng cho Loại bài đăng tùy chỉnh trong Quản trị viên WordPress
(nguồn: mikechinkel.com )

Nếu trước đây, hãy xem câu trả lời này cho câu hỏi Làm thế nào để sắp xếp khu vực quản trị của loại bài đăng tùy chỉnh Wordpress theo trường tùy chỉnh? Nếu đó là những gì bạn cần tôi có thể cung cấp thêm chi tiết cụ thể liên quan đến phân loại.


Tôi đang tìm kiếm 1 danh sách thả xuống ở trên cùng sẽ hiển thị bộ lọc Danh mục. Tôi đã đi lang thang nếu có một cách tiêu chuẩn để làm điều này mà không phải viết mã tùy chỉnh.
Taras Mankovski

Lúc đầu, tôi không nghĩ bạn có thể làm mã tùy chỉnh nhưng sau đó tôi không nghĩ mã tùy chỉnh sẽ có ý nghĩa. Tôi có một cuộc gọi của khách hàng để chuẩn bị vì vậy nó sẽ phải đến vào hôm nay.
MikeSchinkel

2
Trên thực tế, cả hai giải pháp (somatic và MikeSchinkel) đều không hoạt động khi bạn cố lọc 2 phân loại khác nhau trong cùng một bộ lọc: - / Luôn lọc phân loại mới nhất khi cố gắng lọc 2+ cùng một lúc.
Ünsal Korkmaz

1
@ Nsal Phiên bản hiện tại của WordPress (3.0) không hỗ trợ nhiều truy vấn Phân loại nhưng từ những gì tôi nghe được sẽ thay đổi với phiên bản 3.1. Để làm cho ví dụ này hoạt động với nhiều nguyên tắc phân loại, bạn phải thêm một số phép nối và vị trí vào truy vấn thông qua các móc lọc của Post_join và Post_where.
Manny Fleurmond

1
Trong WP 3.1+, bước một và hai tốt hơn trong câu trả lời @ drew-Gourmetley (thực ra, bước 2 của bạn không hiệu quả với tôi, tôi nghĩ có những thay đổi trong cách lọc này trong WordPress mới).
Tomasz Struczyński

44

Chỉ muốn chia sẻ một thực hiện thay thế. Tôi đã không có hướng dẫn đáng kinh ngạc của Mike khi tôi phát hiện ra điều này, vì vậy giải pháp của tôi hơi khác một chút. Cụ thể, tôi sẽ đơn giản hóa bước 1 của Mike và loại bỏ bước # 2 - các bước khác vẫn được áp dụng.

Trong hướng dẫn của Mike, việc sử dụng wp_dropdown_categories()giúp chúng tôi tiết kiệm một số cách xây dựng danh sách thủ công, nhưng yêu cầu một số sửa đổi truy vấn có điều kiện phức tạp ( bước # 2 ) để xử lý việc sử dụng ID thay vì sên. Chưa kể đến những khó khăn trong việc sửa đổi mã đó để đối phó với các kịch bản khác, như nhiều bộ lọc phân loại ..

Một cách tiếp cận khác là đơn giản là không sử dụng lỗ hổng nào wp_dropdown_categories()cả, mà thay vào đó để xây dựng danh sách chọn thả xuống của riêng chúng tôi từ đầu. Nó không phức tạp lắm, chỉ mất chưa đến 30 dòng mã và hoàn toàn không yêu cầu hooking parse_query:

add_action( 'restrict_manage_posts', 'my_restrict_manage_posts' );
function my_restrict_manage_posts() {

    // only display these taxonomy filters on desired custom post_type listings
    global $typenow;
    if ($typenow == 'photos' || $typenow == 'videos') {

        // create an array of taxonomy slugs you want to filter by - if you want to retrieve all taxonomies, could use get_taxonomies() to build the list
        $filters = array('plants', 'animals', 'insects');

        foreach ($filters as $tax_slug) {
            // retrieve the taxonomy object
            $tax_obj = get_taxonomy($tax_slug);
            $tax_name = $tax_obj->labels->name;
            // retrieve array of term objects per taxonomy
            $terms = get_terms($tax_slug);

            // output html for taxonomy dropdown filter
            echo "<select name='$tax_slug' id='$tax_slug' class='postform'>";
            echo "<option value=''>Show All $tax_name</option>";
            foreach ($terms as $term) {
                // output each select option line, check against the last $_GET to show the current option selected
                echo '<option value='. $term->slug, $_GET[$tax_slug] == $term->slug ? ' selected="selected"' : '','>' . $term->name .' (' . $term->count .')</option>';
            }
            echo "</select>";
        }
    }
}

Chỉ cần cắm các phân loại mong muốn vào $filtersmảng, bạn có thể nhanh chóng xuất ra nhiều bộ lọc phân loại. Chúng xuất hiện giống hệt như trong ảnh chụp màn hình của Mike. Sau đó, bạn có thể làm theo thông qua bước 3# 4 .


4
@somatic - Cập nhật đẹp! Có, sử dụng wp_dropdown_categories()không đòi hỏi nhiều cách giải quyết. Tôi cố gắng gắn bó với các chức năng cốt lõi khi có thể nhưng như bạn chỉ ra đôi khi phải mất nhiều công sức hơn theo cách đó. Chỉ cần chứng minh rằng với WordPress thường có nhiều hơn một cách tốt để giải quyết vấn đề. Làm tốt lắm!
MikeSchinkel

Chỉ cần ngừng làm việc cho tôi trên WordPress 3.1. Cố gắng tìm ra những gì chính xác thay đổi. Có vẻ như nó vẫn hoạt động: các phân loại và thuật ngữ sên hiển thị dưới dạng các giá trị GET trong url, nhưng tất cả kết quả là 0 kết quả
Manny Fleurmond

Tôi đã cố gắng để làm việc này nhưng cách duy nhất tôi có thể là sử dụng hook parse_query, kiểm tra var truy vấn của phân loại và đặt các phân loại truy vấn thuật ngữ và thuật ngữ dựa trên đó. Sử dụng WP 3.1. Phân loại & thuật ngữ có nên xuất hiện trong URL khi bộ lọc được gửi không?
sanchothefat

2
Hoạt động như một cơ duyên đối với tôi! Giải pháp rất thanh lịch thực sự. Tôi nợ bạn một cốc bia :)
Michal Mau

@somatic Điều này hoạt động rất tốt nhưng có cách nào để có $ term-> đếm chỉ đếm các điều khoản cho loại bài đăng đó? Ví dụ: nếu tôi có phân loại tùy chỉnh cho cả ảnh và video, nó sẽ hiển thị cho tôi khi xem video loại bài đăng tùy chỉnh tổng số bài đăng cho cụm từ đó từ cả hai loại bài đăng tùy chỉnh thay vì chỉ tổng số bài đăng video sử dụng kỳ hạn.
Greenhoe

13

Đây là phiên bản này tự động tạo và áp dụng các bộ lọc từ tất cả các nguyên tắc phân loại áp dụng cho tất cả các loại bài đăng tùy chỉnh sử dụng chúng. (thật là ngon miệng) Dù sao, tôi cũng đã tinh chỉnh nó để nó hoạt động với wp_dropdown_clists () và wordpress 3.1. Dự án tôi đang thực hiện có tên là ToDo, bạn có thể đổi tên các chức năng thành một cái gì đó có ý nghĩa với bạn, nhưng điều này sẽ làm việc khá nhiều cho mọi thứ tự động.

function todo_restrict_manage_posts() {
    global $typenow;
    $args=array( 'public' => true, '_builtin' => false ); 
    $post_types = get_post_types($args);
    if ( in_array($typenow, $post_types) ) {
    $filters = get_object_taxonomies($typenow);
        foreach ($filters as $tax_slug) {
            $tax_obj = get_taxonomy($tax_slug);
            wp_dropdown_categories(array(
                'show_option_all' => __('Show All '.$tax_obj->label ),
                'taxonomy' => $tax_slug,
                'name' => $tax_obj->name,
                'orderby' => 'term_order',
                'selected' => $_GET[$tax_obj->query_var],
                'hierarchical' => $tax_obj->hierarchical,
                'show_count' => false,
                'hide_empty' => true
            ));
        }
    }
}
function todo_convert_restrict($query) {
    global $pagenow;
    global $typenow;
    if ($pagenow=='edit.php') {
        $filters = get_object_taxonomies($typenow);
        foreach ($filters as $tax_slug) {
            $var = &$query->query_vars[$tax_slug];
            if ( isset($var) ) {
                $term = get_term_by('id',$var,$tax_slug);
                $var = $term->slug;
            }
        }
    }
    return $query;
}
add_action( 'restrict_manage_posts', 'todo_restrict_manage_posts' );
add_filter('parse_query','todo_convert_restrict');

Lưu ý rằng tôi đang sử dụng một plugin có thêm 'term_order' như một cách để đặt hàng các điều khoản, bạn sẽ phải thay đổi điều đó hoặc xóa đối số đó để chuyển về mặc định.


thực sự rất gợi cảm tôi đã nhận được thông báo lỗi, vì vậy tôi đã thay đổi if (isset ($ var)) thành if (isset ($ var) && $ var> 0) để tránh cố gắng tìm các thuật ngữ liên quan đến giá trị Xem tất cả 0. ồ, và tôi đã phải trả về $ truy vấn trong hàm
todo_convert_restrict

11

Câu trả lời muộn

Biên tập

Tôi đã viết Filterama , một plugin sẽ thêm chức năng này một cách dễ dàng nhất có thể.

Cập nhật cho WordPress 3.5+

Bây giờ mọi thứ đã dễ dàng hơn nhiều, đây là một giải pháp rất đơn giản như plugin hoặc mu-plugin.

Nó sử dụng càng ít tài nguyên càng tốt, chỉ tải trên các màn hình cần thiết và thêm Cột + Bộ lọc cho mỗi phân loại tùy chỉnh.

add_action( 'plugins_loaded', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
class WCM_Admin_PT_List_Tax_Filter
{
    private static $instance;

    public $post_type;

    public $taxonomies;

    static function init()
    {
        null === self::$instance AND self::$instance = new self;
        return self::$instance;
    }

    public function __construct()
    {
        add_action( 'load-edit.php', array( $this, 'setup' ) );
    }

    public function setup()
    {
        add_action( current_filter(), array( $this, 'setup_vars' ), 20 );

        add_action( 'restrict_manage_posts', array( $this, 'get_select' ) );

        add_filter( "manage_taxonomies_for_{$this->post_type}_columns", array( $this, 'add_columns' ) );
    }

    public function setup_vars()
    {
        $this->post_type  = get_current_screen()->post_type;
        $this->taxonomies = array_diff(
            get_object_taxonomies( $this->post_type ),
            get_taxonomies( array( 'show_admin_column' => 'false' ) )
        );
    }

    public function add_columns( $taxonomies )
    {
        return array_merge( taxonomies, $this->taxonomies );
    }


    public function get_select()
    {
        $walker = new WCMF_walker;
        foreach ( $this->taxonomies as $tax )
        {
            wp_dropdown_categories( array(
                'taxonomy'        => $tax,
                'hide_if_empty'   => true,
                'show_option_all' => sprintf(
                    get_taxonomy( $tax )->labels->all_items
                ),
                'hide_empty'      => true,
                'hierarchical'    => is_taxonomy_hierarchical( $tax ),
                'show_count'      => true,
                'orderby'         => 'name',
                'selected'        => '0' !== get_query_var( $tax )
                    ? get_query_var( $tax )
                    : false,
                'name'            => $tax,
                'id'              => $tax,
                'walker'          => $walker,
            ) );
        }

    }

}

Và sau đó bạn chỉ cần một lớp Walker tùy chỉnh.

class WCMF_walker extends Walker_CategoryDropdown
{
    public $tree_type = 'category';
    public $db_fields = array(
        'parent' => 'parent',
        'id'     => 'term_id',
    );
    public $tax_name;

    public function start_el( &$output, $term, $depth, $args, $id = 0 )
    {
        $pad = str_repeat( '&nbsp;', $depth * 3 );
        $cat_name = apply_filters( 'list_cats', $term->name, $term );
        $output .= sprintf(
            '<option class="level-%s" value="%s" %s>%s%s</option>',
            $depth,
            $term->slug,
            selected(
                $args['selected'],
                $term->slug,
                false
            ),
            $pad.$cat_name,
            $args['show_count']
                ? "&nbsp;&nbsp;({$term->count})"
                : ''
        );
    }
}

Đã cho điều này một vòng xoáy, nhưng phương thức get_select () dường như bị thiếu.
Dave Romsey

@ goto10 Bạn đã đúng. Đã cập nhật. Btw: Dễ dàng hơn để lấy plugin được liên kết. Nó sẽ có sẵn trong kho plugin sau một hoặc hai tuần. (Đã được xác nhận).
kaiser

Tôi đã phải sử dụng $this->setup_vars();vào đầu public function setup()để có thể "manage_taxonomies_for_{$this->post_type}_columns"làm việc
Christian

Nhưng đó có thể là do tôi sử dụng nó trong chức năng Theme.php vớiadd_action( 'init', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
Christian

@Christian Đây không phải là tài liệu chủ đề. Điều này thuộc về một plugin và như mã ở trên hiện tại nó được tải rất xa trước khi Chủ đề được tải.
kaiser

7

Tôi chỉ muốn làm một ghi chú nhanh. Trên các phiên bản mới hơn của WP, danh sách bài đăng trên quản trị viên được xử lý bởi lớp WP_Posts_List_Table. Mã application_filters hiện tại như sau:

if ( 'page' == $post_type )
        $posts_columns = apply_filters( 'manage_pages_columns', $posts_columns );
    else
        $posts_columns = apply_filters( 'manage_posts_columns', $posts_columns, $post_type );
    $posts_columns = apply_filters( "manage_{$post_type}_posts_columns", $posts_columns );

Vì vậy, để thêm các cột mới, một hook add_filter phải như thế này:

add_filter( 'manage_posts_columns', 'my_add_columns', 10, 2);

Dưới đây là một ví dụ:

function my_add_columns($posts_columns, $post_type)
{
  if ('myposttype' == $post_type) {
    $posts_columns = array(
      "cb"            => "<input type=\"checkbox\" />",
      "title"         => "Title",
      "anothercolumn" => "Bacon",
      "date"          => __( 'Date' )
    );
    return $posts_columns;
  }
} 

Bây giờ, cho các hàng bài. Đây là mã xử lý dữ liệu cột trên danh sách:

default:
            ?>
            <td <?php echo $attributes ?>><?php
                if ( is_post_type_hierarchical( $post->post_type ) )
                    do_action( 'manage_pages_custom_column', $column_name, $post->ID );
                else
                    do_action( 'manage_posts_custom_column', $column_name, $post->ID );
                do_action( "manage_{$post->post_type}_posts_custom_column", $column_name, $post->ID );
            ?></td>
            <?php

Để lấy lại dữ liệu bài đăng của chúng tôi, chúng tôi phải thêm một hook hành động như thế này:

add_action( "manage_(here_goes_your_post_type)_posts_custom_column", "my_posttype_add_column", 10, 2);

Ví dụ (ví dụ này sử dụng các nguyên tắc phân loại, nhưng bạn có thể truy vấn bất kỳ nội dung nào khác):

function my_posttype_add_column($column_name, $post_id)
{
  switch ($column_name) {
    case 'anothercolumn':
      $flavours = get_the_terms($post_id, 'flavour');
      if (is_array($flavours)) {
        foreach($flavours as $key => $flavour) {
          $edit_link = get_term_link($flavour, 'flavour');
          $flavours[$key] = '<a href="'.$edit_link.'">' . $flavour->name . '</a>';
        }
        echo implode(' | ',$flavours);
      }
      break;

    default:
      break;
  }
}

7

CÔNG TRÌNH TRONG WP 3.2!

custom_post_type: sách custom_taxonomy: thể loại

Chỉ sửa đổi là nó nói: // thay đổi TẠI ĐÂY

function restrict_books_by_genre() {
    global $typenow;
    $post_type = 'books'; // change HERE
    $taxonomy = 'genre'; // change HERE
    if ($typenow == $post_type) {
        $selected = isset($_GET[$taxonomy]) ? $_GET[$taxonomy] : '';
        $info_taxonomy = get_taxonomy($taxonomy);
        wp_dropdown_categories(array(
            'show_option_all' => __("Show All {$info_taxonomy->label}"),
            'taxonomy' => $taxonomy,
            'name' => $taxonomy,
            'orderby' => 'name',
            'selected' => $selected,
            'show_count' => true,
            'hide_empty' => true,
        ));
    };
}

add_action('restrict_manage_posts', 'restrict_books_by_genre');


function convert_id_to_term_in_query($query) {
    global $pagenow;
    $post_type = 'books'; // change HERE
    $taxonomy = 'genre'; // change HERE
    $q_vars = &$query->query_vars;
    if ($pagenow == 'edit.php' && isset($q_vars['post_type']) && $q_vars['post_type'] == $post_type && isset($q_vars[$taxonomy]) && is_numeric($q_vars[$taxonomy]) && $q_vars[$taxonomy] != 0) {
        $term = get_term_by('id', $q_vars[$taxonomy], $taxonomy);
        $q_vars[$taxonomy] = $term->slug;
    }
}

add_filter('parse_query', 'convert_id_to_term_in_query');

Đó là một giải pháp tốt đẹp và dễ dàng cho WP 3.2+.
petermolnar

nó hoạt động nhưng __("Show All {$info_taxonomy->label}")là một cách sai để sử dụng các chuỗi có thể dịch.
Đánh dấu Kaplun

2

Đây là một cách để làm điều đó bằng cách sử dụng hành động hạn chế_manage_posts. Nó dường như hoạt động tốt đối với tôi và thêm khả năng lọc theo phân loại cho tất cả các loại bài và có các phân loại liên quan.

// registers each of the taxonomy filter drop downs
function sunrise_fbt_add_taxonomy_filters() {
    global $typenow;            // the current post type
    $taxonomies = get_taxonomies('','objects');
    foreach($taxonomies as $taxName => $tax) {
    if(in_array($typenow,$tax->object_type) && $taxName != 'category' && $taxName != 'tags') {
            $terms = get_terms($taxName);
            if(count($terms) > 0) {
              //Check if hierarchical - if so build hierarchical drop-down
              if($tax->hierarchical) {
                $args = array(
                      'show_option_all'    => 'All '.$tax->labels->name,
                      'show_option_none'   => 'Select '.$tax->labels->name,
                      'show_count'         => 1,
                      'hide_empty'         => 0, 
                      'echo'               => 1,
                      'hierarchical'       => 1,
                      'depth'              => 3, 
                      'name'               => $tax->rewrite['slug'],
                      'id'                 => $tax->rewrite['slug'],                      
                      'class'              => 'postform',
                      'depth'              => 0,
                      'tab_index'          => 0,
                      'taxonomy'           => $taxName,
                      'hide_if_empty'      => false);
            $args['walker'] = new Walker_FilterByTaxonomy;
                wp_dropdown_categories($args);
              } else {
                    echo "<select name='".$tax->rewrite['slug']."' id='".$tax->rewrite['slug']."' class='postform'>";
                    echo "<option value=''>Show All ".$tax->labels->name."</option>";
                    foreach ($terms as $term) { 
              echo '<option value="' . $term->slug . '"', $_GET[$taxName] == $term->slug ? ' selected="selected"' : '','>' . $term->name .' (' . $term->count .')</option>'; 
            }
                    echo "</select>";
                }
            }
    }
    }
}
add_action( 'restrict_manage_posts', 'sunrise_fbt_add_taxonomy_filters', 100 );

/**
 * Create HTML dropdown list of Categories.
 *
 * @package WordPress
 * @since 2.1.0
 * @uses Walker
 */
class Walker_FilterByTaxonomy extends Walker {
    var $tree_type = 'category';
    var $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
    function start_el(&$output, $category, $depth, $args) {
      $args['selected'] = get_query_var( $args['taxonomy'] );
        $pad = str_repeat('&nbsp;', $depth * 3);

        $cat_name = apply_filters('list_cats', $category->name, $category);
        $output .= "\t<option class=\"level-$depth\" value=\"".$category->slug."\"";
        if ( $category->slug == $args['selected'] )
            $output .= ' selected="selected"';
        $output .= '>';
        $output .= $pad.$cat_name;
        if ( $args['show_count'] )
            $output .= '&nbsp;&nbsp;('. $category->count .')';
        if ( $args['show_last_update'] ) {
            $format = 'Y-m-d';
            $output .= '&nbsp;&nbsp;' . gmdate($format, $category->last_update_timestamp);
        }
        $output .= "</option>\n";
        }
} 

Một lưu ý - Tôi đã cố gắng hạn chế độ sâu vì một số phân loại phân cấp của tôi khá lớn nhưng nó không hoạt động - có thể là một lỗi trong chức năng wp_dropdown_clists?


2

Điều này không được biết đến nhiều như tôi đoán, nhưng kể từ wordpress 3.5, bạn có thể chuyển 'show_admin_column' => truesang register_taxonomy. Điều này thực hiện 2 điều:

  1. Thêm cột phân loại vào chế độ xem danh sách bài đăng của quản trị viên
  2. Bằng cách nhấp vào tên của thuật ngữ trên cột phân loại, trên thực tế , nó sẽ lọc danh sách cho thuật ngữ đó .

Vì vậy, không hoàn toàn giống như có một lựa chọn, nhưng gần như cùng chức năng, chiều rộng chỉ bằng một hàng mã.

https://make.wordpress.org/core/2012/12/11/wordpress-3-5-admin-columns-for-custom-taxonomies/

Ngoài ra, như bạn có thể đọc, có một bộ lọc mới được điều chỉnh để thêm cột phân loại thủ công (nếu bạn thực sự cần).


1

Phiên bản phân cấp của câu trả lời của @ somatic, theo yêu cầu của @kevin:

<?php
add_action( 'restrict_manage_posts', 'my_restrict_manage_posts' );
function my_restrict_manage_posts() {

    // only display these taxonomy filters on desired custom post_type listings
    global $typenow;
    if ($typenow == 'photos' || $typenow == 'videos') {

        // create an array of taxonomy slugs you want to filter by - if you want to retrieve all taxonomies, could use get_taxonomies() to build the list
        $filters = array('plants', 'animals', 'insects');

        foreach ($filters as $tax_slug) {
            // retrieve the taxonomy object
            $tax_obj = get_taxonomy($tax_slug);
            $tax_name = $tax_obj->labels->name;

            // output html for taxonomy dropdown filter
            echo "<select name='$tax_slug' id='$tax_slug' class='postform'>";
            echo "<option value=''>Show All $tax_name</option>";
            generate_taxonomy_options($tax_slug,0,0);
            echo "</select>";
        }
    }
}

function generate_taxonomy_options($tax_slug, $parent = '', $level = 0) {
    $args = array('show_empty' => 1);
    if(!is_null($parent)) {
        $args = array('parent' => $parent);
    } 
    $terms = get_terms($tax_slug,$args);
    $tab='';
    for($i=0;$i<$level;$i++){
        $tab.='--';
    }
    foreach ($terms as $term) {
        // output each select option line, check against the last $_GET to show the current option selected
        echo '<option value='. $term->slug, $_GET[$tax_slug] == $term->slug ? ' selected="selected"' : '','>' .$tab. $term->name .' (' . $term->count .')</option>';
        generate_taxonomy_options($tax_slug, $term->term_id, $level+1);
    }

}
?>

Về cơ bản, tôi đã loại bỏ mã tạo ra các tùy chọn và đặt nó vào chức năng của chính nó. Hàm 'created_taxonomy_options', ngoài việc lấy tax_slug, còn lấy tham số cha và mức. Hàm giả định rằng các tùy chọn tạo của nó cho cha 0, sẽ chọn tất cả các thuật ngữ cấp gốc. Trong vòng lặp, hàm sẽ gọi đệ quy chính nó, sử dụng thuật ngữ hiện tại đó làm cha mẹ và tăng cấp độ một. Nó tự động thêm bọ ve vào bên cạnh sâu hơn bạn đi xuống cây và voila!


1

Cập nhật câu trả lời của @Drew Gourley cho WP 3.3.1 (và kết hợp mã từ http://wordpress.org/support/topic/wp_dropdown_clists-generating-url-id-number-instead-of-slug?replies=6#post- 2529115 ):

add_action('restrict_manage_posts', 'xyz_restrict_manage_posts');
function xyz_restrict_manage_posts() {
    global $typenow;

    $args = array('public'=>true, '_builtin'=>false); 
    $post_types = get_post_types($args);

    if(in_array($typenow, $post_types)) {
        $filters = get_object_taxonomies($typenow);

        foreach ($filters as $tax_slug) {
            $tax_obj = get_taxonomy($tax_slug);
            $term = get_term_by('slug', $_GET[$tax_obj->query_var], $tax_slug);

            wp_dropdown_categories(array(
                'show_option_all' => __('Show All '.$tax_obj->label ),
                'taxonomy' => $tax_slug,
                'name' => $tax_obj->name,
                'orderby' => 'term_order',
                'selected' => $term->term_id,
                'hierarchical' => $tax_obj->hierarchical,
                'show_count' => false,
                // 'hide_empty' => true,
                'hide_empty' => false,
                'walker' => new DropdownSlugWalker()
            ));
        }
    }
}


//Dropdown filter class.  Used with wp_dropdown_categories() to cause the resulting dropdown to use term slugs instead of ids.
class DropdownSlugWalker extends Walker_CategoryDropdown {

    function start_el(&$output, $category, $depth, $args) {
        $pad = str_repeat('&nbsp;', $depth * 3);

        $cat_name = apply_filters('list_cats', $category->name, $category);
        $output .= "\t<option class=\"level-$depth\" value=\"".$category->slug."\"";

        if($category->term_id == $args['selected'])
            $output .= ' selected="selected"';

        $output .= '>';
        $output .= $pad.$cat_name;
        $output .= "</option>\n";
    }
}

0

Xin lỗi vì thực tế là, với tư cách là người dùng mới, tôi không thể đăng bình luận nhưng tôi có thể đăng câu trả lời ...

Kể từ WordPress 3.1 (RC 1) Câu trả lời của Mike (đã phục vụ tôi rất tốt trong vài tháng qua) không còn hiệu quả với tôi nữa; hạn chế bởi bất kỳ đứa trẻ phân loại nào cho kết quả trống rỗng. Tôi đã thử cập nhật của Somatic và nó hoạt động rất tốt; thậm chí tốt hơn, nó hoạt động với nhiều truy vấn phân loại đã được thực hiện trong phiên bản này.


Vì một số lý do, phiên bản của somatic không hoạt động trong 3,1
Manny Fleurmond

0

Chỉ cần thử cả hai mã, từ Mike và somatic và đang tự hỏi làm thế nào để có được một điều từ mỗi kỹ thuật:

Với mã của Mike, nó hiển thị danh sách thả xuống với tùy chọn phân cấp , giúp ích rất nhiều. Nhưng để hiển thị hai Dropdowns tôi đã phải lặp lại trong các if ($typenow=='produtos') {...}tuyên bố trong chức năng restrict_listings_by_business()và cũng là if ($pagenow=='edit.php' && ... }trong convert_business_id_to_taxonomy_term_in_query($query)chức năng mà hiện nay cung cấp cho rất nhiều mã.

Với mã của somatic tôi chỉ cần xác định các nguyên tắc phân loại mà tôi muốn xem là thả xuống và bam, hoạt động; $filters = array('taxo1', 'taxo2');

Câu hỏi: tôi có thể có được cách tiếp cận của somatic và cũng có tùy chọn phân cấp không?

Dù sao cũng cảm ơn rất nhiều vì hướng dẫn này, đã giúp rất nhiều!


Hãy xem câu trả lời của tôi cho một giải pháp phân cấp
Manny Fleurmond

0

Hướng dẫn của Mike về điều này là tuyệt vời! Tôi có lẽ đã không bận tâm đến việc thêm chức năng này vào plugin Danh mục phương tiện của mình nếu tôi phải tự mình tìm ra nó.

Điều đó nói rằng, tôi nghĩ rằng sử dụng parse_queryvà sau đó nhận được truy vấn cho thuật ngữ này là không cần thiết. Nó sạch hơn để tạo lớp walker tùy chỉnh của riêng bạn. Có lẽ điều đó là không thể khi anh ấy viết bài đăng của mình - nó đã 3 tuổi vào thời điểm tôi viết bài này.

Kiểm tra đoạn trích tuyệt vời này trên github. Hoạt động như một bùa mê, thay đổi ID trong các giá trị thả xuống thành sên, do đó, nó chỉ hoạt động nguyên bản mà không sửa đổi truy vấn.

https://gist.github.com/stephenh1988/2902509

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.