Aggiunta di un filtro tassonomia all'elenco di amministratori per un tipo di post personalizzato?


129

Ho creato un tipo di post personalizzato chiamato 'listing'e aggiunto una tassonomia personalizzata denominata 'businesses'. Vorrei aggiungere un elenco a discesa delle aziende all'elenco di amministrazione per gli elenchi.

Ecco come appare questa funzionalità nell'elenco di amministrazione per Messaggi (Vorrei lo stesso per il mio Tipo di messaggio personalizzato):

Categorie Elenco a discesa nei post

Ecco il mio codice attuale ( Ed ecco lo stesso codice su 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();
}

Come posso aggiungere un elenco a discesa di aziende all'elenco di amministratori per gli elenchi?


8
Grazie per lo screenshot, aiuta davvero ad avere quelli.
MikeSchinkel,

Esiste un plug-in Filtro di tassonomia dell'amministratore che può fare esattamente il lavoro.
Anh Tran,

Risposte:


140

AGGIORNAMENTO: ho incluso una nuova risposta completa ma anche così ho lasciato la mia risposta originale in fondo alla quale fanno riferimento i primi pochi commenti.


Ciao @tarasm :

Anche se ho detto che non dovrebbe essere difficile, è un po 'coinvolto. Ma prima di scavare nel codice ...

Le schermate:

... diamo un'occhiata ad alcune schermate per il prodotto finito:

Pagina elenco di elenchi senza filtro:

Pagina dell'elenco di elenchi senza filtro
(fonte: mikeschinkel.com )

Pagina elenco di elenchi con filtro:

Pagina elenco di elenchi con filtro
(fonte: mikeschinkel.com )

Il codice

Quindi eccoci qui ... ( Nota: ho usato una forma singolare per il nome della tassonomia di business; spero che corrisponda al tuo. Da molta esperienza con WordPress e lo sviluppo di database in passato, credo che sia meglio farlo in questo modo .)

Passaggio 1: il restrict_manage_postsgancio di azione.

La prima cosa che devi fare è agganciare l' restrict_manage_postsazione che non ha parametri e viene chiamata da /wp-admin/edit.php(nella v3.0.1 quella chiamata è sulla linea 378.) Ciò ti consentirà di generare la selezione a discesa nella posizione appropriata sopra l'elenco di Elencare i post.

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

Iniziamo controllando la $typenowvariabile per assicurarci di essere effettivamente su post_typedi listing. In caso contrario, otterrai questo menu a discesa per tutti i tipi di post che in alcuni casi è quello che desideri, ma non in questo caso.

Successivamente vengono caricate le informazioni sulla tassonomia aziendale utilizzando get_taxonomy(). Ne abbiamo bisogno per recuperare l'etichetta per la tassonomia (ad esempio " Imprese "; avremmo potuto codificare, ma non è molto utile se è necessario internazionalizzare in seguito.) Quindi chiamiamo wp_dropdown_categories()con tutti gli argomenti appropriati $argsnell'array per generare il cadere in picchiata

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

