Adăugarea unui filtru de taxonomie la lista de administrare pentru un tip de postare personalizat?

19 aug. 2010, 18:13:29
Vizualizări: 108K
Voturi: 139

Am creat un Tip de Postare Personalizat numit 'listing' și am adăugat o Taxonomie Personalizată numită 'businesses'. Aș dori să adaug o listă dropdown de Afaceri la lista de administrare pentru Listări.

Iată cum arată această funcționalitate în lista de administrare pentru Postări (Aș dori același lucru pentru Tipul meu de Postare Personalizat):

Listă dropdown de categorii în Postări

Iată codul meu actual (Și aici este același cod pe 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();
}

Cum pot adăuga o listă dropdown de Afaceri la lista de administrare pentru Listări?

2
Comentarii

Mulțumesc pentru captura de ecran, chiar ajută să le ai.

MikeSchinkel MikeSchinkel
19 aug. 2010 20:29:13

Există un plugin Admin Taxonomy Filter care poate face exact acest lucru.

Anh Tran Anh Tran
20 sept. 2017 04:33:05
Toate răspunsurile la întrebare 17
11
150

UPDATE iulie 2024:

Acest cod nu mai funcționează. Testat în versiunea curentă de WP la momentul scrierii (6.5.5). Pentru a-l face să funcționeze din nou, sunt necesare câteva modificări la codul din Pasul 1:

Parametrul name

În wp_dropdown_categories() parametrul name trebuie să fie slug-ul taxonomiei. Așadar, deși în acest caz nu se schimbă, nu este foarte clar ce ar trebui să schimbe alți oameni. Mai ales pentru că documentația oficială nu menționează acest lucru:

name string

Valoarea pentru atributul 'name' al elementului select. Implicit 'cat'.

Aceasta ar putea duce la ideea că este un șir personalizat precum "my_select_name". Pentru a elimina confuzia, putem folosi pur și simplu variabila.

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

Parametrul selected

Parametrul selected trebuie schimbat la:

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

Acest lucru se datorează faptului că term este definit în query_vars în loc de query. Dacă termenul nu există în query_vars, atunci cel mai probabil nu a fost selectat un termen, deci putem folosi operatorul de coalescentă nulă pentru a testa asta și dacă este null|undefined atunci selectăm opțiunea "arată toate" cu valoarea 0.

Parametrul value_field

Un nou parametru a fost adăugat în WP 4.2.0: value_field.

Utilizând acest parametru, putem acum indica WP să folosească un "câmp de termen" specific pentru a popula valorile opțiunilor. Din documentație:

value_field string

Câmpul termenului care ar trebui utilizat pentru a popula atributul 'value' al elementelor de opțiune. Acceptă orice câmp valid al termenului: 'term_id', 'name', 'slug', 'term_group', 'term_taxonomy_id', 'taxonomy', 'description', 'parent', 'count'. Implicit 'term_id'.

Adăugarea slug la acest parametru va popula valorile opțiunilor cu slug-urile termenilor. Deoarece slug-ul este necesar pentru ca funcția de filtrare să funcționeze, acest parametru face ca filtrele să funcționeze doar din codul Pasului 1, fără a fi nevoie de Pasul 2.

Așadar, Pasul 2 poate fi ignorat dacă se utilizează value_field.

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

Am lăsat codul original mai jos, așa că faceți aceste modificări după cum s-a detaliat mai sus la codul de mai jos.



ACTUALIZARE: Am inclus un nou răspuns complet, dar am lăsat și răspunsul meu original la sfârșitul articolului, la care se referă primele comentarii.


Salut @tarasm:

Deși am spus că nu ar trebui să fie dificil, este puțin mai complex. Dar înainte să ne cufundăm în cod...

Capturile de ecran:

...să vedem câteva capturi de ecran pentru produsul final:

Pagina de listare fără filtrare:

Pagina de listare fără filtrare
(sursă: mikeschinkel.com)

Pagina de listare cu filtrare:

Pagina de listare cu filtrare
(sursă: mikeschinkel.com)

Codul

Așadar, să începem... (Notă: Am folosit o formă singulară pentru numele taxonomiei business; sper că se potrivește cu a ta. Din multă experiență cu WordPress și dezvoltarea bazelor de date, cred că este cel mai bine să procedezi așa.)

Pasul #1: Hook-ul de acțiune restrict_manage_posts.

Primul lucru pe care trebuie să-l faci este să agăți acțiunea restrict_manage_posts care nu are parametri și este apelată din /wp-admin/edit.php (în v3.0.1 acel apel este pe linia 378). Aceasta îți va permite să generezi dropdown-ul select în locația potrivită deasupra listei de postări Listing.

<?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, // Arată # listări în paranteze
            'hide_empty'      =>  true, // Nu arăta afaceri fără listări
        ));
    }
}

Începem prin verificarea variabilei $typenow pentru a ne asigura că suntem într-adevăr pe un post_type de listing. Dacă nu faci asta, vei obține acest dropdown pentru toate tipurile de postări, ceea ce în unele cazuri este ceea ce vrei, dar nu în acest caz.

Următorul pas este să încărcăm informații despre taxonomia business folosind get_taxonomy(). Avem nevoie de ea pentru a prelua eticheta taxonomiei (adică "Businesses"; am fi putut hard-coda, dar nu este bine dacă ai nevoie să internaționalizezi mai târziu). Apoi apelăm wp_dropdown_categories() cu toate argumentele adecvate în matricea $args pentru a genera dropdown-ul

<?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, // Arată # listări în paranteze
    'hide_empty'      =>  true, // Nu arăta afaceri fără listări
));

