Додавання фільтра таксономії до списку адміністраторів для користувацького типу публікації?


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, який може виконати точну роботу.
Anh Tran

Відповіді:


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_queryчасто є чудовим місцем, щоб змусити WordPress змінити свою думку про те, які публікації він збирається завантажувати.

У вашому випадку ми хочемо примусити 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_varправду ( 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>«и valueатрибут цього терміна (/ бізнес») term_id, а НЕ термін slug. Тому нам потрібно перетворити $wp_query->query_vars['term']з числового term_idв його рядок slugяк наступний у фрагменті, закованому зверху (зауважте, це не найефективніший спосіб запиту бази даних, але поки WordPress не додасть підтримку для термінів у свій запит, це найкраще, що ми можемо зробити!) :

<?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" як прапорець.
(джерело: 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;
        }
    }
}

Цей гачок називається для кожного стовпця для кожного повідомлення (/ бізнесу) рядка. Спочатку ми перевіряємо, що ми дійсно працюємо лише з 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()функцію , яка просто повертає список термінів для цієї таксономії (тобто бізнес для цього перерахування.) Ось отримати постійне посилання на веб - сторінці фронтального цього терміна , які зазвичай перераховані повідомлення, які пов'язані термін, але, звичайно, може по-різному залежно від теми та / або встановлених плагінів.

Ми використовуємо постійну посилання для гіперпосилання цього терміна лише тому, що мені подобається гіперпосилання. Потім ми об'єднуємо всі гіперпосилання з термінами (/ компанії) разом з розділеним |символом 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 за спеціальним полем? Якщо це те, що вам потрібно, я можу надати більш детальну інформацію про таксономію.


Я шукаю 1 спадне меню вгорі, на якому було б показано фільтр категорій. Я блукав, якщо є стандартний спосіб зробити це без необхідності писати спеціальний код.
Тарас Маньковський

Спочатку рум'яна я не думаю, що ви можете робити без користувальницького коду, але потім не думаю, що користувацький код буде важливим. У мене є дзвінок клієнта, щоб підготуватися, тому це доведеться пізніше сьогодні.
MikeSchinkel

2
Насправді обидва рішення (соматичне та MikeSchinkel) не спрацьовують, коли ви намагаєтесь відфільтрувати 2 різних таксономії в одному фільтрі: - / Завжди фільтруючи останню таксономію при спробі фільтрувати 2+ одночасно.
Ünsal Korkmaz

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-
адресі

Я намагався зробити це робочим, але єдиним способом, яким я міг, було використання гачка parse_query, перевірка варіантів запитів таксономії та встановлення на основі цього таксономії та термінів запитів. Використання WP 3.1. Чи повинні таксономія та термін відображатися в URL-адресі під час подання фільтра?
sanchothefat

2
Діє як шарм для мене! Дійсно дуже елегантне рішення. Я завдячую вам пивом :)
Міхал Мау

@somatic Це чудово працює, але чи є спосіб, щоб $ term-> count розраховував лише умови для цього типу публікації? Наприклад, якщо у мене є спеціальна таксономія як для фотографій, так і для відео, вона відображатиметься при перегляді користувальницької спеціальної публікації, введіть загальну кількість публікацій за цей термін з обох спеціальних типів публікацій, а не лише загальну кількість публікацій відео, які використовують це термін.
Грінхой

13

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

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

Зауважте, що я використовую плагін, який додає "term_order" як спосіб замовлення термінів, вам доведеться змінити це або видалити цей аргумент, щоб повернутися до замовчування.


дійсно дуже сексуально. я отримував повідомлення про помилки, тому я змінив if (isset ($ var)) на if (isset ($ var) && $ var> 0), щоб уникнути спроб знайти терміни, пов'язані зі значенням View all 0. о, і мені довелося повернути $ query у функції todo_convert_restrict
helgatheviking

11

Пізня відповідь

Редагувати

Я написав Filterama , плагін, який додасть цю функціональність найпростішим можливим способом.

Оновлення для WordPress 3.5+

Тепер, коли все набагато простіше, ось таке дуже просте рішення, як плагін або mu-плагін.

Він використовує якомога менше ресурсів, завантажується лише на потрібні екрани та додає стовпці + фільтри для кожної власної систематики.

