Использование пользовательского WP_Query с циклом get_template_part

9

У меня есть запрос для пользовательского типа сообщения:

<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$books = new WP_Query(array(
    'post_type' => 'wiki',
    'posts_per_page' => '50',
    'paged' => $paged
));
?>

И я хочу просмотреть эти сообщения, используя loop-books.php:

<?php get_template_part( 'loop', 'books' ); ?>

Внутри loop-books.php у меня есть такие же, как и в обычном loop.php, я просто изменил функции have_posts и the_post для работы с запросом $ books:

<?php if ( $books->have_posts() ) : ?>      
    <?php while ($books->have_posts()) : $books->the_post(); ?>
        <?php the_title(); ?><br/>
    <?php endwhile; ?>
<?php endif; ?>

Но после этого я получаю ошибку php:

Fatal error: Call to a member function have_posts() on a non-object in .../loop-books.php on line 1

Похоже, переменная $ books не доступна внутри функции get_template_part. Как я могу решить эту проблему? Если я помещаю запрос $ books в loop-books.php, он работает нормально, но я хочу разделить их.

passatgt
источник
Попробуйте удалить $books->из loop-books.php, и я надеюсь, что это будет работать.
Рохит Панде
Если я удалю часть $ books->, она будет использовать запрос по умолчанию, так что это не очень хорошо для меня.
Passatgt
если вы используете что-то вроде: <?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $books = new WP_Query(array( 'post_type' => 'wiki', 'posts_per_page' => '50', 'paged' => $paged )); ?>и здесь вы загружаете get_template_partзапрос. И после этого, если вы, reset postdataто я думаю, что мое решение будет работать правильно.
Рохит Панде

Ответы:

5

Вам нужно будет либо глобализироваться $books(если вы хотите придерживаться get_template_part()), либо использовать

require( locate_template( 'loop-books.php' ) );

вместо get_template_part( 'loop', 'books' );. Эта проблема обусловлена $booksв loop-books.phpнастоящее время определяется только в объеме от get_template_part().

Йоханнес Пилле
источник
2
Эта. Хотя, если $booksзапрос относится к loop-books.phpфайлу части шаблона, я бы порекомендовал просто поместить $books = new WP_Query()вызов в файл части шаблона.
Чип Беннетт
Спасибо. Каково ваше мнение, какое из них является лучшим решением?
Passatgt
То же самое, тот же @Chip - я бы также поместил его в тот же файл и, во-первых, избежал проблемы. Ответили на это, имея в виду, что ОП хотел разделить их.
Йоханнес Пилле
1
@passatgt Насколько лучше, смотрите вышеупомянутые комментарии, я бы предпочел пойти с одним файлом и покончить с ним. Если вы должны разделить их, я бы выбрал locate_template()вариант, чтобы не загромождать глобальное пространство имен.
Йоханнес Пилле
Хорошо, спасибо. Причина, по которой я хочу разделить их, заключается в том, что я хочу использовать тот же цикл с другими запросами, также основанными на других категориях / таксономиях
passatgt
8

Альтернативный метод: открыть / закрыть цикл, а затем использовать, loop-books.phpчтобы содержать только разметку для содержимого цикла. например:

<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
// Get books query
$books = new WP_Query(array(
    'post_type' => 'wiki',
    'posts_per_page' => '50',
    'paged' => $paged
));
// Open books loop
if ( $books->have_posts() ) :     
    while ($books->have_posts()) : $books->the_post();
        // Get loop markup
        get_template_part( 'loop', 'books' );
// Close books loop
    endwhile;
endif;
?>

Тогда внутри loop-books.php:

<?php the_title(); ?><br/>
Чип Беннетт
источник