Hinzufügen eines Taxonomiefilters zur Admin-Liste für einen benutzerdefinierten Beitragstyp?


129

Ich habe einen benutzerdefinierten Beitragstyp mit dem Namen erstellt 'listing'und eine benutzerdefinierte Taxonomie mit dem Namen hinzugefügt 'businesses'. Ich möchte der Admin-Liste für die Listings eine Dropdown-Liste mit Unternehmen hinzufügen.

So sieht diese Funktionalität in der Admin-Liste für Posts aus (ich möchte dasselbe für meinen benutzerdefinierten Post-Typ):

Kategorien Dropdown in Beiträgen

Hier ist mein aktueller Code ( und hier ist derselbe Code auf 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();
}

Wie kann ich der Admin-Liste für die Listings eine Dropdown-Liste mit Unternehmen hinzufügen?


8
Danke für den Screenshot, es hilft wirklich , diese zu haben.
MikeSchinkel

Es gibt einen Plugin- Taxonomiefilter für Administratoren , der die genauen Aufgaben erledigt.
Anh Tran

Antworten:


140

UPDATE: Ich habe eine neue vollständige Antwort eingefügt, aber trotzdem habe ich meine ursprüngliche Antwort unten hinterlassen, auf die sich die ersten Kommentare beziehen.


Hallo @tarasm :

Obwohl ich sagte, dass es nicht schwer sein sollte, ist es ein wenig involviert. Aber bevor wir uns mit dem Code befassen ...

Die Screenshots:

... sehen wir uns ein paar Screenshots zum fertigen Produkt an:

Listings Listenseite ohne Filterung:

Listings Listenseite ohne Filterung
(Quelle: mikeschinkel.com )

Listings Listenseite mit Filterung:

Listings Listenseite mit Filterung
(Quelle: mikeschinkel.com )

Der Code

Also los geht's ... ( Hinweis: Ich habe eine Singularform für den Taxonomienamen von verwendet business. Ich hoffe, dass sie zu Ihrer passt. Aufgrund der langjährigen Erfahrung sowohl mit WordPress als auch mit der Datenbankentwicklung halte ich es für das Beste, dies auf diese Weise zu tun .)

Schritt 1: Der restrict_manage_postsAktionshaken.

Als Erstes müssen Sie die restrict_manage_postsAktion /wp-admin/edit.phpeinbinden, die keine Parameter hat und von der aus aufgerufen wird (in Version 3.0.1 befindet sich dieser Aufruf in Zeile 378). Auf diese Weise können Sie die Dropdown-Auswahl an der entsprechenden Stelle über der Liste von generieren Beiträge auflisten.

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

Wir beginnen damit, die $typenowVariable zu überprüfen , um sicherzustellen, dass wir tatsächlich auf einem post_typevon sind listing. Wenn Sie dies nicht tun, wird dieses Dropdown-Menü für alle Beitragstypen angezeigt. In einigen Fällen ist dies das, was Sie möchten, in diesem Fall jedoch nicht.

Als nächstes laden wir Informationen über die Geschäftstaxonomie mit get_taxonomy(). Wir brauchen es, um das Label für die Taxonomie abzurufen (dh " Unternehmen "; wir hätten es hart codieren können, aber das ist nicht sehr gut, wenn Sie es später internationalisieren müssen.) Dann rufen wir wp_dropdown_categories()alle entsprechenden Argumente im $argsArray auf, um das zu generieren Dropdown-Liste

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

