Cómo ordenar el área de administración de un tipo de publicación personalizada de WordPress por un campo personalizado

52

Al editar uno de mis tipos de publicaciones personalizadas, quiero poder enumerar todas las entradas por un campo personalizado en lugar de la fecha en que se publican (que, para un tipo de publicación personalizada, probablemente no sea relevante). Obtuve una ventaja de los comentarios de una publicación de blog sobre tipos de publicaciones personalizadas y el autor dijo que era posible y que incluso lo hizo para que pudiera hacer clic en los nombres de las columnas para una clasificación personalizada. Mencionó la posts_orderbyfunción que noté en mis propios comentarios, pero ahora ya puedo encontrar la publicación del blog. ¿Alguna sugerencia? Vi una solución que usaba

add_action('wp', 'check_page');

Y la check_pagefunción solía add_filtercambiar la consulta, pero estoy bastante seguro de que solo funcionaría en los archivos de tema, no en el área de administración.

Tooshel
fuente
1
Aquí otra respuesta útil, para ordenar las publicaciones por .... <br/> wordpress.stackexchange.com/questions/66455/…
T.Todua

Respuestas:

66

Como probablemente pueda imaginar por la falta de respuestas proporcionadas, la solución no es exactamente trivial. Lo que he hecho es crear un ejemplo algo autónomo que asume un tipo de publicación personalizado de " movie" y una clave de campo personalizada de " Género ".

Descargo de responsabilidad : esto funciona con WP3.0 pero no puedo estar seguro de que funcionará con versiones anteriores.

Básicamente, necesita enganchar dos (2) ganchos para que funcione y otros dos (2) para que sea obvio y útil.

El primer enlace es ' restrict_manage_posts' que le permite emitir un HTML <select>en el área sobre la lista de publicaciones donde se filtran las " Acciones masivas " y " Mostrar fechas ". El código proporcionado generará la funcionalidad " Ordenar por: " como se ve en este fragmento de pantalla:

Cómo crear la funcionalidad Ordenar por para un tipo de publicación personalizada en el administrador de WordPress
(fuente: mikeschinkel.com )

El código usa SQL directo porque no hay una función API de WordPress para proporcionar la lista de todas las meta_keys para un tipo de publicación (me parece un boleto de tráfico futuro ...) De todos modos, aquí está el código. Tenga en cuenta que toma el tipo de publicación $_GETy lo valida para asegurarse de que sea tanto un tipo de publicación válido post_type_exists()como un movietipo de publicación (esas dos comprobaciones son excesivas, pero lo hice para mostrarle cómo, si no quiere hacerlo) codifique el tipo de publicación.) Por último, uso el sortbyparámetro URL ya que no entra en conflicto con nada más en WordPress:

add_action('restrict_manage_posts','restrict_manage_movie_sort_by_genre');
function restrict_manage_movie_sort_by_genre() {
    if (isset($_GET['post_type'])) {
        $post_type = $_GET['post_type'];
        if (post_type_exists($post_type) && $post_type=='movie') {
            global $wpdb;
            $sql=<<<SQL
SELECT pm.meta_key FROM {$wpdb->postmeta} pm
INNER JOIN {$wpdb->posts} p ON p.ID=pm.post_id
WHERE p.post_type='movie' AND pm.meta_key='Genre'
GROUP BY pm.meta_key
ORDER BY pm.meta_key
SQL;
            $results = $wpdb->get_results($sql);
            $html = array();
            $html[] = "<select id=\"sortby\" name=\"sortby\">";
            $html[] = "<option value=\"None\">No Sort</option>";
            $this_sort = $_GET['sortby'];
            foreach($results as $meta_key) {
                $default = ($this_sort==$meta_key->meta_key ? ' selected="selected"' : '');
                $value = esc_attr($meta_key->meta_key);
                $html[] = "<option value=\"{$meta_key->meta_key}\"$default>{$value}</option>";
            }
            $html[] = "</select>";
            echo "Sort by: " . implode("\n",$html);
        }
    }
}

El segundo paso requerido es usar el parse_querygancho que se llama después de que WordPress decida qué consulta debe ejecutarse pero antes de ejecutarla. Aquí podemos establecer valores de orderbyy meta_keyen la query_varmatriz de la consulta que están documentados en el Codex en el orderbyparámetro para query_posts(). Probamos para asegurarnos de que:

  1. Estamos en el administrador ( is_admin()),
  2. Estamos en la página que enumera las publicaciones en admin ( $pagenow=='edit.php'),
  3. Se ha llamado a la página con un post_typeparámetro de URL igual a movie, y
  4. También se ha llamado a la página con un sortbyparámetro de URL y no se le ha pasado el valor ' Ninguno '

Si todas esas pruebas pasan, configuramos query_vars(como se documenta aquí ) meta_valuey nuestro sortbyvalor para ' Género ':

add_filter( 'parse_query', 'sort_movie_by_meta_value' );
function sort_movie_by_meta_value($query) {
    global $pagenow;
    if (is_admin() && $pagenow=='edit.php' &&
        isset($_GET['post_type']) && $_GET['post_type']=='movie' && 
        isset($_GET['sortby'])  && $_GET['sortby'] !='None')  {
        $query->query_vars['orderby'] = 'meta_value';
        $query->query_vars['meta_key'] = $_GET['sortby'];
    }
}

