Dodawanie filtru taksonomii do listy administratorów dla niestandardowego typu postu?


129

Utworzyłem niestandardowy typ postu o nazwie 'listing'i dodałem niestandardową taksonomię o nazwie 'businesses'. Chciałbym dodać rozwijaną listę firm do listy administracyjnej dla ofert.

Oto jak ta funkcja wygląda na liście administracyjnej dla postów (chciałbym to samo dla mojego niestandardowego typu posta):

Kategorie rozwijane w postach

Oto mój obecny kod ( i tutaj jest ten sam kod na 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();
}

Jak mogę dodać rozwijaną listę firm do listy administracyjnej dla ofert?


8
Dzięki za zrzut ekranu, naprawdę pomaga to mieć.
MikeSchinkel,

Istnieje wtyczka Filtr taksonomii administratora, który może wykonać dokładnie tę pracę.
Anh Tran

Odpowiedzi:


140

AKTUALIZACJA: Dołączyłem nową pełną odpowiedź, ale mimo to zostawiłem swoją oryginalną odpowiedź na dole, do której odwołuje się kilka pierwszych komentarzy.


Cześć @tarasm :

Chociaż powiedziałem, że to nie powinno być trudne, ale jest trochę zaangażowane. Ale zanim zagłębimy się w kod ...

Zrzuty ekranu:

... sprawdźmy kilka zrzutów ekranu dla gotowego produktu:

Strona listy ofert bez filtrowania:

Strona listy ofert bez filtrowania
(źródło: mikeschinkel.com )

Strona listy ofert z filtrowaniem:

Strona listy ofert z filtrowaniem
(źródło: mikeschinkel.com )

Kod

A więc zaczynamy ... ( Uwaga: Użyłem pojedynczej formy nazwy taksonomii business; mam nadzieję, że pasuje ona do ciebie. Z wielu doświadczeń związanych zarówno z WordPress, jak i tworzeniem baz danych w przeszłości, uważam, że najlepiej jest to zrobić w ten sposób .)

Krok # 1: restrict_manage_postsHak akcji.

Pierwszą rzeczą, którą musisz zrobić, to zaczepić restrict_manage_postsakcję, która nie ma parametrów i jest wywoływana z /wp-admin/edit.php(w v3.0.1, to wywołanie jest w linii 378.) Pozwoli ci to wygenerować rozwijaną listę wyboru w odpowiednim miejscu powyżej listy Wyświetlanie wpisów.

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

Zaczynamy od sprawdzenia $typenowzmiennej, aby upewnić się, że faktycznie jesteśmy na jednym post_typez listing. Jeśli nie, otrzymasz tę listę rozwijaną dla wszystkich typów postów, co w niektórych przypadkach jest tym, czego chcesz, ale nie w tym przypadku.

Następnie ładujemy informacje o używanej taksonomii biznesowej get_taxonomy(). Potrzebujemy go, aby pobrać etykietę dla taksonomii (tj. „ Firmy ”; moglibyśmy mieć zakodowane na stałe, ale nie jest to zbyt dobre, jeśli musisz później internacjonalizować). Następnie wywołujemy wp_dropdown_categories()wszystkie odpowiednie argumenty w $argstablicy, aby wygenerować upuścić

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