Aber was sind die passenden Argumente? Schauen wir uns jedes einzeln an:

  • show_optional_all- Ganz einfach, es ist das, was zuerst in der Dropdown-Liste angezeigt wird und wenn keine Filterung angewendet wurde. In unserem Fall ist es "Show All Businesses ", aber wir hätten es auch "Listings for All Businesses" oder was auch immer Sie wollen nennen können.

  • taxonomy- Dieses Argument teilt der Funktion mit, aus welcher Taxonomie Terme abgerufen werden sollen, obwohl die Funktion categoriesim Namen enthalten ist. In v2.8 und früheren Versionen hatte WordPress keine benutzerdefinierten Taxonomien, aber als sie hinzugefügt wurden, entschied das Team, dass es einfacher sein würde, dieser Funktion ein Taxonomieargument hinzuzufügen, als eine andere Funktion mit einem anderen Namen zu erstellen.

  • name- Mit diesem Argument können Sie den Wert angeben, den WordPress für das nameAttribut des <select> -Elements verwendet, das für die Dropdown-Liste generiert wurde. Nur für den Fall, dass es nicht offensichtlich ist, ist dies auch der Wert, der bei der Filterung in der URL verwendet wird.

  • orderby- Dieses Argument teilt WordPress mit, wie die Ergebnisse alphabetisch sortiert werden sollen. In unserem Fall haben wir angegeben, namedie Begriffe in der Taxonomie zu bestellen , dh die Firmennamen in diesem Fall.

  • selected- Dieses Argument wird benötigt, damit das Dropdown-Menü den aktuellen Filter im Dropdown-Menü anzeigt. Es sollte der term_idvon der gewählten Taxonomie abgeleitete Begriff sein. In unserem Fall könnte es das term_idvon "Business # 2" sein . Woher bekommen wir diesen Wert? Aus der globalen Variablen von WordPress $wp_query; Es hat eine Eigenschaft query, die ein Array aller URL-Parameter und ihrer Werte enthält (es sei denn, ein eigenwilliges Plugin hat es bereits geändert). Wenn WordPress die Dinge verarbeitet, wird ein termURL-Parameter an die URL übergeben, wenn der Benutzer auf den Filter klickt Schaltfläche, wenn der Benutzer einen gültigen Begriff ausgewählt hat (dh eines der aufgelisteten Unternehmen).

  • hierarchical- Indem trueSie diese Option auf setzen, weisen Sie die Funktion an, die hierarchische Struktur der Taxonomie zu berücksichtigen und diese in einer Baumansicht anzuzeigen, wenn die Begriffe (Unternehmen) tatsächlich untergeordnet sind. Unten sehen Sie einen Screenshot, um zu sehen, wie dies aussieht.

  • depth- Dieses Argument arbeitet mit dem hierarchicalArgument zusammen, um zu bestimmen, in wie vielen Ebenen die Funktion untergeordnete Elemente anzeigen soll.

  • show_count- Wenn truedieses Argument eine Anzahl von Einträgen in Klammern links vom Termnamen in der Dropdown-Liste anzeigt. In diesem Fall wird die Anzahl der mit einem Unternehmen verknüpften Einträge angezeigt. Unten sehen Sie einen Screenshot, um zu sehen, wie dies aussieht.

  • hide_empty- Wenn es in der Taxonomie schließlich Begriffe gibt, die keinem Eintrag zugeordnet sind (dh Unternehmen, die keinem Eintrag zugeordnet sind), truewerden sie nicht in die Dropdown- Liste aufgenommen , wenn diese Einstellung auf gesetzt wird.

Taxonomie Dropdown sollte Hierarchie und zählt
(Quelle: mikeschinkel.com )

Schritt 2: Der parse_queryFilterhaken.

Als nächstes wenden wir uns dem parse_queryFilter-Hook zu, der einen Parameter ( $query) hat und von /wp-includes/query.php(in Version 3.0.1 ist dieser Aufruf in Zeile 1549) aufgerufen wird. Er wird aufgerufen, wenn WordPress die URL überprüft und alle entsprechenden Werte in der aktuellen Version festgelegt hat aktiv, $wp_queryeinschließlich Dinge wie $wp_query->is_homeund $wp_query->is_authorusw.

Nachdem der parse_queryFilter-Hook ausgeführt wurde, ruft WordPress get_posts()eine Liste mit Beiträgen auf, die auf den Angaben in der aktuell aktiven Liste basieren $wp_query. Daher parse_queryist es oft ein großartiger Ort, um WordPress dazu zu bringen, seine Meinung darüber zu ändern, welche Beiträge geladen werden sollen.