Ma quali sono gli argomenti appropriati? Diamo un'occhiata a ciascuno individualmente:

  • show_optional_all- Abbastanza semplice, è quello che viene visualizzato all'inizio nel menu a discesa e quando non è stato applicato alcun filtro. Nel nostro caso andrà quindi essere "Show All Businesses " ma avremmo potuto chiamarlo "Listings for All Businesses" o come preferisci.

  • taxonomy- Questo argomento indica alla funzione da quale tassonomia estrarre i termini anche se la funzione ha categoriesnel suo nome. In v2.8 e precedenti WordPress non aveva tassonomie personalizzate ma quando furono aggiunte il team decise che sarebbe stato più semplice aggiungere un argomento di tassonomia a questa funzione piuttosto che creare un'altra funzione con un altro nome.

  • name- Questo argomento consente di specificare il valore che WordPress utilizza per l' nameattributo dell'elemento <select> generato per il menu a discesa. Nel caso in cui non sia ovvio, questo è anche il valore che verrà utilizzato nell'URL durante il filtraggio.

  • orderby- Questo argomento dice a WordPress come ordinare i risultati in ordine alfabetico. Nel nostro caso abbiamo specificato di ordinare l'acquisto namedei termini nella tassonomia, ovvero i nomi delle imprese in questo caso.

  • selected- Questo argomento è necessario affinché il menu a discesa possa mostrare il filtro corrente nel menu a discesa. Dovrebbe essere il term_iddal termine di tassonomia selezionato. Nel nostro caso potrebbe essere il term_idda "Business # 2" . Dove otteniamo questo valore? Dalla variabile globale di WordPress $wp_query; ha una proprietà queryche contiene un array di tutti i parametri URL e dei loro valori (ovviamente, a meno che qualche plugin ribelle non lo abbia già modificato, ovviamente). Dato che WordPress elabora le cose, verrà termpassato un parametro URL sull'URL quando l'utente fa clic sul filtro pulsante se l'utente ha selezionato un termine valido (ovvero una delle attività elencate).

  • hierarchical- Impostando questa trueopzione, si dice alla funzione di rispettare la natura gerarchica della tassonomia e di visualizzarla in una vista ad albero se i termini (imprese) in effetti hanno figli. Per una schermata per vedere come appare, vedi sotto.

  • depth- Questo argomento collabora con l' hierarchicalargomento per determinare a quanti livelli deve essere rivolta la funzione di visualizzazione dei bambini.

  • show_count- Se truequesto argomento visualizzerà i messaggi di conteggio tra parentesi a sinistra del nome del termine all'interno del menu a discesa. In questo caso verrebbe visualizzato un conteggio di elenchi associati a un'azienda. Per una schermata per vedere come appare, vedi sotto.

  • hide_empty- Infine, se nella tassonomia ci sono termini che non sono associati a un post (ad esempio attività commerciali non associate a un elenco), impostando questo su truesi ometterà di essere inclusi nel menu a discesa.

Tassonomia Il menu a discesa dovrebbe gerarchia e conteggi
(fonte: mikeschinkel.com )

Passaggio 2: il parse_querygancio del filtro.

Successivamente chiamiamo le nostre attenzioni all'hook del parse_queryfiltro che ha un parametro ( $query) e viene chiamato da /wp-includes/query.php(nella v3.0.1 quella chiamata è sulla linea 1549.) Viene chiamata quando WordPress ha terminato di ispezionare l'URL e impostare tutti i valori appropriati nell'attuale attivo $wp_queryincludendo cose come $wp_query->is_homee $wp_query->is_author, ecc.

Dopo aver parse_queryeseguito l'hook del filtro, WordPress chiamerà get_posts()e caricherà un elenco di post in base a ciò che è specificato in quello attualmente attivo $wp_query. Quindi parse_queryè spesso un ottimo posto per convincere WordPress a cambiare idea su quali post caricherà.

Nel tuo caso d'uso vogliamo far filtrare WordPress in base alle attività selezionate; cioè per visualizzare solo gli elenchi che sono stati associati all'attività selezionata (direi "... solo quegli elenchi che sono stati " classificati " dall'azienda selezionata" ma non è tecnico corretto; categoryè la sua tassonomia sul peer con l' businesseccezione che categoryè integrato in WordPress ed businessè personalizzato. Ma per chi ha familiarità con la categorizzazione dei post questo può aiutarti a capire come funzionano quasi in modo identico. Ma sto divagando ...)

Accedere al codice. La prima cosa che facciamo è prendere un riferimento ai attualmente attivi $wp_query's query_varsin modo che sia più conveniente per lavorare, proprio come come il suo fare all'interno di WordPress' propria parse_query()funzione. Diversamente da ciò $wp_query->queryche viene utilizzato per il mirroring dei parametri passati sull'URL, l' $wp_query->query_varsarray viene utilizzato per controllare la query che WordPress esegue e si prevede che venga modificato. Quindi, se hai bisogno di modificarne uno, sarebbe quello (almeno penso che sia diverso tra i due; se qualcuno lo sa diversamente , fammelo sapere, così posso aggiornarlo!)

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

Successivamente testiamo $pagenowper assicurarci che stiamo effettivamente caricando WordPress dal percorso dell'URL /wp-admin/edit.php. Facciamo questo per evitare di rovinare accidentalmente query su altre pagine. Controlliamo anche per assicurarci di avere sia businesscome taxonomyelemento che come termelemento. (Nota taxonomye termsono una coppia; sono usati insieme per consentire l'interrogazione di un termine di tassonomia; devo avere entrambi o WordPress non sa quale tassonomia controllare.)

