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

129

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

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

Раскрывающиеся категории в сообщениях

Вот мой текущий код ( А вот тот же код на Gist. ):

<?php
/*
Plugin Name: Listing Content Item
Plugin URI:
Description: 
Author: 
Version: 1.0
Author URI: 
*/

class Listing {
  var $meta_fields = array("list-address1","list-address2","list-country","list-province","list-city","list-postcode","list-firstname","list-lastname","list-website","list-mobile","list-phone","list-fax","list-email", "list-profile", "list-distributionrange", "list-distributionarea");

  public function loadStyleScripts() {
    $eventsURL = trailingslashit( WP_PLUGIN_URL ) . trailingslashit( plugin_basename( dirname( __FILE__ ) ) ) . 'css/';
    wp_enqueue_style('listing-style', $eventsURL.'listing.css');
  }

  function Listing() {
    // Register custom post types
    register_post_type('listing', array(
      'labels' => array(
        'name' => __('Listings'), 'singular_name' => __( 'Listing' ),
        'add_new' => __( 'Add Listing' ),
        'add_new_item' => __( 'Add New Listing' ),
        'edit' => __( 'Edit' ),
        'edit_item' => __( 'Edit Listing' ),
        'new_item' => __( 'New Listing' ),
        'view' => __( 'View Listing' ),
        'view_item' => __( 'View Listing' ),
        'search_items' => __( 'Search Listings' ),
        'not_found' => __( 'No listings found' ),
        'not_found_in_trash' => __( 'No listings found in Trash' ),
        'parent' => __( 'Parent Listing' ),
      ),
      'singular_label' => __('Listing'),
      'public' => true,
      'show_ui' => true, // UI in admin panel
      '_builtin' => false, // It's a custom post type, not built in
      '_edit_link' => 'post.php?post=%d',
      'capability_type' => 'post',
      'hierarchical' => false,
      'rewrite' => array("slug" => "listings"), // Permalinks
      'query_var' => "listings", // This goes to the WP_Query schema
      'supports' => array('title','editor')
    ));

    add_filter("manage_edit-listing_columns", array(&$this, "edit_columns"));
    add_action("manage_posts_custom_column", array(&$this, "custom_columns"));

    // Register custom taxonomy

    #Businesses
    register_taxonomy("businesses", array("listing"), array(
      "hierarchical" => true, 
      "label" => "Listing Categories", 
      "singular_label" => "Listing Categorie", 
      "rewrite" => true,
    ));

    # Region
    register_taxonomy("regions", array("listing"), array(
      'labels' => array(
        'search_items' =>  __( 'Search Regions' ),
        'popular_items' => __( 'Popular Regions' ),
        'all_items' => __( 'All Regions' ),
        'parent_item' => null,
        'parent_item_colon' => null,
        'edit_item' => __( 'Edit Region' ), 
        'update_item' => __( 'Update Region' ),
        'add_new_item' => __( 'Add New Region' ),
        'new_item_name' => __( 'New Region Name' ),
        'separate_items_with_commas' => __( 'Separate regions with commas' ),
        'add_or_remove_items' => __( 'Add or remove regions' ),
        'choose_from_most_used' => __( 'Choose from the most used regions' ),
      ),
      "hierarchical" => false, 
      "label" => "Listing Regions", 
      "singular_label" => "Listing Region", 
      "rewrite" => true,
    ));

    # Member Organizations
    register_taxonomy("organizations", array("listing"), array(
      'labels' => array(
        'search_items' =>  __( 'Search Member Organizations' ),
        'popular_items' => __( 'Popular Member Organizations' ),
        'all_items' => __( 'All Member Organizations' ),
        'parent_item' => null,
        'parent_item_colon' => null,
        'edit_item' => __( 'Edit Member Organization' ), 
        'update_item' => __( 'Update Member Organization' ),
        'add_new_item' => __( 'Add New Member Organization' ),
        'new_item_name' => __( 'New Member Organization Name' ),
        'separate_items_with_commas' => __( 'Separate member organizations with commas' ),
        'add_or_remove_items' => __( 'Add or remove member organizations' ),
        'choose_from_most_used' => __( 'Choose from the most used member organizations' ),
      ),
      "hierarchical" => false, 
      "label" => "Member Organizations", 
      "singular_label" => "Member Organization", 
      "rewrite" => true,
    ));

    # Retail Products
    register_taxonomy("retails", array("listing"), array(
      'labels' => array(
        'search_items' =>  __( 'Search Retail Products' ),
        'popular_items' => __( 'Popular Retail Products' ),
        'all_items' => __( 'All Retail Products' ),
        'parent_item' => null,
        'parent_item_colon' => null,
        'edit_item' => __( 'Edit Retail Product' ), 
        'update_item' => __( 'Update Retail Product' ),
        'add_new_item' => __( 'Add New Retail Product' ),
        'new_item_name' => __( 'New Retail Product Name' ),
        'separate_items_with_commas' => __( 'Separate retail products with commas' ),
        'add_or_remove_items' => __( 'Add or remove retail products' ),
        'choose_from_most_used' => __( 'Choose from the most used retail products' ),
      ),
      "hierarchical" => false, 
      "label" => "Retail Products", 
      "singular_label" => "Retail Product", 
      "rewrite" => true,
    ));

    # Farming Practices
    register_taxonomy("practices", array("listing"), array(
      'labels' => array(
        'search_items' =>  __( 'Search Farming Practices' ),
        'popular_items' => __( 'Popular Farming Practices' ),
        'all_items' => __( 'All Farming Practices' ),
        'parent_item' => null,
        'parent_item_colon' => null,
        'edit_item' => __( 'Edit Farming Practice' ), 
        'update_item' => __( 'Update Farming Practice' ),
        'add_new_item' => __( 'Add New Farming Practice' ),
        'new_item_name' => __( 'New Farming Practice Name' ),
        'separate_items_with_commas' => __( 'Separate farming practices with commas' ),
        'add_or_remove_items' => __( 'Add or remove farming practices' ),
        'choose_from_most_used' => __( 'Choose from the most used farming practices' ),
      ),
      "hierarchical" => false, 
      "label" => "Farming Practices", 
      "singular_label" => "Farming Practice", 
      "rewrite" => true,
     ));

    # Products 
    register_taxonomy("products", array("listing"), array(
      'labels' => array(
        'search_items' =>  __( 'Search Products' ),
        'popular_items' => __( 'Popular Products' ),
        'all_items' => __( 'All Products' ),
        'parent_item' => null,
        'parent_item_colon' => null,
        'edit_item' => __( 'Edit Product' ), 
        'update_item' => __( 'Update Product' ),
        'add_new_item' => __( 'Add New Product' ),
        'new_item_name' => __( 'New Product Name' ),
        'separate_items_with_commas' => __( 'Separate products with commas' ),
        'add_or_remove_items' => __( 'Add or remove products' ),
        'choose_from_most_used' => __( 'Choose from the most used products' ),
      ),
      "hierarchical" => false, 
      "label" => "Products", 
      "singular_label" => "Product", 
      "rewrite" => true,
    ));


    // Admin interface init
    add_action("admin_init", array(&$this, "admin_init"));
    add_action("template_redirect", array(&$this, 'template_redirect'));

    // Insert post hook
    add_action("wp_insert_post", array(&$this, "wp_insert_post"), 10, 2);
  }