In Ihrem Anwendungsfall möchten wir WordPress dazu bringen, basierend auf den ausgewählten Unternehmen zu filtern. Das heißt, nur die Listings anzuzeigen, die mit dem ausgewählten Unternehmen verknüpft sind (ich würde sagen "... nur die Listings, die vom ausgewählten Unternehmen" kategorisiert " wurden", aber das ist technisch nicht korrekt; categoryes ist eine eigene Taxonomie auf Peer-Basis mit businessAusnahme dessen, dass categoryes in WordPress integriert und businessbenutzerdefiniert ist. Aber für diejenigen, die mit dem Kategorisieren von Posts vertraut sind, kann dies hilfreich sein, da sie fast identisch funktionieren. Aber ich schweife ab ...)

Weiter zum Code. Das erste, was wir tun, ist, einen Verweis auf die aktuell aktiven zu nehmen $wp_query, query_varsdamit es bequemer ist, damit zu arbeiten, genauso wie es in der eigenen parse_query()Funktion von WordPress gemacht wird . Im Gegensatz $wp_query->queryzu den Parametern, die zur Spiegelung der übergebenen URLs verwendet werden, wird das $wp_query->query_varsArray zur Steuerung der Abfrage verwendet, die von WordPress ausgeführt wird und die voraussichtlich geändert wird. Wenn Sie also einen ändern müssen, ist dies der eine (zumindest denke ich , dass dies der Unterschied zwischen den beiden ist; wenn jemand etwas anderes weiß , lassen Sie es mich bitte wissen, damit ich dies aktualisieren kann!)

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

Als nächstes testen wir, um $pagenowsicherzustellen, dass wir WordPress tatsächlich vom URL-Pfad laden /wp-admin/edit.php. Wir tun dies, um zu verhindern, dass versehentlich Anfragen auf anderen Seiten vermasselt werden. Wir prüfen auch, ob wir sowohl businessein taxonomyElement als auch ein termElement haben. (Beachten Sie taxonomyund termsind ein Paar; sie werden zusammen verwendet, um die Abfrage eines Taxonomiebegriffs zu ermöglichen. Muss beides enthalten, oder WordPress weiß nicht, welche Taxonomie überprüft werden soll.)

Sie fragen businesssich vielleicht, wie das taxonomyElement des query_varsArrays auftaucht . Was wir in unseren parse_queryHook geschrieben haben, löste die interne Magie von WordPress aus, die darauf wartete, als Sie die businessTaxonomie " " query_varals wahr registrierten ( register_taxonomy()kopiert den Namen der Taxonomie als " " query_var; Sie können ihn natürlich ändern, es sei denn, Sie haben einen Konflikt es ist am besten, bei dem gleichen zu bleiben):

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

Jetzt wurde WordPress '$ wp_query so geschrieben, dass Slugs für standardmäßige taxonomie-gefilterte Abfragen verwendet werden, nicht für Taxonomiebegriffs-IDs. Für diesen Anwendungsfall benötigen wir die folgenden Elemente, damit unsere Filterabfrage funktioniert:

taxonomy: business

term: business-1 (dh die slug)

Nicht diese:

taxonomy: business

term: 27 (dh die term_id)

Interessanterweise und leider das Dropdown-Menü, das durch wp_dropdown_categories()Setzen des Attributs <option>'s' valueauf den Begriff (/ business ') term_idund nicht auf den Begriff generiert wird slug. Wir müssen also $wp_query->query_vars['term']von einem numerischen term_idin einen String konvertieren, slugwie im oben abgebildeten Snippet beschrieben. :

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

Und das ist es! Mit diesen beiden Funktionen erhalten Sie die gewünschte Filterung.

ABER WARTEN, ES GIBT MEHR! :-)

Ich habe eine Spalte "Unternehmen" zu Ihrer Auflistungsliste hinzugefügt, da ich wusste, dass dies Ihre nächste Frage sein würde. Ohne eine Spalte für das, was Sie filtern, kann dies für den Endbenutzer sehr verwirrend sein. (Ich habe selbst damit gekämpft, und ich war der Kodierer!) Sie können die Spalte "Unternehmen" in den vorherigen Screenshots oben natürlich bereits sehen .

