Mostrar imagen para una categoría usando get_categories o mostrar una imagen de cualquier entrada hija

19 feb 2014, 18:59:09
Vistas: 70.5K
Votos: 5

Estoy usando get_categories para listar las categorías hijas de una categoría padre.

Quiero añadir una imagen a las categorías hijas, usando la salida de get_categories.

  • Puedo tomar la imagen destacada de cualquiera de las entradas que son hijas de la categoría en la que estoy usando get_categories, es decir, la nieta de la categoría padre. No quiero mostrar ninguna otra información nieta, y solo querría una imagen destacada de cada conjunto de categorías hijas.

El código que uso actualmente es

$args = array('child_of'  => 1  );
$categories = get_categories($args);
  foreach($categories as $category) { 
    echo '<p>Categoría:'. $category->name.' </p> ';
    echo '<p>Descripción:'. $category->description . '</p>';
    echo PONER IMAGEN DE CATEGORÍA AQUÍ;
     } 
  • O podría añadir una imagen a una categoría usando algún plugin, y mostrarla en la salida de foreach($categories as $category).

Pero, ¿cuál es la mejor (y más fácil) manera de implementar esto?

7
Comentarios

Primero deberías decidir cuál de esas dos opciones quieres. Luego podrías agregar cualquier código que ya tengas.

kraftner kraftner
19 feb 2014 19:04:03

Preferiría tomar una imagen destacada de una publicación, pero si esa solución es complicada y la otra es simple, entonces optaría por la solución más sencilla.

Jon Jon
20 feb 2014 08:36:31

Por cierto, si estás buscando un plugin, hay uno llamado Category Thumbnails que podría servirte. No lo he probado personalmente, pero su uso es bastante intuitivo - y está descrito en el repositorio del plugin.

Nicolai Grossherr Nicolai Grossherr
25 feb 2014 17:08:00

pero necesitaría llamarlo en una función get_categories o similar, y esa parte no está tan clara

Jon Jon
25 feb 2014 17:10:09

Deberías decidir cuál de las dos opciones quieres, de lo contrario esto no es una pregunta, sino 3 preguntas. Cómo hago X, Cómo hago Y, y, Debería usar X o Y

Tom J Nowell Tom J Nowell
1 mar 2014 18:43:34

También sospecho que no entiendes cómo funcionan los posts y términos jerárquicos, un término contiene automáticamente todos los posts asignados a términos hijos y nietos. Por ejemplo, todas las canciones del subgénero dance pop siguen siendo parte del género principal Pop, y lo mismo ocurre con los términos jerárquicos en WordPress. Esta parte también contaría como una 4ta pregunta

Tom J Nowell Tom J Nowell
1 mar 2014 18:46:36

Creo que estás perdiendo de vista el panorama general. La pregunta es cómo hago A. X & Y parecen ser las formas de hacer esto. Usando la más simple entre X o Y, ¿cómo hago A? Vuelve a leerlo

Jon Jon
1 mar 2014 19:37:53
Mostrar los 2 comentarios restantes
Todas las respuestas a la pregunta 4
6

Esto es posible con un filtro en get_terms.

function grab_child_image($terms,$taxonomies,$args) {
  // var_dump($terms,$taxonomies,$args); // debug
  foreach ($terms as &$term) {
    $cp = new WP_Query(
      array (
        'cat' => $term->term_id,
        'fields' => 'ids',
        'ignore_sticky_posts' => true
      )
    );
    // var_dump($cp->posts); // debug
    if ($cp->have_posts()) {
      $attach = new WP_Query(
        array (
          'post_parent__in' => $cp->posts,
          'post_type' => 'attachment',
          'post_status' => 'inherit',
          'ignore_sticky_posts' => true,
          'posts_per_page' => 1
        )
      );
      if ($attach->have_posts()) {
        $term->image = wp_get_attachment_image($attach->posts[0]->ID);
      } else {
        $term->image = 'alguna otra imagen';
      }
    }
  }
  return $terms;
}
add_filter('get_terms','grab_child_image',10,3);

$args = array('child_of'  => 1  );
$categories = get_categories($args);
foreach($categories as $category) { 
  echo '<p>Categoría:'. $category->name.' </p> ';
  echo '<p> Descripción:'. $category->description . '</p>';
  echo $category->image;
} 

remove_filter('get_terms','grab_child_image',10,3);

