Отображение изображения для категории с помощью get_categories или показ изображения из дочернего поста

19 февр. 2014 г., 18:59:09
Просмотры: 70.5K
Голосов: 5

Я использую get_categories для вывода дочерних категорий родительской категории.

Я хочу добавить изображение к дочерним категориям, используя вывод get_categories.

  • Я могу либо взять изображение записи из любого из постов, которые являются дочерними для категории, которую я использую с get_categories, то есть внучатые посты родительской категории. Я не хочу показывать никакой другой информации о внучатых категориях и хотел бы получить только одно изображение записи из каждого набора дочерних категорий.

Код, который я сейчас использую:

$args = array('child_of'  => 1  );
$categories = get_categories($args);
  foreach($categories as $category) { 
    echo '<p>Категория:'. $category->name.' </p> ';
    echo '<p>Описание:'. $category->description . '</p>';
    echo ЗДЕСЬ РАЗМЕСТИТЬ ИЗОБРАЖЕНИЕ КАТЕГОРИИ;
     } 
  • Или я мог бы добавить изображение к категории с помощью какого-нибудь плагина и показать его в выводе foreach($categories as $category).

Но какой самый лучший (и самый простой) способ реализовать это?

7
Комментарии

Сначала вам следует определиться, что из этих двух вариантов вам нужно. Затем вы можете добавить любой код, который у вас уже есть.

kraftner kraftner
19 февр. 2014 г. 19:04:03

Я бы предпочел брать featured image из поста, но если это решение слишком громоздкое, а альтернативное простое, то я выберу более простое решение.

Jon Jon
20 февр. 2014 г. 08:36:31

Кстати, если вы ищете плагин, есть один под названием Category Thumbnails, который может вам подойти. Сам не тестировал, но его использование довольно интуитивно понятно - и описано в репозитории плагина.

Nicolai Grossherr Nicolai Grossherr
25 февр. 2014 г. 17:08:00

но мне нужно вызвать эту функцию в get_categories или подобной функции, и эта часть не совсем понятна

Jon Jon
25 февр. 2014 г. 17:10:09

Вам нужно определиться, какой из двух вариантов вам нужен, иначе это не вопрос, а 3 вопроса: "Как сделать X", "Как сделать Y" и "Стоит ли использовать X или Y"

Tom J Nowell Tom J Nowell
1 мар. 2014 г. 18:43:34

Я также подозреваю, что вы не совсем понимаете, как работают записи и иерархические термины. Термин автоматически включает все записи, назначенные дочерним и внучатым терминам. Например, все песни в поджанре dance pop все равно относятся к основному жанру Pop, и то же самое верно для иерархических терминов в WordPress. Эта часть также может считаться 4-м вопросом

Tom J Nowell Tom J Nowell
1 мар. 2014 г. 18:46:36

Мне кажется, вы за деревьями не видите леса. Вопрос в том, как сделать А. X и Y кажутся способами это осуществить. Используя более простой из вариантов (X или Y), как мне сделать А? Перечитайте еще раз.

Jon Jon
1 мар. 2014 г. 19:37:53
Показать остальные 2 комментариев
Все ответы на вопрос 4
6

Это можно реализовать с помощью фильтра для get_terms.

function grab_child_image($terms,$taxonomies,$args) {
  // var_dump($terms,$taxonomies,$args); // отладка
  foreach ($terms as &$term) {
    $cp = new WP_Query(
      array (
        'cat' => $term->term_id,
        'fields' => 'ids',
        'ignore_sticky_posts' => true
      )
    );
    // var_dump($cp->posts); // отладка
    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 = 'какое-то другое изображение';
      }
    }
  }
  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>Категория:'. $category->name.' </p> ';
  echo '<p> Описание:'. $category->description . '</p>';
  echo $category->image;
} 

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

Здесь выполняется несколько запросов, поэтому добавляйте этот фильтр только когда он нужен, и удаляйте его после использования.

Существует ряд связанных функций для работы с изображениями, которые можно использовать вместо wp_get_attachment_image(), если она не подходит под ваши нужды. Вы также можете передать параметр $size в wp_get_attachment_image() (второй параметр) для получения изображений разных размеров. Например, замените строку кода на эту:

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

Вы можете дополнительно изменить вывод wp_get_attachment_image(), применив фильтр к wp_get_attachment_image_attributes — например, чтобы добавить класс, как показано здесь.

1 мар. 2014 г. 18:29:13
Комментарии

работает - отлично! 2 вопроса. Сейчас загружаются миниатюры. Как изменить это на featured image, а не на версию миниатюры? И еще, как добавить класс к тегу img. Спасибо

Jon Jon
1 мар. 2014 г. 20:11:59

@Jon : смотрите правки.

s_ha_dum s_ha_dum
1 мар. 2014 г. 20:30:19

Я добавил фактически рабочий код для изменения размера, так как не был уверен, что делать, пока не попробовал несколько вариантов.

Jon Jon
2 мар. 2014 г. 13:42:03

По поводу изменения класса - при использовании цикла нужно вынести remove_filter из функции и разместить его после цикла, иначе он сработает только один раз.

