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

19 авг. 2010 г., 18:13:29
Просмотры: 108K
Голосов: 139

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

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

Выпадающий список категорий в Записях

Вот мой текущий код (И вот этот же код на 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();
}

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

2
Комментарии

Спасибо за скриншот, это действительно помогает в таких случаях.

MikeSchinkel MikeSchinkel
19 авг. 2010 г. 20:29:13

Существует плагин Admin Taxonomy Filter, который может выполнить именно эту задачу.

Anh Tran Anh Tran
20 сент. 2017 г. 04:33:05
Все ответы на вопрос 17
11
150

ОБНОВЛЕНИЕ за июль 2024:

Этот код больше не работает. Протестировано в текущей версии WP на момент написания (6.5.5). Для его восстановления требуется несколько изменений в коде Шага 1:

Параметр name

В функции wp_dropdown_categories() параметр name должен быть слагом таксономии. Хотя в данном случае это ничего не меняет, не совсем очевидно, что именно нужно менять другим пользователям. Особенно потому, что официальная документация об этом не упоминает:

name string

Значение атрибута 'name' для элемента select. По умолчанию 'cat'.

Это может привести к мысли, что это произвольная строка, например "my_select_name". Чтобы избежать путаницы, можно просто использовать переменную.

wp_dropdown_categories(array(
   'name' => $taxonomy,
    ...
));

Параметр selected

Параметр selected необходимо изменить на:

wp_dropdown_categories(array(
   'selected' => $wp_query->query_vars['term']?? 0,
    ...
));

Это связано с тем, что term определяется в query_vars, а не в query. Если термин отсутствует в query_vars, то, скорее всего, он не был выбран, поэтому можно использовать оператор null coalescing для проверки и, если он null|undefined, просто выбрать опцию "показать все" со значением 0.

Параметр value_field

В WP 4.2.0 был добавлен новый параметр: value_field.

С его помощью можно указать, какое "поле термина" следует использовать для заполнения значений атрибутов value элементов option. Из документации:

value_field string

Поле термина, которое следует использовать для заполнения атрибута 'value' элементов option. Принимает любое допустимое поле термина: 'term_id', 'name', 'slug', 'term_group', 'term_taxonomy_id', 'taxonomy', 'description', 'parent', 'count'. По умолчанию 'term_id'.

Добавление slug в этот параметр заполнит значения option слагами терминов. Поскольку для работы функции фильтрации нужен именно слаг, этот параметр делает фильтры работоспособными прямо из кода Шага 1, без необходимости Шага 2.

Таким образом, Шаг 2 можно пропустить, если используется value_field.

wp_dropdown_categories(array(
   'value_field' => 'slug',
    ...
));

Оригинальный код оставлен ниже, внесите в него изменения, как описано выше.



ОБНОВЛЕНИЕ: Я добавил новый полный ответ, но оставил и оригинальный ответ ниже, на который ссылаются первые комментарии.


Привет, @tarasm:

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

Скриншоты:

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

Страница списка объявлений без фильтрации:

Страница списка объявлений без фильтрации
(источник: mikeschinkel.com)

Страница списка объявлений с фильтрацией:

Страница списка объявлений с фильтрацией
(источник: mikeschinkel.com)

Код

Итак, приступим... (Примечание: я использовал единственное число для названия таксономии - business; надеюсь, это соответствует вашему случаю. Исходя из большого опыта работы как с WordPress, так и с разработкой баз данных в прошлом, я считаю, что это лучший вариант.)

Шаг #1: Хук действия restrict_manage_posts.

Первое, что нужно сделать, - подключить действие restrict_manage_posts, которое не принимает параметров и вызывается из /wp-admin/edit.php (в v3.0.1 этот вызов находится на строке 378). Это позволит вам сгенерировать выпадающий список select в нужном месте над списком записей типа "Объявление".

<?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' =>  __("Показать все {$business_taxonomy->label}"),
            'taxonomy'        =>  $taxonomy,
            'name'            =>  'business',
            'orderby'         =>  'name',
            'selected'        =>  $wp_query->query['term'],
            'hierarchical'    =>  true,
            'depth'           =>  3,
            'show_count'      =>  true, // Показать количество объявлений в скобках
            'hide_empty'      =>  true, // Не показывать бизнесы без объявлений
        ));
    }
}