Schritt 3: Der manage_posts_columnsFilterhaken.

Um der Beitragsliste eine Spalte hinzuzufügen, müssen zwei (2) weitere Hooks aufgerufen werden. Die erste ist manage_posts_columnsoder die posttypspezifische Version manage_listing_posts_columns, die ich stattdessen aufgerufen habe. Es akzeptiert einen Parameter ( posts_columns) und wird von /wp-admin/includes/template.php(in Version 3.0.1 ist dieser Aufruf in Zeile 623) aufgerufen :

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

Ihre manage_posts_columnsHook-Funktion erhält ein Array von Spalten, wobei der Wert die angezeigte Spaltenüberschrift und der Schlüssel die interne Spaltenkennung ist. Standardspalten -IDs können Folgendes und mehr enthalten: " 'cb', 'title", 'author'"Datum" usw.

'cb', ist die checkboxSpalte und beides 'title'und 'date'bezieht sich auf post_titlebzw. post_dateaus der wp_postsTabelle. 'author'Natürlich ist das post_authorFeld, nachdem der Autorenname aus der wp_usersTabelle abgerufen wurde .

Screenshot der Spalte "cb" posts als Kontrollkästchen.
(Quelle: mikeschinkel.com )

Für den manage_posts_columnsHook wollen wir einfach unsere Spalte vorher businessesin das $posts_columnsArray einfügen 'author', vorausgesetzt, ein anderes Plugin wurde noch nicht authoraus der Liste entfernt!

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

( Beachten Sie, wie ich geschrieben add_businesses_column_to_listing_list()habe, dass PHP eine einfachere Möglichkeit haben muss , einen Wert in der richtigen Reihenfolge in ein assoziatives Array einzufügen?!? Oder zumindest muss es eine Funktion in WordPress Core geben, um dies zu tun? Aber seit Google lass mich runter damit ich weiter mache was geklappt hat. Wenn jemand Alternativen vorschlägt, bin ich im Voraus sehr dankbar und dankbar!)

Was uns endlich dazu bringt ...

Schritt 4: Der manage_posts_custom_columnAktionshaken

Das zweite von zwei (2) manage_posts_custom_columnSchritten, die wir ausführen müssen, um unsere Unternehmen in der Spalte anzuzeigen, besteht darin, den Namen jedes zugeordneten Unternehmens mithilfe des Aktions-Hooks auszugeben . Dieser Hook akzeptiert zwei (2) Parameter ( column_idund post_id) und wird auch von /wp-admin/includes/template.php(in Version 3.0.1 ist dieser Aufruf in Zeile 1459) aufgerufen :

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

Dieser Hook wird für jede Spalte für jede Post (/ business) -Zeile aufgerufen. Wir überprüfen zunächst, ob wir tatsächlich nur mit dem listingbenutzerdefinierten Beitragstyp arbeiten, und verwenden dann eine switchAnweisung zum Testen des column_id. Ich habe gewählt, switchweil dieser Hook oft verwendet wird, um Ausgaben für viele verschiedene Spalten zu generieren, besonders wenn wir eine Funktion für viele verschiedene Post-Typen verwenden, die ungefähr so ​​aussehen könnten:

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

Wenn Sie unseren Anwendungsfall etwas näher betrachten, sehen Sie die get_the_terms()Funktion, die einfach die Liste der Begriffe für diese Taxonomie zurückgibt (dh Unternehmen für diese Auflistung). Hier erhalten Sie den Permalink für die Front-End-Webseite des Begriffs, auf der normalerweise Beiträge aufgelistet sind, die zugeordnet sind mit dem begriff könnte das aber natürlich je nach thema und / oder installierten plugins unterschiedlich sein.