Dar care sunt argumentele potrivite? Să le examinăm pe fiecare în parte:

  • show_optional_all - Destul de simplu, este ceea ce este afișat în dropdown inițial și când nu a fost aplicată nicio filtrare. În cazul nostru, va fi "Show All Businesses" dar l-am fi putut numi "Listings for All Businesses" sau orice altceva îți place.

  • taxonomy - Acest argument spune funcției din ce taxonomie să extragă termenii, chiar dacă funcția are categories în numele său. În v2.8 și anterior WordPress nu avea taxonomii personalizate, dar când au fost adăugate, echipa a decis că ar fi mai ușor să adauge un argument de taxonomie la această funcție decât să creeze o altă funcție cu un alt nume.

  • name - Acest argument îți permite să specifici valoarea pe care WordPress o va folosi pentru atributul name al elementului <select> generat pentru dropdown. În caz că nu este evident, aceasta este și valoarea care va fi utilizată în URL atunci când se filtrează.

  • orderby - Acest argument spune WordPress-ului cum să ordoneze rezultatele alfabetic. În cazul nostru am specificat să ordonăm după name al termenilor din taxonomie, adică numele afacerilor în acest caz.

  • selected - Acest argument este necesar pentru ca dropdown-ul să poată afișa filtrul curent. Ar trebui să fie term_id din termenul taxonomiei selectate. În cazul nostru ar putea fi term_id din "Business #2". De unde obținem această valoare? Din variabila globală $wp_query a WordPress; aceasta are o proprietate query care conține o matrice cu toți parametrii URL și valorile lor (cu excepția cazului în care un plugin le-a modificat deja, desigur). Dată fiind modul în care WordPress procesează lucrurile, va exista un parametru URL term transmis pe URL atunci când utilizatorul face clic pe butonul de filtrare dacă utilizatorul a selectat un termen valid (adică una dintre afacerile listate).

  • hierarchical - Setând această opțiune la true, spui funcției să respecte natura ierarhică a taxonomiei și să le afișeze într-o vizualizare arborescentă dacă termenii (afacerile) au de fapt copii. Pentru o captură de ecran care să arate cum arată acest lucru, vezi mai jos.

  • depth - Acest argument colaborează cu argumentul hierarchical pentru a determina cât de adânc trebuie să meargă funcția în afișarea copiilor.

  • show_count - Dacă este true, acest argument va afișa un număr de postări între paranteze în stânga numelui termenului în dropdown. În acest caz, ar afișa un număr de listări asociate cu afacerile. Pentru o captură de ecran care să arate cum arată acest lucru, vezi mai jos.

  • hide_empty - În fine, dacă există termeni în taxonomie care nu sunt asociați cu o postare (adică afaceri neasociate cu o listare), atunci setarea acestui parametru la true îi va omite din dropdown.

Dropdown-ul taxonomiei care arată ierarhia și numărătoarea
(sursă: mikeschinkel.com)

Pasul #2: Hook-ul de filtrare parse_query.

În continuare, ne îndreptăm atenția către hook-ul de filtrare parse_query care are un parametru ($query) și este apelat din /wp-includes/query.php (în v3.0.1 acel apel este pe linia 1549). Este apelat când WordPress a terminat de inspectat URL-ul și de setat toate valorile corespunzătoare în $wp_query-ul activ, inclusiv lucruri precum $wp_query->is_home și $wp_query->is_author, etc.

După ce hook-ul de filtrare parse_query rulează, WordPress va apela get_posts() și va încărca o listă de postări bazate pe ceea ce este specificat în $wp_query-ul activ. Astfel, parse_query este adesea un loc excelent pentru a face WordPress să-și schimbe părerea despre ce postări urmează să încarce.

În cazul tău de utilizare, dorim ca WordPress să filtreze pe baza afacerilor selectate; adică să afișeze doar acele Listări care au fost asociate cu afacerea selectată (aș spune "...doar acele Listări care au fost "categorizate" de afacerea selectată" dar asta nu este tehnic corect; category este propria taxonomie alături de business cu excepția faptului că category este încorporată în WordPress și business este personalizată. Dar pentru cei familiarizați cu categorizarea postărilor, acest lucru îi poate ajuta să înțeleagă, deoarece funcționează aproape identic. Dar divaghez...)

Să trecem la cod. Primul lucru pe care îl facem este să obținem o referință la query_vars din $wp_query-ul activ pentru a fi mai convenabil de lucrat, exact cum se face în funcția parse_query() a WordPress. Spre deosebire de $wp_query->query care este utilizat pentru a oglindi parametrii transmiși pe URL, matricea $wp_query->query_vars este utilizată pentru a controla interogarea pe care o execută WordPress și se așteaptă să fie modificată. Deci, dacă trebuie să modifici una, aceasta ar fi cea aleasă (cel puțin cred că aceasta este diferența dintre cele două; dacă cineva știe altfel, vă rog să mă anunțați pentru a putea actualiza acest lucru!)

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

Apoi testăm $pagenow pentru a ne asigura că într-adevăr încărcăm WordPress de la calea URL /wp-admin/edit.php. Facem acest lucru pentru a nu strica accidental interogările pe alte pagini. De asemenea, verificăm pentru a ne asigura că avem atât business ca element taxonomy, cât și un element term. (Notă: taxonomy și term sunt o pereche; sunt utilizate împreună pentru a permite interogarea unui termen de taxonomie; trebuie să le ai pe amândouă sau WordPress nu știe ce taxonomie să inspecteze.)

Te-ai putea întreba cum a ajuns business în elementul taxonomy al matricei query_vars. Ceea ce am scris în hook-ul nostru parse_query a declanșat magia internă a WordPress care a fost pregătită când ai înregistrat taxonomia "business" setând query_var la true (register_taxonomy() copiază numele taxonomiei ca query_var; poți să-l schimbi, desigur, dar dacă nu ai un conflict, este mai bine să rămâi cu același):

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

Acum $wp_query al WordPress a fost scris pentru a utiliza slug-uri pentru interogări filtrate standard de taxonomie, nu ID-uri de termeni de taxonomie. Pentru acest caz de utilizare, ceea ce avem nevoie cu adevărat pentru a face interogarea noastră de filtrare să funcționeze sunt acestea:

taxonomy: business

term: business-1 (adică slug-ul)

Nu acestea:

taxonomy: business

term: 27 (adică term_id-ul)

În mod interesant și din păcate, dropdown-ul generat de wp_dropdown_categories() setează atributul value al <option> la term_id-ul termenului (/afacerii), nu la slug-ul termenului. Așadar, trebuie să convertim $wp_query->query_vars['term'] de la un term_id numeric la slug-ul său de tip șir, după cum urmează în fragmentul extras de mai sus (Notă: aceasta nu este cea mai performantă modalitate de a interoga o bază de date, dar până când WordPress adaugă suport pentru term_id-uri în interogarea sa, aceasta este cea mai bună metodă pe care o putem folosi!):

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

