Filtrare per campo personalizzato in un custom post type nella pagina admin

21 dic 2015, 15:31:56
Visualizzazioni: 37K
Voti: 13

Ho utilizzato Advanced Custom Fields per creare campi personalizzati per il nome della competizione, risposte ecc. Ho creato un custom post type per le competizioni come mostrato nell'immagine e ho usato il file functions.php di WordPress per creare le colonne dai valori dei miei campi personalizzati.

Sto cercando di ottenere una casella dropdown "Filtra per" con i diversi nomi/etichette delle competizioni come mostrato sotto, ma riesco a trovare solo soluzioni che utilizzano le tassonomie, che preferisco non utilizzare se possibile poiché ho usato solo campi personalizzati per tutto il resto.

È possibile creare un dropdown "Filtra per" personalizzato utilizzando solo campi personalizzati?

Filtro WordPress per campo personalizzato

2
Commenti

Puoi utilizzare l'hook restrict_manage_posts per aggiungere menu a tendina aggiuntivi. Non dimenticare che dovrai anche aggiungere della logica per il filtro, poiché WordPress non saprà cosa farne di default (a differenza dei menu a tendina delle tassonomie, che può gestire automaticamente).

David Gard David Gard
21 dic 2015 15:41:38

Come ulteriore idea - se lo desideri, puoi trasformare il Nome in un link all'interno della tua List Table, il che significa che puoi filtrare una Competizione cliccando sul nome, invece di usare un menu a tendina.

David Gard David Gard
21 dic 2015 17:10:11
Tutte le risposte alla domanda 5
2
14

E per visualizzare il risultato del filtro prova questo codice

add_filter( 'parse_query', 'prefix_parse_filter' );
function  prefix_parse_filter($query) {
   global $pagenow;
   $current_page = isset( $_GET['post_type'] ) ? $_GET['post_type'] : '';
   
   if ( is_admin() && 
     'competition' == $current_page &&
     'edit.php' == $pagenow && 
      isset( $_GET['competition-name'] ) && 
      $_GET['competition-name'] != '' ) {
   
    $competition_name                  = $_GET['competition-name'];
    $query->query_vars['meta_key']     = 'competition_name';
    $query->query_vars['meta_value']   = $competition_name;
    $query->query_vars['meta_compare'] = '=';
  }
}

Modifica la meta key e il meta value come richiesto. Ho utilizzato "competition_name" come meta_key e "competition-name" come nome del menu a tendina select.

21 dic 2015 16:32:28
Commenti

Bene, mi sentivo pigro quindi gli ho suggerito di fare un'ulteriore domanda ;)

David Gard David Gard
21 dic 2015 17:11:00

Sembra che le 2 risposte siano una risposta completa e dovrebbero essere combinate.

RCNeil RCNeil
10 lug 2017 20:28:07
2
11

L'azione restrict_manage_posts attiva la funzione add_extra_tablenav(), che è il modo in cui puoi aggiungere menu a discesa aggiuntivi alla tua List Table desiderata.

Nell'esempio seguente, prima ci assicuriamo che il Post Type sia corretto, e poi recuperiamo tutti i valori del database memorizzati con la chiave competition_name nella tabella postmeta (devi cambiare il nome della chiave se necessario). La query è abbastanza semplice e verifica solo se la Competizione è pubblicata, prende solo valori unici (non vuoi duplicati nel menu a discesa) e poi li ordina alfabeticamente.

