問題描述

我建立了一個名為'listing'的自定義帖子型別,並新增了一個名為'businesses'的自定義分類。我想在 「列表」 的管理列表中新增一個 「企業」 下拉式清單。

這是功能在管理員列表中的功能 (我想對我的自定義帖子型別是一樣的):

這是我現在的程式碼 (And here is the same code on 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="http://'%20.%20get_term_link($speaker->slug,%20'businesses')%20.%20'">' . $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();
}

如何新增企業的下拉式清單到列表的管理列表?

最佳解決方案

更新:我已經包含了一個全新的完整答案,但即使如此,我已經將我的原始回覆留在了前幾個評論引用的底部。


嗨 @tarasm:

雖然我說這不是很難,但有一點涉及。但是在我們挖掘程式碼之前…

截圖:

… 我們來看看成品的一些螢幕快照:

沒有過濾的列表頁面:

列表列表頁面過濾:

程式碼

所以在這裡我們去…(注意:我使用了一個單數形式的分類名稱 business; 我希望匹配你。從很多經驗與 WordPress 和資料庫開發過去我認為最好這樣做辦法。)

步驟#1:restrict_manage_posts 動作掛鉤。

你需要做的第一件事情就是鉤子沒有引數,被稱為從/wp-admin/edit.php(在呼叫上線 378 V3.0.1) 這將讓你產生壓降以高於合適的位置向下選擇的 restrict_manage_posts 行動上市資訊清單。

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

我們首先檢查 $typenow 變數,以確保我們實際上是 post_typelisting 。如果你不這樣做,你會得到所有帖子型別的下拉選單,在某些情況下,這是你想要的,但不是這種情況。

接下來,我們使用 get_taxonomy()載入有關業務分類的資訊。我們需要它來檢索分類標籤 (即”Businesses”; 我們可以使用 hard-coded,但是如果您需要稍後進行國際化,則不太好) 。然後,我們將 $args 陣列中的所有適當引數稱為 wp_dropdown_categories(),以生成下拉式清單

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

但是什麼是適當的論點?讓我們分別看一下:

  •  show_optional_all – 很簡單,它是在下拉式清單中顯示的,當時沒有應用過濾器。在我們這種情況下,這將是 「顯示所有企業」,但我們可以稱之為 「所有企業的列表」 或任何你喜歡的。
  •  taxonomy – 這個引數告訴函式,即使該函式在其名稱中具有 categories,哪個分類法可以提取術語。在 v2.8 及更早版本中,WordPress 沒有自定義分類法,但是當新增了這些分類後,團隊決定為此函式新增分類引數比使用其他名稱建立另一個函式更容易。
  •  name – 此引數允許您指定 WordPress 與< select> 的 name 屬性一起使用的值。生成的元素為下拉選單。為了防止這種情況不明顯,這也是過濾時在 URL 中使用的值。
  •  orderby – 此引數告訴 WordPress 如何按字母順序排列結果。在我們的例子中,我們指定訂購 name 的分類術語,即這種情況下的商業名稱。
  •  selected – 需要此引數,以便下拉式清單可以在下拉式清單中顯示當前過濾器。它應該是所選分類術語中的 term_id 。在我們的例子中,可能是來自 「Business#2」 的 term_id 。我們在哪裡得到這個價值?從 WordPress 的全域性變數 $wp_query; 它具有一個屬性 query,其中包含所有的 URL 引數及其值的陣列 (除非有一些方便的外掛已經修改了,當然) 。如果 WordPress 處理的東西,當使用者點選時會傳遞一個 term URL 引數如果使用者選擇了有效的術語 (即所列商業之一),則過濾器按鈕。
  •  hierarchical – 透過將其設定為 true,您可以告知功能是否遵守分類法的層次性質,如果術語 (商業) 實際上有孩子,則將其顯示在樹狀檢視中。為了看到這樣的螢幕截圖,見下文。
  •  depth – 此引數與 hierarchical 引數進行協作,以確定函式在顯示子級時應該有多少級別。
  •  show_count – 如果 true 此引數將在下拉式清單中的術語名稱左側的括號內顯示計數帖子。在這種情況下,它將顯示與企業相關聯的列表數。為了看到這樣的螢幕截圖,見下文。
  •  hide_empty – 最後,如果分類中沒有與某個職位相關聯的術語 (即與列表無關的業務),則將其設定為 true 將不會將其包含在下拉式清單中。

步驟#2:parse_query 過濾鉤。

接下來,我們將其注意事項稱為 parse_query 過濾器鉤子,它具有一個引數 ($query),並且由/wp-includes/query.php 呼叫 (在 v3.0.1 中,該呼叫位於第 1549 行) 。當 WordPress 檢查 URL 並設定所有適當的值時,將呼叫它在目前活躍的 $wp_query 中,包括 $wp_query->is_home$wp_query->is_author 等。

parse_query 過濾器掛鉤執行後,WordPress 將呼叫 get_posts(),並根據當前活動的 $wp_query 中指定的內容載入帖子列表。所以 parse_query 通常是讓 WordPress 改變它將要載入哪些帖子的好地方。