Y eso es todo lo que necesitas hacer; ¡no se requieren ganchos " posts_order" o " wp"! Por supuesto que realmente necesitas hacer más; necesita agregar algunas columnas en su página que enumeren las publicaciones para que pueda ver los valores por los que está ordenando, de lo contrario, los usuarios se confundirán mucho. Entonces agregue un manage_{$post_type}_posts_columnsgancho, en este caso manage_movie_posts_columns. Este gancho pasa la matriz predeterminada de columnas y, por simplicidad, simplemente lo reemplacé con dos columnas estándar; una casilla de verificación ( cb) y un nombre de publicación ( title). (Puede inspeccionar posts_columnscon a print_r()para ver qué más hay disponible de forma predeterminada).

Decidí agregar un " Ordenado por: " para cuando hay un sortbyparámetro de URL y cuando no lo es None:

add_action('manage_movie_posts_columns', 'manage_movie_posts_columns');
function manage_movie_posts_columns($posts_columns) {
    $posts_columns = array(
        'cb' => $posts_columns['cb'],
        'title' => 'Movie Name',
        );
    if (isset($_GET['sortby']) && $_GET['sortby'] !='None') 
        $posts_columns['meta_value'] = 'Sorted By';

    return $posts_columns;
}

Finalmente, usamos el manage_pages_custom_columngancho para mostrar realmente el valor cuando hay una publicación del tipo de publicación apropiado y con la prueba probablemente redundante para is_admin()y $pagenow=='edit.php'. Cuando hay un sortbyparámetro de URL, extraemos el valor del campo personalizado que se está ordenando por una visualización en nuestra lista. Esto es lo que parece (recuerde, estos son datos de prueba, ¡así que no hay comentarios de la galería de maní sobre las clasificaciones de películas! :):

Columnas personalizadas agregadas para un tipo de publicación personalizada en el administrador de WordPress
(fuente: mikeschinkel.com )

Y aquí está el código:

add_action('manage_pages_custom_column', 'manage_movie_pages_custom_column',10,2);
function manage_movie_pages_custom_column($column_name,$post_id) {
    global $pagenow;
    $post = get_post($post_id);
    if ($post->post_type=='movie' && is_admin() && $pagenow=='edit.php')  {
        switch ($column_name) {
            case 'meta_value':
                if (isset($_GET['sortby']) && $_GET['sortby'] !='None') {
                    echo get_post_meta($post_id,$_GET['sortby'],true);
                }
                break;
        }
    }
}

Tenga en cuenta que esto solo recoge el primer " Género " para a movie, es decir, el primer meta_valor en el caso de valores múltiples para una clave dada. Pero, de nuevo, no estoy seguro de cómo funcionaría de lo contrario.

Y para aquellos que no están familiarizados con dónde colocar este código, pueden ponerlo en un complemento o más probablemente para el novato en el functions.phparchivo en su tema actual.

Cómo ayuda esto

MikeSchinkel
fuente
2
+1, solo por el esfuerzo. Pero sería aún mejor si los círculos fueran dibujados a mano :-)
Jan Fabry
¿Alguna idea de cómo eliminar completamente el filtro MOSTRAR TODAS LAS FECHAS para que solo se muestren mis filtros personalizados para un tipo de publicación determinado?
RailsTweeter
@RailsTweeter Use la técnica que mostré aquí donde están los dos ganchos que encierran la generación HTML 'months_dropdown_results'y 'restrict_manage_posts'. Los votos a favor de PS siempre son apreciados. :)
MikeSchinkel
@MikeSchinkel, ahora que hay una API de WP, ¿esto actualizará un poco su código?
Samjco
@samjco No estoy seguro. Lamentablemente, no tengo tiempo para revisar esto en este momento.
MikeSchinkel
-1

Aquí hay una solución simple:

/* --------Sortable Events on Dashboard - show start date, time, venue--------- */

/*-------------------------------------------------------------------------------
    Custom Columns
-------------------------------------------------------------------------------*/

function my_*YOUR POST TYPE*_columns($columns)
{
    $columns = array(
        'cb'        => '<input type="checkbox" />',
        'title'     => 'Title',
        'your_custom_field'     => 'Custom Field Name',          
        'date'      =>  'Date',
    );
    return $columns;
}

function my_custom_columns($column)
{
    global $post;
    if($column == 'your_custom_field')
    {
        if(get_post_meta($post->ID, 'your_custom_field', true);)
        {
            echo get_post_meta($post->ID, 'your_custom_field', true);
        }
    }

}

add_action("manage_posts_custom_column", "my_custom_columns");
add_filter("manage_edit-*YOUR POST TYPE*_columns", "my_events_columns");

/*-------------------------------------------------------------------------------
    Sortable Columns
-------------------------------------------------------------------------------*/

function my_column_register_sortable( $columns )
{
    $columns['your_custom_field'] = 'your_custom_field';
    return $columns;
}

add_filter("manage_edit-*YOUR POST TYPE*_sortable_columns", "my_column_register_sortable" );

Simplemente reemplace SU TIPO DE PUBLICACIÓN y 'your_custom_field'

jake
fuente