Wir verwenden den Permalink, um den Begriff zu verlinken, nur weil ich Dinge gerne verlinke. Wir führen dann alle mit Hyperlinks versehenen Begriffe (/ Unternehmen) getrennt mit dem Pipe- |Zeichen (' ') zusammen und geben sie in den PHP-Puffer aus, der sie an den Browser / HTTP-Client des Benutzers sendet:

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

JETZT sind wir endlich fertig.

Zusammenfassung

Zusammenfassend müssen Sie also die folgenden vier (4) Hooks verwenden, um sowohl einen Filter als auch eine verwandte Spalte auf der Seite mit der benutzerdefinierten Beitragsliste abzurufen. (Oh, das funktioniert auch mit Beiträgen und Seiten.) Dies sind:

  • Schritt 1: Der restrict_manage_postsAktionshaken.
  • Schritt 2: Der parse_queryFilterhaken.
  • Schritt 3: Der manage_posts_columnsFilterhaken.
  • Schritt 4: Der manage_posts_custom_columnAktionshaken

Wo kann der Code heruntergeladen werden?

Aber wenn ich Sie gezwungen hätte, alles oben Genannte durchzulesen, wäre ich mit Sicherheit keine sehr nette Person, wenn ich Sie auch dazu gebracht hätte, den Code auszuprobieren, nur um ihn ausprobieren zu können! Aber im Gegensatz zu dem, was manche Leute sagen, bin ich nett. Also los geht's:

HINWEIS @tarasm : Ich enthalten Haken für einregister_post_type()undregister_taxonomy()damit andere diese versuchen könnten, ohne sie neu erstellenmüssen. Sie werden diese beiden Funktionsaufrufe wahrscheinlich löschen wollen, bevor Sie dies testen.

DAS ENDE


Ursprüngliche Antwort:

Hallo @tarasm :

Suchen Sie nach einem Dropdown-Menü oben wie diesem Bildschirm oder suchen Sie nach einem Dropdown-Menü pro Beitragsaufzeichnung und wenn ja, wie würden Sie davon ausgehen, dass Letzteres funktioniert?

So erstellen Sie eine Sortierfunktion für einen benutzerdefinierten Beitragstyp in WordPress Admin
(Quelle: mikeschinkel.com )

Wenn dies der Fall ist, sehen Sie sich diese Antwort auf die Frage an, wie Sie den Administrationsbereich eines benutzerdefinierten Wordpress-Beitragstyps nach einem benutzerdefinierten Feld sortieren können. Wenn es das ist, was Sie brauchen, kann ich weitere Einzelheiten zur Taxonomie liefern.


Ich suche nach einer Dropdown-Liste oben, in der der Filter "Kategorien" angezeigt wird. Ich war gespannt, ob es eine Standardmethode dafür gibt, ohne benutzerdefinierten Code schreiben zu müssen.
Taras Mankovski

Anfangs glaube ich nicht, dass Sie ohne benutzerdefinierten Code arbeiten können, aber dann glaube ich nicht, dass der benutzerdefinierte Code von Bedeutung sein wird. Ich muss mich auf einen Kundenanruf vorbereiten, also muss es heute später sein.
MikeSchinkel

2
Tatsächlich funktionieren beide Lösungen (somatic und MikeSchinkel) nicht, wenn Sie versuchen, 2 verschiedene Taxonomien im selben Filter zu filtern: - / Immer die neueste Taxonomie zu filtern, wenn Sie versuchen, 2+ gleichzeitig zu filtern.
Ünsal Korkmaz

1
@ Ünsal Die aktuelle Version von WordPress (3.0) unterstützt nicht mehrere Taxonomie-Abfragen, aber was ich gehört habe, wird sich mit Version 3.1 ändern. Damit dieses Beispiel mit mehreren Taxonomien funktioniert, müssen Sie der Abfrage über die Filter-Hooks Posts_join und posts_where einige Joins und Wheres hinzufügen.
Manny Fleurmond

1
In WP 3.1+ sind die Schritte eins und zwei in @ drew-gourley answer besser (tatsächlich hat Ihr Schritt 2 bei mir nicht funktioniert, ich denke, es gibt Änderungen bei dieser Filterung in neuem WordPress).
Tomasz Struczyński

