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

11 ago 2010, 23:16:49
Vistas: 37.3K
Votos: 55

Cuando edito uno de mis tipos de entrada personalizados, quiero poder listar todas las entradas por un campo personalizado en lugar de la fecha de publicación (que probablemente no es relevante para un tipo de entrada personalizado). Obtuve una pista de los comentarios de una entrada de blog sobre tipos de entrada personalizados donde el autor mencionaba que era posible e incluso logró que se pudiera hacer clic en los nombres de las columnas para un ordenamiento personalizado. Mencionó la función posts_orderby que anoté en mis propios comentarios, pero ahora no puedo encontrar la entrada del blog. ¿Alguna sugerencia? Vi una solución que usaba

add_action('wp', 'check_page');

Y la función check_page utilizaba add_filter para cambiar la consulta, pero estoy bastante seguro de que solo funcionaría en los archivos del tema, no en el área de administración.

1
Comentarios

Aquí otra respuesta útil, para ordenar publicaciones por ....<br/> http://wordpress.stackexchange.com/questions/66455/how-to-change-order-of-posts-in-admin

T.Todua T.Todua
22 may 2014 22:33:20
Todas las respuestas a la pregunta 3
5
68

Como probablemente puedas 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 personalizada de "movie" y una clave de campo personalizado de "Género".

Descargo de responsabilidad: esto funciona con WP3.0 pero no puedo asegurar que funcione con versiones anteriores.

Básicamente necesitas enganchar dos (2) hooks para que funcione y otros dos (2) para hacerlo obvio y útil.

El primer hook es 'restrict_manage_posts' que te permite emitir un HTML <select> en el área sobre la lista de publicaciones donde están los filtros "Acciones en masa" y "Mostrar fechas". El código proporcionado generará la funcionalidad "Ordenar por:" como se ve en este fragmento de pantalla:

Cómo crear funcionalidad de Ordenar Por para un Tipo de Publicación Personalizada en el Admin de WordPress
(fuente: mikeschinkel.com)

El código usa SQL directo porque no hay una función API de WordPress que proporcione la lista de todos los meta_keys para tipos de publicación (suena como un futuro ticket de trac para mí...) De todos modos, aquí está el código. Nota que obtiene el tipo de publicación de $_GET y valida para asegurarse que es un tipo de publicación válido post_type_exists() así como también que sea un tipo de publicación movie (esas dos verificaciones son excesivas pero lo hice para mostrarte cómo hacerlo si no quieres codificar el tipo de publicación). Finalmente uso el parámetro URL sortby 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\">Sin Orden</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 "Ordenar por: " . implode("\n",$html);
        }
    }
}

El segundo paso requerido es usar el hook parse_query que se llama después de que WordPress decide qué consulta ejecutar pero antes de ejecutarla. Aquí podemos establecer valores de orderby y meta_key en el array query_var de la consulta que están documentados en el Codex en el parámetro orderby para query_posts(). Verificamos que:

  1. Estamos en el admin (is_admin()),
  2. Estamos en la página que lista publicaciones en el admin ($pagenow=='edit.php'),
  3. La página ha sido llamada con un parámetro URL post_type igual a movie, y
  4. La página también ha sido llamada con un parámetro URL sortby y que no se pasó un valor de 'None'

Si todas esas pruebas pasan, entonces establecemos los query_vars (como se documenta aquí) a meta_value y nuestro valor sortby 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 hooks "posts_order" o "wp"! Por supuesto, en realidad necesitas hacer más; necesitas agregar algunas columnas en tu página que lista las publicaciones para que realmente puedas ver los valores por los que está ordenando, de lo contrario los usuarios se confundirán mucho. Entonces agrega un hook manage_{$post_type}_posts_columns, en este caso manage_movie_posts_columns. Este hook recibe el array predeterminado de columnas y por simplicidad simplemente lo reemplacé con dos columnas estándar; un checkbox (cb) y un nombre de publicación (title). (Puedes inspeccionar posts_columns con un print_r() para ver qué más está disponible por defecto.)

