web-dev-qa-db-ja.com

カスタム投稿タイプの管理者リストに分類フィルターを追加する

私は'listing'というカスタム投稿タイプを作成し、'businesses'というカスタム分類法を追加しました。私はListingsのadminリストにBusinessのドロップダウンリストを追加したいと思います。

これが投稿の管理者リストの中でこの機能がどのように見えるかです(私は私のカスタム投稿タイプに同じことを望みます):

Categories Dropdown in Posts

これが私の現在のコードそしてこれは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();
}

ListingsのadminリストにBusinessのドロップダウンリストを追加するにはどうすればいいですか?

128
Taras Mankovski

更新:新しい完全な回答を含めましたが、元の回答を最初のいくつかのコメントが参照する下部に残しました。


こんにちは@tarasm

私はそれが難しくないはずだと言ったが、それは少し複雑です。しかし、コードを掘り下げる前に...

スクリーンショット:

...完成品のスクリーンショットをいくつか見てみましょう。

いいえフィルタリングのリストリストページ:

Listings list page with No Filtering
(ソース: mikeschinkel.com

リストリストページフィルタリングあり:

Listings list page With Filtering
(ソース: mikeschinkel.com

コード

だからここに行く...(注:businessの分類名に単数形を使用した;私はそれがあなたと一致することを望む。WordPressとデータベース開発の両方の多くの経験から過去にこのようにするのが最善であると信じています。)

ステップ#1:restrict_manage_postsアクションフック。

最初に行う必要があるのは、パラメーターを持たず、restrict_manage_postsから呼び出される/wp-admin/edit.phpアクションをフックすることです(v3.0.1では、呼び出しは378行目です)。これにより、上の適切な場所でドロップダウン選択を生成できます。リスト投稿のリスト。

<?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変数をチェックして、実際にlistingpost_typeにいることを確認します。そうしないと、すべての投稿タイプでこのドロップダウンが表示されますが、これは場合によっては必要ですが、この場合はそうではありません。

次に、get_taxonomy()を使用してビジネス分類に関する情報を読み込みます。分類法のラベルを取得するために必要です(つまり、「Businesses」。ハードコーディングすることもできますが、後で国際化する必要がある場合はあまり良くありません)。その後、適切なすべてでwp_dropdown_categories()を呼び出します。ドロップダウンを生成する$args配列の引数

<?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-この引数により、ドロップダウン用に生成された<select>要素のname属性に使用するWordPressの値を指定できます。明確でない場合に備えて、これは、フィルタリング時にURLで使用される値でもあります。

  • orderby-この引数は、結果をアルファベット順に並べる方法をWordPressに指示します。このケースでは、分類法の用語のname、つまりこの場合のビジネス名を購入するように指定しました。

  • selected-この引数は、ドロップダウンが現在のフィルターをドロップダウンに表示できるようにするために必要です。選択した分類用語のterm_idである必要があります。この例では、"Business#2"term_idになります。この値はどこで取得できますか? WordPressのグローバル変数$wp_queryから。すべてのURLパラメーターとその値の配列を含むプロパティqueryがあります(もちろん、何らかのわがままなプラグインが既にそれを変更していない限り)。WordPressが物事を処理する方法を考えると、term URLパラメーターが渡されますユーザーが有効な用語(リストされているビジネスのいずれか)を選択した場合にユーザーがフィルターボタンをクリックしたときのURL。

  • hierarchical-これをtrueに設定することにより、分類法の階層的性質を尊重し、実際に用語(ビジネス)に子がある場合にツリービューで表示するように関数に指示します。これがどのように見えるかを確認するスクリーンショットについては、以下を参照してください。

  • depth-この引数は、hierarchical引数と連携して、子を表示する際に関数がどれだけの深さになるかを決定します。

  • show_count-trueの場合、この引数は、ドロップダウン内の用語名の左側の括弧内に投稿数を表示します。この場合、ビジネスに関連付けられたリストの数が表示されます。これがどのように見えるかを確認するスクリーンショットについては、以下を参照してください。

  • hide_empty-最後に、タクソノミーにnotである用語がリストに関連付けられていない場合(つまり、リストに関連付けられていないビジネス)、これをtrueに設定すると、落ちる。

Taxonomy Drop Down should hierarchy and counts
(ソース: mikeschinkel.com

ステップ#2:parse_queryフィルターフック。

次に、1つのパラメーター(parse_query)を持ち、$queryから呼び出される/wp-includes/query.phpフィルターフックに注意を呼びます(v3.0.1では、呼び出しは行1549にあります。)WordPressの検査が終了すると呼び出されます$wp_query$wp_query->is_homeなどを含む、現在アクティブな$wp_query->is_authorのすべての適切な値のURLおよび設定.

parse_queryフィルターフックが実行されると、WordPressはget_posts()を呼び出し、現在アクティブな$wp_queryで指定されている内容に基づいて投稿のリストをロードします。 parse_queryは、多くの場合、どの投稿を読み込むかについての考え方を変えるためにWordPressを取得するのに最適な場所です。

ユースケースでは、選択したビジネスに基づいてフィルタリングするためにWordPressを取得します。つまり、選択したビジネスに関連付けられているリストのみを表示します(「...選択したビジネスによって「分類」されたリストのみ」技術的には正しくありません; categorybusinessと同等の独自の分類法です。ただし、categoryはWordPressに組み込まれ、businessはカスタムです。私は脱線します...)

コードについて。最初に行うことは、現在アクティブな$wp_queryquery_varsへの参照を取得することです。これにより、WordPressのparse_query()関数内で行う方法と同様に、作業がより便利になります。 URLで渡されたパラメーターをミラーリングするために使用される$wp_query->queryとは異なり、$wp_query->query_vars配列はWordPressが実行され、変更されることが予想されるクエリを制御するために使用されます。あなたが1つを変更する必要がある場合、それは1つです(少なくともI考えるそれは2の間で異なります。誰かがそうでないことを知っている場合してくださいこれを更新してください!)

<?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を使用して、どの分類を検査するかわからないようにします。)

query_vars配列のbusiness要素でtaxonomyがどのようになったのか疑問に思うかもしれません。 parse_queryフックで記述した内容は、query_varをtrueに設定して "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は、分類用語IDではなく、標準分類フィルター処理されたクエリにスラッグを使用するように記述されています。この使用例で、フィルタリングクエリを機能させるために本当に必要なのは次のとおりです。

taxonomyビジネス

termbusiness-1(つまりslug

これらではありません:

taxonomyビジネス

term27(つまりterm_id

興味深いことに、残念なことに、wp_dropdown_categories()によって生成されるドロップダウンは、<option>value属性を用語の(/ business ')term_idに設定します。not用語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;

以上です!これらの2つの機能を使用すると、希望するフィルタリングを取得できます。

しかし、待って、もっとあります! :-)

先に進み、リスティングリストに"Businesses"列を追加しました。これは、次の質問になるとわかっていたからです。フィルタリング対象の列がないと、エンドユーザーにとって非常に混乱する可能性があります。 (私は自分で苦労し、私はコーダーでした!)もちろん、上記の前のスクリーンショットの"Businesses"列を既に見ることができます。

ステップ#3:manage_posts_columnsフィルターフック。

投稿リストに列を追加するには、さらに2つのフックを呼び出す必要があります。最初のものはmanage_posts_columnsか、代わりに呼び出した投稿タイプ固有のバージョンmanage_listing_posts_columnsです。 1つのパラメーター(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'は両方ともそれぞれpost_titleテーブルのpost_datewp_postsを参照します。 'author'は、もちろん、post_authorテーブルから著者名が取得された後のwp_usersフィールドです。

Screenshot of the 'cb' posts column as a checkbox.
(ソース: mikeschinkel.com

manage_posts_columnsフックの場合、他のプラグインがリストからbusinessesをまだ削除していないと仮定して、列author$posts_columns配列の'author'の前に挿入するだけです!

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

add_businesses_column_to_listing_list()を書いたとき、PHPが必要であることがわかりました適切な連想配列に値を挿入する簡単な方法があるまたは、少なくともそれを行うためにWordPress coreに関数がなければなりませんか?しかし、Googleが私を失望させたので、私はうまくいったものに行きました。耳と感謝を事前に!)

ついに….

ステップ#4:manage_posts_custom_columnアクションフック

ビジネスを列に表示するために必要な2つのうちの2つ目は、manage_posts_custom_columnアクションフックを使用して、関連するビジネスのそれぞれの名前を実際に出力することです。このフックは2つのパラメーター(column_idおよびpost_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を選択したのは、このフックは多くの異なる列の出力を生成するためによく使用されるためです。特に、次のような多くの異なる投稿タイプに対して1つの関数を使用する場合:

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

ユースケースを少し詳しく調べると、この分類の用語のリストを返すget_the_terms()関数(つまり、このリストのビジネス)が表示されます。ここでは、用語のフロントエンドWebページのパーマリンクを取得します。通常、用語に関連付けられている投稿を一覧表示しますが、もちろんインストールされているテーマやプラグインによって異なる場合があります。

私は物事をハイパーリンクするのが好きだからといって、パーマリンクを使用して用語をハイパーリンクしています。次に、すべてのハイパーリンクされた用語(/ businesses)をパイプ( '|')文字で区切ってマージし、ユーザーのブラウザー/ HTTPクライアントに送信するPHPバッファーに出力します。

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

NOW最終的に完了しました。

概要

したがって、要約すると、次の4つのフックを使用して、カスタム投稿リストページでフィルターと関連列の両方を取得する必要があります(ああ、投稿とページでも機能します)。

  • ステップ#1:restrict_manage_postsアクションフック。
  • ステップ#2:parse_queryフィルターフック。
  • ステップ#3:manage_posts_columnsフィルターフック。
  • ステップ#4:manage_posts_custom_columnアクションフック

コードをダウンロードする場所

しかし、上記のすべてを読み通すように強制した場合、それを試してみるためだけにコードを掘り下げた場合、私は確かにあまりいい人ではないでしょう!しかし、一部の人々が言うことに反して、私はニースです。だからここに行く:

@tarasmへの注意register_post_type()register_taxonomy()のフックを含めて、他の人が再作成せずにこれを試すことができるようにしました。これをテストする前に、おそらくこれらの2つの関数呼び出しを削除する必要があります。

終わり


元の応答:

こんにちは@tarasm

上部に1つのドロップダウンを探していますかこの画面のように、または投稿レコードごとに1つのドロップダウンを探していますかそして、もしそうなら、後者はどのように機能しますか?

How to Create Sort By functionality for a Custom Post Type in the WordPress Admin
(ソース: mikeschinkel.com

前者の場合は、質問へのこの回答をご覧ください Wordpressカスタムフィールドでカスタム投稿タイプの管理領域をソートするには? 必要なものは、分類に関連する詳細を提供できます。

139
MikeSchinkel

代替の実装を共有したいだけでした。私がこれを考え出していたとき、私はマイクの素晴らしいチュートリアルを持っていませんでした、それで私の解決策は少し異なります。具体的には、マイクの ステップ#1 および 消去 ステップ#2 - を簡略化します。その他のステップはまだ適用可能です。

Mikeのチュートリアルでは、wp_dropdown_categories()を使用すると手動でリストを作成する手間が省けますが、slugの代わりにIDを使用するには複雑な条件付きクエリーの修正( step#2 )が必要です。複数の分類フィルターのように、他のシナリオに対処するためにそのコードを修正することの難しさは言うまでもありません..

もう1つの方法は、欠陥のある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配列に差し込むだけで、複数の分類法フィルターをすばやく出力できます。マイクのスクリーンショットとまったく同じように見えます。その後、 ステップ#3 および #4 を実行します。

44
somatic

これを使用するすべてのカスタム投稿タイプに適用されるすべての分類法からフィルタを自動的に作成して適用するバージョンがあります。とにかく、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'を追加するプラグインを使用していることに注意してください、あなたはそれを変更するか、デフォルトにフォールバックするためにその引数を削除する必要があります。

13
Drew Gourley

後の回答

編集する

私は Filterama と書いていますが、これはこの機能を最も簡単に追加できるプラグインです。

WordPress 3.5以降用のアップデート

これで作業がずっと簡単になりました。プラグインまたはmu-pluginとしてのvery簡単な解決策を次に示します。

可能な限り少ないリソースを使用し、必要な画面にのみロードし、カスタム分類ごとにColumns + Filtersを追加します。

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

ちょっとメモをとりたいと思いました。 WPの新しいバージョンでは、adminの投稿リストは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;
  }
}
7
mines

WORKS IN 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');
7
lacroixca

これはよく知られていませんが、WordPress 3.5からは'show_admin_column' => trueregister_taxonomyに渡すことができます。これは2つのことを行います:

  1. 分類列を管理投稿タイプリストビューに追加します
  2. 分類列の という用語の名前をクリックすると、実際にはリストがその用語 にフィルタリングされます。

したがって、selectを使用するのとまったく同じではありませんが、ほぼ同じ機能があり、幅は1行のコードになります。

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

また、ご覧のとおり、分類列を手動で追加するための新しいフィルタがあります(本当に必要な場合)。

2
Luca Reghellin

これはrestrict_manage_postsアクションを使用してそれを行う方法です。それは私にはうまくいくようであり、すべての種類の投稿とそれに関連する分類法について分類法でフィルタリングする機能を追加しています。

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

1つの注意 - 私の階層的分類法のいくつかは非常に大きいのでうまくいきませんでした - wp_dropdown_categories関数のバグかもしれませんので、私は深さを制限しようとしましたか?

2
Brad Trivers

@kevinから要求された、@ somaticの回答の階層バージョン。

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

}
?>

私は基本的にオプションを作成したコードを削除し、それをそれ自身の関数に入れました。関数 'generate_taxonomy_options'は、tax_slugを取ることに加えて、親とレベルのパラメータも取ります。この関数は、親0の作成オプションを前提としています。これにより、すべてのルートレベルの用語が選択されます。ループでは、関数は現在の用語を親として使用してレベルを1ずつ上げながら、自分自身を再帰的に呼び出します。それは自動的にあなたが木を下って深く掘ると横に目盛りを追加します!

1
Manny Fleurmond

WP 3.3.1に対する@Drew Gourleyの回答の更新(および http://wordpress.org/support/topic/wp_dropdown_categories-generating-url-id-number-instead-of-からのコードの組み込み) slug?返信= 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";
    }
}
1
rinogo

Mikeとsomaticの両方のコードを試してみたところ、それぞれのテクニックから1つのものを取得する方法について疑問がありました。

Mikeのコードでは、 hierarchy オプション付きのドロップダウンリストが表示されます。これは非常に役立ちます。しかし、2つのドロップダウンを表示するには、if ($typenow=='produtos') {...}ステートメントをrestrict_listings_by_business()関数に複製し、convert_business_id_to_taxonomy_term_in_query($query)関数にif ($pagenow=='edit.php' && ... }を複製する必要がありました。

Somaticのコードでは、ドロップダウンとバムとして見たい分類法を指定するだけです。 $filters = array('taxo1', 'taxo2');

質問:私は体性のアプローチを得ることができます、そしてまた hierarchy オプションを持つことができますか?

とにかく、このチュートリアルをどうもありがとうございました。

0
kevin

新規ユーザーとして、コメントを投稿することはできませんが、回答を投稿することはできます。

WordPress 3.1(RC 1)から、Mikeの答え(ここ数カ月の間、私は何ヶ月もの間私に役立ってきた)はもはや私のために働かない。任意の分類法の子による制限は空の結果になります。私はSomaticのアップデートを試したところ、うまくいった。さらに良いことに、それは 複数の分類法の問い合わせ で機能します。

0
rsigg

これに関するマイクのチュートリアルは素晴らしいです!私が自分でそれを理解しなければならなかったなら、私はおそらく私のメディアカテゴリープラグインにこの機能を追加することに煩わされなかったでしょう。

そうは言っても、parse_queryを使用してから取得し、その用語を検索する必要はないと思います。独自のカスタムウォーカークラスを作成する方がきれいです。多分それは彼が彼のポストを書いたときには不可能だった - 私がこれを書いている時点でその3歳。

Githubでこの素晴らしいスニペットをチェックしてください。魅力のように機能し、ドロップダウン値のIDをナメクジに変更するので、クエリを変更しなくてもネイティブに機能します。

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

0
eddiemoya