Мы начинаем с проверки переменной $typenow, чтобы убедиться, что мы действительно находимся на типе записи listing. Если не проверить, этот выпадающий список появится для всех типов записей, что в некоторых случаях может быть желаемым, но не в данном.

Затем мы загружаем информацию о таксономии business с помощью get_taxonomy(). Она нам нужна для получения метки таксономии (т.е. "Бизнесы"; можно было бы жестко задать строку, но это не очень хорошо, если позже потребуется интернационализация). Затем мы вызываем wp_dropdown_categories() со всеми необходимыми аргументами в массиве $args, чтобы сгенерировать выпадающий список.

<?php
return wp_dropdown_categories(array(
    'show_option_all' =>  __("Показать все {$business_taxonomy->label}"),
    'taxonomy'        =>  $taxonomy,
    'name'            =>  'business',
    'orderby'         =>  'name',
    'selected'        =>  $wp_query->query['term'],
    'hierarchical'    =>  true,
    'depth'           =>  3,
    'show_count'      =>  true, // Показать количество объявлений в скобках
    'hide_empty'      =>  true, // Не показывать бизнесы без объявлений
));

Но какие именно аргументы нужны? Рассмотрим каждый по отдельности:

  • show_optional_all - Довольно очевидно, это то, что отображается в выпадающем списке сначала и когда фильтрация не применена. В нашем случае это будет "Показать все бизнесы", но можно было бы назвать "Объявления для всех бизнесов" или как угодно.

  • taxonomy - Этот аргумент указывает функции, из какой таксономии брать термины, несмотря на то, что в названии функции присутствует слово categories. В версиях 2.8 и ранее WordPress не имел пользовательских таксономий, но когда они были добавлены, команда решила, что проще добавить аргумент taxonomy в эту функцию, чем создавать другую функцию с другим названием.

  • name - Этот аргумент позволяет указать значение, которое WordPress будет использовать для атрибута name элемента <select>, генерируемого для выпадающего списка. На всякий случай, если это не очевидно, это также значение, которое будет использоваться в URL при фильтрации.

  • orderby - Этот аргумент указывает WordPress, как упорядочивать результаты алфавитно. В нашем случае мы указали сортировку по name терминов таксономии, т.е. в данном случае по названиям бизнесов.

  • selected - Этот аргумент нужен для того, чтобы выпадающий список мог отображать текущий фильтр. Это должен быть term_id выбранного термина таксономии. В нашем случае это может быть term_id для "Бизнес #2". Откуда мы берем это значение? Из глобальной переменной WordPress $wp_query; у нее есть свойство query, содержащее массив всех параметров URL и их значений (если, конечно, какой-нибудь плагин уже не изменил его). Учитывая, как WordPress обрабатывает данные, параметр term будет передан в URL, когда пользователь нажмет кнопку фильтра, если пользователь выбрал допустимый термин (т.е. один из перечисленных бизнесов).

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

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

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

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

Выпадающий список таксономии с иерархией и счетчиками
(источник: 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 - пользовательская. Но для тех, кто знаком с категоризацией записей, это может помочь понять, так как они работают почти одинаково. Но я отвлекся...)

Перейдем к коду. Первое, что мы делаем, - получаем ссылку на массив query_vars текущего активного $wp_query, чтобы было удобнее работать, точно так же, как это делается в собственной функции WordPress parse_query(). В отличие от $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 по пути /wp-admin/edit.php. Это нужно, чтобы случайно не испортить запросы на других страницах. Мы также проверяем, есть ли у нас как элемент taxonomy со значением business, так и элемент 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' => 'Бизнесы',
        'public'=>true,
        'hierarchical'=>true,
        'show_ui'=>true,
        'query_var'=>true
    ));
}

Теперь $wp_query WordPress был написан для использования слаггов в стандартных запросах с фильтрацией по таксономии, а не ID терминов таксономии. Для данного случая нам действительно нужны следующие параметры для работы запроса фильтрации:

taxonomy: business

term: business-1 (т.е. slug)

А не эти:

taxonomy: business

term: 27 (т.е. term_id)

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

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

НО ПОДОЖДИТЕ, ЭТО ЕЩЕ НЕ ВСЁ! :-)

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

Шаг #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'] = 'Бизнесы';
    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.

Скриншот столбца 'cb' записей как чекбокса.
(источник: mikeschinkel.com)

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

$new_posts_columns['businesses'] = 'Бизнесы';