  function edit_columns($columns) {
    $columns = array(
      "cb" => "<input type=\"checkbox\" />",
      "title" => "Business Name",
      "description" => "Description",
      "list-personal" => "Personal Information",
      "list-location" => "Location",
      "list-categorie" => "Categorie",
    );

    return $columns;
  }

  function custom_columns($column) {
    global $post;
    switch ($column) {
      case "description":
        the_excerpt();
        break;
      case "list-personal":
        $custom = get_post_custom();
        if(isset($custom["list-firstname"][0])) echo $custom["list-firstname"][0]."<br />";
        if(isset($custom["list-lastname"][0])) echo $custom["list-lastname"][0]."<br />";
        if(isset($custom["list-email"][0])) echo $custom["list-email"][0]."<br />";
        if(isset($custom["list-website"][0])) echo $custom["list-website"][0]."<br />";
        if(isset($custom["list-phone"][0])) echo $custom["list-phone"][0]."<br />";
        if(isset($custom["list-mobile"][0])) echo $custom["list-mobile"][0]."<br />";
        if(isset($custom["list-fax"][0])) echo $custom["list-fax"][0];
        break;
      case "list-location":
        $custom = get_post_custom();
        if(isset($custom["list-address1"][0])) echo $custom["list-address1"][0]."<br />";
        if(isset($custom["list-address2"][0])) echo $custom["list-address2"][0]."<br />";
        if(isset($custom["list-city"][0])) echo $custom["list-city"][0]."<br />";
        if(isset($custom["list-province"][0])) echo $custom["list-province"][0]."<br />";
        if(isset($custom["list-postcode"][0])) echo $custom["list-postcode"][0]."<br />";
        if(isset($custom["list-country"][0])) echo $custom["list-country"][0]."<br />";
        if(isset($custom["list-profile"][0])) echo $custom["list-profile"][0]."<br />";
        if(isset($custom["list-distributionrange"][0])) echo $custom["list-distributionrange"][0]."<br />";
        if(isset($custom["list-distributionarea"][0])) echo $custom["list-distributionarea"][0];
        break;
      case "list-categorie":
        $speakers = get_the_terms(0, "businesses");
        $speakers_html = array();
        if(is_array($speakers)) {
          foreach ($speakers as $speaker)
          array_push($speakers_html, '<a href="' . get_term_link($speaker->slug, 'businesses') . '">' . $speaker->name . '</a>');
          echo implode($speakers_html, ", ");
        }
        break;
    }
  }

