如果我理解正确的话,您正在输入代码header.php
, 文件中需要的single-dress.php
使用get_header()
, 在同一个文件中,在大约20多行之后,定义在20多行之前使用的变量。
因此,要么您的服务器有嵌入式时间机器,要么您的代码无法工作。
你要做的就是在使用变量之前定义它们。
也许,与其把代码弄乱,不如用一系列if
/ elseif
, 您可以将逻辑与模板分离。
我将编写一个简单的类来处理预取。您可以将其保存在单独的文件中,并从functions.php
.
请阅读内联注释以获取更多解释。
<?php
class My_Theme_Prefetcher {
public $next_url;
public $prev_url;
function setup() {
global $wp_query;
// for empty query there is nothing to prefetch
if ( ! $wp_query instanceof WP_Query || $wp_query->found_posts <= 0 ) return;
if ( $wp_query->is_archive() ) {
// next page URL for archives, that is empty if there is no next page URL
$this->next_url = get_next_posts_page_link();
} elseif ( $wp_query->is_singular( \'dress\' ) ) {
// if on a single page view for dress CPT, run a query for dress posts
$this->set_dress_query( $wp_query->get_queried_object_id() );
}
// A filter to easily get class instance and access to instance methods and vars
add_filter( \'my_theme_prefetcher\', function() { return $this; } );
// output the prefetch strings on wp_head
add_action( \'wp_head\', array( $this, \'output\' ) );
}
/**
* Perform a query to get all dresses in same collection,
* save adjacent post URLs into instance properties
*/
function set_dress_query( $dressid ) {
$args = static::dress_query_args( $dressid );
if ( empty( $args ) ) return;
$dress_query = new WP_Query( $args );
if ( $dress_query->found_posts > 0 ) {
// some dresses found, discover and save adjacent URLs
$adjacents = static::get_adjacents( $dressid, $dress_query->posts );
if ( $adjacents[\'next\'] )
$this->next_url = get_permalink( $adjacents[\'next\'] );
if ( $adjacents[\'prev\'] )
$this->prev_url = get_permalink( $adjacents[\'prev\'] );
}
}
/**
* Given a current ID and a set of posts, discover adjacent posts
*/
static function get_adjacents( $current, Array $all ) {
$adjacents = array( \'prev\' => FALSE, \'next\' => FALSE );
if ( is_numeric( $current ) && ! empty( $all ) ) {
$ids = wp_list_pluck( $all, \'ID\' );
$this_posts = array_search( $current, $ids );
if ( $this_posts !== FALSE ) {
$prev_i = $this_posts > 0 ? $this_posts -1 : FALSE;
$next_i = $this_posts < count( $ids ) - 1 ? $this_posts + 1 : FALSE;
$previous = $prev_i !== FALSE ? $all[ $prev_i ] : FALSE;
$next = $next_i !== FALSE ? $all[ $next_i ] : FALSE;
$adjacents = array( \'prev\' => $previous, \'next\' => $next );
}
}
return $adjacents;
}
/**
* Output prefetch string on wp_head. Do nothing if no, or invalid, URL is set
*/
function output() {
if (
empty( $this->next_url ) ||
! filter_var( $this->next_url, FILTER_VALIDATE_URL )
) return;
$format = \'<link rel="prefetch" href="%1$s"><link rel="prerender" href="%1$s">\';
printf( $format, esc_url( $this->next_url ) );
}
/**
* Returns the args for dress query for a given dress id.
*/
static function dress_query_args( $dressid ) {
$collections = get_the_terms( $dressid, \'collections\' );
if ( is_wp_error( $collections ) || empty( $collections ) ) return;
$term = array_shift( $collections );
$args = array(
\'post_type\' => \'dress\',
\'posts_per_page\' => -1,
\'tax_query\' => array(
array( \'taxonomy\' => \'collections\', \'terms\' => array( $term->term_id ) )
),
\'order\' => \'ASC\',
\'orderby\' => \'title\'
);
return $args;
}
}
所有逻辑都在类中:当
setup()
方法时,类将查看当前查询,如果它是存档,则设置指向下一个存档页的下一个URL。如果该页面用于单个连衣裙视图,则会运行查询以获取同一集合中的所有连衣裙,如果找到,则将相邻的帖子URL保存在实例变量中。
现在我们需要启动该类,即调用setup()
钩子上的方法在设置主查询后激发,但在设置前激发wp_head()
被称为:\'template_include\'
将是完美的。
我不使用template_redirect
此处允许在需要时进行更快的重定向(无需触发其他查询)。然而\'template_include\'
是一个筛选器,因此我们必须返回当前模板。添加到您的functions.php
:
add_filter( \'template_include\', function( $template ) {
$prefetcher = new My_Theme_Prefetcher;
$prefetcher->setup();
return $template;
} );
现在,你只需要确定
header.php
这里有
wp_head()
类将添加调用和预回迁链接。
还有另一项任务要做。在模板文件中(single-dress.php
) 我们需要显示相邻帖子链接,但不需要运行另一个查询,因为相邻帖子URL已经保存在My_Theme_Prefetcher
在上实例化\'template_include\'
.
因此,我们需要访问该实例和自定义筛选器\'my_theme_prefetcher\'
为作用域创建的。
因此,在模板中,您可以:
<figure class="pinboard">
<?php
// here goes your thumbnail image stuff, I will not copy it...
// get the prefetcher instance and check it
$prefetcher = apply_filters( \'my_theme_prefetcher\', NULL );
if ( $prefetcher instanceof My_Theme_Prefetcher ) {
// we got prefetcher instance, get the urls
$prev_url = $prefetcher->prev_url ? : FALSE;
$next_url = $prefetcher->next_url ? : FALSE;
} else {
// something goes wrong, try to run the query
// function that returns arguments is static, so we can access it
$args = My_Theme_Prefetcher::dress_query_args( $post->ID );
$dress_by_tax = ! empty( $args ) ? new WP_Query( $args ) : FALSE;
if ( $dress_by_tax instanceof WP_Query && ! empty( $dress_by_tax->posts ) ) {
// function that returns adjacent posts is static, so we can access it
$adjacents = My_Theme_Prefetcher::get_adjacents( $post->ID, $dress_by_tax->posts );
$next_url = $adjacents[\'next\'] ? get_permalink( $adjacents[\'next\'] ) : FALSE;
$prev_url = $adjacents[\'prev\'] ? get_permalink( $adjacents[\'prev\'] ) : FALSE;
} else {
$next_url = $prev_url = FALSE;
}
}
?>
<?php if ( $next_url ) : ?>
<div class="nav-next arrow block button spaced ribbon">
<a href="<?php echo $next_url ?>">Next</a>
</div>
<?php endif; ?>
<?php if ( $prev_url ) : ?>
<div class="nav-prev arrow-left block button spaced ribbon2 left">
<a href="<?php echo $prev_url ?>">Previous</a>
</div>
<?php endif; ?>
<div class="mask"><span>Click for larger size</span></div>
</figure>