(Примечание: когда я писал add_businesses_column_to_listing_list(), мне пришло в голову, что в PHP должен быть более простой способ вставить значение в ассоциативный массив в правильном порядке?!? Или, по крайней мере, должна быть функция в ядре 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;
        }
    }
}

Этот хук вызывается для каждого столбца каждой строки записи(/бизнеса). Сначала мы проверяем, что работаем только с пользовательским типом записи 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 '...что угодно...';
        break;
    case 'listing:property':
        echo '...что угодно...';
        break;
    case 'agent:listing':
        echo '...что угодно...';
        break;
    }
}

Рассматривая наш случай чуть ближе, вы видите функцию get_the_terms(), которая просто возвращает список терминов для этой таксономии (т.е. бизнесов для этого объявления). Здесь мы получаем постоянную ссылку на страницу термина на фронтенде, которая обычно отображает записи, связанные с термином, но, конечно, может работать иначе в зависимости от темы и/или установленных плагинов.

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

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

ТЕПЕРЬ мы наконец закончили.

Итог

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

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

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

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

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

КОНЕЦ


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

Привет, @tarasm:

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

Как создать функциональность сортировки для пользовательского типа записи в админке WordPress
(источник: mikeschinkel.com)

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

19 авг. 2010 г. 18:58:37
Комментарии

Я ищу один выпадающий список вверху, который бы отображал фильтр по категориям. Интересно, есть ли стандартный способ сделать это без написания пользовательского кода.

Taras Mankovski Taras Mankovski
19 авг. 2010 г. 20:04:44

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

MikeSchinkel MikeSchinkel
19 авг. 2010 г. 20:30:05

На самом деле оба решения (somatic и MikeSchinkel) не работают, когда пытаешься фильтровать по двум разным таксономиям в одном фильтре :-/

Всегда фильтруется только последняя таксономия при попытке фильтрации по двум и более одновременно.

Ünsal Korkmaz Ünsal Korkmaz
3 нояб. 2010 г. 05:24:09

@Ünsal Текущая версия WordPress (3.0) не поддерживает запросы по нескольким таксономиям, но, по слухам, это изменится в версии 3.1. Чтобы заставить этот пример работать с несколькими таксономиями, вам нужно добавить некоторые JOIN и WHERE к запросу через хуки фильтров Posts_join и posts_where.

Manny Fleurmond Manny Fleurmond
5 янв. 2011 г. 18:07:48

спасибо за отличный ответ - но есть небольшая опечатка в примере кода шага #4: должно быть $column_id, а не column_name. Версия на github, однако, правильная.

Philipp Kyeck Philipp Kyeck
13 нояб. 2011 г. 19:14:36

В WP 3.1+ шаги один и два лучше реализованы в ответе @drew-gourley (на самом деле, ваш шаг 2 не сработал у меня, думаю, в новом WordPress произошли изменения в этом фильтре).

Tomasz Struczyński Tomasz Struczyński
3 дек. 2011 г. 12:10:32

Майк, я считаю, что можно улучшить ясность этого (замечательного) руководства, изменив аргументы wp_dropdown_categories так, чтобы 'name' => $taxonomy, чтобы было очевидно, что атрибут name у select должен быть слагом зарегистрированной таксономии (или, точнее, query_var слагом). В текущем виде кажется, что 'taxonomy' должен быть слагом таксономии, но 'name' может быть любым произвольным значением, что, как я полагаю, не совсем так, если только вы не готовы разбирать query string самостоятельно в parse_query

Tom Auger Tom Auger
7 дек. 2011 г. 22:38:32

Очень блестящий и полный ответ, но разве не нужно возвращать переменную $query в вашей функции convert_business_id_to_taxonomy_term_in_query()?

helgatheviking helgatheviking
8 янв. 2012 г. 00:30:22

Присоединяюсь к длинному списку предыдущих комплиментов! Уроки Майка (довольно часто) похожи на университетские лекции... И хотел бы отметить для всех, кто исследует этот вопрос, что ответ @DrewGourley ниже - это чистое золото :)

brasofilo brasofilo
9 июл. 2012 г. 16:42:28

Один момент, который не сразу очевиден - get_term_link() создаст ссылку на публичный архив таксономии, а не покажет отфильтрованные результаты в WP-Admin. Не уверен, есть ли функция для генерации такой ссылки, поэтому её нужно создавать вручную, например: <a href="edit.php?CUSTOM_TAXONOMY=FOO&post_type=CUSTOM_POST_TYPE">НАЗВАНИЕ_ТАКСОНОМИИ</a>. Но за исключением этой мелкой детали, всё просто замечательно!