在您的 use-case 中,我們希望讓 WordPress 根據所選商家進行過濾; 即只顯示與所選業務相關聯的列表 (我會說 「只有所選業務已經”categorized” 的列表」,但這並不是技術上正確的; category 是同行的自己的分類法 business 除了 category 內建在 WordPress 中,business 是習慣的,但對於熟悉帖子的人來說,這可能有助於您理解,因為他們的工作幾乎相同,但我離題…)

對程式碼。我們首先要做的是參考當前活動的 $wp_queryquery_vars,這樣它更方便使用,就像它在 WordPress 自己的 parse_query()功能中所做的一樣。與用於映象在 URL 上傳遞的引數的 $wp_query->query 不同,$wp_query->query_vars 陣列用於控制 WordPress 執行並預期被修改的查詢。所以如果你需要修改一個,那就是一個 (至少我認為是兩者之間的區別; 如果有人知道,請讓我知道,所以我可以更新這個!)

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

接下來我們測試 $pagenow 以確保我們確實從 URL 路徑/wp-admin/edit.php 載入 WordPress 。我們這樣做是為了避免意外地擰緊其他頁面上的查詢。我們還檢查,確保我們同時具有 business taxonomy 元素和 term 元素。 (注意 taxonomyterm 是一對; 它們一起使用以允許查詢分類術語; 必須同時使用或 WordPress 不知道要檢查哪種分類法。)

您可能會想 business query_vars 陣列的 taxonomy 元素如何出現。我們在 parse_query 鉤子中寫入的內容是透過將 query_var 設定為真,將 「business」 分類為 「business」,將 WordPress 的內部魔術放在等待中 (register_taxonomy()) 將其分類的名稱複製為 query_var; 您可以更改當前的除非你有衝突,最好堅持一下):

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

現在 WordPress’$ wp_query 寫入使用 slugs 標準分類過濾查詢,而不是分類術語 ID 。對於這個 use-case,我們真正需要使我們的過濾查詢工作是這些:

taxonomy: business

term: business-1 (i.e. the slug)

不是這些

taxonomy: business

term: 27 (i.e. the term_id)

有趣的是,不幸的是,wp_dropdown_categories()產生的 drop-down 將<option>value 屬性設定為術語’s(/business’)term_id,而不是 slug 術語。因此,我們需要將 $wp_query->query_vars['term']從數字 term_id 轉換為 slug 的字串,如上所述的程式碼片段中所示 (請注意,這不是查詢資料庫的最有效的方法,但是直到 WordPress 將 term_ids 新增到其查詢中是最佳方式) 做!):

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

就是這樣!透過這兩個功能,您可以獲得所需的過濾功能。

不過等等,更多! 🙂

我繼續向您的清單列表新增了一個”Businesses” 列,因為我知道這將是您的下一個問題。沒有一列您所篩選的列可能會讓終端使用者感到困惑。 (我自己努力,我是編碼器!) 您可以在上面的螢幕截圖中看到”Businesses” 列。

步驟 3:manage_posts_columns 過濾鉤。

要向列表中新增列可以呼叫兩個 (2) 個更多的鉤子。第一個是 manage_posts_columns 或者我呼叫 type-specific 版本的 manage_listing_posts_columns 。它接受一個引數 (posts_columns),並從/wp-admin/includes/template.php 呼叫 (在 v3.0.1 中,呼叫位於第 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_columns 鉤子函式透過列陣列,其中值是顯示的列標題,鍵是內部列識別符號。標準列識別符號可以包括以下內容:'cb''title‘,'author',「’date’」 等

 'cb'checkbox 色譜柱,'title''date'都是分別來自 wp_posts 表的 post_titlepost_date'author'當然是 post_author 欄位後,作者姓名從 wp_users 表中檢索。

對於 manage_posts_columns 鉤子,我們只是希望在'author'之前將 businesses 列插入到 $posts_columns 陣列中,假設一些其他外掛尚未從列表中刪除 author

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

(注意,我寫的是 add_businesses_column_to_listing_list(),我發現,PHP 必須有一個更簡單的方法來以正確的順序將值插入到關聯陣列中?!或者至少在 WordPress 核心中必須有一個功能嗎?但是谷歌讓我失望,所以我去做了什麼工作,如果有任何建議的替代方案,我會全部耳朵和提前感謝!)

哪些最終帶給我們…

步驟#4:manage_posts_custom_column 動作鉤

我們需要做的第二件事情 (2) 使我們的業務顯示在列中,實際上是使用 manage_posts_custom_column 動作掛鉤輸出每個相關業務的名稱。該鉤子接受兩個引數 (column_idpost_id),並且也從/wp-admin/includes/template.php 呼叫 (在 v3.0.1 中,呼叫在第 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;
        }
    }
}