44

Ich wollte nur eine alternative Implementierung teilen. Ich hatte Mikes unglaubliches Tutorial nicht, als ich das herausgefunden habe, also ist meine Lösung etwas anders. Insbesondere werde ich Mikes Schritt Nr. 1 vereinfachen und Schritt Nr. 2 eliminieren - die anderen Schritte sind immer noch anwendbar.

In Mikes Tutorial wp_dropdown_categories()erspart uns die Verwendung einige manuelle Listenerstellung, erfordert jedoch einige komplizierte Änderungen an bedingten Abfragen ( Schritt 2 ), um die Verwendung von ID anstelle von Slug zu handhaben. Ganz zu schweigen von der Schwierigkeit, diesen Code zu ändern, um mit anderen Szenarien wie mehreren Taxonomiefiltern fertig zu werden.

Ein anderer Ansatz besteht darin, die fehlerhaften wp_dropdown_categories()überhaupt nicht zu verwenden , sondern unsere eigenen Dropdown-Auswahllisten von Grund auf neu zu erstellen. Es ist nicht so kompliziert, benötigt weniger als 30 Codezeilen und erfordert kein Hooking 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>";
        }
    }
}

Durch einfaches Einfügen der gewünschten Taxonomien in das $filtersArray können Sie schnell mehrere Taxonomiefilter ausgeben. Sie sehen genauso aus wie in Mikes Screenshots. Anschließend können Sie mit Schritt 3 und 4 fortfahren .


4
@somatic - Nettes Update! Ja, die Verwendung wp_dropdown_categories()erfordert viele Problemumgehungen. Ich versuche, wenn möglich bei den Kernfunktionen zu bleiben, aber wie Sie hervorheben, erfordert dies manchmal mehr Arbeit. Nur um zu beweisen, dass es mit WordPress oft mehr als einen guten Weg gibt, ein Problem zu lösen. Gut gemacht!
MikeSchinkel

Hört einfach auf, für mich an WordPress 3.1 zu arbeiten. Ich versuche herauszufinden, was sich genau geändert hat. Es sieht so aus, als ob es immer noch funktionieren sollte: Die Taxonomie und die Term-Slugs werden als GET-Werte in der URL
angezeigt

Ich habe versucht, dies zum Laufen zu bringen, aber die einzige Möglichkeit bestand darin, den parse_query-Hook zu verwenden, die Abfragevariable der Taxonomie zu überprüfen und die Taxonomie- und Termabfragevariablen darauf basierend festzulegen. Verwenden von WP 3.1. Sollte Taxonomie und Begriff in der URL erscheinen, wenn der Filter gesendet wird?
sanchothefat

2
Funktioniert wie ein Zauber für mich! Sehr elegante Lösung. Ich schulde dir ein Bier :)
Michal Mau

@somatic Das funktioniert prima, aber gibt es eine Möglichkeit, dass $ term-> count nur die Begriffe für diesen Beitragstyp zählt? Wenn ich zum Beispiel eine benutzerdefinierte Taxonomie für Fotos und Videos habe, wird mir beim Betrachten des benutzerdefinierten Beitragstyps des Videos die Gesamtzahl der Beiträge für diesen Begriff aus beiden benutzerdefinierten Beitragstypen angezeigt, anstatt nur die Gesamtzahl der Videobeiträge, die diesen verwenden Begriff.
Greenhoe

13

In der folgenden Version werden automatisch Filter aus allen Taxonomien erstellt und angewendet, die für alle benutzerdefinierten Beitragstypen gelten, die diese verwenden. (was für ein Schluck) Wie auch immer, ich habe es auch so optimiert, dass es mit wp_dropdown_categories () und WordPress 3.1 funktioniert. Das Projekt, an dem ich arbeite, heißt ToDo. Sie können die Funktionen in etwas umbenennen, das für Sie sinnvoll ist, aber dies sollte für alles automatisch funktionieren.

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