Potresti chiederti come si è businessrivelato taxonomynell'elemento query_varsdell'array. Ciò che abbiamo scritto nel nostro parse_queryhook ha innescato la magia interna di WordPress che è stata posta in attesa quando hai registrato la " business" tassonomia impostando query_varcome vera ( register_taxonomy()copia il nome della tassonomia come suo query_var; puoi cambiarlo ovviamente ma a meno che tu non abbia un conflitto è meglio attenersi allo stesso):

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

Ora $ wp_query di WordPress è stato scritto per utilizzare gli slug per le query filtrate con tassonomia standard, non per i termini ID tassonomia. Per questo caso d'uso ciò di cui abbiamo veramente bisogno per far funzionare la nostra query di filtro sono questi:

taxonomy: affari

term: business-1 (ovvero il slug)

Non questi:

taxonomy: affari

term: 27 (ovvero il term_id)

È interessante notare che, purtroppo, e la discesa generato dal wp_dropdown_categories()impostare la <option>'s valueattributo del termine (/ incassi') term_id, non è il termine slug. Quindi abbiamo bisogno di convertire $wp_query->query_vars['term']da un valore numerico term_idalla sua stringa slugcome segue nello snippet afferrato dall'alto (Nota che questo non è il modo più efficace per interrogare un database ma fino a quando WordPress non aggiunge il supporto per term_ids nella sua query che è il migliore che possiamo fare!) :

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

E questo è tutto! Con queste due funzioni ottieni il filtro che desideri.

MA ASPETTA, C'È DI PIÙ! :-)

Sono andato avanti e ho aggiunto una colonna "Aziende" al tuo elenco di annunci perché, beh, sapevo che sarebbe stata la tua prossima domanda. Senza avere una colonna per ciò che si filtra, può essere molto confuso per l'utente finale. (Ho lottato da solo, ed ero il programmatore!) Ovviamente puoi già vedere la colonna "Aziende" nelle precedenti schermate sopra.

Passaggio 3: il manage_posts_columnsgancio del filtro.

Per aggiungere una colonna all'elenco dei post è necessario chiamare altri due (2) hook. La prima è manage_posts_columnso la versione specifica del tipo di post manage_listing_posts_columnsche ho chiamato invece. Accetta un parametro ( posts_columns) e viene chiamato da /wp-admin/includes/template.php(nella v3.0.1 quella chiamata è sulla linea 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;
}