為每個 post(/ business) 行的每個列呼叫此鉤子。我們首先驗證我們確實只使用 listing 自定義帖子型別,然後我們使用 switch 語句來測試 column_id 。我選擇了 switch,因為這個鉤子通常用於為許多不同的列生成輸出,特別是如果我們為許多不同的 post 型別使用一個函式,可能看起來像這樣:

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

檢查我們的 use-case,您會看到 get_the_terms()功能,它可以簡單地返回此分類法的術語列表 (即此列表的商家) 。這裡獲得通常列出與該術語相關聯的帖子的 front-end 網頁的固定連結但是當然可能會因安裝的主題和/或外掛而有所不同。

我們使用永久連結超連結這個術語,只是因為我喜歡超連結的東西。然後,我們將所有超連結術語 (/業務) 合併在一起,與管道 (‘|‘) 字元分開並輸出到 PHP 緩衝區,該緩衝區將其傳送到使用者的瀏覽器/ HTTP 客戶端:

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

現在我們終於完成了。

總結

因此,總而言之,您需要使用以下四 (4) 個鉤子來獲取自定義帖子列表頁面中的過濾器和相關列 (哦,它也可以與帖子和頁面一起使用) 它們是:

  • 步驟#1:restrict_manage_posts 動作掛鉤。
  • 步驟#2:parse_query 過濾鉤。
  • 步驟 3:manage_posts_columns 過濾鉤。
  • 步驟#4:manage_posts_custom_column 動作鉤

在哪裡下載程式碼

但是如果我強迫你閱讀所有上述內容,那麼如果我還讓你挖出程式碼,以便能夠嘗試一下,那麼我肯定不會是一個非常好的人!但與某些人說的相反,我很好。所以這裡啊

注意 @tarasm:我包括一個 register_post_type()register_taxonomy()的鉤子,以便其他人可以嘗試這個而不必重新建立它們。在您測試之前,您可能需要刪除這兩個函式呼叫。

結束


原來的回應:

嗨 @tarasm:

你是否在這個螢幕上尋找頂部的一個下拉選單,或者是在每個後​​期記錄中尋找一個下拉選單,如果是這樣,你會如何看待後者?

如果是前者,看看這個答案的問題如何排序一個自定義欄位 WordPress 自定義帖子型別的管理區域?如果這是你需要的,我可以提供更多關於分類學的細節。

次佳解決方案

只是想分享一個替代實現。當我想到這個時,我沒有 Mike 的令人難以置信的教程,所以我的解決方案有點不同。具體來說,我將簡化邁克的步驟#1,並消除步驟#2 – 其他步驟仍然適用。

在 Mike 的教程中,使用 wp_dropdown_categories()為我們提供了一些手冊 list-building,但需要進行一些複雜的條件查詢修改 (步驟 2) 來處理其使用 ID 而不是 slug 。更不用說修改該程式碼以處理其他場景的困難,如多個分類過濾器。

另一種方法是根本不使用有缺陷的 wp_dropdown_categories(),而是從頭開始構建我們自己的下拉式清單。這不是那麼複雜,需要少於 30 行程式碼,並且不需要掛接 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>";
        }
    }
}

只需將所需的分類法插入到 $filters 陣列中即可快速輸出多個分類過濾器。它們與 Mike 的螢幕截圖中的顯示完全相同。然後你可以跟著步驟#3 和#4 。

第三種解決方案

這是一個自動建立和應用所有分類法的過濾器的版本,適用於使用它們的所有自定義帖子型別。 (什麼嘴巴) 無論如何,我也調整它,所以它適用於 wp_dropdown_categories() 和 wordpress 3.1 。我正在開發的專案稱為 ToDo,您可以將功能重新命名為對您有意義的功能,但這應該可以自動完成所有操作。

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

請注意,我正在使用一個外掛來新增’term_order’ 作為一種方式來排序條款,您必須更改該方法,或者將該引數移除回到預設值。

第四種方案

遲到的答案

Edit

我寫了 Filterama,一個外掛,將新增這個功能最簡單可能的方式。

更新 WordPress 3.5+

現在這些東西比較簡單,這裡是一個非常簡單的解決方案作為外掛或 mu-plugin 。

它使用盡可能少的資源,僅在所需的螢幕上載入,併為每個自定義分類法新增列+過濾器。

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

    }

}

然後你只需要一個定製的 Walker 類。

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})"
                : ''
        );
    }
}

第五種方案

我只想快速注意一下。在較新版本的 WP 中,管理員的帖子列表由 WP_Posts_List_Table 類處理。 apply_filters 程式碼現在如下所示:

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

所以要新增新列,add_filter 鉤應該是這樣的:

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

這裡舉一個例子:

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

現在,對於後面的行。這是處理列表中列資料的程式碼:

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

為了檢索我們的帖子資料,我們必須新增一個這樣的動作鉤子:

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

示例 (此示例使用分類法,但您可以查詢任何其他內容):

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

第六種方案

工作在 WP 3.2!

custom_post_type:books custom_taxonomy:流派

只有修改它說://改變這裡

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

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。