it-swarm.xyz

Добавление фильтра таксономии в список администраторов для настраиваемого типа записей?

Я создал пользовательский тип сообщения с именем 'listing' и добавил пользовательскую таксономию с именем 'businesses'. Я хотел бы добавить выпадающий список предприятий в список администраторов для списков.

Вот как эта функция выглядит в списке администраторов для сообщений (я хотел бы то же самое для моего пользовательского типа сообщения):

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

Как я могу добавить выпадающий список предприятий в список администраторов для списков?

128
Taras Mankovski

UPDATE: Я включил новый полный ответ, но, тем не менее, оставил свой оригинальный ответ внизу, на который ссылаются первые несколько комментариев.


Привет @tarasm:

Хотя я сказал, что это не должно быть сложно, это немного сложно. Но прежде чем копаться в коде ...

Скриншоты:

... давайте посмотрим на скриншоты готового продукта:

Страница списка листингов с фильтрацией No:

 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, чтобы убедиться, что мы на самом деле находимся в post_type из listing. Если вы этого не сделаете, вы получите этот раскрывающийся список для всех типов сообщений, что в некоторых случаях является тем, что вы хотите, но не в этом случае.

Далее мы загружаем информацию о бизнес-таксономии, используя get_taxonomy(). Нам нужно получить метку для таксономии (т. Е. "Бизнесы"; мы могли бы жестко запрограммировать ее, но это не очень хорошо, если вам потребуется интернационализация позднее.) Затем мы вызываем 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 из выбранного термина таксономии. В нашем случае это может быть term_id из "Business # 2". Где мы можем получить это значение? Из глобальной переменной WordPress $wp_query; у него есть свойство query, которое содержит массив всех параметров URL-адреса и их значений (если, конечно, какой-то своенравный плагин уже не изменил его.) Учитывая, как WordPress обрабатывает вещи, будет URL-параметр term, передаваемый по URL-адресу, когда пользователь щелкает кнопка фильтра, если пользователь выбрал правильный термин (т. е. один из перечисленных предприятий).

  • hierarchical - Установив для этого значение true, вы указываете функции уважать иерархическую природу таксономии и отображаете их в виде дерева, если термины (компании) на самом деле имеют дочерние элементы. Снимок экрана, чтобы увидеть, как это выглядит, смотрите ниже.

  • depth - этот аргумент взаимодействует с аргументом hierarchical, чтобы определить, на какой глубине должна пройти функция, отображая дочерние элементы.

  • show_count - Если true, этот аргумент будет отображать количество сообщений в скобках слева от названия термина в раскрывающемся списке. В этом случае будет отображаться количество списков, связанных с бизнесом. Снимок экрана, чтобы увидеть, как это выглядит, смотрите ниже.

  • hide_empty - Наконец, если в таксономии есть термины, которые не связаны с постом (т. е. предприятия, не связанные с листингом), то установка этого параметра в true исключит их включение в падать.

 Taxonomy Drop Down should hierarchy and counts 
(источник: mikeschinkel.com )

Шаг № 2: хук фильтра parse_query.

Затем мы обращаем наше внимание на ловушку фильтра parse_query, которая имеет один параметр ($query) и вызывается из /wp-includes/query.php (в v3.0.1 этот вызов выполняется в строке 1549.) Он вызывается, когда WordPress завершил проверку URL и установил все соответствующие значения в текущем активном $wp_query, включая такие вещи, как $wp_query->is_home и $wp_query->is_author и т. д.

После запуска ловушки фильтра parse_query WordPress вызовет функцию get_posts() и загрузит список сообщений на основе того, что указано в текущем активном $wp_query. Так что parse_query - это отличное место, где WordPress может изменить свое мнение о том, какие сообщения он будет загружать.