Successivamente controlliamo se ci sono risultati (non ha senso mostrare il menu a discesa se non c'è nulla), e poi costruiamo le opzioni (includendo un valore predefinito per mostrare tutto). Infine viene mostrato il menu a discesa.

Come indicato nel mio commento, questa non è la fine della storia però; avrai bisogno di qualche logica per dire alla List Table di mostrare solo i risultati desiderati quando il filtro è attivo, ma ti lascio dare un'occhiata a questo e poi aprire un'altra domanda se hai bisogno di ulteriore assistenza. Suggerimento - controlla il file /wp-admin/includes/class-wp-posts-list-table.php, e il suo genitore .../wp-class-list-table.php

/**
 * Aggiunge menu a discesa aggiuntivi alle List Tables
 *
 * @param required string $post_type    Il Post Type che viene visualizzato
 */
add_action('restrict_manage_posts', 'add_extra_tablenav');
function add_extra_tablenav($post_type){
    
    global $wpdb;
    
    /** Assicurati che sia il Post Type corretto */
    if($post_type !== 'competition')
        return;
    
    /** Recupera i risultati dal database */
    $query = $wpdb->prepare('
        SELECT DISTINCT pm.meta_value FROM %1$s pm
        LEFT JOIN %2$s p ON p.ID = pm.post_id
        WHERE pm.meta_key = "%3$s" 
        AND p.post_status = "%4$s" 
        AND p.post_type = "%5$s"
        ORDER BY "%6$s"',
        $wpdb->postmeta,
        $wpdb->posts,
        'competition_name', // La tua meta key - cambia se necessario
        'publish',          // Stato del post - cambia se necessario
        $post_type,
        'competition_name'
    );
    $results = $wpdb->get_col($query);
    
    /** Assicurati che ci siano opzioni da mostrare */
    if(empty($results))
        return;

    // ottieni l'opzione selezionata se ce n'è una
    if (isset( $_GET['competition-name'] ) && $_GET['competition-name'] != '') {
        $selectedName = $_GET['competition-name'];
    } else {
        $selectedName = -1;
    }
    
    /** Recupera tutte le opzioni che dovrebbero essere mostrate */
    $options[] = sprintf('<option value="-1">%1$s</option>', __('Tutte le Competizioni', 'your-text-domain'));
    foreach($results as $result) :
        if ($result == $selectedName) {
            $options[] = sprintf('<option value="%1$s" selected>%2$s</option>', esc_attr($result), $result);
        } else {
            $options[] = sprintf('<option value="%1$s">%2$s</option>', esc_attr($result), $result);
        }
    endforeach;

    /** Mostra il menu a discesa */
    echo '<select class="" id="competition-name" name="competition-name">';
    echo join("\n", $options);
    echo '</select>';

}
21 dic 2015 16:18:17
Commenti

Quando utilizzo questo codice, ottengo l'errore Notice: wpdb::prepare was called incorrectly. The query does not contain the correct number of placeholders (6) for the number of arguments passed (5). Please see Debugging in WordPress for more information. (This message was added in version 4.8.3.) in /[...]/wp-includes/functions.php on line 4773

rassoh rassoh
10 lug 2019 14:28:10

Sto ricevendo lo stesso errore

Vasim Shaikh Vasim Shaikh
30 gen 2020 21:02:37
0

Se questo non funziona per qualcuno, la mia soluzione è stata quella di aggiungere la colonna che stavo cercando di filtrare alla lista delle colonne ordinabili per il mio custom post type.

// Rendi ordinabili le colonne personalizzate del Custom Post Type
function cpt_custom_columns_sortable( $columns ) {

    // Aggiungi le nostre colonne all'array $columns
    $columns['item_number'] = 'item_number';
    $columns['coat_school'] = 'coat_school'; 

    return $columns;
} add_filter( 'manage_edit-your-custom-post-type-slug_sortable_columns', 'cpt_custom_columns_sortable' );
9 apr 2019 18:46:04
0

Sostituisci la query qui sotto per correggere l'errore wpdb:prepare:

$query = $wpdb->prepare('
        SELECT DISTINCT pm.meta_value FROM %1$s pm
        LEFT JOIN %2$s p ON p.ID = pm.post_id
        WHERE pm.meta_key = "%3$s" 
        AND p.post_status = "%4$s" 
        AND p.post_type = "%5$s"
        ORDER BY "%3$s"',
        $wpdb->postmeta,
        $wpdb->posts,
        'competition_name', // La tua meta key - modificare se necessario
        'publish',         // Stato del post - modificare se necessario
        $post_type,
        'competition_name' //necessario una seconda volta per definire "%3$s" in ORDER BY
  );
12 mar 2020 16:44:25
0

Ho affrontato lo stesso problema quando cercavo di filtrare un custom-post-type con un custom-field
ma ho risolto il problema seguendo questi passaggi.
Ho convertito il nome del custom-field da writer a _writer
e poi ho aggiornato il seguente codice all'interno della callback function dell'hook parse_query in modo da poter aggiungere una meta_query per il custom-field come segue

$query->set( 'meta_query', array(
    array(
          'key'     => '_writer',
           'compare' => '=',
           'value'   => $_GET['_writer'],
           'type'    => 'numeric',
      )
) );         

Questa soluzione sopra ha funzionato per me.
Documentazione https://developer.wordpress.org/reference/hooks/pre_get_posts/
Link utili https://developer.wordpress.org/reference/hooks/pre_get_posts/#comment-2571
https://stackoverflow.com/questions/47869905/how-can-i-filter-records-in-custom-post-type-list-in-admin-based-on-user-id-that

8 lug 2020 01:19:25