Jon Jon
2 мар. 2014 г. 14:06:15

remove_filter() действительно находится после цикла foreach в моем коде.

s_ha_dum s_ha_dum
2 мар. 2014 г. 15:49:08

Извините, я имел в виду remove_filter('wp_get_attachment_image_attributes','alter_attr_wpse_102158'); из вашего ответа по ссылке для добавления класса. Я поместил этот remove вместе с remove get_terms. Но ваш ответ по ссылке требует небольшой доработки, если кто-то еще читает это и застрял.

Jon Jon
2 мар. 2014 г. 16:27:45
Показать остальные 1 комментариев
6

Вместо использования get_categories(), я бы предложил вам взглянуть на wp_list_categories(). С его помощью можно получить такой же вывод, но он обладает преимуществом высокой настраиваемости.

Существует два способа настройки: либо через фильтр wp_list_categories - см. в исходном коде - или путем расширения класса Walker_Category - см. в исходном коде. Последний дает гораздо больше возможностей для настройки, но может быть избыточным для незначительных изменений. Поэтому вам нужно оценить, что лучше соответствует вашим потребностям.

Поскольку эта тема довольно хорошо освещена на WPSE и SO, я просто приведу краткий список ссылок. Кроме того, вы не предоставили достаточно конкретного описания своих потребностей, поэтому остается некоторая неопределенность, хотя и можно догадаться, чего вы хотите. В любом случае, приведенные ниже ресурсы должны помочь вам выбрать подходящий метод и, кроме того, позволят вам достичь желаемого.

  1. Фильтр wp_list_categories
  2. Класс Walker_Category

Еще одно замечание: лично я почти всегда выбираю метод расширения класса Walker_Category, за исключением случаев, когда изменения очень незначительны. Это, конечно, немного вопрос личных предпочтений, но имеет под собой основания, особенно из-за возможности повторного использования, расширяемости и - даже если это не кажется очевидным - в конечном итоге часто - возможно, даже в большинстве случаев - это более простой способ достичь желаемого вывода.


Миниатюра из записи в дочерней категории:

Таким образом вы можете получить "миниатюру категории" из случайной записи, принадлежащей одной из дочерних категорий.

Я добавил комментарии к коду, чтобы вам было понятно, как это делается, кроме того, код должен быть достаточно самодостаточным.

/**
 * wpse135208_cat_thumb_from_random_child.
 *
 * Получение миниатюры из случайной записи, принадлежащей одной из дочерних категорий.
 *
 * @version 0.1
 *
 * @link https://wordpress.stackexchange.com/q/135208/22534
 *
 * @param integer $c_cat (по умолчанию: '')
 * @param string/array $size (по умолчанию: 'post-thumbnail')
 * @param string/array $attr (по умолчанию: null)
 *
 * @return string
 */
function wpse135208_cat_thumb_from_random_child( $c_cat = '', $size = 'post-thumbnail', $attr = null ) {
    // ничего не делать, если $c_cat пуст
    if( empty($c_cat) ) return;
    // используется get_terms, так как нам нужны только id
    $taxonomies = array(
        'category'
        );
    $args = array(
        'child_of' => $c_cat,
        'fields' => 'ids'
        );
    // возвращает массив id
    $child_cats = get_terms( $taxonomies, $args );
    // использовать для отладки
    //echo '<pre>'; print_r($child_cats); echo '</pre>';

    $args = array(
        // используем numberposts вместо post_per_page,
        // потому что если используется фильтр pre_get_posts,
        // это может иметь значение в данном случае 
        // нам нужна только одна запись
        'numberposts' => 1,
        // но мы рандомизируем выбор
        'orderby' => 'rand',
        'category__in' => $child_cats,
        'fields' => 'ids',
        // убеждаемся, что учитываются только записи с миниатюрой
        'meta_query' => array(
            array(
                'key' => '_thumbnail_id',
                'compare' => 'EXISTS'
            )
        )
        );
    // возвращает массив, содержащий один id записи
    $ct_p_id = get_posts( $args );
    // использовать для отладки
    //echo '<pre>'; print_r($ct_p_id); echo '</pre>';

    // использовать для отладки
    //echo '<pre>'; print_r( ( 1 /*изменить на 0 для отображения информации о 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>'; 
    // теперь можно использовать это для возврата нашей миниатюры
    return get_the_post_thumbnail( $ct_p_id[0], $size, $attr );
}

Использование:

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

В вашем коде используйте это так:

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



Миниатюра категории через плагин:

Это дает преимущество наличия реальных миниатюр категорий.

Я быстро протестировал плагин - Category Thumbnails - который упомянул в комментарии выше. В целом он работает, и я считаю, что это лучшее решение, чем то, что вы предлагаете в своем ответе, потому что он позволяет управлять миниатюрами через медиатеку WordPress.

Я обнаружил небольшую ошибку, автор плагина уведомлен и ответил мгновенно, так что ошибка скоро будет исправлена. Если вы не можете ждать, вы можете исправить ее самостоятельно следующим образом:

Однако функция

the_category_thumbnail();

