Как получить изображения галереи WordPress в порядке, установленном в админке, используя WP_Query?

13 янв. 2013 г., 19:19:09
Просмотры: 18.9K
Голосов: 5

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

На данный момент у меня есть:

  $my_wp_query = new WP_Query();

  $all_wp_pages = $my_wp_query->query(
    array(
      'post_type' => 'attachment',  // Тип записи - вложение
      'post_parent' => 54,          // ID родительской страницы
      'post_mime_type' =>'image',   // Только изображения
      'post_status' => 'inherit',   // Статус наследуемый
      'posts_per_page' => '20',     // Лимит изображений
      'orderby' => 'menu_order',    // Сортировка по порядку меню
      'order' => 'ASC'              // По возрастанию
    )
  );

  var_dump( $all_wp_pages );

Но этот код возвращает все изображения-вложения в стандартном/дефолтном порядке, а не в том, в котором я их перетаскивал в интерфейсе редактирования галереи в админке.

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

Может ли кто-нибудь подсказать, как получить все изображения галереи для определенного page_id в том порядке, в котором они установлены в админке? На каждой странице будет только одна галерея, если это поможет.

Спасибо

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

используется ли здесь новый создатель галерей из версии 3.5?

Milo Milo
13 янв. 2013 г. 20:34:42
Все ответы на вопрос 4
2
11

Когда вы создаёте галерею через медиа-менеджер WordPress 3.5, параметр menu_order больше не используется для сохранения порядка изображений. Порядок теперь существует только в шорткоде, который вставляется при нажатии кнопки Вставить галерею, через атрибут ids=. Это сделано для поддержки возможности добавления нескольких галерей в одну запись — сортировка через menu_order в таком случае не сработает. Чтобы извлечь эти ID, нам понадобится немного регулярных выражений для поиска шорткодов gallery в контенте записи, а затем использовать эти ID в запросе post__in, который теперь можно удобно сортировать по этим ID с помощью нового в WordPress 3.5 значения orderbypost__in.

Если бы я был лучше в регулярных выражениях, это, вероятно, не было бы так сложно, но, увы, я в них не силён, поэтому мы воспользуемся нативными функциями WordPress и проделаем несколько трюков для извлечения этих атрибутов ID. Этот метод будет работать как для одной, так и для нескольких галерей в контенте записи. Я только что протестировал это, вставив код в цикл записи. Вам нужно будет заменить $post->post_content на источник, откуда вы получаете контент записи/страницы.

$pattern = get_shortcode_regex();

if( preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
    && array_key_exists( 2, $matches )
    && in_array( 'gallery', $matches[2] ) ):

        $keys = array_keys( $matches[2], 'gallery' );

        foreach( $keys as $key ):
            $atts = shortcode_parse_atts( $matches[3][$key] );
                if( array_key_exists( 'ids', $atts ) ):

                    $images = new WP_Query(
                        array(
                            'post_type' => 'attachment',
                            'post_status' => 'inherit',
                            'post__in' => explode( ',', $atts['ids'] ),
                            'orderby' => 'post__in'
                        )
                    );

                    if( $images->have_posts() ):
                        // цикл по возвращённым изображениям
                    endif;

                    wp_reset_query();

                endif;
        endforeach;

endif;
13 янв. 2013 г. 20:59:39
Комментарии

Это сэкономило мне кучу времени! Огромное спасибо.

shipshape shipshape
11 июн. 2013 г. 20:43:54

Привет, это был мой изначальный вопрос, и я про него совсем забыл. Наткнулся на него снова, когда искал ответ на тот же вопрос. Отличная работа :)

Larry B Larry B
16 сент. 2013 г. 17:40:45
1

Вы правы.

Поле menu_order больше не используется для медиафайлов в галерее. К сожалению, похоже, что единственным "источником" порядка галереи является аргумент "ids" в шорткоде галереи, который встроен в контент страницы/записи.

Не уверен, сделано это намеренно или по недосмотру, но возможно это сделано специально, так как теперь можно включать медиафайлы в галерею, даже если они не "прикреплены" к странице/записи. В любом случае, ниже приведён метод, который я использую для получения ID и загрузки вложений в порядке, указанном в шорткоде.

Ключевой момент - параметр "orderby" в вызове get_posts должен быть "post__in", это указывает сортировать по порядку ID записей, указанных в параметре "include". Смотрите ниже.

// Вспомогательная функция для возврата первого совпадения по регулярному выражению
function get_match( $regex, $content ) {
    preg_match($regex, $content, $matches);
    return $matches[1];
} 

// Извлекаем аргументы шорткода из $page или $post
$shortcode_args = shortcode_parse_atts(get_match('/\[gallery\s(.*)\]/isU', $post->post_content));

// Получаем ID, указанные в вызове шорткода
$ids = $shortcode_args["ids"];

// Получаем вложения, указанные в аргументе "ids" шорткода
$attachments = get_posts(
    array(
        'include' => $ids, 
        'post_status' => 'inherit', 
        'post_type' => 'attachment', 
        'post_mime_type' => 'image', 
        'order' => 'menu_order ID', 
        'orderby' => 'post__in', // обязательно для сортировки результатов в порядке, указанном в параметре "include"
    )
);

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

Надеюсь, это поможет!

4 мар. 2013 г. 23:01:58
Комментарии

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

Steve Steve
19 мар. 2013 г. 21:46:55
0
$oImages = get_posts(
    array(
         'numberposts' => -1,
         'post_parent' => $post->ID,
         'post_status' => 'inherit',
         'post_type' => 'attachment',
         'post_mime_type' => 'image',
         'order' => 'ASC',
         'orderby' => 'menu_order'
         )
);

Этот сниппет всегда работал у меня.

13 янв. 2013 г. 20:20:19
0

Если вы всё ещё ищете более простой способ сделать это, вы можете использовать плагин Attachments,

http://wordpress.org/plugins/attachments/

Он хранит галерею отдельно и не добавляет шорткоды галереи в контент записи, что даёт вам полный контроль над отображением изображений в ваших записях/страницах/произвольных типах записей.

Вы также можете изменить порядок изображений простым перетаскиванием.

Вот пример кода для получения изображений галереи:

<?php $attachments = new Attachments( 'attachments' ); /* передаём имя экземпляра */ ?>
<?php if( $attachments->exist() ) : ?>
  <h3>Прикрепления</h3>
  <p>Всего прикреплений: <?php echo $attachments->total(); ?></p>
  <ul>
    <?php while( $attachments->get() ) : ?>
      <li>
        ID: <?php echo $attachments->id(); ?><br />
        Тип: <?php echo $attachments->type(); ?><br />
        Подтип: <?php echo $attachments->subtype(); ?><br />
        URL: <?php echo $attachments->url(); ?><br />
        Изображение: <?php echo $attachments->image( 'thumbnail' ); ?><br />
        Источник: <?php echo $attachments->src( 'full' ); ?><br />
        Размер: <?php echo $attachments->filesize(); ?><br />
        Поле заголовка: <?php echo $attachments->field( 'title' ); ?><br />
        Поле подписи: <?php echo $attachments->field( 'caption' ); ?>
      </li>
    <?php endwhile; ?>
  </ul>
<?php endif; ?> 
1 июл. 2013 г. 14:27:35