Hay varias consultas ahí, así que añade ese filtro solo cuando lo necesites y elimínalo después.

Existen una serie de funciones relacionadas con imágenes que podrías usar en su lugar, si wp_get_attachment_image() no cumple con tus necesidades, y puedes pasar un parámetro $size a wp_get_attachment_image()-- segundo parámetro-- para obtener diferentes tamaños de imagen. Por ejemplo, reemplaza la línea de código con esto:

$term->image = wp_get_attachment_image($attach->posts[0]->ID, $size->full);

Puedes alterar aún más la salida de wp_get_attachment_image() aplicando un filtro a wp_get_attachment_image_attributes-- por ejemplo, para añadir una clase como se hace aquí.

1 mar 2014 18:29:13
Comentarios

funciona - ¡excelente! 2 preguntas. Está extrayendo miniaturas. ¿Cómo puedo cambiarlo para que use la imagen destacada en lugar de la versión miniatura? También, ¿cómo puedo añadir una clase a la etiqueta img? Gracias

Jon Jon
1 mar 2014 20:11:59

@Jon: mira la edición.

s_ha_dum s_ha_dum
1 mar 2014 20:30:19

Agregué el código funcional real para el cambio de tamaño ya que no estaba seguro de qué hacer hasta que probé algunas cosas.

Jon Jon
2 mar 2014 13:42:03

Re: cambiar la clase - Al hacer un bucle, necesitas sacar el filtro de eliminación de la función y ponerlo después del bucle, o solo funcionará una vez.

Jon Jon
2 mar 2014 14:06:15

remove_filter() está después del bucle foreach en mi código.

s_ha_dum s_ha_dum
2 mar 2014 15:49:08

Perdón, me refería al remove_filter('wp_get_attachment_image_attributes','alter_attr_wpse_102158'); de tu respuesta enlazada para agregar clase. Puse ese remove junto con el remove get_terms. Pero tu respuesta enlazada necesita un poco de ajuste, por si alguien más está leyendo esto y está atascado.

Jon Jon
2 mar 2014 16:27:45
Mostrar los 1 comentarios restantes
6

En lugar de usar get_categories(), te sugiero que eches un vistazo a wp_list_categories(). Puedes obtener el mismo resultado con esta función, pero tiene la ventaja de ser altamente personalizable.

Hay dos formas de personalización, ya sea mediante el hook de filtro wp_list_categories - ver en código fuente - o extendiendo la clase Walker_Category - ver en código fuente. La última opción te da muchas más posibilidades de personalización, pero puede ser excesiva para cambios menores. Así que debes evaluar qué se adapta mejor a tus necesidades.

Como este tema está bastante bien cubierto en WPSE y SO, solo te daré una breve lista de referencias. Además, no has dado una descripción lo suficientemente específica de tus necesidades, por lo que sigue siendo un poco vago, aunque se puede intuir lo que quieres. De todos modos, los recursos a continuación deberían ayudarte a elegir el método adecuado y permitirte lograrlo.

  1. Hook de filtro wp_list_categories
  2. Clase Walker_Category

Un comentario más, personalmente casi siempre optaría por extender la clase Walker_Category, excepto para casos donde el cambio que deseas es muy menor. Esto es, por supuesto, un poco de preferencia personal, pero tiene fundamento, particularmente por la reutilización, extensibilidad y - aunque no lo parezca - a menudo, incluso la mayoría de las veces, es la forma más fácil de lograr la salida personalizada.


Miniatura de entrada en categoría hija:

De esta manera puedes recuperar tu "miniatura de categoría" de una entrada aleatoria que pertenezca a una de las categorías hijas.

He comentado el código para que entiendas cómo se hace, además de que debería ser bastante autoexplicativo.

/**
 * wpse135208_cat_thumb_from_random_child.
 *
 * Obtiene la miniatura de una entrada aleatoria perteneciente a una de las categorías hijas.
 *
 * @version 0.1
 *
 * @link https://wordpress.stackexchange.com/q/135208/22534
 *
 * @param integer $c_cat (default: '')
 * @param string/array $size (default: 'post-thumbnail')
 * @param string/array $attr (default: null)
 *
 * @return string
 */