Ale jakie są odpowiednie argumenty? Przyjrzyjmy się każdemu z osobna:

  • show_optional_all- Całkiem proste, to, co jest wyświetlane na liście rozwijanej na początku, a gdy nie zastosowano filtrowania. W naszym przypadku będzie to „Pokaż wszystkie firmy ”, ale moglibyśmy nazwać to „Ofertami dla wszystkich firm” lub czymkolwiek innym .

  • taxonomy- Argumenty te mówią funkcji, z której systematyki należy pobierać terminy, nawet jeśli funkcja ma categoriesw nazwie. W wersji 2.8 i wcześniejszych WordPress nie miał niestandardowych systematyk, ale po ich dodaniu zespół zdecydował, że łatwiej będzie dodać argument funkcji do tej funkcji niż utworzyć inną funkcję o innej nazwie.

  • name- Ten argument pozwala określić wartość, którą WordPress używa dla nameatrybutu elementu <select> wygenerowanego dla menu rozwijanego. Na wypadek, gdyby nie było oczywiste, jest to również wartość, która będzie używana w adresie URL podczas filtrowania.

  • orderby- Ten argument mówi WordPressowi, jak porządkować wyniki alfabetycznie. W naszym przypadku zdecydowaliśmy się na zakup namewarunków w taksonomii, tj. Nazwy firm w tym przypadku.

  • selected- Ten argument jest potrzebny, aby menu rozwijane mogło pokazać aktualny filtr w menu rozwijanym. Powinien pochodzić term_idz wybranego terminu taksonomii. W naszym przypadku może to być term_idod „biznesu # 2” . Skąd ta wartość? Ze zmiennej globalnej WordPress $wp_query; ma właściwość, queryktóra zawiera tablicę wszystkich parametrów URL i ich wartości (chyba, że ​​jakaś niepoprawna wtyczka już go zmodyfikowała). Biorąc pod uwagę, jak WordPress przetwarza rzeczy, termparametr URL zostanie przekazany na adres URL, gdy użytkownik kliknie filtr przycisk, jeśli użytkownik wybrał prawidłowy termin (tj. jedną z firm wymienionych na liście).

  • hierarchical- Ustawiając tę trueopcję, powiedz funkcji szanującej hierarchiczny charakter taksonomii i wyświetl ją w widoku drzewa, jeśli warunki (firmy) faktycznie mają dzieci. Zrzut ekranu pokazujący, jak to wygląda, patrz poniżej.

  • depth- Ten argument współpracuje z hierarchicalargumentem w celu ustalenia, o ile poziomów głębokość powinna przejść funkcja wyświetlania dzieci.

  • show_count- Jeśli trueten argument wyświetli liczbę postów w nawiasach po lewej stronie nazwy terminu w menu rozwijanym. W takim przypadku wyświetlałaby liczbę ofert powiązanych z firmą. Zrzut ekranu pokazujący, jak to wygląda, patrz poniżej.

  • hide_empty- Wreszcie, jeśli w taksonomii występują warunki, które nie są powiązane ze stanowiskiem (tj. Firmy niepowiązane z listą), ustawienie tej opcji truespowoduje pominięcie ich w liście rozwijanej.

Lista rozwijana taksonomii powinna hierarchizować i się liczyć
(źródło: mikeschinkel.com )

Krok # 2: parse_queryHak filtra.

Następnie zwracamy uwagę na parse_queryhak filtrujący, który ma jeden parametr ( $query) i jest wywoływany z /wp-includes/query.php(w wersji 3.0.1 to wywołanie jest w linii 1549.) Jest wywoływane, gdy WordPress zakończy sprawdzanie adresu URL i ustawianie wszystkich odpowiednich wartości w aktualnie aktywne, w $wp_querytym takie jak $wp_query->is_homei $wp_query->is_authoritp.

Po uruchomieniu parse_queryhaka filtru WordPress wywoła get_posts()i załaduje listę postów na podstawie tego, co jest określone w aktualnie aktywnym $wp_query. Dlatego parse_queryczęsto jest to świetne miejsce, aby WordPress zmienił zdanie na temat tego, które posty będą ładowane.

W twoim przypadku użycia chcemy, aby WordPress filtrował na podstawie wybranych firm; tzn. wyświetlać tylko te Oferty, które zostały powiązane z wybraną firmą (powiedziałbym „... tylko te Listy, które zostały „ skategoryzowane ” przez wybraną firmę”, ale to nie jest poprawne technicznie; czy categoryjest to własna taksonomia na równi z innymi z businesswyjątkiem tego, że categoryjest wbudowany w WordPress i businessjest niestandardowy. Ale dla tych, którzy znają kategoryzowanie postów, może to pomóc ci zrozumieć, ponieważ działają prawie identycznie. Ale dygresję ...)

Do kodu. Pierwszą rzeczą, którą robimy, jest pobranie odniesienia do aktualnie aktywnych $wp_query, query_varstak aby wygodniej było z nim pracować, tak jak w przypadku własnej parse_query()funkcji WordPressa . W przeciwieństwie do tego, $wp_query->queryktóry służy do dublowania parametrów przekazywanych na adres URL, $wp_query->query_varstablica służy do kontrolowania zapytania uruchamianego przez WordPress i oczekuje się, że zostanie zmodyfikowany. Więc jeśli trzeba zmodyfikować jeden, to byłoby jedno (przynajmniej ja myślę , że jest różnica między nimi, jeśli ktoś wie, w przeciwnym razie proszę ! Daj mi znać, żebym mógł zaktualizować ten temat)

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

