ti-enxame.com

Adicionando um filtro de taxonomia à lista de administradores para um tipo de postagem personalizado?

Eu criei um tipo de postagem personalizada chamado 'listing' e adicionei uma taxonomia personalizada chamada 'businesses'. Gostaria de adicionar uma lista suspensa de empresas à lista de administradores das listagens.

Aqui está como esta funcionalidade se parece na lista de administradores para Posts (eu gostaria do mesmo para o meu tipo de postagem personalizada):

Categories Dropdown in Posts

Aqui está o meu código atual ( E aqui está o mesmo código no 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();
}

Como posso adicionar uma lista suspensa de empresas à lista de administradores das listagens?

128
Taras Mankovski

UPDATE: Eu incluí uma nova resposta completa, mas mesmo assim deixei minha resposta original na parte inferior à qual os primeiros comentários fazem referência.


Oi @tarasm:

Embora eu tenha dito que não deveria ser difícil, é um pouco complicado. Mas antes de cavarmos o código ...

As capturas de tela:

... vamos verificar algumas capturas de tela para o produto acabado:

Página da lista de listagens com NãoFiltragem:

Listings list page with No Filtering
(fonte: mikeschinkel.com )

Página da lista de listagens ComFiltragem:

Listings list page With Filtering
(fonte: mikeschinkel.com )

O código

Então, aqui vamos nós ... (Nota: Eu usei um formulário singular para o nome taxonomia de business; Espero que corresponda ao seu. De muita experiência com o WordPress e desenvolvimento de banco de dados no passado eu acredito que é melhor para fazer isso dessa maneira.)

Etapa 1: o gancho de ação restrict_manage_posts.

A primeira coisa que você precisa fazer é ligar a ação restrict_manage_posts que não possui parâmetros e é chamada de /wp-admin/edit.phpna v3.0.1 essa chamada está na linha 378.) Isso permitirá que você gere o menu suspenso no local apropriado acima do lista de postagens da listagem.

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

Começamos verificando a variável $typenow para garantir que estamos de fato em um post_type de listing. Se você não fizer isso, você obterá esta lista suspensa para todos os tipos de postagens que, em alguns casos, é o que você deseja, mas não neste caso.

Em seguida, carregamos informações sobre a taxonomia comercial usando get_taxonomy(). Precisamos recuperar o rótulo da taxonomia (por exemplo, "_ (Businesses"; poderíamos ter código permanente, mas isso não é muito bom se você precisar internacionalizar mais tarde). Então, chamamos wp_dropdown_categories() com todos os argumentos apropriados em o array $args para gerar o menu suspenso

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

Mas quais são os argumentos apropriados? Vamos olhar para cada um individualmente:

  • show_optional_all - Muito simples, é o que é exibido no menu suspenso no início e quando não houve filtragem aplicada. No nosso caso, vai ser "Show All Businesses" mas poderíamos chamá-lo de "Listings for All Businesses"ou o que você quiser).

  • taxonomy - Este argumento diz à função de qual taxonomia usar os termos, embora a função tenha categoriesem seu nome. Na v2.8 e anterior, o WordPress não tinha taxonomias customizadas, mas quando elas foram adicionadas, A equipe decidiu que seria mais fácil adicionar um argumento de taxonomia a essa função do que criar outra função com outro nome.

  • name - Este argumento permite que você especifique o valor que o WordPress usa para o atributo name do elemento <select> gerado para o menu suspenso. Apenas no caso de não ser óbvio, este é também o valor que será usado no URL durante a filtragem.

  • orderby - Este argumento diz ao WordPress como ordenar os resultados em ordem alfabética. No nosso caso, especificamos comprar o name dos termos da taxonomia, ou seja, os nomes comerciais neste caso.

  • selected - Este argumento é necessário para que o menu suspenso possa mostrar o filtro atual no menu suspenso. Deve ser o term_id do termo de taxonomia selecionado. No nosso caso, pode ser o term_id de "Business # 2". Onde podemos obter esse valor? Do WordPress 'variável global $wp_query; ele tem uma propriedade query que contém uma matriz de todos os parâmetros de URL e seus valores (a menos que algum plugin rebelde já o tenha modificado.) Dado como o WordPress processa coisas, haverá um parâmetro de URL term passado na URL quando o usuário clica no botão de filtro se o usuário selecionou um termo válido (ou seja, uma das empresas listadas ).

  • hierarchical - Configurando isto para true, você diz à função para respeitar a natureza hierárquica da taxonomia e exibi-los em uma visualização em árvore, se os termos (negócios) de fato tiverem filhos. Para uma captura de tela para ver o que parece, veja abaixo.

  • depth - Este argumento colabora com o argumento hierarchical para determinar quantos níveis de profundidade a função deve ter na exibição de filhos.

  • show_count - Se true este argumento exibirá uma contagem de posts entre parênteses à esquerda do nome do termo dentro do menu suspenso. Nesse caso, exibiria uma contagem de listagens associadas a uma empresa. Para uma captura de tela para ver o que parece, veja abaixo.

  • hide_empty - Finalmente, se há termos na taxonomia que são nãoassociados a um post (ou seja, empresas não associadas a uma listagem), então configurá-lo como true irá omiti-los de serem incluídos no menu suspenso. .