Beachten Sie, dass ich ein Plugin verwende, das 'term_order' als Methode zum Ordnen von Begriffen hinzufügt. Sie müssen dies ändern oder das Argument entfernen, um auf die Standardeinstellung zurückzugreifen.


sehr sexy in der Tat. Ich habe Fehlermeldungen erhalten, daher habe ich if (isset ($ var)) in if (isset ($ var) && $ var> 0) geändert, um nicht zu versuchen, Begriffe zu finden, die mit dem Wert 0 von Alle anzeigen verknüpft sind. oh, und ich musste $ query in der Funktion
todo_convert_restrict zurückgeben

11

Späte Antwort

Bearbeiten

Ich habe Filterama geschrieben , ein Plugin, das diese Funktionalität auf einfachste Weise hinzufügt.

Update für WordPress 3.5+

Jetzt, da die Dinge viel einfacher sind, gibt es hier eine sehr einfache Lösung als Plugin oder Mu-Plugin.

Es verwendet so wenig Ressourcen wie möglich, lädt nur die benötigten Bildschirme und fügt Spalten + Filter für jede benutzerdefinierte Taxonomie hinzu.

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

    }

}

Und dann brauchen Sie nur noch eine angepasste Walker-Klasse.

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

Wirbelte das durch, aber die Methode get_select () scheint zu fehlen.
Dave Romsey

@ goto10 Du hattest recht. Aktualisiert. Übrigens: Es ist einfacher, einfach das verknüpfte Plugin zu greifen. Es wird in ein oder zwei Wochen im Plugin-Repository verfügbar sein. (Schon bestätigt).
Kaiser

Ich musste $this->setup_vars();am Anfang von verwenden, public function setup()um zu "manage_taxonomies_for_{$this->post_type}_columns"arbeiten
Christian

Aber es könnte sein, dass ich es in einer Theme function.php mitadd_action( 'init', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
Christian

@ Christian Dies ist kein Thema Material. Dies gehört in ein Plugin und wird, wie der obige Code zeigt, weit vor dem Laden von Themes geladen.
Kaiser

7

Ich wollte nur eine kurze Notiz machen. In neueren Versionen von WP werden Post-Listings auf admin von der Klasse WP_Posts_List_Table behandelt. Der apply_filters-Code lautet nun wie folgt:

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

Um also neue Spalten hinzuzufügen, sollte ein add_filter-Hook folgendermaßen aussehen:

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

Hier ist ein Beispiel:

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

Nun zu den Postreihen. Dies ist der Code, der Spaltendaten in den Auflistungen verarbeitet:

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

Um unsere Beitragsdaten abzurufen, müssen wir einen Aktions-Hook wie diesen hinzufügen:

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

Beispiel (in diesem Beispiel werden Taxonomien verwendet, Sie können jedoch auch andere Dinge abfragen):

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

ARBEITET IN WP 3.2!

custom_post_type: books custom_taxonomy: genre

Nur ändern, wo es heißt: // HIER ändern

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

Das ist eine schöne und einfache Lösung für WP 3.2+.
Petermolnar

Es funktioniert, __("Show All {$info_taxonomy->label}")ist jedoch eine falsche Methode, um übersetzbare Zeichenfolgen zu verwenden.
Mark Kaplun

2

Hier ist eine Möglichkeit, dies mit der Aktion restrict_manage_posts zu tun. Es scheint für mich gut zu funktionieren und bietet die Möglichkeit, nach Taxonomie für alle Beitragstypen und die damit verbundenen Taxonomien zu filtern.

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

Ein Hinweis: Ich habe versucht, die Tiefe einzuschränken, da einige meiner hierarchischen Taxonomien ziemlich groß sind, aber es hat nicht funktioniert. Könnte dies ein Fehler in der Funktion wp_dropdown_categories sein?


2

Dies ist nicht bekannt , glaube ich, aber wie von Wordpress 3.5 können Sie weitergeben 'show_admin_column' => truezu register_taxonomy. Das macht 2 Dinge:

  1. Fügt die Taxonomiespalte der Listenansicht für Administrationsbeiträge hinzu
  2. Durch Klicken auf den Namen des Begriffs in der Taxonomiespalte wird die Liste tatsächlich nach diesem Begriff gefiltert .

Also nicht genau das Gleiche wie ein Select, aber fast die gleiche Funktionalität, nur eine Codezeile breit.

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

Außerdem gibt es, wie Sie lesen können, einen neuen Filter, der auf das manuelle Hinzufügen von Taxonomiespalten zugeschnitten ist (falls dies wirklich erforderlich ist).


1

Hierarchische Version der Antwort von @somatic, wie von @kevin angefordert:

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

}
?>