  // Template selection
  function template_redirect() {
    global $wp;
    if (isset($wp->query_vars["post_type"]) && ($wp->query_vars["post_type"] == "listing")) {
      include(STYLESHEETPATH . "/listing.php");
      die();
    }
  }

  // When a post is inserted or updated
  function wp_insert_post($post_id, $post = null) {
    if ($post->post_type == "listing") {
      // Loop through the POST data
      foreach ($this->meta_fields as $key) {
        $value = @$_POST[$key];
        if (empty($value)) {
          delete_post_meta($post_id, $key);
          continue;
        }

        // If value is a string it should be unique
        if (!is_array($value)) {
          // Update meta
          if (!update_post_meta($post_id, $key, $value)) {
            // Or add the meta data
            add_post_meta($post_id, $key, $value);
          }
        }
        else
        {
          // If passed along is an array, we should remove all previous data
          delete_post_meta($post_id, $key);

          // Loop through the array adding new values to the post meta as different entries with the same name
          foreach ($value as $entry)
            add_post_meta($post_id, $key, $entry);
        }
      }
    }
  }

  function admin_init() {
    // Custom meta boxes for the edit listing screen
    add_meta_box("list-pers-meta", "Personal Information", array(&$this, "meta_personal"), "listing", "normal", "low");
    add_meta_box("list-meta", "Location", array(&$this, "meta_location"), "listing", "normal", "low");
  }