Taxonomy Drop Down should hierarchy and counts
(fonte: mikeschinkel.com )

Etapa 2: O gancho de filtro parse_query.

Em seguida, chamamos nossas atenções para o gancho de filtro parse_query que tem um parâmetro ($query) e é chamado de /wp-includes/query.phpna v3.0.1 que a chamada está na linha 1549.) É chamado quando o WordPress termina de inspecionar a URL e definir todos os valores apropriados no $wp_query atualmente ativo, incluindo itens como $wp_query->is_home e $wp_query->is_author, etc.

Depois que o gancho de filtro parse_query for executado, o WordPress chamará get_posts() e carregará uma lista de posts com base no que está especificado no $wp_query atualmente ativo. Então, parse_query costuma ser um ótimo lugar para fazer com que o WordPress mude de ideia sobre quais postagens serão carregadas.

Em seu caso de uso, queremos que o WordPress seja filtrado com base nas empresas selecionadas; ou seja, para exibir apenas as listagens que foram associadas à empresa selecionada (eu diria _ ("... somente as listagens que foram " categorizadas " pela empresa selecionada"mas isso não é técnico correto; category é sua própria taxonomia no peer com business exceto que category está embutido no WordPress e business é customizado. Mas para aqueles que estão familiarizados com a categorização de posts isso pode ajudá-lo a entender como eles funcionam quase identicamente.

Para o código. A primeira coisa que fazemos é pegar uma referência ao $wp_query do query_vars ativo no momento, para que seja mais conveniente trabalhar com ele, da mesma forma como é feito dentro da própria função parse_query() do WordPress. Ao contrário de $wp_query->query, que é usado para espelhar os parâmetros passados ​​na URL, a matriz $wp_query->query_vars é usada para controlar a consulta que o WordPress executa e espera-se que seja modificada. Então, se você precisar modificar um, esse seria o único (pelo menos eu penseque é o diferente entre os dois; se alguém souber o contrário por favorme avise para que eu possa atualizar isso!)

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

Em seguida, testamos $pagenow para garantir que, de fato, estamos carregando o WordPress do caminho da URL /wp-admin/edit.php. Fazemos isso para evitar que consultas sejam acidentais em outras páginas. Também verificamos se temos tanto business como um elemento taxonomy e um elemento term também. (Nota taxonomy e term são um par; eles são usados ​​juntos para permitir a consulta de um termo de taxonomia; precisa ter os dois ou o WordPress não sabe qual taxonomia deve ser inspecionada.)

Você pode se perguntar como business apareceu no elemento taxonomy da matriz query_vars. O que escrevemos em nossa magia interna parse_query trigger desencadeada do WordPress que foi colocada em espera quando você registrou a taxonomia "business" definindo query_var como true (register_taxonomy() copia o nome da taxonomia como query_var; você pode alterá-la, é claro, mas a menos que você tenha um conflito, é melhor ficar com o mesmo):

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

Agora o WordPress '$ wp_query foi escrito para usar slugs para consultas filtradas de taxonomia padrão, e não para IDs de termos de taxonomia. Para este caso de uso, o que realmente precisamos para fazer nosso trabalho de consulta de filtragem é o seguinte:

taxonomy: business

term: business-1(isto é, o slug)

Não estes:

taxonomy: business

term: 27(isto é, o term_id)

Curiosamente e infelizmente a lista suspensa gerada por wp_dropdown_categories() configura o atributo <option>value para o termo (/ business ') term_id, noto termo slug. Portanto, precisamos converter $wp_query->query_vars['term'] de um term_id numérico para ele é string slug da seguinte forma no snippet snagged from above (Observe que essa não é a maneira mais eficiente de consultar um banco de dados, mas até que o WordPress adicione suporte para term_ids em sua consulta, isso é o melhor que podemos fazer!):

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

E é isso! Com essas duas funções, você obtém a filtragem desejada.

MAS ESPERE, EXISTE MAIS! :-)

Fui em frente e adicionei uma "Businesses"coluna à sua lista de listagem porque, bem, eu sabia que seria a próxima pergunta. Sem ter uma coluna para o filtro, pode ser muito confuso para o usuário final (Eu lutei com isso eu mesmo, e eu era o codificador!) Você pode, claro, já ver a coluna "Empresas"nas capturas de tela anteriores acima.

Etapa # 3: O gancho de filtro manage_posts_columns.

Para adicionar uma coluna à lista de postagens, é necessário chamar dois (2) mais ganchos. O primeiro deles é manage_posts_columns ou a versão específica do tipo de post manage_listing_posts_columns que eu chamei em vez disso. Ele aceita um parâmetro (posts_columns) e é chamado de /wp-admin/includes/template.phpna v3.0.1 essa chamada está na linha 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;
}

Sua função manage_posts_columns hook é passada em uma matriz de colunas onde o valor é o cabeçalho da coluna exibida e a chave é o identificador interno da coluna. Os identificadores de coluna padrão podem incluir estes e mais: 'cb', 'title ', 'author', ``' date'`, etc.

'cb', é a coluna checkbox e tanto 'title' e 'date' referem-se a post_title e post_date da tabela wp_posts, respectivamente. 'author', claro, é o campo post_author depois que o nome do autor é recuperado da tabela wp_users.

Screenshot of the 'cb' posts column as a checkbox.
(fonte: mikeschinkel.com )

Para o gancho manage_posts_columns estamos simplesmente querendo inserir nossa coluna businesses no array $posts_columns antes de 'author', assumindo que algum outro plugin ainda não removeu author da lista!

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

(_ (Nota como eu escrevi add_businesses_column_to_listing_list() ocorreu-me que PHP deveter uma maneira mais fácil de inserir um valor em um array associativo na ordem correta?!? Ou pelo menos tem que haver uma função no núcleo do WordPress para fazê-lo? Mas desde que o Google me decepcionou, então eu fui com o que funcionou. Se alguém tem alguma sugestão de alternativas eu vou ser todos os ouvidos e agradecer antecipadamente!)

O que finalmente nos leva a ...

Etapa 4: o gancho de ação manage_posts_custom_column

A segunda coisa de dois (2) que precisamos fazer para exibir nossas empresas na coluna é realmente exibir o nome de cada uma das empresas associadas usando o gancho de ação manage_posts_custom_column. Este hook aceita dois (2) parâmetros (column_id e post_id) e também é chamado de /wp-admin/includes/template.phpna v3.0.1 essa chamada está na linha 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;
        }
    }
}

Esse gancho é chamado para cada coluna para cada linha de postagem (/ business). Primeiro, verificamos que estamos realmente trabalhando apenas com o tipo de postagem personalizado listing e, em seguida, usamos uma instrução switch para testar o column_id. Eu escolhi switch porque esse hook é freqüentemente usado para gerar saída para muitas colunas diferentes, especialmente se usarmos uma função para muitos tipos diferentes de posts que podem ser parecidos com isto:

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

Inspecionando nosso caso de uso um pouco mais de perto, você verá a função get_the_terms() que simplesmente retorna a lista de termos para esta taxonomia (por exemplo, negócios para esta listagem). Aqui, obtenha o _ (permalinkpara a página inicial do termo que normalmente lista as postagens que estão associadas ao termo, mas é claro que poderiam ser diferentes dependendo do tema e/ou dos plugins instalados.

Usamos o permalink para hiperlink do termo apenas porque eu gosto de hiperlink coisas. Em seguida, mesclamos todos os termos de hiperlink (/ business) juntos, separados pelo caractere pipe ('|') e emitimos para o buffer PHP que o envia ao navegador/cliente HTTP do usuário:

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

NOW finalmente estamos prontos.

Resumo

Então, em resumo, você precisa usar os quatro (4) ganchos a seguir para obter um filtro e uma coluna relacionada na página da lista de posts personalizados (Ah, ele também funcionará com Posts e Pages.) Eles são:

  • Etapa 1: o gancho de ação restrict_manage_posts.
  • Etapa 2: O gancho de filtro parse_query.
  • Etapa # 3: O gancho de filtro manage_posts_columns.
  • Etapa 4: o gancho de ação manage_posts_custom_column

Onde baixar o código

Mas se eu forçá-lo a ler todo o acima, então eu certamente não seria uma pessoa muito legal se eu também fizesse você escavar o código apenas para poder experimentá-lo! Mas ao contrário do que algumas pessoas dizem, eu sou legal. Então aqui vai você:

NOTE to @tarasm: Incluí ganchos para register_post_type() e register_taxonomy() para que outras pessoas pudessem fazer isso sem precisar recriá-las. Você provavelmente desejará excluir essas duas chamadas de função antes de testar isso .

O FIM


Resposta Original:

Oi @tarasm:

Você está procurando um menu suspenso no topocomo esta tela ou está procurando uma lista suspensa por registro de postageme, em caso afirmativo, como você esperaria que o último funcionasse?)

How to Create Sort By functionality for a Custom Post Type in the WordPress Admin
(fonte: mikeschinkel.com )

Se o primeiro, dê uma olhada nesta resposta à pergunta Como classificar a área de administração de um tipo de postagem personalizada do Wordpress por um campo personalizado? Se é isso que você precisa, posso fornecer mais detalhes relacionados para taxonomia.

138
MikeSchinkel

Só queria compartilhar uma implementação alternativa. Eu não tive o incrível tutorial de Mike quando estava resolvendo isso, então minha solução é um pouco diferente. Especificamente, vou simplificar o passo de Mike # 1 e eliminar passo # 2 - as outras etapas ainda são aplicáveis.

No tutorial de Mike, o uso de wp_dropdown_categories() nos salva um pouco de construção de lista manual, mas requer alguma modificação complicada de consulta condicional ( passo # 2 ) para lidar com o uso de ID em vez de slug. Sem mencionar a dificuldade de modificar esse código para lidar com outros cenários, como vários filtros de taxonomia.

Outra abordagem é simplesmente não usar a wp_dropdown_categories() defeituosa, mas criar as listas suspensas do zero. Não é tão complicado, leva menos de 30 linhas de código, e não requer a conexão de 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>";
        }
    }
}

Simplesmente conectando as taxonomias desejadas ao array $filters, você pode produzir rapidamente vários filtros de taxonomia. Eles aparecem exatamente iguais aos das imagens de Mike. Então você pode seguir com passo # 3 e # 4 .

44
somatic

Aqui está uma versão disso que cria e aplica automaticamente filtros de todas as taxonomias que se aplicam a todos os tipos de postagem personalizados que os utilizam. (o que é um bocado) De qualquer forma, eu também ajustei para que funcione com wp_dropdown_categories () e wordpress 3.1. O projeto em que estou trabalhando é chamado ToDo, você pode renomear as funções para algo que faça sentido para você, mas isso deve funcionar muito bem para tudo automaticamente.

function todo_restrict_manage_posts() {
    global $typenow;
    $args=array( 'public' => true, '_builtin' => false ); 
    $post_types = get_post_types($args);
    if ( in_array($typenow, $post_types) ) {
    $filters = get_object_taxonomies($typenow);
        foreach ($filters as $tax_slug) {
            $tax_obj = get_taxonomy($tax_slug);
            wp_dropdown_categories(array(
                'show_option_all' => __('Show All '.$tax_obj->label ),
                'taxonomy' => $tax_slug,
                'name' => $tax_obj->name,
                'orderby' => 'term_order',
                'selected' => $_GET[$tax_obj->query_var],
                'hierarchical' => $tax_obj->hierarchical,
                'show_count' => false,
                'hide_empty' => true
            ));
        }
    }
}
function todo_convert_restrict($query) {
    global $pagenow;
    global $typenow;
    if ($pagenow=='edit.php') {
        $filters = get_object_taxonomies($typenow);
        foreach ($filters as $tax_slug) {
            $var = &$query->query_vars[$tax_slug];
            if ( isset($var) ) {
                $term = get_term_by('id',$var,$tax_slug);
                $var = $term->slug;
            }
        }
    }
    return $query;
}
add_action( 'restrict_manage_posts', 'todo_restrict_manage_posts' );
add_filter('parse_query','todo_convert_restrict');

Observe que estou usando um plug-in que adiciona 'term_order' como uma maneira de ordenar termos, você terá que alterar isso ou remover esse argumento para retornar ao padrão.

13
Drew Gourley

Resposta atrasada

Editar

Eu escrevi Filterama , um plugin que irá adicionar essa funcionalidade da maneira mais fácil possível.

Atualização para o WordPress 3.5+

Agora que as coisas estão muito mais fáceis, aqui está uma solução muito simples como plugin ou plugin mu.

Ele usa como menos recursos possível, carrega apenas nas telas necessárias e adiciona colunas + filtros para cada taxonomia personalizada.

add_action( 'plugins_loaded', array( 'WCM_Admin_PT_List_Tax_Filter', 'init' ) );
class WCM_Admin_PT_List_Tax_Filter
{
    private static $instance;

    public $post_type;

    public $taxonomies;

    static function init()
    {
        null === self::$instance AND self::$instance = new self;
        return self::$instance;
    }

    public function __construct()
    {
        add_action( 'load-edit.php', array( $this, 'setup' ) );
    }

    public function setup()
    {
        add_action( current_filter(), array( $this, 'setup_vars' ), 20 );

        add_action( 'restrict_manage_posts', array( $this, 'get_select' ) );

        add_filter( "manage_taxonomies_for_{$this->post_type}_columns", array( $this, 'add_columns' ) );
    }

    public function setup_vars()
    {
        $this->post_type  = get_current_screen()->post_type;
        $this->taxonomies = array_diff(
            get_object_taxonomies( $this->post_type ),
            get_taxonomies( array( 'show_admin_column' => 'false' ) )
        );
    }

    public function add_columns( $taxonomies )
    {
        return array_merge( taxonomies, $this->taxonomies );
    }


    public function get_select()
    {
        $walker = new WCMF_walker;
        foreach ( $this->taxonomies as $tax )
        {
            wp_dropdown_categories( array(
                'taxonomy'        => $tax,
                'hide_if_empty'   => true,
                'show_option_all' => sprintf(
                    get_taxonomy( $tax )->labels->all_items
                ),
                'hide_empty'      => true,
                'hierarchical'    => is_taxonomy_hierarchical( $tax ),
                'show_count'      => true,
                'orderby'         => 'name',
                'selected'        => '0' !== get_query_var( $tax )
                    ? get_query_var( $tax )
                    : false,
                'name'            => $tax,
                'id'              => $tax,
                'walker'          => $walker,
            ) );
        }

    }

}

E então você só precisa de uma classe de Walker personalizada.

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

Eu só queria fazer uma nota rápida. Nas versões mais recentes do WP, as listagens de postagem no admin são tratadas pela classe WP_Posts_List_Table. O código apply_filters agora é o seguinte:

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

Então, para adicionar novas colunas, um gancho add_filter deve ser assim:

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

Aqui vai um exemplo:

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

Agora, para as linhas post. Este é o código que manipula os dados da coluna nas listagens:

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

Para recuperar os dados das nossas postagens, precisamos adicionar um gancho de ação como este:

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

Exemplo (este exemplo usa taxonomias, mas você pode consultar qualquer outro material):

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
mines

TRABALHA EM WP 3.2!

custom_post_type: books custom_taxonomy: genre

Modifique apenas se ele diz: // muda AQUI

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

Isso não é bem conhecido, eu acho, mas a partir do wordpress 3.5, você pode passar 'show_admin_column' => true para register_taxonomy. Isso faz duas coisas:

  1. Adiciona a coluna de taxonomia à visualização de lista do tipo de postagem admin
  2. Ao clicar no nome do termo na coluna de taxonomia, ele na verdade filtrará a lista para esse termo .

Portanto, não é exatamente o mesmo que ter um select, mas quase a mesma funcionalidade, largura apenas uma linha de código.

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

Além disso, como você pode ler, há um novo filtro adaptado para adicionar manualmente a coluna de taxonomia (se você realmente precisar).

2
Luca Reghellin

Aqui está uma maneira de fazer isso usando a ação restrict_manage_posts. Parece funcionar bem para mim e adiciona a capacidade de filtrar por taxonomia para todos os tipos de postagem e para as taxonomias relacionadas.

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

Uma nota - tentei restringir a profundidade porque algumas das minhas taxonomias hierárquicas são muito grandes, mas não funcionou - poderia ser um bug na função wp_dropdown_categories?

2
Brad Trivers

Versão hierárquica da resposta do @ somatic, conforme solicitado pelo @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);
    }

}
?>

Eu basicamente removi o código que criou as opções e coloquei isso em sua própria função. A função 'generate_taxonomy_options', além de pegar o tax_slug, também recebe um parâmetro pai e de nível. A função assume que suas opções de criação para o pai 0, que irá selecionar todos os termos do nível raiz. No loop, a função se chama recursivamente, usando o termo atual como pai e aumentando o nível em um. Ele automaticamente adiciona carrapatos ao lado, quanto mais fundo você desce a árvore e voila!

1
Manny Fleurmond

Atualização da resposta de @Drew Gourley para WP 3.3.1 (e incorporação de código de http://wordpress.org/support/topic/wp_dropdown_categories-generating-url-id-number-instead-of- lesma? respostas = 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";
    }
}
1
rinogo

Apenas tentei os dois códigos, do Mike e do somático, e fiquei imaginando como obter uma coisa de cada técnica:

Com o código de Mike, ele mostra a lista suspensa com a opção hierárquica , o que ajuda muito. Mas para exibir dois dropdowns eu tive que duplicar a instrução if ($typenow=='produtos') {...} na função restrict_listings_by_business() e também o if ($pagenow=='edit.php' && ... } na função convert_business_id_to_taxonomy_term_in_query($query) que agora fornece muito código.

Com o código do somático eu só preciso especificar as taxonomias que gostaria de ver como dropdowns e bam, works; $filters = array('taxo1', 'taxo2');

Pergunta: posso obter a abordagem somática e também ter a opção hierárquica ?

Muito obrigado mesmo assim por este tutorial, ajudei muito!

0
kevin

Desculpas pelo fato de que, como novo usuário, não posso postar comentários, mas posso postar uma resposta ...

A partir do WordPress 3.1 (RC 1), a resposta de Mike (que me serviu tão bem para os últimos dois meses) não funciona mais para mim; restringir por qualquer criança taxonomia dá um resultado vazio. Eu tentei atualizar o Somatic e funcionou muito bem; melhor ainda, funciona com várias consultas de taxonomia que foram trabalhadas nesta versão.

0
rsigg

O tutorial de Mike sobre isso é ótimo! Eu provavelmente não teria me incomodado em adicionar essa funcionalidade ao meu plugin Media Categories se eu tivesse que descobrir sozinho.

Dito isso, acho que usar parse_query e, em seguida, obter consulta para o termo não é necessário. É mais limpo para criar sua própria classe de caminhante personalizada. Talvez isso não fosse possível quando ele escreveu seu post - seus 3 anos de idade no momento da minha escrita isso.

Confira este ótimo trecho no github. Funciona como um encanto, altera os ID's nos valores suspensos em slugs, por isso funciona apenas de forma nativa sem modificar a consulta.

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

0
eddiemoya