Și asta e tot! Cu aceste două funcții obții filtrarea pe care o dorești.

DAR STAI, ESTE MAI MULT! :-)

Am adăugat o coloană "Businesses" listei tale Listing pentru că, ei bine, știam că va fi următoarea ta întrebare. Fără a avea o coloană pentru ceea ce filtrezi, poate fi foarte confuz pentru utilizatorul final. (Eu însumi m-am chinuit cu asta, și eu am fost programatorul!) Poți vedea deja coloana "Businesses" în capturile de ecran anterioare de mai sus.

Pasul #3: Hook-ul de filtrare manage_posts_columns.

Pentru a adăuga o coloană la lista de postări, trebuie să apelezi încă două (2) hook-uri. Primul este manage_posts_columns sau versiunea specifică tipului de postare manage_listing_posts_columns pe care am apelat-o în schimb. Acceptă un parametru (posts_columns) și este apelat din /wp-admin/includes/template.php (în v3.0.1 acel apel este pe linia 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;
}

Funcția ta hook manage_posts_columns primește o matrice de coloane unde valoarea este antetul coloanei afișat și cheia este identificatorul intern al coloanei. Identificatorii standard de coloane pot include următoarele și altele: 'cb', 'title', 'author', ``'date'`, etc.

'cb' este coloana checkbox, iar atât 'title', cât și 'date' se referă la post_title și post_date din tabelul wp_posts, respectiv. 'author' este, desigur, câmpul post_author după ce numele autorului este preluat din tabelul wp_users.

Captură de ecran a coloanei 'cb' de postări ca o casetă de bifare.
(sursă: mikeschinkel.com)

Pentru hook-ul manage_posts_columns, dorim pur și simplu să inserăm coloana noastră businesses în matricea $posts_columns înainte de 'author', presupunând că alt plugin nu a eliminat încă author din listă!

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

(Notă în timp ce scriam add_businesses_column_to_listing_list() mi-a venit în minte că PHP trebuie să aibă o modalitate mai ușoară de a insera o valoare într-o matrice asociativă în ordinea corespunzătoare?!? Sau cel puțin trebuie să existe o funcție în nucleul WordPress pentru a face acest lucru? Dar deoarece Google m-a dezamăgit, am folosit ceea ce a funcționat. Dacă cineva are sugestii alternative, voi fi recunoscător în avans!)

Ceea ce ne aduce în final la...

Pasul #4: Hook-ul de acțiune manage_posts_custom_column

Al doilea lucru din două (2) de care avem nevoie pentru a face afacerile noastre să apară în coloană este să afișăm efectiv numele fiecăreia dintre afacerile asociate folosind hook-ul de acțiune manage_posts_custom_column. Acest hook acceptă doi (2) parametri (column_id și post_id) și este apelat tot din /wp-admin/includes/template.php (în v3.0.1 acel apel este pe linia 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;
        }
    }
}

Acest hook este apelat pentru fiecare coloană pentru fiecare rând de postare(/afacere). Verificăm mai întâi că lucrăm într-adevăr doar cu tipul de postare personalizat listing și apoi folosim o instrucțiune switch pentru a testa column_id. Am ales switch deoarece acest hook este adesea folosit pentru a genera output pentru multe coloane diferite, mai ales dacă folosim o funcție pentru multe tipuri de postări diferite, care ar putea arăta ceva de genul:

<?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 '...orice...';
        break;
    case 'listing:property':
        echo '...orice...';
        break;
    case 'agent:listing':
        echo '...orice...';
        break;
    }
}

Inspectând cazul nostru de utilizare puțin mai îndeaproape, vedem funcția get_the_terms() care simplu returnează lista termenilor pentru această taxonomie (adică afacerile pentru această înregistrare). Aici obținem permalink-ul pentru pagina web front-end a termenului care în mod normal listează postările asociate cu termenul, dar care ar putea funcționa diferit în funcție de tema și/sau plugin-urile instalate.

Folosim permalink-ul pentru a crea un hyperlink către termen pentru că îmi place să creez linkuri. Apoi combinăm toate termenii (afacerile) cu hyperlink împreună, separate prin caracterul pipe ('|') și trimitem către buffer-ul PHP care îl transmite către browser-ul/clientul HTTP al utilizatorului:

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

ACUM am terminat în sfârșit.

Sumar

Așadar, în rezumat, trebuie să folosiți următoarele patru (4) hook-uri pentru a obține atât un filtru cât și o coloană asociată în pagina de listare a postărilor personalizate (Da, va funcționa și cu Articole și Pagini). Acestea sunt:

  • Pasul #1: Hook-ul de acțiune restrict_manage_posts
  • Pasul #2: Hook-ul de filtrare parse_query
  • Pasul #3: Hook-ul de filtrare manage_posts_columns
  • Pasul #4: Hook-ul de acțiune manage_posts_custom_column

De unde să descărcați codul

Dar dacă v-am făcut să citiți tot ce este mai sus, nu aș fi o persoană foarte drăguță dacă v-aș face să căutați și codul doar pentru a-l putea încerca! Dar contrar a ceea ce spun unii oameni, sunt drăguț. Așa că poftim:

NOTĂ pentru @tarasm: Am inclus hook-uri pentru register_post_type() și register_taxonomy() astfel încât alții să poată încerca acest cod fără a trebui să le recreeze. Probabil veți dori să ștergeți aceste două apeluri de funcții înainte de a testa.

SFÂRȘIT


Răspuns Original:

Salut @tarasm:

Cauți un dropdown în partea de sus ca în acest ecran sau cauți un dropdown pentru fiecare înregistrare de postare și dacă da, cum te-ai aștepta să funcționeze cel din urmă?

Cum să creezi funcționalitatea Sortare După pentru un Tip de Postare Personalizat în WordPress Admin
(sursa: mikeschinkel.com)

Dacă e primul caz, aruncă o privire la acest răspuns la întrebarea Cum să sortezi zona de administrare a unui tip de postare personalizat WordPress după un câmp personalizat? Dacă asta este ceea ce ai nevoie, pot oferi mai multe detalii specifice legate de taxonomie.

19 aug. 2010 18:58:37
Comentarii

Caut un meniu derulant în partea de sus care să afișeze un filtru pe categorii. Mă întrebam dacă există o metodă standard de a face asta fără a fi nevoie să scriu cod personalizat.

Taras Mankovski Taras Mankovski
19 aug. 2010 20:04:44

La prima vedere, nu cred că se poate fără cod personalizat, dar nici că ar fi nevoie de mult cod custom. Am un apel cu un client de pregătit, așa că va trebui să revin mai târziu azi.

MikeSchinkel MikeSchinkel
19 aug. 2010 20:30:05

De fapt, ambele soluții (somatic și MikeSchinkel) nu funcționează când încerci să filtrezi 2 taxonomii diferite în același filtru :-/

Întotdeauna se filtrează după ultima taxonomie când încerci să filtrezi 2+ simultan.

Ünsal Korkmaz Ünsal Korkmaz
3 nov. 2010 05:24:09

@Ünsal Versiunea actuală de WordPress (3.0) nu suportă interogări multiple de Taxonomie, dar din ce am auzit, acest lucru se va schimba cu versiunea 3.1. Pentru a face acest exemplu să funcționeze cu mai multe taxonomii, ar trebui să adăugați unele join-uri și condiții la interogare prin intermediul hook-urilor de filtrare Posts_join și posts_where.

Manny Fleurmond Manny Fleurmond
5 ian. 2011 18:07:48

mulțumesc pentru răspunsul excelent - dar există o mică greșeală de tipar în exemplul de cod din pasul #4: ar trebui să fie $column_id și nu column_name. versiunea de pe github este corectă însă.

Philipp Kyeck Philipp Kyeck
13 nov. 2011 19:14:36

În WP 3.1+, pașii unu și doi sunt mai bine prezenți în răspunsul lui @drew-gourley (de fapt, pasul 2 din exemplul tău nu a funcționat pentru mine, cred că au fost schimbări în această filtrare în noile versiuni de WordPress).

Tomasz Struczyński Tomasz Struczyński
3 dec. 2011 12:10:32

Mike, cred că ai putea îmbunătăți claritatea acestui (minunat) tutorial, schimbând argumentele wp_dropdown_categories astfel încât 'name' => $taxonomy, pentru a face evident faptul că atributul 'name' al câmpului select trebuie să fie slug-ul taxonomiei înregistrate (sau mai precis, slug-ul query_var). În forma actuală, pare că 'taxonomy' trebuie să fie slug-ul taxonomiei, dar 'name' poate fi orice nume arbitrar, ceea ce cred că nu este chiar cazul, decât dacă ești dispus să analizezi manual șirul de interogare în parse_query

Tom Auger Tom Auger
7 dec. 2011 22:38:32

un răspuns foarte strălucit și complet, dar nu ar trebui să returnezi variabila $query în funcția ta convert_business_id_to_taxonomy_term_in_query()?

helgatheviking helgatheviking
8 ian. 2012 00:30:22

Mă adaug și eu la lunga listă de complimente anterioare! Lecțiile lui Mike sunt (destul de frecvent) ca un curs universitar. . . . Și aș dori să subliniez pentru oricine cercetează această problemă că răspunsul lui @DrewGourley de mai jos este aur curat :)

brasofilo brasofilo
9 iul. 2012 16:42:28

Un lucru care nu este imediat evident este că get_term_link() va lega la arhiva publică a unei taxonomii, în loc să afișeze rezultatele filtrate în WP-Admin. Nu sunt sigur dacă există o funcție pentru a genera acest link, așa că trebuie creat manual, de exemplu: <a href="edit.php?CUSTOM_TAXONOMY=FOO&post_type=CUSTOM_POST_TYPE">NUME_TAXONOMIE</a> dar în afară de acest detaliu minor, acest lucru este minunat!

User User
7 mai 2013 21:34:46

Aș menționa că începând cu WordPress v3.5, puteți adăuga coloane de taxonomie pur și simplu prin adăugarea 'show_admin_column' => true la parametrii register_taxonomy.

Luca Reghellin Luca Reghellin
15 sept. 2017 12:06:14
Arată celelalte 6 comentarii
6
46

Am vrut să împărtășesc o implementare alternativă. Nu am avut incredibilul tutorial al lui Mike când am încercat să rezolv această problemă, așa că soluția mea este puțin diferită. Mai exact, voi simplifica pasul #1 al lui Mike și voi elimina pasul #2 - ceilalți pași rămân valabili.

În tutorialul lui Mike, folosirea funcției wp_dropdown_categories() ne scutește de construirea manuală a listei, dar necesită o modificare condiționată complicată a interogării (pasul #2) pentru a gestiona utilizarea ID-ului în loc de slug. Ca să nu mai vorbim de dificultatea de a modifica acel cod pentru a gestiona alte scenarii, cum ar fi filtrele pentru multiple taxonomii.

O altă abordare este să nu folosim deloc funcția imperfectă wp_dropdown_categories(), ci să construim propriile noastre liste dropdown de la zero. Nu este atât de complicat, necesită mai puțin de 30 de linii de cod și nu necesită deloc utilizarea hook-ului parse_query:

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

    // afișăm aceste filtre de taxonomie doar pe listările dorite de custom post_type
    global $typenow;
    if ($typenow == 'photos' || $typenow == 'videos') {

        // creăm un array de slug-uri de taxonomii pe care vrem să le filtrăm - dacă vrem să preluăm toate taxonomiile, putem folosi get_taxonomies() pentru a construi lista
        $filters = array('plants', 'animals', 'insects');

        foreach ($filters as $tax_slug) {
            // preluăm obiectul taxonomiei
            $tax_obj = get_taxonomy($tax_slug);
            $tax_name = $tax_obj->labels->name;
            // preluăm array-ul de obiecte termen pentru fiecare taxonomie
            $terms = get_terms($tax_slug);

            // generăm html pentru dropdown-ul de filtrare a taxonomiei
            echo "<select name='$tax_slug' id='$tax_slug' class='postform'>";
            echo "<option value=''>Afișează tot $tax_name</option>";
            foreach ($terms as $term) {
                // generăm fiecare opțiune selectată, verificând ultima valoare $_GET pentru a afișa opțiunea curentă selectată
                echo '<option value='. $term->slug, $_GET[$tax_slug] == $term->slug ? ' selected="selected"' : '','>' . $term->name .' (' . $term->count .')</option>';
            }
            echo "</select>";
        }
    }
}

Prin simpla introducere a taxonomiilor dorite în array-ul $filters, puteți genera rapid mai multe filtre de taxonomie. Acestea apar exact la fel ca în capturile de ecran ale lui Mike. Apoi puteți continua cu pasul #3 și #4.

23 oct. 2010 08:00:36
Comentarii

@somatic - Actualizare frumoasă! Da, utilizarea funcției wp_dropdown_categories() necesită multe soluții alternative. Încerc să folosesc funcții de bază când este posibil, dar după cum subliniezi, uneori asta presupune mai multă muncă. Doar demonstrează că în WordPress există adesea mai multe modalități bune de a rezolva o problemă. Bună treabă!

MikeSchinkel MikeSchinkel
23 oct. 2010 12:53:41

Tocmai a încetat să funcționeze pentru mine pe WordPress 3.1. Încerc să înțeleg exact ce s-a schimbat. Pare că ar trebui să funcționeze în continuare: taxonomia și termenii apar ca valori GET în URL, dar rezultatul este întotdeauna 0 rezultate.

Manny Fleurmond Manny Fleurmond
24 feb. 2011 08:40:11

Am încercat să fac asta să funcționeze, dar singura modalitate a fost să folosesc hook-ul parse_query, să verific variabila de interogare a taxonomiei și să setez variabilele de interogare pentru taxonomie și termen pe baza acesteia. Folosesc WP 3.1. Ar trebui să apară taxonomia și termenii în URL când este trimis filtrul?

sanchothefat sanchothefat
22 mar. 2011 19:36:16

Funcționează perfect pentru mine! O soluție foarte elegantă, într-adevăr. Îți datorez o bere :)

Michal Mau Michal Mau
26 apr. 2011 14:31:51

@somatic Funcționează excelent, dar există vreo modalitate de a face ca $term->count să numere doar termenii pentru acel tip de post? De exemplu, dacă am o taxonomie personalizată atât pentru fotografi cât și pentru videoclipuri, când mă uit la tipul de postare personalizată pentru videoclipuri, îmi va afișa numărul total de postări pentru acel termen din ambele tipuri de postări personalizate, în loc doar numărul total de postări video care folosesc acel termen.

Greenhoe Greenhoe
11 iun. 2015 16:40:45

Poți îmbunătăți linia echo "<option value=''>Show All $tax_name</option>"; cu $tax_labels = get_taxonomy_labels( $tax_obj ); apoi echo "<option value=''>". sprintf( __( 'Show %s', 'textdomain'), mb_strtolower( $tax_labels->all_items ) ) ."</option>";

ZalemCitizen ZalemCitizen
29 mar. 2024 16:37:15
Arată celelalte 1 comentarii
1
13

Iată o versiune care creează și aplică automat filtre pentru toate taxonomiile care se aplică tuturor tipurilor de postări personalizate care le folosesc. (ce formulare lungi) Oricum, am ajustat-o să funcționeze cu wp_dropdown_categories() și WordPress 3.1. Proiectul la care lucrez se numește ToDo, poți redenumi funcțiile cu ceva care are sens pentru tine, dar acest cod ar trebui să funcționeze pentru aproape orice în mod automat.

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' => __('Afișează Tot '.$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');

Reține că folosesc un plugin care adaugă 'term_order' ca modalitate de ordonare a termenilor, va trebui să modifici acest lucru sau să elimini acel argument pentru a reveni la valoarea implicită.

23 mar. 2011 22:40:00
Comentarii

foarte sexy într-adevăr. primeam notificări de eroare, așa că am schimbat if ( isset($var)) în if ( isset($var) && $var>0) pentru a evita încercarea de a găsi termeni asociați cu valoarea 0 din View all. ah, și a trebuit să returnez $query în funcția todo_convert_restrict

helgatheviking helgatheviking
8 ian. 2012 00:17:27
7
11

Răspuns întârziat

Editare

Am creat Filterama, un plugin care va adăuga această funcționalitate în cel mai simplu mod posibil.

Actualizare pentru WordPress 3.5+

Acum că lucrurile sunt mult mai simple, iată o soluție foarte ușoară ca plugin sau mu-plugin.

Folosește cât mai puține resurse, se încarcă doar pe ecranele necesare și adaugă Coloane + Filtre pentru fiecare taxonomie personalizată.

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

    }

}

Apoi aveți nevoie doar de o clasă Walker personalizată.

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

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

Am încercat asta, dar metoda get_select() pare să lipsească.

Dave Romsey Dave Romsey
15 mar. 2013 17:40:39

@goto10 Aveți dreptate. Am actualizat. Apropo: e mai ușor să folosiți direct plugin-ul linked. Va fi disponibil în repository-ul de plugin-uri în una sau două săptămâni. (Deja confirmat).

kaiser kaiser
16 mar. 2013 13:09:12

A trebuit să folosesc $this->setup_vars(); la începutul funcției public function setup() pentru a avea "manage_taxonomies_for_{$this->post_type}_columns" funcțional

Christian Christian
2 iul. 2013 14:44:22

Dar ar putea fi pentru că îl folosesc într-un fișier function.php al Temei cu add_action( 'init', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );

Christian Christian
2 iul. 2013 14:52:45

@Christian Acesta nu este material pentru temă. Aceasta ar trebui să fie într-un plugin și așa cum stă codul de mai sus, se încarcă cu mult înainte de încărcarea Temelor.

kaiser kaiser
2 iul. 2013 15:49:28

Plugin-ul nu a făcut nimic pentru mine în WP 4.8

BadHorsie BadHorsie
18 aug. 2017 19:38:26

@BadHorsie Te rog să încerci dev–Branch. Am început refactorizarea, dar nu am avut timp să o finalizez.

kaiser kaiser
18 aug. 2017 21:08:51
Arată celelalte 2 comentarii
0

Am vrut să fac o notă rapidă. În versiunile mai noi de WP, afișarea postărilor în administrare este gestionată de clasa WP_Posts_List_Table. Codul apply_filters arată acum astfel:

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

Deci, pentru a adăuga coloane noi, un add_filter ar trebui să arate astfel:

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

Iată un exemplu:

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

Acum, pentru rândurile de postări. Acesta este codul care gestionează datele coloanelor în liste:

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

Pentru a prelua datele postărilor noastre, trebuie să adăugăm un action hook astfel:

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

Exemplu (acest exemplu folosește taxonomii, dar puteți interoga orice altceva):

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

    default:
      break;
  }
}
29 aug. 2011 14:44:11
2

FUNCȚIONEAZĂ ÎN WP 3.2!

custom_post_type: books custom_taxonomy: genre

Modifică doar unde scrie: // change HERE

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' => __("Arată toate {$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');
16 oct. 2011 06:54:53
Comentarii

Aceasta este o soluție frumoasă și ușoară pentru WP 3.2+.

petermolnar petermolnar
30 iul. 2015 13:27:00

funcționează, dar __("Show All {$info_taxonomy->label}") este un mod greșit de a folosi șirurile traductibile.

Mark Kaplun Mark Kaplun
23 aug. 2017 08:24:24
1

A trebuit să lucrez la o funcționalitate similară nu cu mult timp în urmă și nefiind mulțumit de răspunsurile existente, iată alternativa mea. Anul este 2021.

Am dorit ceva simplu și ușor de implementat. O modalitate rapidă și eficientă de a obține toate taxonomiile personalizate din fiecare tip de postare personalizată și de a le adăuga ca opțiuni de filtrare.

Erau câteva cerințe preliminare:

  • Am vrut să evit utilizarea variabilelor globale.
  • Codul trebuia să fie portabil, fără variabile hardcodate, pentru a fi reutilizabil.
  • Să aibă o ierarhie vizibilă, perfectă pentru taxonomii cu termeni înrudite.
  • Să respecte opțiunile de vizibilitate ale taxonomiei. (ex: argumentul show_admin_column din funcția register_taxonomy.
  • Afișarea numărului de postări.
  • Aspectul general să se potrivească cu WordPress.

Am transformat-o într-un plugin pentru o integrare mai ușoară, puteți obține ultima versiune la https://wordpress.org/plugins/cpt-admin-taxonomy-filtering/.

Filtrare cu ierarhie de termeni și număr de postări Filtre multiple pentru tipuri de postări personalizate
Filtru ierarhic cu număr de postări pentru taxonomii personalizate Filtre multiple pentru tipuri de postări personalizate

Dacă doriți doar să o adăugați în function.php, copiați și lipiți următorul script.

Necesită cel puțin WordPress 4.8.0 și PHP: 4.0.

<?php

add_action( 'restrict_manage_posts', 'cpt_admin_taxonomy_filtering' );

if ( ! function_exists( 'cpt_admin_taxonomy_filtering' ) ) {

    function cpt_admin_taxonomy_filtering() {

        /**
         * Obține obiectul ecranului curent.
         * 
         * @link https://developer.wordpress.org/reference/functions/get_current_screen/
         */
        $screen = get_current_screen();

        // Tipuri de postări implicite WordPress
        $restricted_post_types = array(
            'post',
            'page',
            'attachment',
            'revision',
            'nav_menu_item',
        );

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

            /**
             * Returnează numele sau obiectele taxonomiilor înregistrate pentru obiectul sau tipul de obiect solicitat, cum ar fi un obiect de postare sau numele tipului de postare.
             * 
             * @link https://developer.wordpress.org/reference/functions/get_object_taxonomies/
             */
            $taxonomies = get_object_taxonomies( $screen->post_type, 'objects' );

            // Parcurge fiecare taxonomie
            foreach ( $taxonomies as $taxonomy ) {

                if ( $taxonomy->show_admin_column ) {

                    /**
                     * Afișează sau returnează lista dropdown HTML de categorii.
                     * 
                     * @link https://developer.wordpress.org/reference/functions/wp_dropdown_categories/
                     */
                    wp_dropdown_categories(
                        array(
                            'show_option_all' => $taxonomy->labels->all_items,
                            'pad_counts' => true,
                            'show_count' => true,
                            'hierarchical' => true,
                            'name' => $taxonomy->query_var,
                            'id' => 'filter-by-' . $taxonomy->query_var,
                            'class' => '',
                            'value_field' => 'slug',
                            'taxonomy' => $taxonomy->query_var,
                            'hide_if_empty' => true,
                        )
                    );

                };

            };

        };

    };

};
1 mai 2021 16:39:29
Comentarii

Aceasta funcționează foarte bine, mulțumesc!

Gavin Gavin
17 iul. 2021 05:25:59
0

Această funcționalitate nu este foarte cunoscută, dar începând cu WordPress 3.5, poți pasa parametrul 'show_admin_column' => true la register_taxonomy. Aceasta face două lucruri:

  1. Adaugă coloana taxonomiei în vizualizarea listei tipurilor de postări din panoul de administrare
  2. Făcând clic pe numele termenului din coloana taxonomiei, lista va fi filtrată automat după acel termen.

Deci, nu exact la fel ca un câmp de selectare, dar aproape aceeași funcționalitate, cu doar o singură linie de cod.

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

De asemenea, după cum poți citi, există un nou filtru special pentru adăugarea manuală a coloanei taxonomiei (dacă chiar ai nevoie de asta).

15 sept. 2017 15:00:54
2

Mulțumesc tuturor pentru răspunsuri. Știu că aceasta este o întrebare veche, dar aș dori să adaug soluția mai simplă care poate fi folosită în prezent. Acest lucru va necesita doar 2 pași și va folosi mai multe funcționalități disponibile în nucleu. Sper că acest lucru va ajuta pe cineva.

Pasul 1: adăugați 'show_admin_column' => true în funcția register_taxonomy.

Acest lucru va adăuga o coloană în vizualizarea listă care conține link-uri pentru filtrarea listei după acel termen. Poate fi aplicat atât pentru taxonomii ierarhice, cât și pentru cele neierarhice.

Exemplu:

register_taxonomy( 'custom_cat', array( 'custom_post_type' ), array(
    'hierarchical'      => true,
    'labels'            => array(
        'name'              => __( 'Categorii', 'iside' ),
        'singular_name'     => __( 'Categorie', 'iside' ),
        'search_items'      => __( 'Caută Categorii', 'iside' ),
        'all_items'         => __( 'Toate Categoriile', 'iside' ),
        'parent_item'       => __( 'Categorie Părinte', 'iside' ),
        'parent_item_colon' => __( 'Categorie Părinte:', 'iside' ),
        'edit_item'         => __( 'Editează Categorie', 'iside' ),
        'update_item'       => __( 'Actualizează Categorie', 'iside' ),
        'add_new_item'      => __( 'Adaugă Categorie Nouă', 'iside' ),
        'new_item_name'     => __( 'Nouă Categorie', 'iside' ),
        'menu_name'         => __( 'Categorii', 'iside' ),
    ),
    'public'            => true,
    'publicly_queryable'=> true,
    'show_ui'           => true,
    'show_in_menu'      => true,
    'show_in_nav_menus' => true,
    'show_in_rest'      => true,
    'show_tagcloud'     => false,
    'show_in_quick_edit'=> true,
    'show_admin_column' => true, // <-- magia aplicată aici
    'query_var'         => true,
) );

Pasul 2: adăugați dropdown-ul de taxonomie prin filtrul restrict_manage_posts

Acest lucru va adăuga un meniu dropdown de selectare în opțiunile de filtrare din partea de sus. Va folosi funcția implicită wp_dropdown_categories pentru a simplifica procesul. Rețineți că trebuie să setăm numele dropdown-ului la query_var folosit pentru taxonomie. De asemenea, rețineți că value_field trebuie setat la slug (implicit va fi term_id).

Exemplu:

add_action( 'restrict_manage_posts', 'iside_add_filter_to_admin', 10, 2 );
function iside_add_filter_to_admin( $post_type = 'post', $which = 'top' ) {
    if( $post_type == 'custom_post_type' ) {
        $selected = isset( $_GET['custom_cat'] ) ? esc_attr($_GET['custom_cat']) : 0;
        wp_dropdown_categories(array(
            'show_option_all' =>  __( 'Arată Toate Categoriile', 'iside' ),
            'taxonomy'        =>  'custom_cat',
            'name'            =>  'custom_cat', // <-- asigurați-vă că se potrivește cu query_var
            'orderby'         =>  'name',
            'selected'        =>  $selected,
            'hierarchical'    =>  true,
            'depth'           =>  3,
            'show_count'      =>  true,
            'hide_empty'      =>  true,
            'value_field'     => 'slug', // <-- folosește slug în loc de term_id
        ));
    }
}

Atât. Nu este nevoie să adăugați mai mult :-)

18 mar. 2022 11:52:55
Comentarii

Foarte frumos și simplu, mulțumesc. Un punct de remarcat - ai o eroare în sintaxa ta aici (există o paranteză în plus): $selected = isset( $_GET['custom_cat'] ) ? esc_attr($_GET['custom_cat') ]) : 0; care ar trebui să fie în schimb astfel: $selected = isset( $_GET['custom_cat'] ) ? esc_attr($_GET['custom_cat' ]) : 0;

SolaceBeforeDawn SolaceBeforeDawn
27 mai 2023 09:05:51

Mulțumesc @SolaceBeforeDawn. Am editat răspunsul meu

leendertvb leendertvb
27 mai 2023 23:30:21
0

Iată o modalitate de a face acest lucru folosind acțiunea restrict_manage_posts. Pare să funcționeze bine pentru mine și adaugă abilitatea de a filtra după taxonomie pentru toate tipurile de postări și taxonomiile aferente.

// înregistrează fiecare meniu derulant pentru filtrarea după taxonomii
function sunrise_fbt_add_taxonomy_filters() {
    global $typenow;            // tipul curent de postare
    $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) {
              // Verifică dacă e ierarhic - dacă da, construiește meniu derulant ierarhic
              if($tax->hierarchical) {
                $args = array(
                      'show_option_all'    => 'Toate '.$tax->labels->name,
                      'show_option_none'   => 'Selectează '.$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=''>Afișează toate ".$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 );

/**
 * Creează o listă derulantă HTML de Categorii.
 *
 * @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";
        }
} 

O observație - am încercat să limitez adâncimea deoarece unele dintre taxonomiile mele ierarhice sunt destul de mari, dar nu a funcționat - ar putea fi o eroare în funcția wp_dropdown_categories?

17 feb. 2012 21:53:24
0

Actualizare a răspunsului lui @Drew Gourley pentru WP 3.3.1 (și incorporând codul de la 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' => __('Arată Tot '.$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()
            ));
        }
    }
}


//Clasă pentru filtrarea dropdown. Folosită cu wp_dropdown_categories() pentru a face dropdown-ul să folosească slug-uri în loc de ID-uri.
class DropdownSlugWalker extends Walker_CategoryDropdown {

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

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

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

        $output .= '>';
        $output .= $pad.$cat_name;
        $output .= "</option>\n";
    }
}
25 ian. 2013 22:47:17
0

Versiunea ierarhică a răspunsului lui @somatic, la cererea lui @kevin:

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

    // afișează aceste filtre de taxonomie doar pe listările dorite de tipuri personalizate de postări
    global $typenow;
    if ($typenow == 'photos' || $typenow == 'videos') {

        // creează o listă de slug-uri de taxonomii după care dorești să filtrezi - dacă vrei să obții toate taxonomiile, poți folosi get_taxonomies() pentru a construi lista
        $filters = array('plants', 'animals', 'insects');

        foreach ($filters as $tax_slug) {
            // obține obiectul taxonomiei
            $tax_obj = get_taxonomy($tax_slug);
            $tax_name = $tax_obj->labels->name;

            // generează HTML pentru meniul dropdown de filtrare după taxonomie
            echo "<select name='$tax_slug' id='$tax_slug' class='postform'>";
            echo "<option value=''>Afișează tot $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) {
        // generează fiecare opțiune pentru select, verifică ultima valoare $_GET pentru a afișa opțiunea curentă selectată
        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);
    }

}
?>

Am eliminat practic codul care crea opțiunile și l-am pus într-o funcție separată. Funcția 'generate_taxonomy_options', pe lângă parametrul tax_slug, mai primește și parametrii parent și level. Funcția presupune că creează opțiuni pentru părintele 0, care va selecta toți termenii de la nivelul rădăcină. În buclă, funcția se va apela recursiv, folosind termenul curent ca părinte și crește nivelul cu unu. Adaugă automat liniuțe pe măsură ce cobori în ierarhie și voila!

7 ian. 2011 09:12:50
1

Adaugă pur și simplu acest cod în fișierul functions.php sau în codul unui plugin (și înlocuiește YOURCUSTOMTYPE și YOURCUSTOMTAXONOMY). (Am obținut codul de pe generatewp)

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

function filter_backend_by_taxonomies( $post_type, $which ) {
    // Aplică acest filtru doar pentru un anumit tip de postare personalizată (CPT)
    if ( 'YOURCUSTOMTYPE' !== $post_type )
        return;
    // Listă de taxonomii personalizate după care se filtrează
    $taxonomies = array( 'YOURCUSTOMTAXONOMY' );
    foreach ( $taxonomies as $taxonomy_slug ) {
        // Preluare date despre taxonomie
        $taxonomy_obj = get_taxonomy( $taxonomy_slug );
        $taxonomy_name = $taxonomy_obj->labels->name;
        // Preluare termeni ai taxonomiei
        $terms = get_terms( $taxonomy_slug );
        // Afișare HTML pentru filtru
        echo "<select name='{$taxonomy_slug}' id='{$taxonomy_slug}' class='postform'>";
        echo '<option value="">' . sprintf( esc_html__( 'Categorie', 'text_domain' ), $taxonomy_name ) . '</option>';
        foreach ( $terms as $term ) {
            printf(
                '<option value="%1$s" %2$s>%3$s (%4$s)</option>',
                $term->slug,
                ( ( isset( $_GET[$taxonomy_slug] ) && ( $_GET[$taxonomy_slug] == $term->slug ) ) ? ' selected="selected"' : '' ),
                $term->name,
                $term->count
            );
        }
        echo '</select>';
    }
}
29 iun. 2020 14:28:23
Comentarii

Superb! Cel mai bun răspuns!

Carl Brubaker Carl Brubaker
21 apr. 2021 23:42:23
0

Tutorialul lui Mike pe acest subiect este excelent! Probabil că nu m-aș fi obosit să adaug această funcționalitate în plugin-ul meu Media Categories dacă ar fi trebuit să o descopăr singur.

Cu toate acestea, cred că utilizarea parse_query și apoi interogarea pentru termen nu este necesară. Este mai curat să creezi propria clasă personalizată walker. Poate că acest lucru nu era posibil atunci când a scris postarea sa - are 3 ani la momentul scrierii acestui text.

Verifică acest fragment de cod minunat de pe github. Funcționează perfect, schimbă ID-urile din valorile dropdown-ului în slug-uri, astfel încât funcționează în mod nativ fără a modifica interogarea.

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

27 mar. 2014 22:04:55
1

Am încercat ambele coduri, de la Mike și somatic, și m-am întrebat cum să obțin un lucru din fiecare tehnică:

Cu codul lui Mike, afișează lista derulantă cu opțiunea ierarhică, ceea ce ajută foarte mult. Dar pentru a afișa două liste derulante a trebuit să duplic instrucțiunea if ($typenow=='produtos') {...} în funcția restrict_listings_by_business() și de asemenea if ($pagenow=='edit.php' && ... } în funcția convert_business_id_to_taxonomy_term_in_query($query), ceea ce acum produce mult cod.

Cu codul lui somatic, trebuie doar să specific taxonomiile pe care doresc să le văd ca liste derulante și funcționează; $filters = array('taxo1', 'taxo2');

Întrebare: pot să folosesc abordarea lui somatic și să am și opțiunea ierarhică?

Mulțumesc mult oricum pentru acest tutorial, a fost de mare ajutor!

6 ian. 2011 21:00:53
Comentarii

Vezi răspunsul meu pentru o soluție ierarhică

Manny Fleurmond Manny Fleurmond
8 ian. 2011 08:02:39
0

Acesta este un fragment de cod util care permite filtrarea postărilor sau a unui tip de postare personalizată după un termen specific dintr-o taxonomie în panoul de administrare WordPress.

/* Filtrează CPT după Taxonomie Personalizată */
function rave_core_backend_by_portfolio_taxonomies( $post_type, $which ) {
    // Aplică acest filtru doar pentru un anumit CPT
    if ( 'portfolio' !== $post_type )
        return;

    // Listă de slug-uri de taxonomii personalizate după care se filtrează
    $taxonomies = array( 'portfolio_cat' );

    foreach ( $taxonomies as $taxonomy_slug ) {

        // Preluare date despre taxonomie
        $taxonomy_obj = get_taxonomy( $taxonomy_slug );
        $taxonomy_name = $taxonomy_obj->labels->name;

        // Preluare termeni din taxonomie
        $terms = get_terms( $taxonomy_slug );

        // Afișare HTML pentru filtru
        echo "<select name='{$taxonomy_slug}' id='{$taxonomy_slug}' class='postform'>";
        echo '<option value="">' . sprintf( esc_html__( 'Toate %s', 'rave-core' ), $taxonomy_name ) . '</option>';
        foreach ( $terms as $term ) {
            printf(
                '<option value="%1$s" %2$s>%3$s (%4$s)</option>',
                $term->slug,
                ( ( isset( $_GET[$taxonomy_slug] ) && ( $_GET[$taxonomy_slug] == $term->slug ) ) ? ' selected="selected"' : '' ),
                $term->name,
                $term->count
            );
        }
        echo '</select>';
    }
}

add_action( 'restrict_manage_posts', 'rave_core_backend_by_portfolio_taxonomies' , 99, 2);
13 iun. 2021 08:51:24
1

Îmi cer scuze pentru faptul că, fiind un utilizator nou, nu pot posta comentarii, dar pot posta un răspuns...

Începând cu WordPress 3.1 (RC 1), răspunsul lui Mike (care m-a ajutat atât de bine în ultimele luni) nu mai funcționează pentru mine; limitarea după orice termen dintr-o taxonomie copil returnează un rezultat gol.

Am încercat actualizarea lui Somatic și a funcționat excelent; chiar mai bine, funcționează cu interogări multiple de taxonomii, care au fost integrate în această versiune.

27 dec. 2010 22:37:04
Comentarii

Din anumite motive, versiunea lui somatic nu funcționează nici ea pentru 3.1

Manny Fleurmond Manny Fleurmond
24 feb. 2011 08:17:18