Ajout d'un filtre de taxonomie à la liste des administrateurs pour un type de publication personnalisé?

129

J'ai créé un type de publication personnalisé appelé 'listing'et ajouté une taxonomie personnalisée appelée 'businesses'. J'aimerais ajouter une liste déroulante des entreprises à la liste des administrateurs pour les listes.

Voici à quoi ressemble cette fonctionnalité dans la liste des administrateurs pour les messages (je voudrais la même chose pour mon type de message personnalisé):

Catégories Dropdown dans les messages

Voici mon code actuel ( Et voici le même code sur 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();
}

Comment puis-je ajouter une liste déroulante des entreprises à la liste des administrateurs pour les listes?

Taras Mankovski
la source
8
Merci pour la capture d'écran, cela aide vraiment d'avoir ceux-ci.
MikeSchinkel
Il existe un filtre de taxinomie administrateur capable de faire le travail exact.
Anh Tran

Réponses:

140

UPDATE: J'ai inclus une nouvelle réponse complète mais j'ai quand même laissé ma réponse originale au bas de la page, à laquelle font référence les premiers commentaires.


Bonjour @tarasm :

Bien que j'ai dit que cela ne devrait pas être difficile, c'est un peu impliqué. Mais avant de creuser dans le code ...

Les captures d'écran:

... vérifions quelques captures d'écran du produit fini:

Page de liste d'annonces sans filtrage:

Page de liste d'annonces sans filtrage
(source: mikeschinkel.com )

Page de liste d'annonces avec filtrage:

Page de liste d'annonces avec filtrage
(source: mikeschinkel.com )

Le code