add_action( 'plugins_loaded', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
class WCM_Admin_PT_List_Tax_Filter
{
    private static $instance;

    public $post_type;

    public $taxonomies;

    static function init()
    {
        null === self::$instance AND self::$instance = new self;
        return self::$instance;
    }

    public function __construct()
    {
        add_action( 'load-edit.php', array( $this, 'setup' ) );
    }

    public function setup()
    {
        add_action( current_filter(), array( $this, 'setup_vars' ), 20 );

        add_action( 'restrict_manage_posts', array( $this, 'get_select' ) );

        add_filter( "manage_taxonomies_for_{$this->post_type}_columns", array( $this, 'add_columns' ) );
    }

    public function setup_vars()
    {
        $this->post_type  = get_current_screen()->post_type;
        $this->taxonomies = array_diff(
            get_object_taxonomies( $this->post_type ),
            get_taxonomies( array( 'show_admin_column' => 'false' ) )
        );
    }

    public function add_columns( $taxonomies )
    {
        return array_merge( taxonomies, $this->taxonomies );
    }


    public function get_select()
    {
        $walker = new WCMF_walker;
        foreach ( $this->taxonomies as $tax )
        {
            wp_dropdown_categories( array(
                'taxonomy'        => $tax,
                'hide_if_empty'   => true,
                'show_option_all' => sprintf(
                    get_taxonomy( $tax )->labels->all_items
                ),
                'hide_empty'      => true,
                'hierarchical'    => is_taxonomy_hierarchical( $tax ),
                'show_count'      => true,
                'orderby'         => 'name',
                'selected'        => '0' !== get_query_var( $tax )
                    ? get_query_var( $tax )
                    : false,
                'name'            => $tax,
                'id'              => $tax,
                'walker'          => $walker,
            ) );
        }

    }

}

І тоді вам просто потрібен індивідуальний клас Walker.

class WCMF_walker extends Walker_CategoryDropdown
{
    public $tree_type = 'category';
    public $db_fields = array(
        'parent' => 'parent',
        'id'     => 'term_id',
    );
    public $tax_name;

    public function start_el( &$output, $term, $depth, $args, $id = 0 )
    {
        $pad = str_repeat( '&nbsp;', $depth * 3 );
        $cat_name = apply_filters( 'list_cats', $term->name, $term );
        $output .= sprintf(
            '<option class="level-%s" value="%s" %s>%s%s</option>',
            $depth,
            $term->slug,
            selected(
                $args['selected'],
                $term->slug,
                false
            ),
            $pad.$cat_name,
            $args['show_count']
                ? "&nbsp;&nbsp;({$term->count})"
                : ''
        );
    }
}

Це дало вир, але метод get_select (), здається, відсутній.
Дейв Ромсі

@ goto10 Ви мали рацію. Оновлено. Btw: Простіше просто схопити пов'язаний плагін. Він буде доступний у сховищі плагінів через один-два тижні. (Вже підтверджено).
кайзер

Мені довелося користуватися $this->setup_vars();на початку 2007 рокуpublic function setup() , щоб "manage_taxonomies_for_{$this->post_type}_columns"працювати
Крістіан

Але це може бути тому, що я використовую його в темі function.php зadd_action( 'init', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
Крістіан

@Christian Це не тема теми. Це належить до плагіна, і як код, який знаходиться вище, він завантажений набагато до завантаження тем.
кайзер

7

Я просто хотів зробити швидку записку. У нових версіях WP списки публікацій адміністратора обробляються класом WP_Posts_List_Table. Код apply_filters тепер такий:

if ( 'page' == $post_type )
        $posts_columns = apply_filters( 'manage_pages_columns', $posts_columns );
    else
        $posts_columns = apply_filters( 'manage_posts_columns', $posts_columns, $post_type );
    $posts_columns = apply_filters( "manage_{$post_type}_posts_columns", $posts_columns );

Отже, для додавання нових стовпців гак add_filter повинен бути таким:

add_filter( 'manage_posts_columns', 'my_add_columns', 10, 2);

Ось приклад:

function my_add_columns($posts_columns, $post_type)
{
  if ('myposttype' == $post_type) {
    $posts_columns = array(
      "cb"            => "<input type=\"checkbox\" />",
      "title"         => "Title",
      "anothercolumn" => "Bacon",
      "date"          => __( 'Date' )
    );
    return $posts_columns;
  }
} 

Тепер для рядків публікацій. Це код, який обробляє дані стовпців у списках:

default:
            ?>
            <td <?php echo $attributes ?>><?php
                if ( is_post_type_hierarchical( $post->post_type ) )
                    do_action( 'manage_pages_custom_column', $column_name, $post->ID );
                else
                    do_action( 'manage_posts_custom_column', $column_name, $post->ID );
                do_action( "manage_{$post->post_type}_posts_custom_column", $column_name, $post->ID );
            ?></td>
            <?php

Щоб отримати дані наших публікацій, ми повинні додати гак дій так:

add_action( "manage_(here_goes_your_post_type)_posts_custom_column", "my_posttype_add_column", 10, 2);

Приклад (у цьому прикладі використовуються таксономії, але ви можете запитувати будь-які інші речі):

function my_posttype_add_column($column_name, $post_id)
{
  switch ($column_name) {
    case 'anothercolumn':
      $flavours = get_the_terms($post_id, 'flavour');
      if (is_array($flavours)) {
        foreach($flavours as $key => $flavour) {
          $edit_link = get_term_link($flavour, 'flavour');
          $flavours[$key] = '<a href="'.$edit_link.'">' . $flavour->name . '</a>';
        }
        echo implode(' | ',$flavours);
      }
      break;

    default:
      break;
  }
}

7

РОБОТА В WP 3.2!

custom_post_type: книги custom_taxonomy: жанр

Тільки модифікуйте, як це сказано: // змінити ТУТ

function restrict_books_by_genre() {
    global $typenow;
    $post_type = 'books'; // change HERE
    $taxonomy = 'genre'; // change HERE
    if ($typenow == $post_type) {
        $selected = isset($_GET[$taxonomy]) ? $_GET[$taxonomy] : '';
        $info_taxonomy = get_taxonomy($taxonomy);
        wp_dropdown_categories(array(
            'show_option_all' => __("Show All {$info_taxonomy->label}"),
            'taxonomy' => $taxonomy,
            'name' => $taxonomy,
            'orderby' => 'name',
            'selected' => $selected,
            'show_count' => true,
            'hide_empty' => true,
        ));
    };
}

add_action('restrict_manage_posts', 'restrict_books_by_genre');


function convert_id_to_term_in_query($query) {
    global $pagenow;
    $post_type = 'books'; // change HERE
    $taxonomy = 'genre'; // change HERE
    $q_vars = &$query->query_vars;
    if ($pagenow == 'edit.php' && isset($q_vars['post_type']) && $q_vars['post_type'] == $post_type && isset($q_vars[$taxonomy]) && is_numeric($q_vars[$taxonomy]) && $q_vars[$taxonomy] != 0) {
        $term = get_term_by('id', $q_vars[$taxonomy], $taxonomy);
        $q_vars[$taxonomy] = $term->slug;
    }
}

add_filter('parse_query', 'convert_id_to_term_in_query');

Приємне та просте рішення для WP 3.2+.
petermolnar

це працює, але __("Show All {$info_taxonomy->label}")це неправильний спосіб використання рядків, що перекладаються.
Марк Каплун

2

Ось спосіб це зробити за допомогою дії restrict_manage_posts. Мені здається, що це добре працює для мене і додає можливість фільтрувати за системою таксономії для всіх типів публікацій та відповідних систематик.

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

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

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

Одна примітка - я спробував обмежити глибину, оскільки деякі мої ієрархічні таксономії досить великі, але це не спрацювало - може бути помилка у функції wp_dropdown_categories?


2

Це не дуже добре відомо , я думаю, але на WordPress 3.5, ви можете перейти 'show_admin_column' => trueдо register_taxonomy. Це робить 2 речі:

  1. Додає стовпчик таксономії до подання списку типів адміністративного повідомлення
  2. Натиснувши назву терміна в стовпці таксономії, він фактично фільтрує список до цього терміна .

Отже, не зовсім те саме, що у вас вибрано, але майже однаковий функціонал, ширина лише одного рядка коду.

https://make.wordpress.org/core/2012/12/11/wordpress-3-5-admin-column-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);
    }

}
?>

Я в основному видалив код, який створив параметри, і поставив це у власну функцію. Функція 'create_taxonomy_options', окрім прийняття податкового_вітка, також приймає параметр батьків і рівня. Функція передбачає, що вона створює параметри для батьківського 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";
    }
}

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

Підручник Майка з цього приводу чудовий! Я, мабуть, не заважав би додавати цю функціональність у свій плагін Медіа Категорії, якби мені довелося розібратися в цьому самостійно.

Це сказав, я думаю, використовуючи parse_query а потім отримати запит на термін не потрібно. Це чистіше для створення власного власного класу ходунків. Можливо, це було неможливо, коли він написав свою посаду - її 3 роки на момент мого написання цього.

Отримайте цей чудовий фрагмент на Github. Працює як шарм, змінює ідентифікаційні дані у випадаючих значеннях на молюски, тож він просто працює натурно, не змінюючи запит.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.