User User
7 мая 2013 г. 21:34:46

Хочу отметить, что начиная с WordPress 3.5 можно добавлять колонки таксономий просто добавив 'show_admin_column' => true в параметры register_taxonomy.

Luca Reghellin Luca Reghellin
15 сент. 2017 г. 12:06:14
Показать остальные 6 комментариев
6
46

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

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

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

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

    // отображать эти фильтры таксономий только для нужных типов записей
    global $typenow;
    if ($typenow == 'photos' || $typenow == 'videos') {

        // массив слэгов таксономий для фильтрации - можно использовать get_taxonomies() для получения всех таксономий
        $filters = array('plants', 'animals', 'insects');

        foreach ($filters as $tax_slug) {
            // получаем объект таксономии
            $tax_obj = get_taxonomy($tax_slug);
            $tax_name = $tax_obj->labels->name;
            // получаем массив объектов терминов для таксономии
            $terms = get_terms($tax_slug);

            // выводим HTML для выпадающего списка фильтра
            echo "<select name='$tax_slug' id='$tax_slug' class='postform'>";
            echo "<option value=''>Показать все $tax_name</option>";
            foreach ($terms as $term) {
                // выводим каждый вариант выбора, проверяем $_GET для выделения текущего выбранного варианта
                echo '<option value='. $term->slug, $_GET[$tax_slug] == $term->slug ? ' selected="selected"' : '','>' . $term->name .' (' . $term->count .')</option>';
            }
            echo "</select>";
        }
    }
}

Просто добавив нужные таксономии в массив $filters, вы можете быстро вывести несколько фильтров. Они выглядят точно так же, как на скриншотах Майка. Затем можно переходить к шагу #3 и #4.

23 окт. 2010 г. 08:00:36
Комментарии

@somatic - Отличное обновление! Да, использование wp_dropdown_categories() действительно требует множества обходных решений. Я стараюсь по возможности использовать основные функции WordPress, но, как вы правильно заметили, иногда это требует больше работы. Это лишний раз доказывает, что в WordPress часто существует несколько хороших способов решения одной задачи. Отличная работа!

MikeSchinkel MikeSchinkel
23 окт. 2010 г. 12:53:41

Перестало работать у меня на WordPress 3.1. Пытаюсь разобраться, что именно изменилось. Похоже, что всё должно работать: таксономия и ярлыки терминов отображаются как GET-параметры в URL, но в результате получаю 0 найденных записей.

Manny Fleurmond Manny Fleurmond
24 февр. 2011 г. 08:40:11

Я пытался заставить это работать, но единственный способ, который сработал - использовать хук parse_query, проверять query_var таксономии и устанавливать query_var для таксономии и термина на основе этого. Использую WP 3.1. Должны ли таксономия и термин появляться в URL при отправке фильтра?

sanchothefat sanchothefat
22 мар. 2011 г. 19:36:16

Работает отлично! Действительно элегантное решение. Я должен тебе пиво :)

Michal Mau Michal Mau
26 апр. 2011 г. 14:31:51

@somatic Это отлично работает, но есть ли способ сделать так, чтобы $term->count считал только термины для этого типа записи? Например, если у меня есть пользовательская таксономия и для фото, и для видео, то при просмотре типа записи видео она будет показывать общее количество записей для этого термина из обоих типов записей, вместо того чтобы показывать только количество видео-записей, использующих этот термин.

Greenhoe Greenhoe
11 июн. 2015 г. 16:40:45

Вы можете улучшить строку echo "<option value=''>Show All $tax_name</option>"; с помощью $tax_labels = get_taxonomy_labels( $tax_obj );, а затем echo "<option value=''>". sprintf( __( 'Show %s', 'textdomain'), mb_strtolower( $tax_labels->all_items ) ) ."</option>";

ZalemCitizen ZalemCitizen
29 мар. 2024 г. 16:37:15
Показать остальные 1 комментариев
1
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' => __('Показать все '.$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' как способ сортировки терминов. Вам нужно будет изменить это или удалить этот аргумент, чтобы использовать значение по умолчанию.

23 мар. 2011 г. 22:40:00
Комментарии