Ich habe im Grunde den Code entfernt, der die Optionen erstellt hat, und habe ihn in seine eigene Funktion eingefügt. Die Funktion 'generate_taxonomy_options' übernimmt zusätzlich zum tax_slug auch einen Parent- und Level-Parameter. Die Funktion geht davon aus, dass sie Optionen für das übergeordnete Element 0 erstellt, mit denen alle Begriffe der Stammebene ausgewählt werden. In der Schleife ruft die Funktion sich selbst rekursiv auf, wobei sie diesen aktuellen Term als übergeordnetes Element verwendet und die Ebene um eins erhöht. Es fügt automatisch Zecken zur Seite hinzu, je tiefer Sie den Baum hinuntergehen und voila!


1

Aktualisierung der Antwort von @Drew Gourley für WP 3.3.1 (einschließlich Code von 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

Entschuldigung für die Tatsache, dass ich als neuer Benutzer keine Kommentare posten kann, aber ich kann eine Antwort posten ...

Ab WordPress 3.1 (RC 1) funktioniert Mikes Antwort (die mir in den letzten Monaten so gut gedient hat) bei mir nicht mehr. Einschränkung durch ein Taxonomiekind ergibt ein leeres Ergebnis. Ich habe Somatics Update ausprobiert und es hat großartig funktioniert. Noch besser ist, dass es mit mehreren Taxonomie-Abfragen funktioniert, die in dieser Version verarbeitet wurden.


Aus irgendeinem Grund funktioniert die Version von somatic auch nicht für 3.1
Manny Fleurmond

0

Ich habe gerade beide Codes von Mike und Somatic ausprobiert und mich gefragt, wie ich aus jeder Technik eines herausholen kann:

Mit Mikes Code wird die Dropdown-Liste mit der hierarchischen Option angezeigt , was sehr hilfreich ist . Aber um zwei Dropdowns anzuzeigen, musste ich die if ($typenow=='produtos') {...}Anweisung in der Funktion restrict_listings_by_business()und auch if ($pagenow=='edit.php' && ... }in der convert_business_id_to_taxonomy_term_in_query($query)Funktion, die jetzt viel Code enthält , duplizieren .

Mit dem Code von somatic muss ich nur die Taxonomien spezifizieren, die ich als Dropdowns und Bam sehen möchte, funktioniert; $filters = array('taxo1', 'taxo2');

Frage: Kann ich mich an somatic wenden und auch die hierarchische Option haben?

Trotzdem vielen Dank für dieses Tutorial, das mir sehr geholfen hat!



0

Mikes Tutorial dazu ist großartig! Ich hätte mich wahrscheinlich nicht darum gekümmert, diese Funktionalität zu meinem Plugin für Medienkategorien hinzuzufügen, wenn ich es selbst herausgefunden hätte.

Trotzdem denke ich, dass parse_queryes nicht notwendig ist, den Begriff zu verwenden und ihn dann abzufragen. Es ist übersichtlicher, wenn Sie Ihre eigene Klasse für Wanderer erstellen möchten. Vielleicht war das nicht möglich, als er seinen Beitrag schrieb - der zum Zeitpunkt meines Schreibens dieses Artikels 3 Jahre alt war.

Kasse dieses große Schnipsel auf Github. Funktioniert wie ein Charm, wandelt die IDs in den Dropdown-Werten in Slugs um, sodass es nur von Haus aus funktioniert, ohne die Abfrage zu ändern.

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.