La manage_posts_columnsfunzione hook viene passata a una matrice di colonne in cui il valore è l'intestazione di colonna visualizzata e la chiave è l'identificatore di colonna interno. Identificatori colonna standard possono includere questi e di più: 'cb', 'title' 'author', ``' date'`, etc.

'cb', è la checkboxcolonna ed entrambi 'title'e si 'date'riferiscono rispettivamente a post_titlee post_datedalla wp_poststabella. 'author'ovviamente è il post_authorcampo dopo che il nome dell'autore è stato recuperato dalla wp_userstabella.

Schermata della colonna dei post "cb" come casella di controllo.
(fonte: mikeschinkel.com )

Per il manage_posts_columnsgancio stiamo semplicemente volendo inserire nostra colonna businessesnella $posts_columnsmatrice prima 'author', ipotizzando un altro plugin non ha tolto authorancora dalla lista!

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

( Nota come ho scritto, mi add_businesses_column_to_listing_list()è venuto in mente che PHP deve avere un modo più semplice per inserire un valore in un array associativo nell'ordine corretto?!? O almeno ci deve essere una funzione nel core di WordPress per farlo? Ma dal momento che Google mi ha deluso così sono andato con quello che ha funzionato. Se qualcuno ha qualche suggerimento alternative sarò tutto orecchi e apprezzamento in anticipo!)

Il che finalmente ci porta a ...

Passaggio n. 4: il manage_posts_custom_columngancio di azione

La seconda cosa di due (2) che dobbiamo fare per rendere le nostre attività commerciali visualizzate nella colonna è in realtà l'output del nome di ciascuna delle aziende associate usando il manage_posts_custom_columngancio di azione. Questo hook accetta due (2) parametri ( column_ide post_id) ed è anche chiamato da /wp-admin/includes/template.php(nella v3.0.1 che la chiamata è sulla linea 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;
        }
    }
}

Questo hook viene chiamato per ogni colonna per ogni riga di post (/ business). Verifichiamo innanzitutto che stiamo effettivamente lavorando solo con il listingtipo di post personalizzato e quindi utilizziamo switchun'istruzione per testare il column_id. Ho scelto switchperché questo hook viene spesso utilizzato per generare output per molte colonne diverse, soprattutto se utilizziamo una funzione per molti tipi di post diversi che potrebbero assomigliare a questo:

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

Ispezionando il nostro caso d'uso solo un po 'più da vicino, viene visualizzata la get_the_terms()funzione che restituisce semplicemente l'elenco dei termini per questa tassonomia (ovvero le attività commerciali per questo elenco). Qui ottieni il permalink per la pagina Web front-end del termine che normalmente elenca i post associati con il termine, ma ovviamente potrebbe differire a seconda del tema e / o dei plugin installati.

Usiamo il permalink per il collegamento ipertestuale del termine solo perché mi piace collegare i collegamenti ipertestuali. Uniamo quindi tutti i termini ipertestuali (/ imprese) insieme separati con il carattere pipe (' |') e l'output nel buffer PHP che lo invia al browser dell'utente / client 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);
}

ORA finalmente abbiamo finito.

Sommario

Quindi, in sintesi, devi usare i seguenti quattro (4) hook per ottenere sia un filtro che una colonna correlata nella pagina dell'elenco dei post personalizzati (Oh, funzionerà anche con Post e Pagine). Sono:

  • Passaggio 1: il restrict_manage_postsgancio di azione.
  • Passaggio 2: il parse_querygancio del filtro.
  • Passaggio 3: il manage_posts_columnsgancio del filtro.
  • Passaggio n. 4: il manage_posts_custom_columngancio di azione

Dove scaricare il codice

Ma se ti costringessi a leggere tutto quanto sopra, non sarei certamente una persona molto simpatica se ti facessi anche scovare il codice solo per poterlo provare! Ma contrariamente a quanto dicono alcune persone, sono gentile. Quindi ecco qui:

NOTA per @tarasm : ho incluso hook per aregister_post_type()e inregister_taxonomy()modo che altri possano provarlo senza doverli ricreare. Probabilmente vorrai eliminare quelle due chiamate di funzione prima di provarlo.

FINE


Risposta originale:

Ciao @tarasm :

Stai cercando un menu a discesa in alto come questa schermata o stai cercando un menu a discesa per post record e, in caso affermativo, come ti aspetteresti che funzioni?

Come creare la funzionalità Ordina per per un tipo di post personalizzato nell'amministratore di WordPress
(fonte: mikeschinkel.com )

Se il primo, dai un'occhiata a questa risposta alla domanda Come ordinare l'area di amministrazione di un tipo di post personalizzato di Wordpress in base a un campo personalizzato? Se questo è ciò di cui hai bisogno, posso fornire ulteriori dettagli relativi alla tassonomia.


Sto cercando 1 menu a discesa in alto che mostrerebbe il filtro Categorie. Stavo vagando se esiste un modo standard per farlo senza dover scrivere codice personalizzato.
Taras Mankovski,

A prima vista non credo che tu possa fare senza il codice personalizzato ma poi non penso che il codice personalizzato sarà significativo. Devo prepararmi per una chiamata del cliente, quindi dovrà essere più tardi oggi.
MikeSchinkel,

2
In realtà entrambe le soluzioni (somatic e MikeSchinkel) non funzionano quando si tenta di filtrare 2 diverse tassonomie nello stesso filtro: - / Filtrare sempre la tassonomia più recente quando si tenta di filtrare 2+ contemporaneamente.
Ünsal Korkmaz,

1
@ Ünsal La versione attuale di WordPress (3.0) non supporta più query di tassonomia ma da quello che ho sentito cambierà con la versione 3.1. Per far funzionare questo esempio con più tassonomie, è necessario aggiungere alcuni join e ubicazioni alla query tramite gli hook del filtro Posts_join e posts_where.
Manny Fleurmond,

1
In WP 3.1+, i passaggi uno e due sono migliori nella risposta @ drew-gourley (in realtà, il tuo passaggio 2 non ha funzionato per me, penso che ci siano cambiamenti in questo filtro nel nuovo WordPress).
Tomasz Struczyński,

44

Volevo solo condividere un'implementazione alternativa. Non avevo l'incredibile tutorial di Mike quando lo stavo capendo, quindi la mia soluzione è un po 'diversa. In particolare, semplificherò il passaggio n. 1 di Mike ed eliminerò il passaggio n. 2 : gli altri passaggi sono ancora applicabili.

Nel tutorial di Mike, l'uso wp_dropdown_categories()ci salva un po 'di costruzione manuale di elenchi, ma richiede alcune complicate modifiche alla query condizionale ( passaggio # 2 ) per gestire il suo uso di ID invece di lumaca. Per non parlare della difficoltà di modificare quel codice per gestire altri scenari, come i filtri di tassonomia multipli.

Un altro approccio è semplicemente quello di non utilizzare affatto i difetti wp_dropdown_categories(), ma invece di creare da zero i nostri elenchi a discesa. Non è così complicato, richiede meno di 30 righe di codice e non richiede affatto l'aggancio 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>";
        }
    }
}

Collegando semplicemente le tassonomie desiderate $filtersall'array, è possibile generare rapidamente più filtri di tassonomia. Sembrano esattamente gli stessi degli screenshot di Mike. Quindi puoi proseguire con i passaggi 3 e 4 .


4
@somatic - Bel aggiornamento! Sì, l'utilizzo wp_dropdown_categories()richiede molte soluzioni alternative. Cerco di attenermi alle funzioni principali quando possibile, ma come fai notare a volte ci vuole più lavoro in quel modo. Dimostra solo che con WordPress c'è spesso più di un buon modo per risolvere un problema. Buon lavoro!
MikeSchinkel,

Ho appena smesso di funzionare per me su WordPress 3.1. Cercando di capire cosa è esattamente cambiato. Sembra che dovrebbe ancora funzionare: la tassonomia e il termine slug vengono visualizzati come valori GET
nell'URL

Ho cercato di farlo funzionare, ma l'unico modo che ho potuto è stato di utilizzare l'hook parse_query, verificare la var della query della tassonomia e impostare la tassonomia e il termine varia in base a quello. Utilizzo di WP 3.1. Tassonomia e termine devono apparire nell'URL quando viene inviato il filtro?
sanchothefat,

2
Funziona come un incanto per me! Soluzione davvero elegante. Ti devo una birra :)
Michal Mau,

@somatic Funziona benissimo ma c'è un modo per far sì che $ term-> count contino solo i termini per quel tipo di post? Ad esempio, se ho una tassonomia personalizzata sia per le foto che per i video, questo mi mostrerà quando guardo i video personalizzati post digitare il numero totale di post per quel termine da entrambi i tipi di post personalizzati anziché solo il numero totale di post video che lo usano termine.
Greenhoe,

13

Ecco una versione di questo che crea e applica automaticamente i filtri da tutte le tassonomie che si applicano a tutti i tipi di posta personalizzati che li utilizzano. (che boccone) Comunque, l'ho anche modificato in modo che funzioni con wp_dropdown_categories () e wordpress 3.1. Il progetto a cui sto lavorando si chiama ToDo, puoi rinominare le funzioni in qualcosa che ha senso per te, ma questo dovrebbe funzionare praticamente per tutto automaticamente.

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

Nota che sto usando un plug-in che aggiunge "term_order" come modo per ordinare i termini, dovrai modificarlo o rimuovere tale argomento per ripristinare il valore predefinito.


molto sexy davvero. stavo ricevendo avvisi di errore, quindi ho cambiato if (isset ($ var)) in if (isset ($ var) && $ var> 0) per evitare di cercare i termini associati al valore Visualizza tutto di 0. oh, e ho dovuto restituire $ query nella funzione
todo_convert_restrict

11

Risposta in ritardo

modificare

Ho scritto Filterama , un plugin che aggiungerà questa funzionalità nel modo più semplice possibile.

Aggiornamento per WordPress 3.5+

Ora che le cose sono molto più facili, ecco una soluzione molto semplice come plugin o mu-plugin.

Utilizza il minor numero di risorse possibile, carica solo sulle schermate necessarie e aggiunge colonne + filtri per ogni tassonomia personalizzata.

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

    }

}

E poi hai solo bisogno di una classe Walker personalizzata.

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})"
                : ''
        );
    }
}

Ho dato un vortice, ma il metodo get_select () sembra mancare.
Dave Romsey,

@ goto10 Avevi ragione. Aggiornato. Btw: è più semplice prendere il plugin collegato. Sarà disponibile nel repository dei plug-in tra una o due settimane. (Già confermato).
Kaiser

Ho dovuto usare $this->setup_vars();all'inizio di public function setup()per "manage_taxonomies_for_{$this->post_type}_columns"lavorare
Christian

Ma potrebbe essere perché lo uso in un tema function.php conadd_action( 'init', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
Christian

@Christian Questo non è materiale tematico. Questo appartiene a un plug-in e poiché attualmente il codice sopra lo sta caricando molto prima che vengano caricati i Temi.
Kaiser

7

Volevo solo fare una breve nota. Nelle versioni più recenti di WP, gli elenchi di post sull'amministratore sono gestiti dalla classe WP_Posts_List_Table. Il codice apply_filters è ora il seguente:

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

Quindi per aggiungere nuove colonne un hook add_filter dovrebbe essere così:

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

Ecco un esempio:

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

Ora, per le righe dei post. Questo è il codice che gestisce i dati di colonna sugli elenchi:

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

Per recuperare i dati dei nostri post, dobbiamo aggiungere un hook di azione come questo:

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

Esempio (questo esempio utilizza tassonomie, ma è possibile eseguire query su qualsiasi altra cosa):

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

FUNZIONA IN WP 3.2!

custom_post_type: libri custom_taxonomy: genere

Modifica solo se dice: // cambia QUI

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

È una soluzione semplice e piacevole per WP 3.2+.
petermolnar,

funziona ma __("Show All {$info_taxonomy->label}")è un modo sbagliato di usare stringhe traducibili.
Mark Kaplun,

2

Ecco un modo per farlo usando l'azione Limit_manage_posts. Sembra funzionare bene per me e aggiunge la possibilità di filtrare in base alla tassonomia per tutti i tipi di posta e le relative tassonomie.

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

Una nota - ho provato a limitare la profondità perché alcune delle mie tassonomie gerarchiche sono piuttosto grandi ma non ha funzionato - potrebbe essere un bug nella funzione wp_dropdown_categories?


2

Questo non è ben noto immagino, ma a partire da Wordpress 3.5, puoi passare 'show_admin_column' => truearegister_taxonomy . Questo fa 2 cose:

  1. Aggiunge la colonna della tassonomia alla vista elenco dei tipi di post dell'amministratore
  2. Facendo clic sul nome del termine nella colonna della tassonomia, filtrerà di fatto l'elenco su quel termine .

Quindi, non esattamente lo stesso di avere una selezione, ma quasi la stessa funzionalità, larghezza solo una riga di codice.

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

Inoltre, come puoi leggere, esiste un nuovo filtro su misura per l'aggiunta manuale della colonna della tassonomia (se davvero necessario).


1

Versione gerarchica della risposta di @ somatic, come richiesto da @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);
    }

}
?>

Ho praticamente rimosso il codice che ha creato le opzioni e l'ho messo nella sua funzione. La funzione 'generate_taxonomy_options', oltre a prendere tax_slug, accetta anche un parametro parent e level. La funzione presuppone che stia creando opzioni per il genitore 0, che selezionerà tutti i termini a livello di radice. Nel loop la funzione chiamerà ricorsivamente se stessa, usando quel termine corrente come genitore e aumentando il livello di uno. Aggiunge automaticamente le zecche sul lato più in profondità si scende giù per l'albero e voilà!


1

Aggiornamento della risposta di @Drew Gourley per WP 3.3.1 (e codice incorporato da 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

Ci scusiamo per il fatto che, come nuovo utente, non posso pubblicare commenti ma posso pubblicare una risposta ...

A partire da WordPress 3.1 (RC 1) la risposta di Mike (che mi ha servito così bene negli ultimi due mesi) non funziona più per me; la limitazione da parte di qualsiasi figlio di tassonomia dà un risultato vuoto. Ho provato l'aggiornamento di Somatic e ha funzionato benissimo; ancora meglio, funziona con più domande di tassonomia che sono state elaborate in questa versione.


Per qualche ragione la versione di
Somatic

0

Ho appena provato entrambi i codici, da Mike e Somatic, e mi chiedevo come ottenere una cosa da ogni tecnica:

Con il codice di Mike, mostra l'elenco a discesa con l' opzione gerarchica , che aiuta molto. Ma per visualizzare due menu a discesa ho dovuto duplicare la if ($typenow=='produtos') {...}dichiarazione nella funzione restrict_listings_by_business()e anche if ($pagenow=='edit.php' && ... }nella convert_business_id_to_taxonomy_term_in_query($query) funzione che ora fornisce molto codice.

Con il codice di Somatic ho solo bisogno di specificare le tassonomie che vorrei vedere come dropdown e bam, funziona; $filters = array('taxo1', 'taxo2');

Domanda: posso ottenere l'approccio di Somatic e avere anche quello gerarchico opzione ?

Grazie mille per questo tutorial, aiutato molto!


Vedi la mia risposta per una soluzione gerarchica
Manny Fleurmond,

0

Il tutorial di Mike su questo è fantastico! Probabilmente non mi sarei preso la briga di aggiungere questa funzionalità al mio plug-in Categorie multimediali se avessi dovuto capirlo da solo.

Detto questo, penso che non sia necessario utilizzare parse_querye quindi ottenere query per il termine. È più pulito per creare la tua classe walker personalizzata. Forse non è stato possibile quando ha scritto il suo post: i suoi 3 anni al momento in cui ho scritto questo.

Dai un'occhiata a questo fantastico frammento su github. Funziona come un incantesimo, cambia gli ID nei valori a discesa in lumache, quindi funziona in modo nativo senza modificare la query.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.