Alors on y va ... ( Note: j'ai utilisé une forme singulière pour le nom de taxonomie de business; j'espère que cela correspond à votre. Grâce à de nombreuses expériences avec le développement de WordPress et de bases de données dans le passé, je pense qu'il est préférable de le faire de cette façon. .)

Étape 1: Le restrict_manage_postscrochet d’action.

La première chose à faire est d’attacher l’ restrict_manage_postsaction qui n’a pas de paramètre et qui est appelée /wp-admin/edit.php(cet appel est dans la v3.0.1 sur la ligne 378.) Cela vous permettra de générer la liste déroulante à l’emplacement approprié au-dessus de la liste des Liste des articles.

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

Nous commençons par vérifier la $typenowvariable pour nous assurer que nous sommes en fait sur post_typedes listing. Si vous ne le faites pas, vous obtiendrez cette liste déroulante pour tous les types de publication, ce qui dans certains cas correspond à vos souhaits, mais pas dans ce cas.

Ensuite, nous chargeons des informations sur la taxonomie commerciale à l’aide de get_taxonomy(). Nous en avons besoin pour récupérer l'étiquette de la taxonomie (c'est-à-dire " Entreprises "; nous aurions pu coder en dur, mais ce n'est pas très bien si vous devez internationaliser plus tard.) Ensuite, nous appelons wp_dropdown_categories()avec tous les arguments appropriés dans le $argstableau pour générer le menu déroulant

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

Mais quels sont les arguments appropriés? Regardons chacun individuellement:

  • show_optional_all- C'est assez simple, c'est ce qui est affiché dans la liste déroulante au début et quand aucun filtrage n'a été appliqué. Dans notre cas, cela va donc être "Afficher toutes les entreprises " mais nous aurions pu l'appeler "Inscriptions pour toutes les entreprises" ou ce que vous aimez.

  • taxonomy- Cet argument indique à la fonction de quelle taxonomie extraire les termes même si la fonction a categoriesson nom. Dans la version 2.8 et antérieure, WordPress n’avait pas de taxonomies personnalisées, mais lorsqu’elles ont été ajoutées, l’équipe a décidé qu’il serait simplement plus facile d’ajouter un argument de taxonomie à cette fonction que de créer une autre fonction portant un autre nom.

  • name- Cet argument vous permet de spécifier la valeur utilisée par WordPress pour l' nameattribut de l'élément <select> généré pour la liste déroulante. Juste au cas où cela ne serait pas évident, c'est également la valeur qui sera utilisée dans l'URL lors du filtrage.

  • orderby- Cet argument indique à WordPress comment classer les résultats par ordre alphabétique. Dans notre cas, nous avons spécifié pour commander acheter les nametermes de la taxonomie, c'est-à-dire les noms commerciaux dans ce cas.

  • selected- Cet argument est nécessaire pour que le menu déroulant puisse afficher le filtre actuel dans le menu déroulant. Ce devrait être le term_idterme de taxonomie sélectionné. Dans notre cas, il pourrait s'agir term_iddu "Business # 2" . Où obtenons-nous cette valeur? De la variable globale de WordPress $wp_query; il a une propriété queryqui contient un tableau de tous les paramètres d'URL et leurs valeurs (à moins qu'un plugin égaré ne l'ait déjà modifié, bien sûr.) Compte tenu de la façon dont WordPress traite les choses, un termparamètre d'URL sera transmis à l'URL lorsque l'utilisateur clique sur le filtre. bouton si l’utilisateur a sélectionné un terme valide (c’est-à-dire un des commerces listés).

  • hierarchical- En définissant cette trueoption, vous indiquez à la fonction de respecter la nature hiérarchique de la taxonomie et de l'afficher dans une arborescence si les termes (entreprises) ont effectivement des enfants. Pour une capture d'écran pour voir à quoi cela ressemble, voir ci-dessous.

  • depth- Cet argument collabore avec l' hierarchicalargument pour déterminer combien de niveaux la fonction doit afficher pour afficher les enfants.

  • show_count- Si truecet argument affichera un nombre de messages entre parenthèses à gauche du nom du terme dans la liste déroulante. Dans ce cas, le nombre d'inscriptions associées à une entreprise serait affiché. Pour une capture d'écran pour voir à quoi cela ressemble, voir ci-dessous.

  • hide_empty- Enfin, si la taxonomie contient des termes qui ne sont pas associés à une publication (c'est-à-dire aux entreprises qui ne sont pas associées à une liste), le fait de les définir de manière à trueleur éviter d'être inclus dans la liste déroulante.

La taxonomie Drop Down doit hiérarchiser et compter
(source: mikeschinkel.com )

Étape 2: Le parse_querycrochet du filtre.

Ensuite, nous appelons notre attention sur le parse_querycrochet de filtre qui a un paramètre ( $query) et qui est appelé depuis /wp-includes/query.php(dans la v3.0.1, cet appel est sur la ligne 1549.) Il est appelé lorsque WordPress a fini d'inspecter l'URL et de définir toutes les valeurs appropriées actif, $wp_queryy compris des choses comme $wp_query->is_homeet $wp_query->is_author, etc.

Une fois le parse_querycrochet de filtre exécuté, WordPress appellera get_posts()et chargera une liste de publications en fonction de ce qui est spécifié dans l'actif $wp_query. C’est donc parse_querysouvent un bon endroit pour que WordPress change d’avis sur les publications qu’il va charger.

Dans votre cas d'utilisation, nous souhaitons que WordPress filtre en fonction des entreprises sélectionnées. c.-à-d. pour afficher uniquement les annonces associées à l'entreprise sélectionnée (je dirais "... uniquement les annonces " classées " par l'entreprise sélectionnée" mais ce n'est pas techniquement correct; categoryc'est sa propre taxonomie sur les pairs avec businessexcept categoryest intégré à WordPress et businessest personnalisé. Mais pour ceux qui sont familiers avec la catégorisation des articles, cela peut vous aider à comprendre car ils fonctionnent presque à l'identique. Mais je m'éloigne du sujet ...)

Sur le code. La première chose que nous faisons est de récupérer une référence aux actifs actuellement $wp_query's query_varsafin qu'il soit plus facile de travailler avec, tout comme la façon dont le fait dans WordPress sa propre parse_query()fonction. Contrairement à $wp_query->queryce qui est utilisé pour refléter les paramètres passés sur l'URL, le $wp_query->query_varstableau est utilisé pour contrôler la requête que WordPress exécute et doit être modifiée. Donc, si vous devez en modifier un, ce serait celui-là (du moins, je pense que c'est différent entre les deux; si quelqu'un sait le contraire, merci de me le faire savoir afin que je puisse le mettre à jour!)

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

Ensuite, nous testons $pagenowpour nous assurer que nous chargeons effectivement WordPress à partir du chemin d’URL /wp-admin/edit.php. Nous faisons cela pour éviter de rater accidentellement des requêtes sur d'autres pages. Nous vérifions également que nous avons à la fois businessun taxonomyélément et un termélément. (Remarque taxonomyet termsont une paire; ils sont utilisés ensemble pour permettre l'interrogation d'un terme de taxonomie; il faut avoir les deux ou WordPress ne sait pas quelle taxonomie inspecter.)

Vous pourriez vous demander comment businessest apparu l' taxonomyélément du query_varstableau. Ce que nous avons écrit entre nos parse_querymains a déclenché la magie interne de WordPress qui a été mise en attente lorsque vous avez enregistré la businesstaxonomie " " en définissant query_varpour être vrai ( register_taxonomy()copie le nom de la taxonomie en tant que son query_var; vous pouvez le changer bien sûr, mais en cas de conflit il vaut mieux s'en tenir à la même chose):

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

Maintenant, WordPress '$ wp_query a été écrit pour utiliser des slugs pour les requêtes filtrées par taxonomie standard, pas pour les identificateurs de terme de taxonomie. Pour ce cas d’utilisation, voici ce dont nous avons vraiment besoin pour que notre requête de filtrage fonctionne:

taxonomy: entreprise

term: business-1 (c'est -à- dire le slug)

Pas ceux-ci:

taxonomy: entreprise

term: 27 (c'est à dire le term_id)

Chose intéressante et malheureusement, la liste déroulante générée par wp_dropdown_categories()l' attribut <option>'s est définie valuesur le terme (/ entreprise) term_id, et non sur le terme slug. Nous avons donc besoin de convertir $wp_query->query_vars['term']une term_idchaîne numérique en chaîne, slugcomme indiqué dans l'extrait extrait ci-dessus (notez que ce n'est pas le moyen le plus performant d'interroger une base de données, mais jusqu'à ce que WordPress ajoute le support pour term_ids dans sa requête, c'est ce que nous pouvons faire de mieux!) :

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

Et c'est tout! Avec ces deux fonctions, vous obtenez le filtrage que vous désirez.

MAIS ATTENDRE, IL Y A PLUS! :-)

Je suis allé de l'avant et j'ai ajouté une colonne "Entreprises" à votre liste car, eh bien, je savais que ce serait votre prochaine question. Sans avoir une colonne pour ce que vous filtrez, cela peut être très déroutant pour l'utilisateur final. (J'avais moi-même eu du mal avec cela, et j'étais le codeur!) Vous pouvez bien sûr déjà voir la colonne "Entreprises" dans les captures d'écran précédentes ci-dessus.

Étape # 3: Le manage_posts_columnscrochet de filtre.

Pour ajouter une colonne à la liste des publications, il faut appeler deux (2) autres hooks. Le premier est manage_posts_columnsla version spécifique au type de post manage_listing_posts_columnsque j'ai appelée à la place. Il accepte un paramètre ( posts_columns) et est appelé depuis /wp-admin/includes/template.php(dans la v3.0.1 cet appel est sur la ligne 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;
}

Votre manage_posts_columnsfonction hook reçoit un tableau de colonnes dont la valeur correspond à l'en-tête de colonne affiché et la clé à l'identificateur de colonne interne. Identificateurs de colonnes standard peuvent inclure ceux - ci et plus: 'cb', 'title' 'author', ``' date'`, etc.

'cb', est la checkboxcolonne et les deux 'title'et 'date'font référence à post_titleet post_datede la wp_poststable, respectivement. 'author'Bien sûr, c'est le post_authorchamp après que le nom de l'auteur est extrait de la wp_userstable.

Capture d'écran de la colonne "cb" posts sous forme de case à cocher.
(source: mikeschinkel.com )

Pour le manage_posts_columnshook, nous souhaitons simplement insérer notre colonne businessesdans le $posts_columnstableau auparavant 'author', en supposant qu'un autre plugin n'ait pas encore été supprimé authorde la liste!

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

( Notez que j'ai écrit add_businesses_column_to_listing_list()qu'il m'était venu à l'esprit que PHP devait disposer d'un moyen plus simple d'insérer une valeur dans un tableau associatif dans le bon ordre?!? laissez-moi donc aller avec ce qui a fonctionné. Si quelqu'un a des alternatives suggérées, je serai tout ouïe et reconnaissant à l’avance!)

Ce qui nous amène enfin à ...

Étape n ° 4: le manage_posts_custom_columncrochet d'action

La deuxième chose que nous devons faire pour que nos entreprises apparaissent dans la colonne est d’afficher le nom de chacune des entreprises associées à l’aide du manage_posts_custom_columncrochet d’action. Ce hook accepte deux (2) paramètres ( column_idet post_id) et est également appelé depuis /wp-admin/includes/template.php(cet appel est dans la v3.0.1 sur la ligne 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;
        }
    }
}

Ce hook est appelé pour chaque colonne pour chaque ligne post (/ business). Nous vérifions d’abord que nous ne travaillons effectivement qu’avec le listingtype de publication personnalisé, puis nous utilisons une switchinstruction pour tester le column_id. J'ai choisi switchparce que ce hook est souvent utilisé pour générer une sortie pour de nombreuses colonnes différentes, en particulier si nous utilisons une fonction pour plusieurs types de publication différents qui pourraient ressembler à ceci:

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

En examinant notre cas d'utilisation un peu plus près, vous voyez la get_the_terms()fonction qui renvoie simplement la liste des termes de cette taxonomie (c'est-à-dire les entreprises pour cette liste.) Ici, obtenez le lien permanent pour la page Web front-end du terme qui répertorie normalement les publications associées. avec le terme mais bien sûr pourrait différer selon le thème et / ou les plugins installés.

Nous utilisons le lien permanent pour créer un lien hypertexte simplement parce que j'aime bien créer des liens hypertextes. Nous fusionnons ensuite tous les termes hyperliens (/ entreprises), séparés par le caractère pipe (' |'), puis renvoyés dans le tampon PHP qui les envoie au navigateur / client HTTP de l'utilisateur:

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

Maintenant, nous avons enfin fini.

Sommaire

Donc, en résumé, vous devez utiliser les quatre (4) crochets suivants pour obtenir à la fois un filtre et une colonne associée dans la page de liste de messages personnalisée (Oh, cela fonctionnera également avec des messages et des pages.) Ils sont:

  • Étape 1: Le restrict_manage_postscrochet d’action.
  • Étape 2: Le parse_querycrochet du filtre.
  • Étape # 3: Le manage_posts_columnscrochet de filtre.
  • Étape n ° 4: le manage_posts_custom_columncrochet d'action

Où télécharger le code

Mais si je vous forçais à lire tout ce qui précède, je ne serais certainement pas une personne très gentille si je vous faisais aussi creuser le code pour pouvoir l'essayer! Mais contrairement à ce que certaines personnes disent, je suis gentil. Alors voilà:

NOTE à @tarasm : J'ai inclus des crochets pour aregister_post_type()etregister_taxonomy()pour que les autres puissent l'essayer sans avoir à les recréer. Vous voudrez probablement supprimer ces deux appels de fonction avant de le tester.

LA FIN


Réponse d'origine:

Bonjour @tarasm :

Cherchez-vous un menu déroulant en haut comme dans cet écran ou recherchez-vous un menu déroulant par enregistrement de publication et si tel était le cas, comment vous attendriez-vous que ce dernier fonctionne?

Comment créer la fonctionnalité Trier par pour un type de message personnalisé dans l'administrateur WordPress
(source: mikeschinkel.com )

Si c'est le cas, jetez un coup d'œil à cette réponse à la question Comment trier la zone d'administration d'un type de message personnalisé Wordpress par un champ personnalisé? Si c'est ce dont vous avez besoin, je peux fournir plus de détails sur la taxonomie.

Mike Schinkel
la source
Je cherche 1 liste déroulante en haut qui montrerait le filtre Catégories. Je me demandais s'il existait un moyen standard de le faire sans écrire de code personnalisé.
Taras Mankovski
À première vue, je ne pense pas que vous puissiez faire sans code personnalisé, mais je ne pense pas que le code personnalisé sera significatif. J'ai un appel à préparer pour le client, donc il faudra le faire plus tard aujourd'hui.
MikeSchinkel
2
En fait, les deux solutions (somatic et MikeSchinkel) ne fonctionnent pas lorsque vous essayez de filtrer 2 taxonomies différentes dans le même filtre: - / Toujours filtrer la dernière taxonomie lorsque vous essayez de filtrer 2+ en même temps.
Ünsal Korkmaz
1
@ Ünsal La version actuelle de WordPress (3.0) ne prend pas en charge plusieurs requêtes Taxonomy, mais d'après ce que j'ai entendu dire, cela changera avec la version 3.1. Pour que cet exemple fonctionne avec plusieurs taxonomies, vous devez ajouter des jointures à la requête via les crochets de filtre Posts_join et posts_where.
Manny Fleurmond
1
Dans WP 3.1+, les étapes un et deux sont meilleures dans la réponse @ drew-gourley (en fait, votre étape 2 n'a pas fonctionné pour moi, je pense qu'il y a des changements dans ce filtrage dans le nouveau WordPress).
Tomasz Struczyński
44

Je voulais juste partager une implémentation alternative. Le tutoriel incroyable de Mike ne m'avait pas été fourni lorsque j'ai découvert cela, alors ma solution est un peu différente. Plus précisément, je vais simplifier l’ étape 1 de Mike et éliminer l’ étape 2 - les autres étapes sont toujours applicables.

Dans le tutoriel de Mike, l’utilisation de cette méthode wp_dropdown_categories()enregistre une construction de liste manuelle, mais nécessite quelques modifications compliquées dans les requêtes conditionnelles ( étape 2 ) pour gérer son utilisation de l’ID au lieu de slug. Sans parler de la difficulté de modifier ce code pour traiter d'autres scénarios, tels que les filtres de taxonomie multiples.

Une autre approche consiste simplement à ne pas utiliser du tout les défauts wp_dropdown_categories(), mais à créer notre propre liste de sélection à partir de zéro. Ce n'est pas si compliqué, ça prend moins de 30 lignes de code, et ça ne nécessite aucun accrochage 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>";
        }
    }
}

En connectant simplement les taxonomies souhaitées au $filterstableau, vous pouvez générer rapidement plusieurs filtres de taxonomie. Ils apparaissent exactement les mêmes que ceux des captures d'écran de Mike. Ensuite, vous pourrez suivre les étapes 3 et 4 .

somatique
la source
4
@somatic - Belle mise à jour! Oui, l’utilisation de wp_dropdown_categories()ce logiciel nécessite de nombreuses solutions de contournement. J'essaie de m'en tenir aux fonctions principales lorsque cela est possible, mais comme vous le soulignez, cela demande parfois plus de travail. Cela prouve qu’avec WordPress, il existe souvent plus d’un bon moyen de résoudre un problème. Bon travail!
MikeSchinkel
Vient de cesser de travailler pour moi sur WordPress 3.1. Essayer de comprendre ce qui a changé exactement. Il semble que cela devrait encore fonctionner: la taxonomie et les slugs apparaissent comme des valeurs GET dans l'URL, mais le résultat
obtenu
J'ai essayé de faire en sorte que cela fonctionne, mais la seule façon dont je pouvais utiliser était d'utiliser le hook parse_query, de rechercher la variable var de la taxonomie et de définir la taxonomie et les variables de requête de termes en fonction. Utiliser WP 3.1. La taxonomie et le terme doivent-ils apparaître dans l'URL lors de la soumission du filtre?
Sanchothefat
2
Fonctionne comme un charme pour moi! Solution très élégante en effet. Je te dois une bière :)
Michal Mau
@somatic Cela fonctionne très bien, mais y a-t-il moyen de faire en sorte que $ term-> count ne compte que les termes de ce type de message? Par exemple, si j'ai une taxonomie personnalisée pour les photos et les vidéos, elle apparaîtra lorsque vous regardez les vidéos personnalisées, tapez le nombre total de publications pour ce terme dans les deux types de publications personnalisées au lieu du nombre total de publications vidéo qui utilisent cette publication. terme.
Greenhoe
13

Voici une version de this qui crée et applique automatiquement des filtres de toutes les taxonomies qui s'appliquent à tous les types de publication personnalisés qui les utilisent. Quoi qu'il en soit, je l'ai aussi modifié pour qu'il fonctionne avec wp_dropdown_categories () et wordpress 3.1. Le projet sur lequel je travaille s'appelle ToDo. Vous pouvez renommer les fonctions pour créer quelque chose de logique, mais cela devrait fonctionner automatiquement pour tout.

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

Notez que j'utilise un plugin qui ajoute 'term_order' comme moyen de commander des termes. Vous devrez changer cela ou supprimer cet argument pour revenir à la valeur par défaut.

Drew Gourley
la source
très sexy en effet. Je recevais des avis d'erreur, donc j'ai changé si (isset ($ var)) en if (isset ($ var) && $ var> 0) pour éviter d'essayer de trouver des termes associés à la valeur Tout afficher de 0. oh, et je devais retourner $ query dans la fonction
todo_convert_restrict
11

Réponse tardive

Modifier

J'ai écrit Filterama , un plugin qui ajoutera cette fonctionnalité de la manière la plus simple possible.

Mise à jour pour WordPress 3.5+

Maintenant que les choses sont beaucoup plus simples , voici une solution très simple: plugin ou mu-plugin.

Il utilise le moins de ressources possible, ne se charge que sur les écrans nécessaires et ajoute Colonnes + Filtres pour chaque taxonomie personnalisée.

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

    }

}

Et puis vous avez juste besoin d'une classe de Walker personnalisée.

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})"
                : ''
        );
    }
}
kaiser
la source
Cela a tourné, mais la méthode get_select () semble être manquante.
Dave Romsey
@ goto10 Tu avais raison. Mis à jour. Btw: Il est plus facile de simplement récupérer le plugin lié. Il sera disponible dans le référentiel du plugin dans une ou deux semaines. (Déjà confirmé).
Kaiser
Je devais utiliser $this->setup_vars();au début de public function setup()pour avoir le "manage_taxonomies_for_{$this->post_type}_columns"travail
Christian le
Mais c'est peut-être parce que je l'utilise dans un thème function.php avecadd_action( 'init', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
Christian
@Christian Ce n'est pas un thème. Cela appartient à un plugin et comme le code ci-dessus le supporte, il est chargé bien avant que les thèmes ne soient chargés.
Kaiser
7

Je voulais juste faire une note rapide. Sur les versions plus récentes de WP, les publications ultérieures sur admin sont gérées par la classe WP_Posts_List_Table. Le code apply_filters est maintenant comme suit:

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

Donc, pour ajouter de nouvelles colonnes, un hook add_filter devrait ressembler à ceci:

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

Voici un exemple:

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

Maintenant, pour les lignes de poste. C'est le code qui gère les données de colonne sur les listes:

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

Afin de récupérer nos données de publication, nous devons ajouter un hook d’action comme celui-ci:

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

Exemple (cet exemple utilise des taxonomies, mais vous pouvez interroger tout autre élément):

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;
  }
}
les mines
la source
7

TRAVAUX DANS WP 3.2!

custom_post_type: books custom_taxonomy: genre

Seulement modifier où il est dit: // change ICI

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

add_action('restrict_manage_posts', 'restrict_books_by_genre');


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

add_filter('parse_query', 'convert_id_to_term_in_query');
Lacroixca
la source
C'est une solution simple et intéressante pour WP 3.2+.
petermolnar
cela fonctionne mais __("Show All {$info_taxonomy->label}")c’est une mauvaise façon d’utiliser des chaînes traduisibles.
Mark Kaplun
2

Voici un moyen de le faire en utilisant l'action restrict_manage_posts. Cela semble bien fonctionner pour moi et ajoute la possibilité de filtrer par taxonomie pour tous les types de publication et les taxonomies associées.

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

Une remarque - j'ai essayé de restreindre la profondeur parce que certaines de mes taxonomies hiérarchiques sont assez grandes mais cela n'a pas fonctionné - cela pourrait être un bug dans la fonction wp_dropdown_categories?

Brad Trivers
la source
2

Je suppose que ce n’est pas très connu, mais à partir de wordpress 3.5, vous pouvez passer 'show_admin_column' => trueà register_taxonomy. Cela fait 2 choses:

  1. Ajoute la colonne de taxonomie à la vue liste des types de publications de l'administrateur
  2. En cliquant sur le nom du terme dans la colonne taxonomie, il filtrera la liste en fonction de ce terme .

Donc, pas exactement la même chose que d'avoir une sélection, mais presque la même fonctionnalité, ne largeur qu'une ligne de code.

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

En outre, comme vous pouvez le lire, un nouveau filtre est conçu pour l’ajout manuel de la colonne de taxonomie (si vous en avez vraiment besoin).

Luca Reghellin
la source
1

Version hiérarchique de la réponse de @ somatic, à la demande de @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);
    }

}
?>

J'ai essentiellement supprimé le code qui a créé les options et l'ai mis dans sa propre fonction. La fonction 'generate_taxonomy_options', en plus de prendre le tax_slug, prend également un paramètre parent et un niveau. La fonction suppose que ses options de création pour le parent 0, qui sélectionnera tous les termes de niveau racine. Dans la boucle, la fonction s’appellera de manière récursive en utilisant le terme actuel comme parent et en augmentant le niveau de un. Il ajoute automatiquement des tiques sur le côté au plus profond de l'arbre et le tour est joué!

Manny Fleurmond
la source
1

Mise à jour de la réponse de @Drew Gourley pour le WP 3.3.1 (et incorporation du code provenant de http://wordpress.org/support/topic/wp_dropdown_categories-generating-url-id-number-instead-of-slug?replies=6#post- 2529115 ):

add_action('restrict_manage_posts', 'xyz_restrict_manage_posts');
function xyz_restrict_manage_posts() {
    global $typenow;

    $args = array('public'=>true, '_builtin'=>false); 
    $post_types = get_post_types($args);

    if(in_array($typenow, $post_types)) {
        $filters = get_object_taxonomies($typenow);

        foreach ($filters as $tax_slug) {
            $tax_obj = get_taxonomy($tax_slug);
            $term = get_term_by('slug', $_GET[$tax_obj->query_var], $tax_slug);

            wp_dropdown_categories(array(
                'show_option_all' => __('Show All '.$tax_obj->label ),
                'taxonomy' => $tax_slug,
                'name' => $tax_obj->name,
                'orderby' => 'term_order',
                'selected' => $term->term_id,
                'hierarchical' => $tax_obj->hierarchical,
                'show_count' => false,
                // 'hide_empty' => true,
                'hide_empty' => false,
                'walker' => new DropdownSlugWalker()
            ));
        }
    }
}


//Dropdown filter class.  Used with wp_dropdown_categories() to cause the resulting dropdown to use term slugs instead of ids.
class DropdownSlugWalker extends Walker_CategoryDropdown {

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

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

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

        $output .= '>';
        $output .= $pad.$cat_name;
        $output .= "</option>\n";
    }
}
rinogo
la source
0

Toutes mes excuses pour le fait qu'en tant que nouvel utilisateur, je ne peux pas poster de commentaires, mais je peux poster une réponse ...

À partir de WordPress 3.1 (RC 1), la réponse de Mike (qui me sert si bien depuis quelques mois) ne fonctionne plus pour moi; restreindre par une taxonomie enfant donne un résultat vide. J'ai essayé la mise à jour de Somatic et cela a très bien fonctionné. Mieux encore, il fonctionne avec plusieurs requêtes de taxonomie qui ont été intégrées à cette version.


la source
Pour une raison quelconque, la version de
somatic
0

J'ai juste essayé les deux codes, de Mike et somatic, et je me demandais comment obtenir une chose de chaque technique:

Avec le code de Mike, il affiche la liste déroulante avec la hiérarchique option, qui aide beaucoup. Mais pour afficher deux listes déroulantes, je devais dupliquer la if ($typenow=='produtos') {...}déclaration dans la fonction restrict_listings_by_business()et également if ($pagenow=='edit.php' && ... }dans la convert_business_id_to_taxonomy_term_in_query($query)fonction qui donne maintenant beaucoup de code.

Avec le code de somatic, il me suffit de spécifier les taxonomies que j'aimerais voir comme listes déroulantes et bam, fonctionne; $filters = array('taxo1', 'taxo2');

Question: est-ce que je peux avoir l’approche de somatic et aussi avoir l’ option hiérarchique ?

Merci quand même pour ce tutoriel, beaucoup aidé!

Kevin
la source
Voir ma réponse pour une solution hiérarchique
Manny Fleurmond
0

Le tutoriel de Mike à ce sujet est génial! Je n'aurais probablement pas pris la peine d'ajouter cette fonctionnalité à mon plugin Media Categories si j'avais dû le découvrir moi-même.

Cela dit, je pense en utilisant parse_query et ensuite obtenir une requête pour le terme n’est pas nécessaire. C'est plus propre pour créer votre propre classe de marcheur personnalisée. Peut-être que ce n'était pas possible quand il a écrit son post - il a 3 ans au moment d'écrire ceci.

Commander ce super extrait sur github. Fonctionne comme un charme, change les identifiants des valeurs de liste déroulante en slugs, de sorte que cela fonctionne simplement en natif sans modifier la requête.

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

Eddiemoya
la source