  function meta_personal() {
    global $post;
    $custom = get_post_custom($post->ID);
    if(isset($custom["list-firstname"][0])) $first_name = $custom["list-firstname"][0];else $first_name = '';
    if(isset($custom["list-lastname"][0])) $last_name = $custom["list-lastname"][0];else $last_name = '';
    if(isset($custom["list-website"][0])) $website = $custom["list-website"][0];else $website = '';
    if(isset($custom["list-phone"][0])) $phone = $custom["list-phone"][0];else $phone = '';
    if(isset($custom["list-mobile"][0])) $mobile = $custom["list-mobile"][0];else $mobile = '';
    if(isset($custom["list-fax"][0])) $fax = $custom["list-fax"][0];else $fax = '';
    if(isset($custom["list-email"][0])) $email = $custom["list-email"][0];else $email = '';
?>
<div class="personal">
<table border="0" id="personal">
<tr><td class="personal_field"><label>Firstname:</label></td><td class="personal_input"><input name="list-firstname" value="<?php echo $first_name; ?>" /></td></tr>
<tr><td class="personal_field"><label>Lastname:</label></td><td class="personal_input"><input name="list-lastname" value="<?php echo $last_name; ?>" /></td></tr>
<tr><td class="personal_field"><label>Email:</label></td><td class="personal_input"><input name="list-email" value="<?php echo $email; ?>" size="40"/></td></tr>
<tr><td class="personal_field"><label>Website:</label></td><td class="personal_input"><input name="list-website" value="<?php echo $website; ?>" size="40"/></td></tr>
<tr><td class="personal_field"><label>Phone:</label></td><td class="personal_input"><input name="list-phone" value="<?php echo $phone; ?>" /></td></tr>
<tr><td class="personal_field"><label>Mobile:</label></td><td class="personal_input"><input name="list-mobile" value="<?php echo $mobile; ?>" /></td></tr>
<tr><td class="personal_field"><label>Fax:</label></td><td class="personal_input"><input name="list-fax" value="<?php echo $fax; ?>" /></td></tr>
</table>
</div>
     <?php
  }

  // Admin post meta contents
  function meta_location() {
    global $post;
    $custom = get_post_custom($post->ID);
    if(isset($custom["list-address1"])) $address1 = $custom["list-address1"][0];else $address1 = '';
    if(isset($custom["list-address2"])) $address2 = $custom["list-address2"][0];else $address2 = '';
    if(isset($custom["list-country"])) $country = $custom["list-country"][0];else $country = '';
    if(isset($custom["list-province"])) $province = $custom["list-province"][0];else $province = '';
    if(isset($custom["list-city"])) $city = $custom["list-city"][0];else $city = '';
    if(isset($custom["list-postcode"])) $post_code = $custom["list-postcode"][0];else $post_code = '';
    if(isset($custom["list-profile"])) $profile = $custom["list-profile"][0];else $profile = '';
    if(isset($custom["list-distributionrange"])) $distribution_range = $custom["list-distributionrange"][0];else $distribution_range = '';
    if(isset($custom["list-distributionarea"])) $distribution_area = $custom["list-distributionarea"][0];else $ddistribution_area = '';
  ?>
<div class="location">
<table border="0" id="location">
<tr><td class="location_field"><label>Address 1:</label></td><td class="location_input"><input name="list-address1" value="<?php echo $address1; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>Address 2:</label></td><td class="location_input"><input name="list-address2" value="<?php echo $address2; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>City:</label></td><td class="location_input"><input name="list-city" value="<?php echo $city; ?>" /></td></tr>
<tr><td class="location_field"><label>Province:</label></td><td class="location_input"><input name="list-province" value="Ontario" readonly /></td></tr>
<tr><td class="location_field"><label>Postal Code:</label></td><td class="location_input"><input name="list-postcode" value="<?php echo $post_code; ?>" /></td></tr>
<tr><td class="location_field"><label>Country:</label></td><td class="location_input"><input name="list-country" value="Canada" readonly /></td></tr>
<tr><td class="location_field"><label>Profile:</label></td><td class="location_input"><input name="list-profile" value="<?php echo $profile; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>Distribution Range:</label></td><td class="location_input"><input name="list-distributionrange" value="<?php echo $distribution_range; ?>" size="60" /></td></tr>
<tr><td class="location_field"><label>Distribution Area:</label></td><td class="location_input"><input name="list-distributionarea" value="<?php echo $distribution_area; ?>" size="60" /></td></tr>
</table>
</div>
   <?php
  }
}

