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


129

というカスタム投稿タイプを作成し、'listing'というカスタム分類を追加しました'businesses'。リストの管理者リストにビジネスのドロップダウンリストを追加したいと思います。

以下は、投稿の管理者リストでこの機能がどのように見えるかです(カスタム投稿タイプでも同じようにしたいです):

投稿のカテゴリのドロップダウン

これが私の現在のコードです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();
}

リストの管理者リストにビジネスのドロップダウンリストを追加するにはどうすればよいですか?


8
スクリーンショットのおかげで、それらを持っていると本当に助かります。
-MikeSchinkel

正確なジョブを実行できるプラグインAdmin Taxonomy Filterがあります。
アントラン

回答:


140

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


こんにちは@tarasm

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

スクリーンショット:

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

フィルタリングなしのリストリストページ:

フィルタリングなしのリストリストページ
(ソース:mikeschinkel.com

フィルタリングを使用したリストリストページ:

フィルタリング付きのリストリストページ
(ソース: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我々は上の事実であることを確認するために変数をpost_typeしますlisting。そうしないと、すべての投稿タイプでこのドロップダウンが表示されますが、これは場合によっては必要ですが、この場合はそうではありません。

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

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

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

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

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

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

  • hide_empty-最後に、投稿に関連付けられていない用語(つまり、リストに関連付けられていないビジネス)が分類法にある場合、これを設定するtrueと、ドロップダウンに含まれないようになります。

分類ドロップダウンは階層化およびカウントする必要があります
(ソース:mikeschinkel.com

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

次に、parse_query1つのパラメーター($query)から呼び出されるフィルターフックに注意を呼びます(/wp-includes/query.phpv3.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がどの投稿を読み込むかについての考えを変更するのに最適な場所です。

ユースケースでは、選択したビジネスに基づいてWordPressにフィルターを適用します。すなわち、選択されたビジネスに関連付けられているリストのみを表示します(「... 選択されたビジネスによって「分類」されたリストのみ」と言いますが、技術的には正しくありません。categoryピアの独自の分類法ですbusinessこと以外は、categoryワードプレスに組み込まれbusinessたカスタムである。しかし、分類の記事に精通している人のために)...これは、彼らはほとんど同じ仕事として、あなたが理解するのに役立つことがあります。しかし、私は脱線

コードについて。最初に行うことは、現在アクティブな$wp_queryの参照を取得するquery_varsことです。これにより、WordPressのparse_query()機能内で行われるのと同じように、作業がより便利になります。$wp_query->queryURLで渡されたパラメーターをミラー化するために使用されるものとは異なり、$wp_query->query_vars配列はWordPressが実行するクエリを制御するために使用され、変更される予定です。したがって、1つを変更する必要がある場合は、それが1つになります(少なくとも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パスからWordPressをロードしていることを確認するためにテストします/wp-admin/edit.php。これは、他のページで誤ってクエリを台無しにすることを防ぐためです。またbusinesstaxonomy要素としても要素としても持っていることを確認しtermます。(注taxonomyterm対である;それらは分類タームの照会を可能にするために一緒に使用され、お奨めの両方を持っているか、ワードプレスを検査するためにどの分類を知りません。)

配列の要素がどのようにbusinessなっているのか疑問に思うかもしれません。私たちは私たちの中で書いたものを使用すると、 『登録された待機中に敷設されたWordPressの内部マジックトリガーフック設定することで、』分類を真実であることを(コピーにそのよう分類の名前を、あなたはもちろん、それを変更することはできますが、競合がない限り、同じことに固執するのが最善です):taxonomyquery_varsparse_querybusinessquery_varregister_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(用語の/ビジネス)への属性」を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;

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

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

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

ステップ#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_titlepost_dateからwp_posts、それぞれ表。'author'もちろんpost_author、著者名がwp_usersテーブルから取得された後のフィールドです。

チェックボックスとしての「cb」投稿列のスクリーンショット。
(ソース:mikeschinkel.com

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

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

なお、私が書いたようにadd_businesses_column_to_listing_list()、PHPがいることを私に発生しなければならない適切な順序で連想配列に値を挿入する簡単な方法を持っている?!?あるいは、少なくともそれを行うにはWordPressのコア内の関数があるように持っている?しかし、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このフックは、多くの場合、多くの異なる列のための出力を生成するために使用されているので、我々はこのようになります多くの異なるポストタイプに対して一つの関数を使用する場合は特に、:

<?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ページのパーマリンクを取得します。この用語はもちろん、インストールされているテーマやプラグインによって異なる場合があります。

私は物事をハイパーリンクするのが好きだからといって、パーマリンクを使用して用語をハイパーリンクします。次に、すべてのハイパーリンクされた用語(/ business)をパイプ( ' |')文字で区切ってマージし、ユーザーのブラウザー/ 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);
}

我々は最終的に行われます。

概要

したがって、要約すると、次の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つのドロップダウンを探していますか?その場合、後者の動作をどのように期待しますか?

WordPress Adminでカスタム投稿タイプの並べ替え機能を作成する方法
(ソース:mikeschinkel.com

前者の場合は、Wordpressカスタム投稿タイプの管理領域をカスタムフィールドで並べ替えるにはどうすればよいかという質問に対する回答をご覧ください。 それが必要な場合は、分類法に関連する詳細を提供できます。


カテゴリフィルターを表示するドロップダウンを上部に1つ探しています。カスタムコードを記述せずにこれを行う標準的な方法がある場合、私はさまよっていました。
タラスマンコフスキー

最初は、カスタムコードなしで実行できるとは思いませんが、カスタムコードが重要になるとは思いません。クライアントコールの準備をしているので、今日は遅くなります。
MikeSchinkel

2
実際には、同じフィルターで2つの異なる分類法をフィルターしようとすると、両方のソリューション(somaticとMikeSchinkel)が機能しません。
ウンサルコルクマズ

1
@ÜnsalWordPressの現在のバージョン(3.0)は複数のタクソノミークエリをサポートしていませんが、バージョン3.1で変更されると聞いています。この例を複数の分類法で機能させるには、Posts_joinおよびposts_whereフィルターフックを使用して、クエリにいくつかの結合と場所を追加する必要があります。
マニーフルーモンド

1
WP 3.1+では、ステップ1と2は@ drew-gourleyの回答の方が優れています(実際、ステップ2は私にとってはうまくいきませんでした。新しいWordPressでこのフィルタリングに変更があると思います)。
トマスシュトゥッチスキ

44

別の実装を共有したかっただけです。私がこれを理解していたとき、マイクの素晴らしいチュートリアルを持っていなかったので、私の解決策は少し異なります。具体的には、Mikeのステップ1を単純化し、ステップ2削除し ます。他のステップは引き続き適用可能です。

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

別のアプローチは、単純に欠陥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配列にプラグインするだけで、複数の分類法フィルターをすばやく出力できます。マイクのスクリーンショットとまったく同じように表示されます。その後、手順34を実行できます。


4
@somatic-素敵なアップデート!はい、使用wp_dropdown_categories()するには多くの回避策が必要です。可能な場合はコア機能に固執するようにしますが、あなたが指摘しているように、時にはそのようにより多くの作業が必要になります。WordPressには、多くの場合、問題を解決するための複数の良い方法があることを証明するだけです。よくやった!
MikeSchinkel

WordPress 3.1での作業が停止しました。何が正確に変わったかを把握しようとしています。まだ動作するように見えます:分類法と用語スラッグはurlのGET値として表示されますが、結果はすべて0結果です
マニー・フルーモンド

私はこれを機能させようとしていましたが、私ができる唯一の方法は、parse_queryフックを使用し、分類法のクエリ変数を確認し、それに基づいて分類法と用語クエリ変数を設定することでした。WP 3.1を使用します。フィルターを送信するときに、URLに分類法と用語を表示する必要がありますか?
サンチョテファ

2
私にとって魅力的な作品です!とてもエレガントなソリューションです。私はあなたにビール:)を借りて
ミハル・マウ

@somaticこれはうまく機能しますが、$ term-> countでその投稿タイプの用語のみをカウントする方法はありますか?たとえば、写真とビデオの両方にカスタム分類がある場合、ビデオのカスタム投稿タイプを見ると、それを使用するビデオ投稿の総数だけではなく、両方のカスタム投稿タイプからその用語の投稿の総数が表示されます期間。
グリーンホー

13

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


とてもセクシーです。エラー通知を受け取っていたので、if(isset($ var))をif(isset($ var)&& $ var> 0)に変更して、View allの0の値に関連する用語を見つけようとしないようにしました。ああ、todo_convert_restrict関数で$ queryを返さなければなりませんでした
12

11

遅い答え

編集

この機能を最も簡単な方法で追加するプラグイン、Filteramaを作成しました。

WordPress 3.5+のアップデート

物事がはるかに簡単になったので、プラグインまたはmuプラグインとしての非常に簡単なソリューションを次に示します。

可能な限り少ないリソースを使用し、必要な画面にのみロードし、すべてのカスタム分類に列+フィルターを追加します。

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

これを旋回させましたが、get_select()メソッドが欠落しているようです。
デイブロムジー

@ goto10あなたは正しかった。更新しました。Btw:リンクされたプラグインを取得する方が簡単です。プラグインリポジトリで1週間または2週間で利用可能になります。(確認済み)。
カイザー

私が使用していた$this->setup_vars();の初めにpublic function setup()持たせるために"manage_taxonomies_for_{$this->post_type}_columns"作業
キリスト教の

私はテーマfunction.phpにそれを使用するので、しかし、それは可能性add_action( 'init', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
キリスト教の

@Christianこれはテーマの素材ではありません。これはプラグインに属し、上記のコードは現在、テーマがロードされるずっと前にロードされているためです。
カイザー

7

簡単にメモしたかっただけです。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

WP 3.2で動作します!

custom_post_type:書籍 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');

これはWP 3.2+の素晴らしく簡単なソリューションです。
petermolnar

それは機能します__("Show All {$info_taxonomy->label}")が、翻訳可能な文字列を使用する間違った方法です。
マークカプルン

2

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

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


2

これは私が推測するあまり知られていないが、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/

また、読むことができるように、手動で分類列を追加するために調整された新しいフィルターがあります(本当に必要な場合)。


1

@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

WP 3.3.1に対する@Drew Gourleyの回答の更新(およびhttp://wordpress.org/support/topic/wp_dropdown_categories-generated-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

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

WordPress 3.1(RC 1)の時点で、Mikeの答え(過去数か月にわたって私に非常に役立ってきた)はもはや私には役に立たない。分類子によって制限すると、空の結果が得られます。Somaticのアップデートを試してみましたが、うまくいきました。さらに良いことに、このリリースに組み込まれた複数の分類クエリで機能します。


何らかの理由で、ソマティックのバージョンは3.1でも動作しません
マニー・フルーモンド

0

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

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

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

質問:somaticのアプローチを取得し、階層オプションも使用できますか?

とにかくこのチュートリアルをどうもありがとう、大いに助けてくれました!


階層的ソリューションに対する私の答えを
ご覧ください

0

これに関するマイクのチュートリアルは素晴らしいです!もし私が自分でそれを理解しなければならなかったなら、私はおそらくこの機能を私のMedia Categoriesプラグインに追加することを気にしなかっただろう。

そうは言っても、parse_query用語を使用してからクエリを取得する必要はないと思います。独自のカスタムウォーカークラスを作成するのに便利です。たぶん、彼が彼の投稿を書いたとき、それは不可能でした-私がこれを書いている時点で3歳です。

このすばらしいスニペットをgithubでチェックしてください。チャームのように機能し、ドロップダウン値のIDをスラッグに変更するため、クエリを変更せずにネイティブで機能します。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.