Następnie testujemy, $pagenowaby upewnić się, że rzeczywiście ładujemy WordPress ze ścieżki URL /wp-admin/edit.php. Robimy to, aby zapobiec przypadkowemu zepsuciu zapytań na innych stronach. Mamy również sprawdzić, aby upewnić się, że mamy zarówno businessjako taxonomyelementu i termelementu też. (Uwaga taxonomyi termsą parą; są one używane razem, aby umożliwić kwerendę terminu taksonomii; muszę mieć oba lub WordPress nie wie, którą taksonomię należy sprawdzić).

Możesz się zastanawiać, jak się businesspojawił w taxonomyelemencie query_varstablicy. To, co napisaliśmy w naszym parse_queryhaku, wywołało wewnętrzną magię WordPress, która została wyczekiwana, gdy zarejestrowałeś businesstaksonomię, ustawiając query_varją na prawdziwą ( register_taxonomy()kopiuje nazwę taksonomii jako taką query_var; możesz ją zmienić oczywiście, ale chyba że masz konflikt najlepiej trzymać się tego samego):

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

Teraz WordPress „$ wp_query został napisany, aby używać ślimaków do standardowych zapytań filtrowanych według taksonomii, a nie identyfikatorów terminów taksonomicznych. W tym przypadku użycia naprawdę potrzebujemy, aby nasze zapytanie filtrujące działało:

taxonomy: biznes

term: business-1 (tj. slug)

Nie te:

taxonomy: biznes

term: 27 (tj. term_id)

Co ciekawe i niestety rozwijanej generowane przez wp_dropdown_categories()ustawienie <option>„s valueatrybut do terminu w biznesie” (/) term_id, nie termin slug. Musimy więc przekonwertować $wp_query->query_vars['term']ciąg liczbowy term_idna ciąg znaków, slugjak następuje we fragmencie zaczepionym z góry (uwaga: nie jest to najskuteczniejszy sposób zapytania do bazy danych, ale dopóki WordPress nie doda obsługi term_ids do zapytania, to najlepsze, co możemy zrobić!) :

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

I to wszystko! Dzięki tym dwóm funkcjom uzyskasz pożądane filtrowanie.

ALE CZEKAJ, WIĘCEJ! :-)

Poszedłem dalej i dodałem kolumnę „Firmy” do twojej listy, ponieważ, cóż, wiedziałem, że to będzie twoje następne pytanie. Bez kolumny dla tego, co filtrujesz, może być bardzo mylące dla użytkownika końcowego. (Sam się z tym zmagałem i byłem programistą!) Oczywiście można już zobaczyć kolumnę „Firmy” na poprzednich zrzutach ekranu powyżej.

Krok # 3: manage_posts_columnsHak filtra.

Aby dodać kolumnę do listy postów, trzeba wywołać dwa (2) kolejne haki. Pierwsza to manage_posts_columnswersja specyficzna dla typu postu manage_listing_posts_columns, którą zamiast tego nazwałem. Akceptuje jeden parametr ( posts_columns) i jest wywoływany z /wp-admin/includes/template.php(w wersji 3.0.1 to wywołanie jest w linii 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;
}