В вашем случае мы хотим, чтобы WordPress фильтровал по выбранным компаниям; т.е. отображать только те листинги, которые были связаны с выбранным бизнесом (я бы сказал "... только те листинги, которые были " классифицированы " выбранным бизнесом", но это не технически правильно; category - это его собственная таксономия для однорангового узла с business, за исключением того, что category встроен в WordPress, а business настраивается. Но для тех, кто знаком с категоризацией постов, это может помочь вам понять, поскольку они работают почти одинаково. Но я отвлекся ...)

На коду. Первое, что мы делаем, это получаем ссылку на текущий $wp_query's query_vars, чтобы с ним было удобнее работать, так же, как это делается в собственной функции parse_query() в WordPress. В отличие от $wp_query->query, который используется для зеркального отображения параметров, переданных по URL, массив $wp_query->query_vars используется для управления запросом, который запускает WordPress и ожидается, что он будет изменен. Поэтому, если вам нужно изменить один, это будет тот (по крайней мере, я думаю, который отличается между двумя; если кто-то знает иначе пожалуйста, дайте мне знать, чтобы я мог обновить это!)

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

Затем мы проверяем $pagenow, чтобы убедиться, что мы действительно загружаем WordPress из URL-пути /wp-admin/edit.php. Мы делаем это, чтобы избежать случайных ошибок на других страницах. Мы также проверяем, что у нас есть и business как элемент taxonomy, и элемент term. (Обратите внимание, что taxonomy и term являются парой; они используются вместе, чтобы разрешить запрос термина таксономии; должен иметь оба, или WordPress не знает, какую таксономию проверять.)

Вы можете задаться вопросом, как business появился в элементе taxonomy массива query_vars. То, что мы написали в нашей ловушке parse_query, вызвало внутреннюю магию WordPress, которая была заложена в ожидании, когда вы зарегистрировали таксономию "business", установив для query_var значение true (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 был написан для использования слагов для стандартных запросов таксономии, а не идентификаторов терминов таксономии. Для этого варианта использования нам нужно, чтобы наш фильтрующий запрос работал:

taxonomy: business

term: business-1 (то есть slug)

Не эти

taxonomy: business

term: 27 (то есть term_id)

Интересно и, к сожалению, в раскрывающемся списке wp_dropdown_categories() атрибут <option>'s 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;

И это все! С этими двумя функциями вы получаете желаемую фильтрацию.

НО ЖДУ, ТАМ БОЛЬШЕ! :-)

Я пошел дальше и добавил колонку "Бизнес" в ваш список, потому что, ну, я знал, что это будет ваш следующий вопрос. Без столбца для того, что вы фильтруете, это может очень запутать конечного пользователя. (Я боролся с этим сам, и я был программистом!) Конечно, вы уже можете видеть столбец "Бизнес" на предыдущих снимках экрана выше.

Шаг № 3: Хук фильтра manage_posts_columns.

Чтобы добавить столбец в список сообщений, нужно вызвать еще два (2) хука. Первый - manage_posts_columns или версия пост-специфического типа manage_listing_posts_columns, которую я назвал вместо этого. Он принимает один параметр (posts_columns) и вызывается из /wp-admin/includes/template.php (в v3.0.1 этот вызов находится на линии 623):

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