function wpse135208_cat_thumb_from_random_child( $c_cat = '', $size = 'post-thumbnail', $attr = null ) {
    // no hacer nada si $c_cat está vacío
    if( empty($c_cat) ) return;
    // se usa get_terms porque solo necesitamos ids
    $taxonomies = array(
        'category'
        );
    $args = array(
        'child_of' => $c_cat,
        'fields' => 'ids'
        );
    // retorna un array de ids
    $child_cats = get_terms( $taxonomies, $args );
    // usar esto para depuración
    //echo '<pre>'; print_r($child_cats); echo '</pre>';

    $args = array(
        // usamos numberposts en lugar de post_per_page,
        // porque si se usa el filtro pre_get_posts,
        // puede hacer una diferencia en este caso
        // solo queremos una entrada
        'numberposts' => 1,
        // pero la aleatorizamos
        'orderby' => 'rand',
        'category__in' => $child_cats,
        'fields' => 'ids',
        // asegurarse de solo considerar entradas con imagen destacada
        'meta_query' => array(
            array(
                'key' => '_thumbnail_id',
                'compare' => 'EXISTS'
            )
        )
        );
    // retorna un array conteniendo un id de entrada
    $ct_p_id = get_posts( $args );
    // usar esto para depuración
    //echo '<pre>'; print_r($ct_p_id); echo '</pre>';

    // usar esto para depuración
    //echo '<pre>'; print_r( ( 1 /*cambiar a 0 para mostrar info de src*/ ) ? get_the_post_thumbnail( $ct_p_id[0], $size, $attr ) : wp_get_attachment_image_src( get_post_thumbnail_id( $ct_p_id[0] ) ) ); echo '</pre>';
    // ahora podemos usar esto para retornar nuestra miniatura
    return get_the_post_thumbnail( $ct_p_id[0], $size, $attr );
}

Uso así:

echo wpse135208_cat_thumb_from_random_child( '1', 'thumbnail', null );

En tu código úsalo como se muestra a continuación:

$categories = get_categories($args);
foreach($categories as $category) {
    echo wpse135208_cat_thumb_from_random_child($category->cat_ID);
}

Miniatura de categoría vía plugin:

Esto tiene el beneficio de tener miniaturas reales para categorías.

Le he dado una prueba rápida al plugin - Category Thumbnails - que mencioné en el comentario anterior. Funciona generalmente y siento que es una mejor solución que lo que propones en tu respuesta, porque te permite gestionar las miniaturas a través de la biblioteca multimedia de WordPress.

Descubrí un pequeño error, el autor del plugin ha sido notificado y respondió al instante, por lo que el error se corregirá pronto. Si no puedes esperar puedes corregirlo tú mismo así:

Sin embargo la función

the_category_thumbnail();

no produce una salida. En el código fuente de la versión 1.0.3 se ve así:

function the_category_thumbnail($category_id = null, $sizes = array()) {
    print get_the_category_thumbnail($cat, $sizes);
}

Solucioné el problema así:

function the_category_thumbnail($category_id = null, $sizes = array()) {
    print get_the_category_thumbnail($category_id, $sizes);
}

Es decir, igualando el nombre del parámetro/argumento.

O simplemente puedes usar get_the_category_thumbnail() en su lugar, solo tienes que hacer echo:

echo get_the_category_thumbnail('1');

Otra pequeña decepción es que el plugin y las funciones que ofrece no te dan la posibilidad de trabajar con los tamaños de imagen generados. Lo cual no es tan bueno, porque queremos el tamaño correcto y no siempre el tamaño completo. Voy a notificar al autor sobre esto también, para que pueda mejorar su plugin. Mientras tanto, esto puede solucionarse fácilmente construyendo una función personalizada:

/**
 * wpse135208_cat_thumb_wrapper.
 *
 * Función envoltorio para tener la capacidad de usar tamaños de imagen predefinidos via wp_get_attachment_image().
 *
 * @version 0.1
 *
 * @link https://wordpress.stackexchange.com/q/135208/22534
 *
 * @param integer $category_id (default: null)
 * @param string/array $size (default: 'thumbnail')
 * @param boolean $icon (default: false)
 * @param string/array (default: null)
 *
 * @return string
 */
function wpse135208_cat_thumb_wrapper( $category_id = null, $size = 'thumbnail', $icon = false, $attr = null ) {
    $category_thumbnail_obj = get_the_category_data( $category_id );
    return wp_get_attachment_image( $category_thumbnail_obj->id, $size, $icon, $attr );
}

Uso así:

echo wpse135208_cat_thumb_wrapper( '1', 'thumbnail', false, null );

Esto debería ayudarte a que funcione. Como dije, es preferible porque puedes gestionar tu miniatura de categoría a través de la biblioteca multimedia. En tu código úsalo como se muestra a continuación:

$categories = get_categories($args);
foreach($categories as $category) {
    echo wpse135208_cat_thumb_wrapper($category->cat_ID);
}
23 feb 2014 19:57:28
Comentarios

Quiero un bucle de una sola categoría con título, descripción e imagen de las subcategorías, sin información de entradas, pero que pueda tomar cualquier imagen de cualquier entrada nieta para la imagen de la categoría hija. Tengo un get categories funcionando y el for each que hace el bucle. He visto otras publicaciones usando get categories con varios plugins para obtener una imagen. No sé cómo implementaron su plugin. Pero quizás una función walker funcionaría mejor que un plugin para esto?

Jon Jon
23 feb 2014 20:41:23

"Thumbnail from post in child category" es exactamente lo que estaba buscando. No estoy enamorado de mi solución pero funciona, pero esta claramente es mejor - pero no obtengo ningún resultado. Intenté tanto echo function( '1', 'thumbnail', null ); como usando $category->cat_ID y $category->term_id pero nada

Jon Jon
1 mar 2014 19:58:17

Sí, ahora muestra imágenes. Pero parece estar repitiendo la misma imagen de una sola categoría, no una imagen de cada categoría. La solución de s_ha_dum funciona bien. Gracias

Jon Jon
2 mar 2014 13:29:33

Ya veo, la lección aquí es no hacer las cosas con prisa, tenía un error tipográfico ahí. Además cambié post_per_page por numberposts, porque en este caso es o al menos puede ser beneficioso. Aparte de eso, usa la respuesta que mejor se adapte a ti. @Jon

Nicolai Grossherr Nicolai Grossherr
2 mar 2014 15:32:06

Gracias por la solución, y aprendí mucho de la función

Jon Jon
2 mar 2014 15:35:30

Un placer, por cierto, elegir las respuestas de s_ha_dum nunca es mala idea, porque es increíblemente bueno en esto. @Jon

Nicolai Grossherr Nicolai Grossherr
2 mar 2014 15:49:48
Mostrar los 1 comentarios restantes
1

Bueno, logré hacer lo que creo que quieres hacer usando Advanced Custom Fields, creando un nuevo conjunto de campos personalizados con un campo personalizado de tipo imagen. Desde allí, establece las reglas de ubicación como "Taxonomy Term" > "is equal to" > "Categories" (o cualquier taxonomía para la que estés usando esto).

Una vez que publiques esto, debería actualizar la sección donde editas las taxonomías con un nuevo campo para una imagen. Ahora, todo se reduce a usar la función de ACF "get_field()" dentro de tu bucle foreach de categorías. Aquí está cómo obtener el campo desde la categoría.

Ejemplo:

<?php foreach ( $categories as $category ) {
    echo get_field('field_name_for_image', $category->taxonomy . "_" . $category->term_id);
} ?>

Si usaste la configuración predeterminada de ACF, deberías obtener un array, que es el objeto de la imagen. Para eso, revisa la documentación sobre Image Field Types de ACF.

Me tomó menos de 5 minutos configurar esto, y el plugin es gratuito. ¡Espero que sea rápido y fácil para ti!

¡Mucha suerte!

25 feb 2014 16:50:10
Comentarios

Voy a echar un vistazo y ver si puedo hacer que funcione. Gracias

Jon Jon
25 feb 2014 16:53:56
0

WordPress tiene el código - http://codex.wordpress.org/Function_Reference/get_the_category

     Mostrar Imágenes de Categorías
Este código muestra imágenes de categorías nombradas según el cat_ID con el atributo alt establecido como cat_name. También puedes usar cualquiera de las otras variables miembro.

<?php 
foreach((get_the_category()) as $category) { 
    echo '<img src="http://example.com/images/' . $category->cat_ID . '.jpg" alt="' . $category->cat_name . '" />'; 
} 
?>

Esto permite configurar imágenes dentro de las funciones get_categories. Las imágenes deben configurarse para que coincidan con la función. Por lo tanto, si se usa $category->name, la imagen debe guardarse en la carpeta correcta con el nombre que coincida con la categoría.

26 feb 2014 18:27:59