не выводит результат. В исходном коде версии 1.0.3 это выглядит так:

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

Я исправил проблему следующим образом:

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

То есть, сделав названия параметров/аргументов одинаковыми.

Или вы можете просто использовать get_the_category_thumbnail(), вам нужно только вывести его:

echo get_the_category_thumbnail('1');

Еще одним небольшим разочарованием является то, что плагин и предоставляемые им функции не дают возможности работать с генерируемыми размерами изображений. Это не очень хорошо, потому что нам нужен правильный размер, а не всегда полный размер. Я собираюсь уведомить автора и об этом, чтобы он мог дальше улучшить свой плагин. А пока эту проблему можно легко решить, создав пользовательскую функцию:

/**
 * wpse135208_cat_thumb_wrapper.
 *
 * Обертка для функции, чтобы иметь возможность использовать предопределенные размеры изображений через wp_get_attachment_image().
 *
 * @version 0.1
 *
 * @link https://wordpress.stackexchange.com/q/135208/22534
 *
 * @param integer $category_id (по умолчанию: null)
 * @param string/array $size (по умолчанию: 'thumbnail')
 * @param boolean $icon (по умолчанию: false)
 * @param string/array (по умолчанию: 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 );
}

Использование:

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

Это должно помочь вам заставить это работать. Как я уже сказал, это предпочтительнее, потому что вы можете управлять миниатюрами категорий через медиатеку. В вашем коде используйте это так:

$categories = get_categories($args);
foreach($categories as $category) { 
    echo wpse135208_cat_thumb_wrapper($category->cat_ID); 
} 
23 февр. 2014 г. 19:57:28
Комментарии

Мне нужен цикл для одной категории с заголовком, описанием и изображением подкатегорий, без информации о записях, но можно использовать любую картинку из любой дочерней записи для изображения дочерней категории. У меня есть рабочий get_categories, и for each выполняет цикл. Я видел другие посты, где используют get_categories с различными плагинами для получения изображения. Я не знаю, как они реализовали свой плагин. Но, возможно, функция walker подойдет лучше, чем плагин для этого?

Jon Jon
23 февр. 2014 г. 20:41:23

"Thumbnail from post in child category" — это именно то, что я искал. Мне не очень нравится мое решение, но оно работает, но этот вариант явно лучше — однако я не могу получить вывод. Я пробовал и echo function( '1', 'thumbnail', null ), и использование $category->cat_ID & $category->term_id, но ничего не вышло.

Jon Jon
1 мар. 2014 г. 19:58:17

Да, теперь изображения отображаются. Но, кажется, повторяется одно и то же изображение из одной категории, а не изображение из каждой категории. Решение s_ha_dum работает отлично. Спасибо.

Jon Jon
2 мар. 2014 г. 13:29:33

Понял, урок здесь — не делать вещи в спешке, у меня была опечатка. Кроме того, я заменил post_per_page на numberposts, потому что в данном случае это может быть полезно. В остальном, используйте тот ответ, который вам больше подходит. @Jon

Nicolai Grossherr Nicolai Grossherr
2 мар. 2014 г. 15:32:06

Спасибо за решение, и я действительно многое узнал из этой функции

Jon Jon
2 мар. 2014 г. 15:35:30

Всегда пожалуйста, кстати, следовать ответам s_ha_dum — никогда не плохая идея, потому что он чертовски хорош в этом. @Jon

Nicolai Grossherr Nicolai Grossherr
2 мар. 2014 г. 15:49:48
Показать остальные 1 комментариев
1

Что ж, мне удалось сделать то, что, как я полагаю, вы хотите, используя Advanced Custom Fields, создав новый набор произвольных полей с одним полем для изображения. Затем установите правила размещения на "Таксономия" > "равно" > "Категории" (или любую другую таксономию, которую вы используете для этого).

После публикации это должно обновить интерфейс редактирования таксономий, добавив новое поле для изображения. Теперь остаётся только использовать функцию ACF "get_field()" внутри вашего цикла по категориям. Вот как получить поле из категории.

Пример:

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

Если вы использовали стандартные настройки ACF, вы получите массив - это объект изображения. Чтобы работать с ним, ознакомьтесь с Типами полей изображений в ACF.

У меня на настройку ушло менее 5 минут, и этот плагин бесплатный. Надеюсь, это будет быстро и просто для вас!

Удачи!

25 февр. 2014 г. 16:50:10
Комментарии

Я посмотрю и попробую сделать так, чтобы это работало. Спасибо.

Jon Jon
25 февр. 2014 г. 16:53:56
0

В WordPress есть код - http://codex.wordpress.org/Function_Reference/get_the_category

     Вывод изображений категорий
Этот код выводит изображения категорий, названные по cat_ID с атрибутом alt, установленным в cat_name. Вы также можете использовать любые другие переменные-члены вместо них.

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

Это позволяет настроить изображения внутри функций get_categories. Изображения должны быть настроены в соответствии с функцией. Поэтому, если используется $category->name, изображение должно быть сохранено в правильной папке с соответствующим именем категории.

26 февр. 2014 г. 18:27:59