Twoja manage_posts_columnsfunkcja hak zostaje przekazana tablicę kolumn, w których wartość jest wyświetlana nagłówek kolumny, a klucz jest wewnętrzny identyfikator kolumna. Standardowe identyfikatory kolumn mogą obejmować te i więcej: 'cb', 'title' 'author'``' date'`, etc.

'cb', to checkboxkolumna i oba, 'title'i 'date'odnoszą się odpowiednio do post_titlei post_datez wp_poststabeli. 'author'oczywiście jest to post_authorpole po pobraniu nazwiska autora z wp_userstabeli.

Zrzut ekranu kolumny postów „cb” jako pola wyboru.
(źródło: mikeschinkel.com )

W przypadku manage_posts_columnshaka chcemy po prostu wstawić wcześniej naszą kolumnę businessesdo $posts_columnstablicy 'author', zakładając, że jakaś inna wtyczka nie została jeszcze usunięta authorz listy!

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

( Zauważ, że jak napisałem add_businesses_column_to_listing_list(), przyszło mi do głowy, że PHP musi mieć łatwiejszy sposób na wstawienie wartości do tablicy asocjacyjnej w odpowiedniej kolejności?!? A przynajmniej musi być funkcja w rdzeniu WordPress, aby to zrobić? Ale od Google zawiodłem, więc poszedłem z tym, co zadziałało. Jeśli ktoś ma jakieś sugerowane alternatywy, z góry będę wdzięczny i wdzięczny!)

Co w końcu prowadzi nas do ...

Krok # 4: manage_posts_custom_columnHak akcji

Drugą rzeczą z dwóch (2), które musimy zrobić, aby nasze firmy wyświetlały się w kolumnie, jest podanie nazwy każdej z powiązanych firm za pomocą manage_posts_custom_columnhaka akcji. Ten hook akceptuje dwa (2) parametry ( column_idi post_id) i jest również wywoływany z /wp-admin/includes/template.php(w wersji 3.0.1 to wywołanie jest w linii 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;
        }
    }
}

Ten zaczep jest wywoływany dla każdej kolumny dla każdego wiersza postu (/ biznes). Najpierw sprawdzamy, czy rzeczywiście pracujemy tylko z listingniestandardowym typem postu, a następnie używamy switchinstrukcji do testowania column_id. Wybrałem, switchponieważ ten hak jest często używany do generowania danych wyjściowych dla wielu różnych kolumn, zwłaszcza jeśli używamy jednej funkcji dla wielu różnych typów postów, które mogą wyglądać mniej więcej tak:

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

Przyglądając się naszemu przypadkowi użycia nieco bliżej, widzisz get_the_terms()funkcję, która po prostu zwraca listę terminów dla tej taksonomii (tj. Firmy dla tego wpisu). Tutaj możesz uzyskać bezpośredni link do strony frontonu tego terminu, która normalnie zawiera listę powiązanych postów z tym terminem, ale oczywiście może się to różnić w zależności od motywu i / lub zainstalowanych wtyczek.

Używamy permalink do hiperłącza tego terminu tylko dlatego, że lubię hiperłącza rzeczy. Następnie łączymy wszystkie hiperłącza (/ biznes) razem oddzielone |znakiem potoku (' ') i wysyłamy do bufora PHP, który wysyła go do przeglądarki użytkownika / klienta HTTP:

<?php
$businesses = get_the_terms($post_id,$taxonomy);
if (is_array($businesses)) {
    foreach($businesses as $key => $business) {
        $edit_link = get_term_link($business,$taxonomy);
        $businesses[$key] = '<a href="'.$edit_link.'">' . $business->name . '</a>';
    }
    //echo implode("<br/>",$businesses);
    echo implode(' | ',$businesses);
}

TERAZ jesteśmy w końcu skończeni.

Podsumowanie

Podsumowując, musisz użyć następujących czterech (4) haczyków, aby uzyskać zarówno filtr, jak i powiązaną kolumnę na stronie listy niestandardowych postów (Och, to również będzie działać z postami i stronami). Są to:

  • Krok # 1: restrict_manage_postsHak akcji.
  • Krok # 2: parse_queryHak filtra.
  • Krok # 3: manage_posts_columnsHak filtra.
  • Krok # 4: manage_posts_custom_columnHak akcji

Skąd pobrać kod

Ale gdybym zmusił cię do przeczytania powyższego, na pewno nie byłbym bardzo miłą osobą, gdybym zmusił cię do wykopania kodu tylko po to, aby go wypróbować! Ale wbrew temu, co mówią niektórzy ludzie, jestem miły. Więc proszę:

UWAGA do @tarasm : Dołączyłem haki dlaregister_post_type()iregister_taxonomy(), aby inni mogli to wypróbować bez konieczności ich ponownego tworzenia. Prawdopodobnie będziesz chciał usunąć te dwa wywołania funkcji przed przetestowaniem tego.

KONIEC


Oryginalna odpowiedź:

Cześć @tarasm :

Czy szukasz jednej listy rozwijanej na górze, takiej jak ten ekran, czy też jednej listy rozwijanej na rekord postu, a jeśli tak, jak możesz oczekiwać, że ten ostatni zadziała?

Jak utworzyć funkcję Sortuj według dla niestandardowego typu postu w Administratorze WordPress
(źródło: mikeschinkel.com )

Jeśli to pierwsze, spójrz na tę odpowiedź na pytanie Jak posortować obszar administracyjny niestandardowego typu postu Wordpress według niestandardowego pola? Jeśli tego potrzebujesz, mogę podać więcej szczegółów związanych z taksonomią.


Szukam 1 menu u góry, które pokazuje filtr Kategorie. Wędrowałem, czy istnieje standardowy sposób na zrobienie tego bez konieczności pisania niestandardowego kodu.
Taras Mankovski

Na pierwszy rzut oka nie sądzę, że możesz zrobić bez kodu niestandardowego, ale potem nie sądzę, aby kod niestandardowy był znaczący. Muszę przygotować się do rozmowy z klientem, więc będzie to musiało być później.
MikeSchinkel,

2
W rzeczywistości oba rozwiązania (somatic i MikeSchinkel) nie działają, gdy próbujesz filtrować 2 różne taksonomie w tym samym filtrze: - / Zawsze filtruj najnowszą taksonomię, gdy próbujesz filtrować 2+ w tym samym czasie.
Ünsal Korkmaz

1
@ Ünsal Obecna wersja WordPress (3.0) nie obsługuje wielu zapytań taksonomicznych, ale z tego, co słyszałem, zmieni się w wersji 3.1. Aby ten przykład działał z wieloma taksonomiami, musisz dodać do zapytania kilka złączeń i skrętów za pośrednictwem haków filtru Posts_join i posts_where.
Manny Fleurmond

1
W WP 3.1+ kroki 1 i 2 są lepsze w odpowiedzi na @ Draw-Gourley (tak naprawdę, twój krok 2 nie działał dla mnie, myślę, że są zmiany w tym filtrowaniu w nowym WordPress).
Tomasz Struczyński,

44

Chciałem tylko udostępnić alternatywną implementację. Nie miałem niesamowitego samouczka Mike'a, kiedy to rozgryzałem, więc moje rozwiązanie jest trochę inne. W szczególności zamierzam uprościć krok 1 Mike'a i wyeliminować krok 2 - pozostałe kroki nadal obowiązują.

W samouczku Mike'a użycie wp_dropdown_categories()oszczędza nam ręcznego budowania listy, ale wymaga skomplikowanej modyfikacji warunkowego zapytania ( krok 2 ), aby obsłużyć użycie ID zamiast ślimaka. Nie wspominając już o trudnościach z modyfikowaniem tego kodu w celu obsługi innych scenariuszy, takich jak wiele filtrów taksonomii.

Innym podejściem jest po prostu nie używanie wp_dropdown_categories()w ogóle wadliwych , ale budowanie własnych list wyboru od zera. To nie jest takie skomplikowane, zajmuje mniej niż 30 linii kodu i wcale nie wymaga zaczepiania 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>";
        }
    }
}

Po prostu podłączając pożądane taksonomie do $filterstablicy, możesz szybko wygenerować wiele filtrów taksonomii. Wyglądają dokładnie tak samo jak na zrzutach ekranu Mike'a. Następnie możesz wykonać kroki 3 i 4 .


4
@somatic - Ładna aktualizacja! Tak, używanie wp_dropdown_categories()wymaga wielu obejść. Staram się trzymać podstawowych funkcji, gdy jest to możliwe, ale jak zauważasz, czasami wymaga to więcej pracy. Po prostu udowadnia, że ​​z WordPress często jest więcej niż jeden dobry sposób na rozwiązanie problemu. Dobra robota!
MikeSchinkel,

Właśnie przestałem działać na WordPress 3.1. Próbuję dowiedzieć się, co dokładnie się zmieniło. Wygląda na to, że powinno nadal działać: taksonomia i ślimaki terminów są wyświetlane jako wartości GET w
adresie

Starałem się, aby to działało, ale jedynym sposobem, w jaki mogłem, było użycie haka parse_query, sprawdzenie zmiennej zapytania w taksonomii var i ustawienie w oparciu o nią różnych zmiennych taksonomii i terminów. Korzystanie z WP 3.1. Czy taksonomia i terminy powinny pojawiać się w adresie URL po przesłaniu filtra?
sanchothefat

2
Działa jak dla mnie urok! Rzeczywiście bardzo eleganckie rozwiązanie. Jestem ci winien piwo :)
Michał Mau,

@somatic Działa to świetnie, ale czy istnieje sposób, aby $ term-> liczył tylko warunki dla tego typu postów? Na przykład, jeśli mam niestandardową taksonomię zarówno zdjęć, jak i filmów, pokaże mi, gdy patrzę na niestandardowy typ filmu wideo, całkowita liczba postów dla tego terminu z obu niestandardowych typów postów, a nie tylko całkowita liczba postów wideo, które używają tego semestr.
Greenhoe

13

Oto wersja tego, która automatycznie tworzy i stosuje filtry ze wszystkich taksonomii, które mają zastosowanie do wszystkich niestandardowych typów postów, które ich używają. (co za kęs) W każdym razie poprawiłem go, aby działał z wp_dropdown_categories () i wordpress 3.1. Projekt, nad którym pracuję, nazywa się ToDo, możesz zmienić nazwę funkcji na coś, co ma dla ciebie sens, ale to powinno działać prawie wszystko automatycznie.

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

Zauważ, że używam wtyczki, która dodaje „term_order” jako sposób porządkowania warunków, będziesz musiał to zmienić lub usunąć ten argument, aby powrócić do wartości domyślnej.


naprawdę bardzo seksowny. otrzymywałem powiadomienia o błędach, więc zmieniłem if (isset ($ var)) na if (isset ($ var) && $ var> 0), aby uniknąć próby znalezienia warunków związanych z wartością Wyświetl wszystkie 0. och, i musiałem zwrócić zapytanie $ w funkcji
todo_convert_restrict

11

Spóźniona odpowiedź

Edytować

Napisałem Filterama , wtyczkę, która doda tę funkcjonalność w najprostszy możliwy sposób.

Aktualizacja dla WordPress 3.5+

Teraz, gdy wszystko jest znacznie łatwiejsze, oto bardzo proste rozwiązanie, takie jak wtyczka lub wtyczka mu.

Zużywa jak najmniej zasobów, ładuje tylko potrzebne ekrany i dodaje kolumny + filtry dla każdej niestandardowej systematyki.

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

    }

}

A potem potrzebujesz tylko dostosowanej klasy Walker.

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

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

Dało to wir, ale wydaje się, że brakuje metody get_select ().
Dave Romsey

@ goto10 Miałeś rację. Zaktualizowano Btw: Łatwiej jest po prostu pobrać połączoną wtyczkę. Będzie on dostępny w repozytorium wtyczek za tydzień lub dwa. (Już potwierdzony).
kaiser

Musiałem użyć $this->setup_vars();na początku public function setup(), żeby mieć "manage_taxonomies_for_{$this->post_type}_columns"pracę
Christian

Ale może tak być, ponieważ używam go w funkcji Theme.php zadd_action( 'init', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
Christian

@Christian To nie jest materiał tematyczny. Należy do wtyczki, a ponieważ powyższy kod oznacza, że ​​jest ładowany na długo przed załadowaniem motywów.
kaiser

7

Chciałem tylko szybko zanotować. W nowszych wersjach WP, ogłoszenia na admin są obsługiwane przez klasę WP_Posts_List_Table. Kod Apply_filters jest teraz następujący:

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

Aby dodać nowe kolumny, haczyk add_filter powinien wyglądać tak:

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

Oto przykład:

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

Teraz dla wierszy postu. Oto kod, który obsługuje dane kolumn na listach:

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

Aby odzyskać dane z naszych postów, musimy dodać taki hak akcji:

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

Przykład (w tym przykładzie użyto taksonomii, ale można zapytać o inne rzeczy):

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

DZIAŁA W WP 3.2!

custom_post_type: books custom_taxonomy: gatunek

Modyfikuj tylko wtedy, gdy mówi: // zmień TUTAJ

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

To miłe i łatwe rozwiązanie dla WP 3.2+.
petermolnar

działa, ale __("Show All {$info_taxonomy->label}")jest złym sposobem na użycie ciągów do tłumaczenia.
Mark Kaplun,

2

Oto sposób na zrobienie tego za pomocą akcji ograniczania_manage_posts. Wydaje mi się, że działa dobrze i dodaje możliwość filtrowania według taksonomii dla wszystkich typów postów i powiązanych taksonomii.

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

Jedna uwaga - próbowałem ograniczyć głębokość, ponieważ niektóre z moich hierarchicznych taksonomii są dość duże, ale to nie zadziałało - może to być błąd w funkcji wp_dropdown_categories?


2

Chyba nie jest to dobrze znane, ale od wersji Wordpress 3.5 można przejść 'show_admin_column' => truedo register_taxonomy. To robi 2 rzeczy:

  1. Dodaje kolumnę systematyki do widoku listy typów postów administratora
  2. Klikając nazwę terminu w kolumnie taksonomii, faktycznie filtruje listę do tego terminu .

Tak więc, nie dokładnie to samo, co posiadanie zaznaczenia, ale prawie taka sama funkcjonalność, szerokość tylko jeden wiersz kodu.

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

Ponadto, jak możesz przeczytać, istnieje nowy filtr dostosowany do ręcznego dodawania kolumny taksonomii (jeśli naprawdę potrzebujesz).


1

Hierarchiczna wersja odpowiedzi @ somatic, zgodnie z prośbą @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);
    }

}
?>

Zasadniczo usunąłem kod, który utworzył opcje i umieściłem go we własnej funkcji. Funkcja „generate_taxonomy_options”, oprócz pobrania tax_slug, przyjmuje również parametr nadrzędny i poziom. Funkcja zakłada, że ​​tworzy opcje tworzenia dla rodzica 0, który wybierze wszystkie warunki na poziomie głównym. W pętli funkcja wywoła się rekurencyjnie, wykorzystując bieżący termin jako element nadrzędny i zwiększając poziom o jeden. Automatycznie dodaje tyknięcia z boku, im głębiej zejdziesz po drzewie i voila!


1

Aktualizacja odpowiedzi @Drew Gourley dla WP 3.3.1 (i zawierająca kod z 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

Przepraszamy za to, że jako nowy użytkownik nie mogę komentować, ale mogę opublikować odpowiedź ...

Począwszy od WordPress 3.1 (RC 1) odpowiedź Mike'a (która tak dobrze służyła mi przez ostatnie kilka miesięcy) nie działa już dla mnie; ograniczenie przez jakąkolwiek taksonomię dziecko daje pusty wynik. Wypróbowałem aktualizację Somatic i działała świetnie; jeszcze lepiej, działa z wieloma zapytaniami taksonomicznymi, które zostały opracowane w tej wersji.


Z jakiegoś powodu wersja
somatic

0

Właśnie wypróbowałem oba kody, od Mike'a i somatic, i zastanawiałem się, jak uzyskać jedną rzecz z każdej techniki:

Z kodem Mike'a pokazuje listę rozwijaną z opcją hierarchiczną , co bardzo pomaga. Ale aby wyświetlić dwa menu rozwijane, musiałem zduplikować if ($typenow=='produtos') {...}instrukcję w funkcji, restrict_listings_by_business()a także if ($pagenow=='edit.php' && ... }w convert_business_id_to_taxonomy_term_in_query($query)funkcji, która daje teraz dużo kodu.

W kodzie somatycznym muszę tylko określić taksonomie, które chciałbym widzieć jako listy rozwijane i bam, działa; $filters = array('taxo1', 'taxo2');

Pytanie: czy mogę uzyskać podejście somatyczne i mieć również opcję hierarchiczną ?

W każdym razie bardzo dziękuję za ten samouczek, bardzo pomogłem!


Zobacz moją odpowiedź na rozwiązanie hierarchiczne
Manny Fleurmond

0

Samouczek Mike'a na ten temat jest świetny! Prawdopodobnie nie zadałbym sobie trudu dodania tej funkcji do mojej wtyczki Media Categories, gdybym musiał ją sam odkryć.

To powiedziawszy, myślę, że użycie, parse_querya następnie uzyskanie zapytania o termin nie jest konieczne. Jest czystszy, aby stworzyć własną niestandardową klasę walker. Może nie było to możliwe, kiedy napisał swój post - ma on 3 lata w chwili, gdy to piszę.

Sprawdź ten świetny fragment w witrynie github. Działa jak urok, zmienia identyfikatory w rozwijanych wartościach na ślimaki, więc działa po prostu natywnie bez modyfikowania zapytania.

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.