템플릿 파일 / 사용자 정의 페이지 템플릿에 사용자 정의 / 보조 쿼리를 추가했습니다. 기본 쿼리 루프의 페이지 매김을 사용하는 대신 WordPress에서 페이지 매김에 사용자 정의 쿼리를 사용하도록하려면 어떻게해야합니까?
추가
를 통해 기본 루프 쿼리를 수정했습니다 query_posts()
. 페이지 매김이 작동하지 않는 이유는 무엇이며 어떻게 수정합니까?
템플릿 파일 / 사용자 정의 페이지 템플릿에 사용자 정의 / 보조 쿼리를 추가했습니다. 기본 쿼리 루프의 페이지 매김을 사용하는 대신 WordPress에서 페이지 매김에 사용자 정의 쿼리를 사용하도록하려면 어떻게해야합니까?
를 통해 기본 루프 쿼리를 수정했습니다 query_posts()
. 페이지 매김이 작동하지 않는 이유는 무엇이며 어떻게 수정합니까?
답변:
주어진 상황에서 WordPress는 기본 쿼리를 사용하여 페이지 매김을 결정합니다. 기본 쿼리 개체는 $wp_query
전역에 저장되며 기본 쿼리 루프를 출력하는 데에도 사용됩니다.
if ( have_posts() ) : while ( have_posts() ) : the_post();
이 때 사용자 지정 쿼리를 사용하여 , 당신은 완전히 별도의 쿼리 객체를 생성 :
$custom_query = new WP_Query( $custom_query_args );
그리고 해당 쿼리는 완전히 별도의 루프를 통해 출력됩니다.
if ( $custom_query->have_posts() ) :
while ( $custom_query->have_posts() ) :
$custom_query->the_post();
그러나 포함 매김 템플릿 태그는, previous_posts_link()
, next_posts_link()
, posts_nav_link()
,와 paginate_links()
, 온 자신의 출력을 기반으로 주요 질의 객체를 , $wp_query
. 이 기본 쿼리는 페이지 매김이 될 수도 있고 아닐 수도 있습니다. 예를 들어 현재 컨텍스트가 사용자 정의 페이지 템플리트 인 경우 기본 $wp_query
오브젝트는 단일 페이지 (사용자 정의 페이지 템플리트가 지정된 페이지의 ID) 로만 구성 됩니다.
현재 상황이 어떤 종류의 아카이브 지수 인 경우, 메인은 $wp_query
주를 위해 : 문제의 다음 부분에 이르게 매김 일으킬만큼 게시물로 구성 될 수있다 $wp_query
객체, 워드 프레스는 통과 할 paged
에 기초하여, 쿼리에 매개 변수를 paged
URL 쿼리 변수 쿼리를 가져 오면 해당 paged
매개 변수를 사용하여 페이지 매김 된 게시물 집합을 확인할 수 있습니다. 표시된 페이지 매김 링크를 클릭하고 다음 페이지가로드되면 맞춤 검색어에 페이지 매김이 변경되었음을 알 수있는 방법이 없습니다 .
사용자 정의 쿼리가 args 배열을 사용한다고 가정합니다.
$custom_query_args = array(
// Custom query parameters go here
);
올바른 paged
매개 변수를 배열 로 전달해야합니다 . 다음을 통해 현재 페이지를 결정하는 데 사용되는 URL 쿼리 변수를 가져 와서 수행 할 수 있습니다 get_query_var()
.
get_query_var( 'paged' );
그런 다음 해당 매개 변수를 사용자 정의 조회 인수 배열에 추가 할 수 있습니다.
$custom_query_args['paged'] = get_query_var( 'paged' )
? get_query_var( 'paged' )
: 1;
참고 : 페이지가 있으면 정적 프론트 페이지 , 사용하십시오 page
대신에 paged
정적 앞 페이지를 사용하기 때문에 page
하지 paged
. 이것이 정적 프론트 페이지에 필요한 것입니다
$custom_query_args['paged'] = get_query_var( 'page' )
? get_query_var( 'page' )
: 1;
이제 사용자 지정 쿼리를 가져 오면 페이지 매김 된 올바른 게시물 세트가 반환됩니다.
페이지 매김 함수가 올바른 출력 (즉, 사용자 정의 쿼리와 관련된 이전 / 다음 / 페이지 링크)을 생성하려면 WordPress에서 사용자 정의 쿼리를 인식해야합니다. 여기에는 약간의 "해킹"이 필요합니다. 기본 $wp_query
개체를 사용자 지정 쿼리 개체로 바꾸십시오 $custom_query
.
$temp_query = $wp_query
$wp_query = NULL;
사용자 지정 쿼리를 기본 쿼리 개체로 바꾸십시오. $wp_query = $custom_query;
$temp_query = $wp_query;
$wp_query = NULL;
$wp_query = $custom_query;
이 "해킹"은 페이지 매김 함수를 호출하기 전에 수행해야합니다.
페이지 매김 함수가 출력되면 기본 쿼리 개체를 재설정하십시오.
$wp_query = NULL;
$wp_query = $temp_query;
이 previous_posts_link()
기능은 페이지 매김에 관계없이 정상적으로 작동합니다. 단지 현재 페이지를 결정한 다음에 대한 링크를 출력합니다 page - 1
. 그러나 next_posts_link()
제대로 출력하려면 수정이 필요합니다 . 매개 변수를 next_posts_link()
사용 하기 때문입니다 max_num_pages
.
<?php next_posts_link( $label , $max_pages ); ?>
다른 쿼리 매개 변수와 마찬가지로 기본적으로이 함수는 max_num_pages
기본 $wp_query
개체에 사용됩니다. 객체 를 강제 next_posts_link()
로 설명 $custom_query
하려면를 max_num_pages
함수 에 전달해야 합니다. $custom_query
객체 에서이 값을 가져올 수 있습니다 . $custom_query->max_num_pages
:
<?php next_posts_link( 'Older Posts' , $custom_query->max_num_pages ); ?>
다음은 올바르게 기능하는 페이지 매김 함수를 가진 사용자 정의 쿼리 루프의 기본 구성입니다.
// Define custom query parameters
$custom_query_args = array( /* Parameters go here */ );
// Get current page and append to custom query parameters array
$custom_query_args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
// Instantiate custom query
$custom_query = new WP_Query( $custom_query_args );
// Pagination fix
$temp_query = $wp_query;
$wp_query = NULL;
$wp_query = $custom_query;
// Output custom query loop
if ( $custom_query->have_posts() ) :
while ( $custom_query->have_posts() ) :
$custom_query->the_post();
// Loop output goes here
endwhile;
endif;
// Reset postdata
wp_reset_postdata();
// Custom query loop pagination
previous_posts_link( 'Older Posts' );
next_posts_link( 'Newer Posts', $custom_query->max_num_pages );
// Reset main query object
$wp_query = NULL;
$wp_query = $temp_query;
query_posts()
습니까?query_posts()
보조 루프 용당신이 사용하는 경우 query_posts()
출력에 사용자 정의 루프를,보다는 통해 사용자 지정 쿼리에 대해 별도의 객체를 인스턴스화 WP_Query()
당신이있어, _doing_it_wrong()
그리고 몇 가지 문제 (안으로 실행됩니다 적어도 어느 매김 문제가 될 것입니다). 이러한 문제를 해결하기위한 첫 번째 단계는 부적절한 사용을 query_posts()
적절한 WP_Query()
통화 로 전환하는 것입니다 .
query_posts()
메인 루프 수정에 사용페이지 당 게시물 수 변경 또는 카테고리 제외와 같은 기본 루프 쿼리에 대한 매개 변수 만 수정하려는 경우 사용하고 싶을 수 있습니다 query_posts()
. 그러나 당신은 여전히해서는 안됩니다. 당신이 사용하는 경우 query_posts()
, 당신은 할 수 워드 프레스를 강제로 대체 메인 쿼리 개체를. (WordPress는 실제로 두 번째 쿼리를 작성하고 덮어 씁니다 $wp_query
.) 문제는 페이지 매김을 업데이트하기 위해 프로세스에서 너무 늦게 교체를 수행한다는 것입니다.
해결책은 후크 를 통해 게시물을 가져 오기 전에 기본 쿼리 를 필터링하는 것pre_get_posts
입니다.
이것을 카테고리 템플릿 파일 ( category.php
) 에 추가하는 대신 :
query_posts( array(
'posts_per_page' => 5
) );
다음에 추가하십시오 functions.php
:
function wpse120407_pre_get_posts( $query ) {
// Test for category archive index
// and ensure that the query is the main query
// and not a secondary query (such as a nav menu
// or recent posts widget output, etc.
if ( is_category() && $query->is_main_query() ) {
// Modify posts per page
$query->set( 'posts_per_page', 5 );
}
}
add_action( 'pre_get_posts', 'wpse120407_pre_get_posts' );
이것을 블로그 게시물 색인 템플릿 파일 ( home.php
) 에 추가하는 대신 :
query_posts( array(
'cat' => '-5'
) );
다음에 추가하십시오 functions.php
:
function wpse120407_pre_get_posts( $query ) {
// Test for main blog posts index
// and ensure that the query is the main query
// and not a secondary query (such as a nav menu
// or recent posts widget output, etc.
if ( is_home() && $query->is_main_query() ) {
// Exclude category ID 5
$query->set( 'category__not_in', array( 5 ) );
}
}
add_action( 'pre_get_posts', 'wpse120407_pre_get_posts' );
이런 식으로 WordPress는 $wp_query
템플릿 수정없이 페이지 매김을 결정할 때 이미 수정 된 개체를 사용합니다.
연구 이 질문을하고 답변을 하고 이 질문에 대답 하는 방법과 때 사용할 이해 WP_Query
, pre_get_posts
그리고 query_posts()
.
paged
이 업데이트되지 않았다는 것을 알았습니다 (관리자와 관련이 있음) ajax.php 환경) 그래서 나는 이것을 추가했다 : global $paged; $paged = $custom_query_args['paged'];
그리고 그것은 효과가 있었다 :)
페이지 매김과 함께 사용자 정의 루프 에이 코드를 사용합니다.
<?php
if ( get_query_var('paged') ) {
$paged = get_query_var('paged');
} elseif ( get_query_var('page') ) { // 'page' is used instead of 'paged' on Static Front Page
$paged = get_query_var('page');
} else {
$paged = 1;
}
$custom_query_args = array(
'post_type' => 'post',
'posts_per_page' => get_option('posts_per_page'),
'paged' => $paged,
'post_status' => 'publish',
'ignore_sticky_posts' => true,
//'category_name' => 'custom-cat',
'order' => 'DESC', // 'ASC'
'orderby' => 'date' // modified | title | name | ID | rand
);
$custom_query = new WP_Query( $custom_query_args );
if ( $custom_query->have_posts() ) :
while( $custom_query->have_posts() ) : $custom_query->the_post(); ?>
<article <?php post_class(); ?>>
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<small><?php the_time('F jS, Y') ?> by <?php the_author_posts_link() ?></small>
<div><?php the_excerpt(); ?></div>
</article>
<?php
endwhile;
?>
<?php if ($custom_query->max_num_pages > 1) : // custom pagination ?>
<?php
$orig_query = $wp_query; // fix for pagination to work
$wp_query = $custom_query;
?>
<nav class="prev-next-posts">
<div class="prev-posts-link">
<?php echo get_next_posts_link( 'Older Entries', $custom_query->max_num_pages ); ?>
</div>
<div class="next-posts-link">
<?php echo get_previous_posts_link( 'Newer Entries' ); ?>
</div>
</nav>
<?php
$wp_query = $orig_query; // fix for pagination to work
?>
<?php endif; ?>
<?php
wp_reset_postdata(); // reset the query
else:
echo '<p>'.__('Sorry, no posts matched your criteria.').'</p>';
endif;
?>
출처:
언제나 칩처럼 굉장합니다. 이에 대한 부록으로서, "소개 텍스트"에 대해 페이지에 첨부 된 글로벌 페이지 템플리트를 사용하고 그 다음에 페이징하려는 서브 쿼리가 뒤 따르는 상황을 고려하십시오.
사용 ) (paginate_links를 위에서 언급으로, 대부분 기본값으로, (당신은 꽤 영구 링크가 설정 한 가정) 당신의 페이지 매김 링크가 기본값으로하는하는 mysite.ca/page-slug/page/#
사랑이다하지만 발생합니다 404
워드 프레스는 특정 URL 구조에 대해 알고하지 않기 때문에 실제로 오류를합니다 "page-slug"의 하위 인 "page"의 하위 페이지를 찾으십시오.
여기서의 트릭은 /page/#/
구조 를 승인하고 WordPress CAN이 이해할 수있는 쿼리 문자열, 즉 구조 를 승인하는 특정 "의사 아카이브 페이지"페이지 슬러그에만 적용되는 멋진 다시 쓰기 규칙을 삽입하는 것 mysite.ca/?pagename=page-slug&paged=#
입니다. 참고 pagename
및 paged
하지 name
와 page
(여기 답을 동기 부여, 나에게 슬픔의 말 그대로 시간이 발생하는!).
리디렉션 규칙은 다음과 같습니다.
add_rewrite_rule( "page-slug/page/([0-9]{1,})/?$", 'index.php?pagename=page-slug&paged=$matches[1]', "top" );
항상 다시 쓰기 규칙을 변경할 때 관리자 백엔드에서 설정> 영구 링크 를 방문 하여 영구 링크 를 플러시해야합니다 .
이러한 방식으로 작동 할 페이지가 여러 개인 경우 (예 : 여러 사용자 정의 게시물 유형을 처리 할 때) 각 페이지 슬러그에 대해 새 재 작성 규칙을 작성하지 않을 수 있습니다. 식별 한 모든 페이지 슬러그에 대해보다 일반적인 정규식을 작성할 수 있습니다.
한 가지 접근 방식은 다음과 같습니다.
function wpse_120407_pseudo_archive_rewrite(){
// Add the slugs of the pages that are using a Global Template to simulate being an "archive" page
$pseudo_archive_pages = array(
"all-movies",
"all-actors"
);
$slug_clause = implode( "|", $pseudo_archive_pages );
add_rewrite_rule( "($slug_clause)/page/([0-9]{1,})/?$", 'index.php?pagename=$matches[1]&paged=$matches[2]', "top" );
}
add_action( 'init', 'wpse_120407_pseudo_archive_rewrite' );
입에서 약간의 소리를내는이 접근법의 한 가지 단점은 페이지 슬러그의 하드 코딩입니다. 관리자가 해당 의사 아카이브 페이지의 페이지 슬러그를 변경하면 다시 작성됩니다.
이 방법에 대한 해결 방법을 생각할 수는 없지만 글로벌 페이지 템플릿이 다시 쓰기 규칙을 트리거 한 경우 좋을 것입니다. 언젠가 다른 사람이 그 특정 너트에 금을 입히지 않으면이 답변을 다시 볼 수 있습니다.
_wp_page_template
다음 다른 다시 쓰기 및 플러시 규칙을 추가 할 수 있습니다.
를 통해 기본 루프 쿼리를 수정했습니다
query_posts()
. 페이지 매김이 작동하지 않는 이유는 무엇이며 어떻게 수정합니까?
오늘 생성 된 훌륭한 답변 칩을 수정해야합니다.
얼마 동안 우리는 메인 쿼리가 실행 된 직후에 전역 $wp_the_query
변수와 같아야하는 변수가 있습니다 $wp_query
.
이것이 이것이 칩의 답변에서 나온 부분입니다.
기본 쿼리 객체 해킹
더 이상 필요하지 않습니다. 임시 변수를 만들어이 부분을 잊을 수 있습니다.
// Pagination fix
$temp_query = $wp_query;
$wp_query = NULL;
$wp_query = $custom_query;
이제 전화 할 수 있습니다 :
$wp_query = $wp_the_query;
또는 더 나은 전화 :
wp_reset_query();
다른 칩이 설명하는 모든 것은 유지됩니다. 해당 쿼리 리셋 부분 후에는 페이지 매김 기능을 호출 할 수 있습니다 f($wp_query)
그들이에 따라 달라집니다 -, $wp_query
세계를.
페이지 매김 메커니즘을 추가로 개선하고 query_posts
기능에 더 많은 자유를주기 위해 다음과 같은 가능한 개선을 만들었습니다.
global $wp_query;
$paged = get_query_var('paged', 1);
$args = array(
'post_type' => '{your_post_type_name}',
'meta_query' => array('{add your meta query argument if need}'),
'orderby' => 'modified',
'order' => 'DESC',
'posts_per_page' => 20,
'paged' => $paged
);
$query = new WP_Query($args);
if($query->have_posts()):
while ($query->have_posts()) : $query->the_post();
//add your code here
endwhile;
wp_reset_query();
//manage pagination based on custom Query.
$GLOBALS['wp_query']->max_num_pages = $query->max_num_pages;
the_posts_pagination(array(
'mid_size' => 1,
'prev_text' => __('Previous page', 'patelextensions'),
'next_text' => __('Next page', 'patelextensions'),
'before_page_number' => '<span class="meta-nav screen-reader-text">' . __('Page', 'patelextensions') . ' </span>',
));
else:
?>
<div class="container text-center"><?php echo _d('Result not found','30'); ?></div>
<?php
endif;
?>