// Initiate the plugin
add_action("init", "ListingInit");
function ListingInit() { 
  global $listing;
  $listing = new Listing();
  $add_css = $listing->loadStyleScripts();
}

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

Тарас Маньковский
источник
8
Спасибо за скриншот, это действительно помогает иметь те.
MikeSchinkel
Существует плагин Admin Taxonomy Filter, который может выполнять точную работу.
Ань Чан

Ответы:

140

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


Привет @tarasm :

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

Скриншоты:

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

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

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

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

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

Код

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

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

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

<?php
add_action('restrict_manage_posts','restrict_listings_by_business');
function restrict_listings_by_business() {
    global $typenow;
    global $wp_query;
    if ($typenow=='listing') {
        $taxonomy = 'business';
        $business_taxonomy = get_taxonomy($taxonomy);
        wp_dropdown_categories(array(
            'show_option_all' =>  __("Show All {$business_taxonomy->label}"),
            'taxonomy'        =>  $taxonomy,
            'name'            =>  'business',
            'orderby'         =>  'name',
            'selected'        =>  $wp_query->query['term'],
            'hierarchical'    =>  true,
            'depth'           =>  3,
            'show_count'      =>  true, // Show # listings in parens
            'hide_empty'      =>  true, // Don't show businesses w/o listings
        ));
    }
}

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

Далее мы загружаем информацию о бизнес - систематике использования get_taxonomy(). Нам нужно , чтобы получить ярлык для систематики (т.е. « бизнес », мы могли бы жестко, но это не очень хорошо , если вам нужно интернационализировать позже.) Затем мы вызываем 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 обрабатывает вещи, будет termURL-параметр, передаваемый по 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_queryWordPress - отличное место для того, чтобы изменить свое мнение о том, какие сообщения он будет загружать.

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

На коду. Первое, что мы делаем, это получаем ссылку на текущие активные $wp_queryэлементы, 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_vartrue ( 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: бизнес

term: бизнес-1 (то есть slug)

Не эти

taxonomy: бизнес

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

Интересно и, к сожалению, раскрывающийся список, созданный путем wp_dropdown_categories()установки атрибута <option>'s valueдля термина (/ business') term_id, а не для термина slug. Поэтому нам нужно преобразовать $wp_query->query_vars['term']числовое значение term_idв его строку, slugкак показано в приведенном выше фрагменте кода (обратите внимание, что это не самый эффективный способ сделать запрос к базе данных, но пока WordPress не добавит поддержку term_ids в свой запрос, это лучшее, что мы можем сделать!) :

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

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

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

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

Шаг № 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таблицы.

Снимок экрана: столбец cb posts в качестве флажка.
(источник: mikeschinkel.com )

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

$new_posts_columns['businesses'] = '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;
        }
    }
}