Decidí agregar un "Ordenado Por:" para cuando hay un parámetro URL sortby y cuando no 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' => 'Nombre de Película',
        );
    if (isset($_GET['sortby']) && $_GET['sortby'] !='None') 
        $posts_columns['meta_value'] = 'Ordenado Por';

    return $posts_columns;
}

Finalmente usamos el hook manage_pages_custom_column para mostrar 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 parámetro URL sortby extraemos el valor del campo personalizado que se está ordenando y lo mostramos en nuestra lista. Así es como se ve (recuerda, estos son datos de prueba, ¡así que sin comentarios sobre las clasificaciones de películas! :):

Columnas Personalizadas agregadas para un Tipo de Publicación Personalizada en el Admin 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;
        }
    }
}

Nota que esto solo captura el primer "Género" para una movie, es decir, el primer meta_value en caso de múltiples valores para una clave dada. ¡Pero de nuevo, no estoy seguro de cómo funcionaría de otra manera!

Y para aquellos no familiarizados con dónde poner este código, puedes ponerlo en un plugin o, más probablemente para los principiantes, en el archivo functions.php de tu tema actual.

Espero que esto ayude.

12 ago 2010 04:13:49
Comentarios

+1, solo por el esfuerzo. Pero sería aún mejor si los círculos estuvieran dibujados a mano :-)

Jan Fabry Jan Fabry
12 ago 2010 10:34:03

¿Alguna idea sobre cómo eliminar completamente el filtro MOSTRAR TODAS LAS FECHAS para que solo se muestren mis filtros personalizados para un tipo de publicación específico?

RailsTweeter RailsTweeter
22 may 2014 20:02:41

@RailsTweeter Usa la técnica que mostré aquí donde los dos hooks que enmarcan la generación del HTML son 'months_dropdown_results' y 'restrict_manage_posts'. PD: Los votos positivos siempre son apreciados. :)

MikeSchinkel MikeSchinkel
23 may 2014 02:56:47

@MikeSchinkel, ahora que existe la API de WP, ¿esto actualizará tu código de alguna manera?

samjco-com samjco-com
16 feb 2019 22:23:09

@samjco No estoy seguro. Lamentablemente no tengo tiempo para revisar esto en este momento.

MikeSchinkel MikeSchinkel
17 feb 2019 04:53:09
0

A partir de WordPress 3.1 (estoy usando la versión beta) las columnas ahora pueden ser ordenables a través de sus títulos.

El siguiente artículo detalla cómo implementarlas.

http://scribu.net/wordpress/custom-sortable-columns.html

12 dic 2010 14:23:06
0
-1

Aquí tienes una solución simple:

/* --------Eventos ordenables en el Dashboard - mostrar fecha de inicio, hora, lugar--------- */

/*-------------------------------------------------------------------------------
    Columnas Personalizadas
-------------------------------------------------------------------------------*/

function mis_columnas_*TU TIPO DE POST*($columns)
{
    $columns = array(
        'cb'        => '<input type="checkbox" />',
        'title'     => 'Título',
        'tu_campo_personalizado'     => 'Nombre del Campo Personalizado',          
        'date'      =>  'Fecha',
    );
    return $columns;
}

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

}

add_action("manage_posts_custom_column", "mis_columnas_personalizadas");
add_filter("manage_edit-*TU TIPO DE POST*_columns", "mis_columnas_eventos");

/*-------------------------------------------------------------------------------
    Columnas Ordenables
-------------------------------------------------------------------------------*/

function registrar_columnas_ordenables( $columns )
{
    $columns['tu_campo_personalizado'] = 'tu_campo_personalizado';
    return $columns;
}

add_filter("manage_edit-*TU TIPO DE POST*_sortable_columns", "registrar_columnas_ordenables" );

Solo reemplaza TU TIPO DE POST y 'tu_campo_personalizado'

16 may 2016 15:57:05