действительно очень сексуально. я получал уведомления об ошибках, поэтому изменил if (isset($var)) на if (isset($var) && $var>0), чтобы избежать попыток найти термины, связанные со значением 0 в "View all". и ещё мне пришлось добавить return $query в функцию todo_convert_restrict

helgatheviking helgatheviking
8 янв. 2012 г. 00:17:27
7
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})"
                : ''
        );
    }
}
19 янв. 2013 г. 21:57:01
Комментарии

Попробовал это, но метод get_select(), похоже, отсутствует.

Dave Romsey Dave Romsey
15 мар. 2013 г. 17:40:39

@goto10 Ты был прав. Обновил. Кстати: проще просто взять связанный плагин. Он будет доступен в репозитории плагинов через одну-две недели. (Уже подтверждено).

kaiser kaiser
16 мар. 2013 г. 13:09:12

Мне пришлось использовать $this->setup_vars(); в начале public function setup(), чтобы "manage_taxonomies_for_{$this->post_type}_columns" работал

Christian Christian
2 июл. 2013 г. 14:44:22

Но возможно это потому, что я использую его в файле function.php темы с add_action( 'init', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );

Christian Christian
2 июл. 2013 г. 14:52:45

@Christian Это не относится к теме. Это должно быть в плагине, и в текущем виде код загружается намного раньше, чем загружаются темы.

kaiser kaiser
2 июл. 2013 г. 15:49:28

Плагин ничего не сделал для меня в WP 4.8

BadHorsie BadHorsie
18 авг. 2017 г. 19:38:26

@BadHorsie Пожалуйста, попробуй ветку dev. Я начал рефакторинг, но не смог найти время, чтобы закончить его.

kaiser kaiser
18 авг. 2017 г. 21:08:51
Показать остальные 2 комментариев
0

Хочу сделать небольшое замечание. В новых версиях WordPress список записей в админке обрабатывается классом 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"         => "Заголовок",
      "anothercolumn" => "Bacon",
      "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

Чтобы получить данные наших записей, нам нужно добавить хук action следующим образом:

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;
  }
}
29 авг. 2011 г. 14:44:11
2

РАБОТАЕТ В WP 3.2!

Пользовательский тип записи: books Пользовательская таксономия: genre

Изменяйте только там, где указано: // change HERE