Этот хук вызывается для каждого столбца для каждой строки сообщения (/ 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 :

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

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

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

MikeSchinkel
источник
Я ищу 1 выпадающий в верхней части, который показал бы фильтр категорий. Я бродил, если есть стандартный способ сделать это без необходимости писать собственный код.
Тарас Маньковский
На первый взгляд, я не думаю, что вы можете сделать без пользовательского кода, но потом я не думаю, что пользовательский код будет значительным. У меня есть звонок от клиента, чтобы подготовиться к нему, так что это должно быть позже сегодня.
MikeSchinkel
2
На самом деле оба решения (соматические и MikeSchinkel) не работают, когда вы пытаетесь отфильтровать 2 разных таксономии в одном и том же фильтре: - / Всегда фильтровать последнюю таксономию, когда пытаетесь отфильтровать 2+ одновременно.
Юнсал Коркмаз
1
@ Ünsal Текущая версия WordPress (3.0) не поддерживает несколько запросов таксономии, но, как я слышал, изменится с версией 3.1. Чтобы этот пример работал с несколькими таксономиями, вам нужно добавить несколько запросов и ссылок в запрос через хуки фильтров Posts_join и posts_where.
Мэнни Флермонд
1
В WP 3.1+ шаги один и два лучше в ответе @ drew-gourley (на самом деле, ваш шаг 2 не сработал для меня, я думаю, что изменения в этой фильтрации в новом WordPress есть).
Томаш Стручински
44

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

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

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

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

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

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

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

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

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

соматический
источник
4
@somatic - Хорошее обновление! Да, использование wp_dropdown_categories()требует много обходных путей. Я стараюсь придерживаться основных функций, когда это возможно, но, как вы отмечаете, иногда это требует больше работы. Просто доказывает, что с WordPress часто существует более одного хорошего способа решения проблемы. Отличная работа!
MikeSchinkel
Просто перестал работать для меня на WordPress 3.1. Пытаюсь выяснить, что именно изменилось. Похоже, что он все еще должен работать: таксономия и термины-слагы отображаются как значения GET в URL, но все это приводит к 0 результатам
Мэнни Флермонд
Я пытался заставить это работать, но единственный способ, которым я мог, - это использовать хук parse_query, проверить запрос var таксономии и установить переменные таксономии и запроса термина на основе этого. Использование WP 3.1. Должны ли таксономия и термин появляться в URL при отправке фильтра?
sanchothefat
2
Работает как шарм для меня! Действительно, очень элегантное решение. Я должен тебе пива :)
Михал Мау
@somatic Это прекрасно работает, но есть ли способ, чтобы $ term-> count считал только термины для этого типа записей? Например, если у меня есть пользовательская таксономия для фотографий и видео, она будет отображаться при просмотре пользовательских видеообъявлений: введите общее количество постов для этого термина из обоих пользовательских типов постов, а не просто общее количество постов, использующих видео. срок.
Greenhoe
13

Вот версия этого, которая автоматически создает и применяет фильтры из всех таксономий, которые применяются ко всем настраиваемым типам записей, которые их используют. (что за глоток) В любом случае, я также настроил его так, чтобы он работал с wp_dropdown_categories () и wordpress 3.1. Проект, над которым я работаю, называется ToDo, вы можете переименовать функции во что-то, что имеет смысл для вас, но это должно в значительной степени работать для всего автоматически.

function todo_restrict_manage_posts() {
    global $typenow;
    $args=array( 'public' => true, '_builtin' => false ); 
    $post_types = get_post_types($args);
    if ( in_array($typenow, $post_types) ) {
    $filters = get_object_taxonomies($typenow);
        foreach ($filters as $tax_slug) {
            $tax_obj = get_taxonomy($tax_slug);
            wp_dropdown_categories(array(
                'show_option_all' => __('Show All '.$tax_obj->label ),
                'taxonomy' => $tax_slug,
                'name' => $tax_obj->name,
                'orderby' => 'term_order',
                'selected' => $_GET[$tax_obj->query_var],
                'hierarchical' => $tax_obj->hierarchical,
                'show_count' => false,
                'hide_empty' => true
            ));
        }
    }
}
function todo_convert_restrict($query) {
    global $pagenow;
    global $typenow;
    if ($pagenow=='edit.php') {
        $filters = get_object_taxonomies($typenow);
        foreach ($filters as $tax_slug) {
            $var = &$query->query_vars[$tax_slug];
            if ( isset($var) ) {
                $term = get_term_by('id',$var,$tax_slug);
                $var = $term->slug;
            }
        }
    }
    return $query;
}
add_action( 'restrict_manage_posts', 'todo_restrict_manage_posts' );
add_filter('parse_query','todo_convert_restrict');

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

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

Поздний ответ

редактировать