Ваша хук-функция manage_posts_columns получает массив столбцов, где значением является отображаемый заголовок столбца, а ключом является внутренний идентификатор столбца. Стандартные идентификаторы столбцов могут включать эти и другие параметры: 'cb', 'title ', 'author', ``' date'` и т.д.

'cb', это столбец checkbox, и оба 'title' и 'date' ссылаются на post_title и post_date из таблицы wp_posts соответственно. 'author', конечно, это поле post_author после того, как имя автора получено из таблицы wp_users.

 Screenshot of the 'cb' posts column as a checkbox. 
(источник: mikeschinkel.com )

Для ловушки manage_posts_columns мы просто хотим вставить наш столбец businesses в массив $posts_columns до 'author', предполагая, что какой-то другой плагин еще не удалил author из списка!

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

(Примечание, как я написал add_businesses_column_to_listing_list(), мне пришло в голову, что PHP must есть более простой способ вставить значение в ассоциативный массив в соответствующем заказать?!? Или, по крайней мере, должна быть функция в ядре WordPress, чтобы сделать это? Но так как Google подвел меня, я пошел с тем, что сработало. Если у кого-нибудь есть какие-либо предложенные альтернативы, я буду заранее благодарен всем! )

Что, наконец, подводит нас к ...

Шаг № 4: Хук действия manage_posts_custom_column

Второе (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;
        }
    }
}

Этот хук вызывается для каждого столбца для каждой строки сообщения (/ 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(), которая просто возвращает список терминов для этой таксономии (т. Е. Предприятия для этого списка.) Здесь получаем постоянная ссылка для интерфейсной веб-страницы термина обычно в нем перечислены сообщения, связанные с этим термином, но, конечно, они могут отличаться в зависимости от темы и/или установленных плагинов.

Мы используем постоянную ссылку для гиперссылки на термин только потому, что мне нравится гиперссылка. Затем мы объединяем все гиперссылки (/ business) вместе, разделенные символом канала ('|'), и выводим их в буфер PHP, который отправляет его в браузер пользователя/клиент HTTP:

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

СЕЙЧАС мы наконец закончили.

Резюме

Итак, в итоге вам нужно использовать следующие четыре (4) хука, чтобы получить как фильтр, так и связанный столбец на странице списка пользовательских сообщений (О, это также будет работать с сообщениями и страницами.) Это:

  • Шаг № 1: Хук действия restrict_manage_posts.
  • Шаг № 2: хук фильтра parse_query.
  • Шаг № 3: Хук фильтра manage_posts_columns.
  • Шаг № 4: Хук действия manage_posts_custom_column

Где скачать код

Но если бы я заставил вас прочитать все вышеперечисленное, то, конечно, я был бы не очень приятным человеком, если бы я также заставил вас выкопать код только для того, чтобы попробовать его! Но вопреки тому, что некоторые люди говорят, я хороший. Итак, поехали:

ПРИМЕЧАНИЕ к @tarasm: я включил хуки для register_post_type() и register_taxonomy(), чтобы другие могли попробовать это без необходимости их воссоздания. Возможно, вы захотите удалить эти два вызова функций, прежде чем проверить это.

КОНЕЦ


Оригинальный ответ:

Привет @tarasm:

Вы ищете одно раскрывающееся меню вверху, как этот экран, или вы ищете одно раскрывающееся меню на каждую запись записи и если да, то как бы вы ожидали, что последнее будет работать?

 How to Create Sort By functionality for a Custom Post Type in the WordPress Admin 
(источник: mikeschinkel.com )

Если первое, взгляните на этот ответ на вопрос Как отсортировать область администратора настраиваемого типа записи Wordpress по настраиваемому полю? Если это то, что вам нужно, я могу предоставить более подробную информацию, связанную с таксономией.

138
MikeSchinkel

Просто хотел поделиться альтернативной реализацией. У меня не было невероятного учебника Майка, когда я выяснял это, поэтому мое решение немного другое. В частности, я собираюсь упростить у Майка шаг # 1 и исключить шаг # 2 - остальные шаги все еще применимы.

В руководстве Майка использование wp_dropdown_categories() экономит нам некоторое ручное построение списка, но требует некоторой сложной модификации условного запроса ( step # 2 ) для обработки использования идентификатора вместо slug. Не говоря уже о сложности модификации этого кода для работы с другими сценариями, такими как несколько фильтров таксономии.

Другой подход заключается в том, чтобы просто не использовать некорректную функцию wp_dropdown_categories(), а создавать собственные выпадающие списки выбора с нуля. Это не так сложно, занимает менее 30 строк кода и вообще не требует перехвата parse_query:

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

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

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

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

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

Просто подключив нужные таксономии в массив $filters, вы можете быстро вывести несколько фильтров таксономии. Они выглядят точно так же, как на скриншотах Майка. Затем вы можете выполнить с помощью шаг # 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+

Теперь, когда все намного проще, вот очень простое решение как плагин или мю-плагин.

Он использует как можно меньше ресурсов, загружает только необходимые экраны и добавляет столбцы + фильтры для каждой пользовательской таксономии.

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

    }

}

И тогда вам просто нужен настроенный класс Уокера.

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 списки сообщений администратора обрабатываются классом 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

РАБОТАЕТ В 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' => true в register_taxonomy. Это делает 2 вещи:

  1. Добавляет столбец таксономии в представление списка типов записей администратора
  2. Нажав на название термина в столбце таксономии, он фактически отфильтрует список к этому термину .

Таким образом, это не совсем то же самое, что и выбор, но почти такая же функциональность, ширина всего лишь одной строки кода.

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

Одно замечание - я пытался ограничить глубину, потому что некоторые из моих иерархических таксономий довольно велики, но это не сработало - может быть ошибка в функции wp_dropdown_categories?

2
Brad Trivers

Иерархическая версия ответа @ somatic, запрошенная @kevin:

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

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

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

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

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

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

}
?>

Я в основном удалил код, который создал параметры, и поместил его в свою собственную функцию. Функция "generate_taxonomy_options", в дополнение к принятию tax_slug, также принимает параметр parent и level. Функция предполагает, что ее параметры создания для родительского 0, который будет выбирать все термины корневого уровня. В цикле функция будет рекурсивно вызывать себя, используя этот текущий термин как родительский и увеличивая уровень на единицу. Он автоматически добавляет галочки в сторону, чем глубже вы спускаетесь по дереву и вуаля!

1
Manny Fleurmond

Обновление ответа @Drew Gourley для WP 3.3.1 (и включение кода из http://wordpress.org/support/topic/wp_dropdown_categories-generating-url-id-number-instead-of- slug? replies = 6 # post-2529115 ):

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

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

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

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

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


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

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

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

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

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

Просто попробовал оба кода, от Майка и Соматика, и задавался вопросом, как получить одну вещь из каждой техники:

С кодом Майка он показывает выпадающий список с параметром иерархический , что очень помогает. Но для отображения двух выпадающих списков мне пришлось продублировать оператор if ($typenow=='produtos') {...} в функции restrict_listings_by_business(), а также if ($pagenow=='edit.php' && ... } в функции convert_business_id_to_taxonomy_term_in_query($query), которая теперь выдает много кода.

С кодом соматики мне просто нужно указать таксономии, которые я хотел бы видеть как выпадающие списки, так и работает; $filters = array('taxo1', 'taxo2');

Вопрос: могу ли я получить соматический подход, а также иметь параметр иерархический ?

В любом случае, большое спасибо за этот урок, очень помог!

0
kevin

Извиняюсь за то, что, как новый пользователь, я не могу оставлять комментарии, но я могу опубликовать ответ ...

Начиная с WordPress 3.1 (RC 1) ответ Майка (который так хорошо служил мне последние пару месяцев) больше не работает для меня; ограничение по любой таксономии ребенка дает пустой результат. Я попробовал обновление Somatic, и оно работало отлично; еще лучше, он работает с несколькими запросами таксономии который был включен в этот выпуск.

0
rsigg

Учебник Майка по этому вопросу великолепен! Я, вероятно, не стал бы беспокоиться о добавлении этой функции в свой плагин Media Categories, если бы мне пришлось это выяснять самостоятельно.

Тем не менее, я думаю, что с помощью parse_query и затем get тогда запрос по термину не нужен. Это чище для создания вашего собственного класса ходунков. Может быть, это было невозможно, когда он написал свой пост - ему было 3 года, когда я писал это.

Оформить заказ на github. Работает как шарм, изменяет идентификаторы в выпадающих значениях на слагов, поэтому он просто работает без изменения запроса.

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

0
eddiemoya