function restrict_books_by_genre() {
    global $typenow;
    $post_type = 'books'; // измените ЗДЕСЬ
    $taxonomy = 'genre'; // измените ЗДЕСЬ
    if ($typenow == $post_type) {
        $selected = isset($_GET[$taxonomy]) ? $_GET[$taxonomy] : '';
        $info_taxonomy = get_taxonomy($taxonomy);
        wp_dropdown_categories(array(
            'show_option_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'; // измените ЗДЕСЬ
    $taxonomy = 'genre'; // измените ЗДЕСЬ
    $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');
16 окт. 2011 г. 06:54:53
Комментарии

Это простое и удобное решение для WP 3.2+.

petermolnar petermolnar
30 июл. 2015 г. 13:27:00

оно работает, но __("Show All {$info_taxonomy->label}") - неправильный способ использования переводимых строк.

Mark Kaplun Mark Kaplun
23 авг. 2017 г. 08:24:24
1

Недавно мне пришлось работать над подобной функциональностью, так как существующие решения меня не устраивали. Вот мой альтернативный вариант. Год 2021.

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

Было несколько требований:

  • Я хотел избежать использования глобальных переменных.
  • Код должен быть переносимым, без жестко закодированных переменных, для возможности повторного использования.
  • Наличие видимой иерархии, идеально подходящей для таксономий с большим количеством терминов.
  • Необходимо учитывать настройки видимости таксономии (например: параметр show_admin_column в функции register_taxonomy).
  • Отображение количества записей.
  • Внешний вид должен соответствовать стилю WordPress.

Я сделал это в виде плагина для более простой интеграции. Последнюю версию можно получить по адресу https://wordpress.org/plugins/cpt-admin-taxonomy-filtering/.

Фильтр с иерархией терминов и подсчетом записей Множественные фильтры для пользовательских типов записей
Фильтр с иерархией терминов и подсчетом записей в админке WordPress Множественные фильтры для разных типов записей в WordPress

Если вы хотите просто добавить этот функционал в ваш function.php, скопируйте и вставьте следующий скрипт.

Требуется WordPress версии не ниже 4.8.0 и PHP: 4.0.

<?php

add_action( 'restrict_manage_posts', 'cpt_admin_taxonomy_filtering' );

if ( ! function_exists( 'cpt_admin_taxonomy_filtering' ) ) {

    function cpt_admin_taxonomy_filtering() {

        /**
         * Получаем текущий объект экрана.
         * 
         * @link https://developer.wordpress.org/reference/functions/get_current_screen/
         */
        $screen = get_current_screen();

        // Исключаем стандартные типы записей WordPress
        $restricted_post_types = array(
            'post',
            'page',
            'attachment',
            'revision',
            'nav_menu_item',
        );

        if ( 'edit' === $screen->base && ! in_array( $screen->post_type, $restricted_post_types ) ) {

            /**
             * Возвращает имена или объекты таксономий, зарегистрированных для запрашиваемого объекта или типа объекта.
             * 
             * @link https://developer.wordpress.org/reference/functions/get_object_taxonomies/
             */
            $taxonomies = get_object_taxonomies( $screen->post_type, 'objects' );

            // Перебираем каждую таксономию
            foreach ( $taxonomies as $taxonomy ) {

                if ( $taxonomy->show_admin_column ) {

                    /**
                     * Отображает или возвращает HTML выпадающий список категорий.
                     * 
                     * @link https://developer.wordpress.org/reference/functions/wp_dropdown_categories/
                     */
                    wp_dropdown_categories(
                        array(
                            'show_option_all' => $taxonomy->labels->all_items,
                            'pad_counts' => true,
                            'show_count' => true,
                            'hierarchical' => true,
                            'name' => $taxonomy->query_var,
                            'id' => 'filter-by-' . $taxonomy->query_var,
                            'class' => '',
                            'value_field' => 'slug',
                            'taxonomy' => $taxonomy->query_var,
                            'hide_if_empty' => true,
                        )
                    );

                };

            };

        };

    };

};
1 мая 2021 г. 16:39:29
Комментарии

Это работает отлично, спасибо!

Gavin Gavin
17 июл. 2021 г. 05:25:59
0

Это не очень известная возможность, но начиная с WordPress 3.5, вы можете передавать параметр 'show_admin_column' => true в функцию register_taxonomy. Это делает две вещи:

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

Это не совсем то же самое, что иметь выпадающий список, но функциональность почти идентичная, всего одной строкой кода.

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

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

15 сент. 2017 г. 15:00:54
2

Спасибо всем за ответы. Я знаю, что это старый вопрос, но хотел бы добавить более простое решение, которое можно использовать сегодня. Оно потребует всего 2 шага и задействует больше встроенных возможностей. Надеюсь, это кому-то поможет.

Шаг 1: добавьте 'show_admin_column' => true в вашу функцию register_taxonomy.

Это добавит колонку в список записей с ссылками для фильтрации по этому термину. Применяется как для иерархических, так и для неиерархических таксономий.

Пример:

register_taxonomy( 'custom_cat', array( 'custom_post_type' ), array(
    'hierarchical'      => true,
    'labels'            => array(
        'name'              => __( 'Категории', 'iside' ),
        'singular_name'     => __( 'Категория', 'iside' ),
        'search_items'      => __( 'Искать категории', 'iside' ),
        'all_items'         => __( 'Все категории', 'iside' ),
        'parent_item'       => __( 'Родительская категория', 'iside' ),
        'parent_item_colon' => __( 'Родительская категория:', 'iside' ),
        'edit_item'         => __( 'Редактировать категорию', 'iside' ),
        'update_item'       => __( 'Обновить категорию', 'iside' ),
        'add_new_item'      => __( 'Добавить новую категорию', 'iside' ),
        'new_item_name'     => __( 'Новая категория', 'iside' ),
        'menu_name'         => __( 'Категории', 'iside' ),
    ),
    'public'            => true,
    'publicly_queryable'=> true,
    'show_ui'           => true,
    'show_in_menu'      => true,
    'show_in_nav_menus' => true,
    'show_in_rest'      => true,
    'show_tagcloud'     => false,
    'show_in_quick_edit'=> true,
    'show_admin_column' => true, // <-- вот где применяется магия
    'query_var'         => true,
) );

Шаг 2: добавьте выпадающий список таксономии через фильтр restrict_manage_posts

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

Пример:

add_action( 'restrict_manage_posts', 'iside_add_filter_to_admin', 10, 2 );
function iside_add_filter_to_admin( $post_type = 'post', $which = 'top' ) {
    if( $post_type == 'custom_post_type' ) {
        $selected = isset( $_GET['custom_cat'] ) ? esc_attr($_GET['custom_cat']) : 0;
        wp_dropdown_categories(array(
            'show_option_all' =>  __( 'Показать все категории', 'iside' ),
            'taxonomy'        =>  'custom_cat',
            'name'            =>  'custom_cat', // <-- убедитесь, что совпадает с query_var
            'orderby'         =>  'name',
            'selected'        =>  $selected,
            'hierarchical'    =>  true,
            'depth'           =>  3,
            'show_count'      =>  true,
            'hide_empty'      =>  true,
            'value_field'     => 'slug', // <-- используем slug вместо term_id
        ));
    }
}

Всё. Больше ничего добавлять не нужно :-)

18 мар. 2022 г. 11:52:55
Комментарии

Очень красиво и просто, спасибо. Хочу отметить одну деталь - у вас есть ошибка в синтаксисе (лишняя скобка): $selected = isset( $_GET['custom_cat'] ) ? esc_attr($_GET['custom_cat') ]) : 0; что должно быть исправлено следующим образом: $selected = isset( $_GET['custom_cat'] ) ? esc_attr($_GET['custom_cat' ]) : 0;

SolaceBeforeDawn SolaceBeforeDawn
27 мая 2023 г. 09:05:51

Спасибо @SolaceBeforeDawn. Я исправил свой ответ

leendertvb leendertvb
27 мая 2023 г. 23:30:21
0

Вот способ сделать это с помощью действия restrict_manage_posts. У меня это работает хорошо и добавляет возможность фильтрации по таксономиям для всех типов записей и связанных с ними таксономий.

// регистрирует каждый выпадающий список фильтров таксономий
function sunrise_fbt_add_taxonomy_filters() {
    global $typenow;            // текущий тип записи
    $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) {
              // Проверяем иерархичность - если да, строим иерархический выпадающий список
              if($tax->hierarchical) {
                $args = array(
                      'show_option_all'    => 'Все '.$tax->labels->name,
                      'show_option_none'   => 'Выбрать '.$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=''>Показать все ".$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 );

/**
 * Создает HTML выпадающий список категорий.
 *
 * @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?

17 февр. 2012 г. 21:53:24
0

Обновление ответа @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' => __('Показать все '.$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()
            ));
        }
    }
}


//Класс для фильтрации выпадающего списка. Используется с wp_dropdown_categories() для использования слагов терминов вместо ID.
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";
    }
}
25 янв. 2013 г. 22:47:17
0

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

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

    // отображать эти фильтры таксономий только для нужных типов записей
    global $typenow;
    if ($typenow == 'photos' || $typenow == 'videos') {

        // создаем массив слогов таксономий для фильтрации - если нужно получить все таксономии, можно использовать get_taxonomies()
        $filters = array('plants', 'animals', 'insects');

        foreach ($filters as $tax_slug) {
            // получаем объект таксономии
            $tax_obj = get_taxonomy($tax_slug);
            $tax_name = $tax_obj->labels->name;

            // выводим HTML для выпадающего списка фильтра таксономии
            echo "<select name='$tax_slug' id='$tax_slug' class='postform'>";
            echo "<option value=''>Показать все $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) {
        // выводим каждую опцию select, проверяем $_GET чтобы показать выбранную опцию
        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, который выберет все корневые термины. В цикле функция будет рекурсивно вызывать саму себя, используя текущий термин в качестве родителя и увеличивая уровень на единицу. Она автоматически добавляет тире сбоку, чем глубже вы спускаетесь по дереву, и вуаля!

7 янв. 2011 г. 09:12:50
1

Просто добавьте это в ваш functions.php или код плагина (и замените YOURCUSTOMTYPE и YOURCUSTOMTAXONOMY). (Я получил этот код с generatewp)

add_action( 'restrict_manage_posts', 'filter_backend_by_taxonomies' , 99, 2);

function filter_backend_by_taxonomies( $post_type, $which ) {
    // Применяем это к определенному CPT
    if ( 'YOURCUSTOMTYPE' !== $post_type )
        return;
    // Список слогов таксономий для фильтрации
    $taxonomies = array( 'YOURCUSTOMTAXONOMY' );
    foreach ( $taxonomies as $taxonomy_slug ) {
        // Получаем данные таксономии
        $taxonomy_obj = get_taxonomy( $taxonomy_slug );
        $taxonomy_name = $taxonomy_obj->labels->name;
        // Получаем термины таксономии
        $terms = get_terms( $taxonomy_slug );
        // Выводим HTML фильтра
        echo "<select name='{$taxonomy_slug}' id='{$taxonomy_slug}' class='postform'>";
        echo '<option value="">' . sprintf( esc_html__( 'Категория', 'text_domain' ), $taxonomy_name ) . '</option>';
        foreach ( $terms as $term ) {
            printf(
                '<option value="%1$s" %2$s>%3$s (%4$s)</option>',
                $term->slug,
                ( ( isset( $_GET[$taxonomy_slug] ) && ( $_GET[$taxonomy_slug] == $term->slug ) ) ? ' selected="selected"' : '' ),
                $term->name,
                $term->count
            );
        }
        echo '</select>';
    }
}
29 июн. 2020 г. 14:28:23
Комментарии

Отлично! Лучший ответ!

Carl Brubaker Carl Brubaker
21 апр. 2021 г. 23:42:23
0
```html

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

Однако, я считаю, что использование parse_query с последующим запросом термина не является необходимым. Гораздо чище создать собственный класс-обработчик (walker class). Возможно, во время написания его поста (3 года назад на момент моего комментария) такой вариант был недоступен.

Обратите внимание на этот замечательный сниппет на GitHub. Работает идеально - преобразует ID в выпадающем списке в slugs, поэтому всё работает нативно без модификации запроса.

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

```
27 мар. 2014 г. 22:04:55
1

Попробовал оба кода - от Mike и somatic, и задумался, как можно получить лучшее от каждого подхода:

С кодом Mike выпадающий список отображается с опцией иерархичности, что очень помогает. Но чтобы отобразить два выпадающих списка, мне пришлось дублировать условие 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, но с сохранением опции иерархичности?

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

6 янв. 2011 г. 21:00:53
Комментарии

Смотрите мой ответ для иерархического решения

Manny Fleurmond Manny Fleurmond
8 янв. 2011 г. 08:02:39
0

Это небольшой, но мощный сниппет, который позволяет фильтровать записи или пользовательские типы записей по терминам таксономии в админке WordPress.

/* Фильтрация CPT через пользовательскую таксономию */
function rave_core_backend_by_portfolio_taxonomies( $post_type, $which ) {
    // Применяем только к определенному CPT
    if ( 'portfolio' !== $post_type )
        return;

    // Список слаг пользовательских таксономий для фильтрации
    $taxonomies = array( 'portfolio_cat' );

    foreach ( $taxonomies as $taxonomy_slug ) {

        // Получаем данные таксономии
        $taxonomy_obj = get_taxonomy( $taxonomy_slug );
        $taxonomy_name = $taxonomy_obj->labels->name;

        // Получаем термины таксономии
        $terms = get_terms( $taxonomy_slug );

        // Выводим HTML для фильтра
        echo "<select name='{$taxonomy_slug}' id='{$taxonomy_slug}' class='postform'>";
        echo '<option value="">' . sprintf( esc_html__( 'Все %s', 'rave-core' ), $taxonomy_name ) . '</option>';
        foreach ( $terms as $term ) {
            printf(
                '<option value="%1$s" %2$s>%3$s (%4$s)</option>',
                $term->slug,
                ( ( isset( $_GET[$taxonomy_slug] ) && ( $_GET[$taxonomy_slug] == $term->slug ) ) ? ' selected="selected"' : '' ),
                $term->name,
                $term->count
            );
        }
        echo '</select>';
    }
}

add_action( 'restrict_manage_posts', 'rave_core_backend_by_portfolio_taxonomies' , 99, 2);
13 июн. 2021 г. 08:51:24
1

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

Начиная с WordPress 3.1 (RC 1) ответ Майка (который отлично работал у меня последние пару месяцев) перестал работать — фильтрация по любому дочернему термину таксономии возвращает пустой результат.

Я попробовал обновление от Somatic, и оно сработало отлично; более того, теперь поддерживаются запросы по нескольким таксономиям, что было реализовано в этом релизе.

27 дек. 2010 г. 22:37:04
Комментарии

По какой-то причине версия somatic тоже не работает для 3.1

Manny Fleurmond Manny Fleurmond
24 февр. 2011 г. 08:17:18