Я написал 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})"
                : ''
        );
    }
}
кайзер
источник
Это вызвало бурю, но метод get_select (), похоже, отсутствует.
Дэйв Ромси
@ goto10 Ты был прав. Обновлено. Кстати: проще просто взять связанный плагин. Он будет доступен в репозитории плагинов через одну или две недели. (Уже подтверждено).
Кайзер
Я должен был использовать $this->setup_vars();в начале public function setup(), чтобы иметь "manage_taxonomies_for_{$this->post_type}_columns"работу
Кристиан
Но это может быть потому, что я использую его в функции Theme function.php сadd_action( 'init', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
Christian
@Christian Это не тематический материал. Это относится к плагину, и, как показывает код выше, он загружается задолго до загрузки тем.
Кайзер
7

Я просто хотел сделать небольшую заметку. В более новых версиях 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

РАБОТАЕТ В 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');
lacroixca
источник
Это хорошее и простое решение для WP 3.2+.
petermolnar
это работает, но __("Show All {$info_taxonomy->label}")это неправильный способ использовать переводимые строки.
Марк Каплун
2

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

// registers each of the taxonomy filter drop downs
function sunrise_fbt_add_taxonomy_filters() {
    global $typenow;            // the current post type
    $taxonomies = get_taxonomies('','objects');
    foreach($taxonomies as $taxName => $tax) {
    if(in_array($typenow,$tax->object_type) && $taxName != 'category' && $taxName != 'tags') {
            $terms = get_terms($taxName);
            if(count($terms) > 0) {
              //Check if hierarchical - if so build hierarchical drop-down
              if($tax->hierarchical) {
                $args = array(
                      'show_option_all'    => 'All '.$tax->labels->name,
                      'show_option_none'   => 'Select '.$tax->labels->name,
                      'show_count'         => 1,
                      'hide_empty'         => 0, 
                      'echo'               => 1,
                      'hierarchical'       => 1,
                      'depth'              => 3, 
                      'name'               => $tax->rewrite['slug'],
                      'id'                 => $tax->rewrite['slug'],                      
                      'class'              => 'postform',
                      'depth'              => 0,
                      'tab_index'          => 0,
                      'taxonomy'           => $taxName,
                      'hide_if_empty'      => false);
            $args['walker'] = new Walker_FilterByTaxonomy;
                wp_dropdown_categories($args);
              } else {
                    echo "<select name='".$tax->rewrite['slug']."' id='".$tax->rewrite['slug']."' class='postform'>";
                    echo "<option value=''>Show All ".$tax->labels->name."</option>";
                    foreach ($terms as $term) { 
              echo '<option value="' . $term->slug . '"', $_GET[$taxName] == $term->slug ? ' selected="selected"' : '','>' . $term->name .' (' . $term->count .')</option>'; 
            }
                    echo "</select>";
                }
            }
    }
    }
}
add_action( 'restrict_manage_posts', 'sunrise_fbt_add_taxonomy_filters', 100 );

/**
 * Create HTML dropdown list of Categories.
 *
 * @package WordPress
 * @since 2.1.0
 * @uses Walker
 */
class Walker_FilterByTaxonomy extends Walker {
    var $tree_type = 'category';
    var $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
    function start_el(&$output, $category, $depth, $args) {
      $args['selected'] = get_query_var( $args['taxonomy'] );
        $pad = str_repeat('&nbsp;', $depth * 3);

        $cat_name = apply_filters('list_cats', $category->name, $category);
        $output .= "\t<option class=\"level-$depth\" value=\"".$category->slug."\"";
        if ( $category->slug == $args['selected'] )
            $output .= ' selected="selected"';
        $output .= '>';
        $output .= $pad.$cat_name;
        if ( $args['show_count'] )
            $output .= '&nbsp;&nbsp;('. $category->count .')';
        if ( $args['show_last_update'] ) {
            $format = 'Y-m-d';
            $output .= '&nbsp;&nbsp;' . gmdate($format, $category->last_update_timestamp);
        }
        $output .= "</option>\n";
        }
} 

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

Брэд Триверс
источник
2

Я думаю, это не очень хорошо известно, но на 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/

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

Лука Регеллин
источник
1

Иерархическая версия ответа @ 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

Обновление ответа @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";
    }
}
rinogo
источник
0

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

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


источник
По какой-то причине версия
соматика
0

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

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

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

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

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

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

eddiemoya
источник