Php 为单页循环保留post筛选器
我希望wordpress将查询过滤器保留在单页循环中。例如,当用户按类别X排序时,该类别页面仅收到来自类别X的帖子。但是,当用户单击该帖子并转到单个页面时,下一个帖子链接将在所有帖子之间循环 以下是single.php中的代码:Php 为单页循环保留post筛选器,php,wordpress,Php,Wordpress,我希望wordpress将查询过滤器保留在单页循环中。例如,当用户按类别X排序时,该类别页面仅收到来自类别X的帖子。但是,当用户单击该帖子并转到单个页面时,下一个帖子链接将在所有帖子之间循环 以下是single.php中的代码: <?php if ( have_posts() ): ?> <?php while ( have_posts() ): the_post(); ... <!-- pa
<?php if ( have_posts() ): ?>
<?php while ( have_posts() ): the_post();
...
<!-- pagination functions here. -->
<div class="nav-previous pull-left">
<?php next_post_link('%link', '<span class="hidden-xs btn-black btn"><i class="fa fa-angle-left"></i> Next Question </span><span class="visible-xs btn btn-black"><i class="fa fa-angle-left"></i> Next </span>'); // next post ?>
</div>
<div class="nav-next pull-right">
<?php previous_post_link('%link', '<span class="btn btn-black hidden-xs"> Previous Question <i class="fa fa-angle-right"></i></span><span class="btn btn-black visible-xs"> Previous <i class="fa fa-angle-right"></i></span>'); // previous post ?>
</div>
<div class="clearfix"></div>
<!-- pagination functions ends here -->
<br />
<br />
<!-- comments template -->
<?php if ( is_singular() ) wp_enqueue_script("comment-reply"); ?>
<?php comments_template(); // include comments.php ?>
</div>
<div class="clearfix"></div>
</div>
</article>
<!-- end post-format -->
<?php endwhile; ?>
<?php endif; ?>
我刚刚完成了一个非常密集的后链接功能,在这一周同样的事情。此函数不使用会话、cookie或HTTP引用进行分页。我也在WPSE上发布了这篇文章,所以我打算在这里转载这篇文章
预告
- 我不仅为类别编写了此函数,还为标记、分类法、作者和搜索查询编写了此函数。你可以删除你不想要的东西
- 默认情况下,在任何其他页面上,单击一篇文章时,下一篇和上一篇文章将来自同一个术语,您可以像在文章底部的用法部分一样禁用该术语
- 这篇文章应该与其他人一起阅读
来自WPSE的帖子
这个问题的初衷是要知道某个职位是从哪里推荐的,然后根据该职位推荐人提供下一个和上一个职位
我想要完成的是一个例子:
从类别、分类、标记、搜索或作者页面中单击帖子。这些档案作为参考资料。现在,像我的问题一样,人们通常会使用wp\u get\u referer()
来获取该referer,并在进一步的查询中使用它。如所述,此方法不可靠,因此我使用了他的替代解决方案
另一个问题是,您需要使用某种cookie或会话来存储此引用对象,这样,当您离开从特定存档中单击的原始单篇帖子时,您仍然可以向原始引用对象发送帖子。由于Cookie也由最终用户控制,因此不可靠,而且Wordpress默认不使用会话,因此我使用@G.M.替代解决方案重构了下一个和上一个帖子链接,以便有一种可靠的方法来检查和存储我的原始推荐人
这就是我想到的,我希望不久的将来有人会发现它有用。请使用和滥用代码以满足您的需要,只需一个请求,留下一个指向此问题的链接。:-)
关于要遵循的代码的注释
- 这段代码相当长且密集,所以我不打算详细介绍。代码已经被很好地注释了
- 此代码可以在同一期限内的帖子之间翻页,就像Wordpress中默认的
next\u post\u link()
和previous\u post\u link()
函数一样。与本机函数一样,您必须设置分类法。同一术语中的默认值为true
,分类法为category
- 最重要的是,此代码需要PHP5.4+
代码
为什么不将过滤器存储在会话中,然后从会话应用到所有搜索?我很难想象你的意思。我可以看到如何在会话中存储筛选器。从会话应用到所有搜索是什么意思?问题是下一个链接和上一个链接不会保留您的筛选器。我不太了解wordpress,也不知道如何使用它,但这些函数使用了一个过滤器,它们会保留用户在列表中的位置以及提供列表本身的过滤器,这样下一个过滤链接就可以链接到它。@DanFarrell会话不是这样做的,因为wordpress默认情况下不使用会话,检查我的答案:-)谢谢你。不过我还有一个问题。我的帖子通常分为多个类别。例如,一篇文章可以是主题a和难度Z。假设我希望文章出现在下一篇文章链接中,其主题也是主题a。但是,我不想局限于难度Z。有什么方法可以做到这一点吗?看起来,单后导航的参数是以这种方式构造的。如果你的文章属于多个类别,就没有办法选择一个特定的类别。这个功能是否也适用于自定义帖子类型(即仅显示其他帖子自定义帖子类型B)。我认为当帖子属于多个类别时,没有任何简单的方法。您需要a.)以某种暂时性的方式保存帖子的类别,或者b.)使用我在代码中使用的相同方法,但老实说,这可能会变得笨重。我仍然需要添加对多种帖子类型的支持。将很快发布更新代码的更新。添加了post_types
参数,它是一个post类型数组。我只是想更新一下,我实现了这段代码(做了一些修改,以满足我的目的,但没有做太多修改),它非常有效,非常感谢您发布这个答案。
<?php
/**
* @author Pieter Goosen
* @license GPLv2
* @link http://www.gnu.org/licenses/gpl-2.0.html
*
* The functions on this page returns the next and previous post links
* depending what is been set
*
* @return function single_post_navigation()
*/
/**
* Register six new query variables aq, ,cq, tq, ttq, taq, and sq set by
* the term_referer_link function
*
* @see http://codex.wordpress.org/WordPress_Query_Vars
*
*/
add_filter( 'query_vars', function ( $vars ) {
$vars[] = 'cq'; // Will hold category ID
$vars[] = 'tq'; // Will hold taxonomy name
$vars[] = 'ttq'; // Will hold term slug
$vars[] = 'sq'; // Will hold search query
$vars[] = 'aq'; // Will hold author name
$vars[] = 'taq'; // Will hold tag id
return $vars;
}, 10, 3 );
/**
* Conditional tag to check whether or not a query_var has been set
*
* @param string $query_var query_var to check
* @return (bool) true if query_var exists, false on failure
*
*/
function has_query_var( $query_var ) {
$array = $GLOBALS['wp_query']->query_vars;
return array_key_exists( $query_var, $array );
}
/**
* For posts being clicked from a category page, the query_var, 'cq' is set.
* 'cq' holds the category ID
*
* Set two query_var, 'tq' and 'ttq' to single posts that was clicked on from
* taxonomy pages. 'tq' holds the taxonomy name while 'ttq' holds the term name
*
* For search queries, the query_var, 'sq' is set to single posts that was clicked on from
* the search page. 'sq' holds the search query value
*
* For posts being clicked from an author page, the query_var, 'aq' is set.
* 'aq' holds the author ID
*
* For posts being clicked from a tag page, the query_var, 'taq' is set.
* 'taq' holds the tag ID
*
* This function replaces the wp_get_referer() and $_SERVER['HTTP_REFERER']
* functions that are not very reliable
* @see php.net manual $_SERVER['HTTP_REFERER']
* @link http://php.net/manual/en/reserved.variables.server.php
*
* @uses add_query_arg()
* @uses post_link
* @uses post_type_link
*
*/
add_filter( 'post_type_link', 'term_referer_link', 10, 3 );
add_filter( 'post_link', 'term_referer_link', 10, 3 );
function term_referer_link( $permalink, $post ) {
switch ( true ) {
case ( is_category() ):
$category = get_queried_object_id();
$args = [
'cq' => $category,
];
break;
case ( is_tax() ):
$term = get_queried_object();
$args = [
'tq' => $term->taxonomy,
'ttq' => $term->slug
];
break;
case ( is_search() ):
$search = get_search_query();
$args = [
'sq' => $search,
];
break;
case ( is_author() ):
$author = get_queried_object_id();
$args = [
'aq' => $author,
];
break;
case ( is_tag() ):
$tag = get_queried_object_id();
$args = [
'taq' => $tag,
];
break;
}
if( isset( $args ) ) {
$permalink = add_query_arg( $args, $permalink );
}
return $permalink;
}
/**
* @access private
* This function is marked private and should not be used in any other functions
*
* This is a helper function for the main navigation function
*
* This function checks if any of the query variables is set in the single
* post page URL. If they exists, the values are retrieved that was set
* by the query variables
*
* This query variables is converted into query arguments for the query that will
* be used to determine the current post position and the posts adjacent to the
* current post which will translate in the next and previous post.
*
* When no query variables are present, and empty array of argument is returned
*
* @uses has_query_var()
* @return (array) $add_query_args_to_args Query variable to determine the next/previous post links
* @see http://codex.wordpress.org/Function_Reference/add_query_arg
*
*/
function _query_vars_to_query_args() {
switch ( true ) {
case ( has_query_var( 'cq' ) ): // For category referrer
$category = get_query_var( 'cq' );
$add_query_args_to_args = [
'cat' => $category,
];
break;
case ( has_query_var( 'tq' ) && has_query_var( 'ttq' ) ): // For taxonomy term referrer
$taxonomy = get_query_var( 'tq' );
$term = get_query_var( 'ttq' );
$add_query_args_to_args = [
'tax_query' => [
[
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $term,
'include_children' => false,
],
],
];
break;
case ( has_query_var( 'sq' ) ): // For search referrer
$search = get_query_var( 'sq' );
$add_query_args_to_args = [
's' => $search,
];
break;
case ( has_query_var( 'aq' ) ): // For author referrer
$author = get_query_var( 'aq' );
$add_query_args_to_args = [
'author' => $author,
];
break;
case ( has_query_var( 'taq' ) ): // For tag referrer
$tag = get_query_var( 'taq' );
$add_query_args_to_args = [
'tag_id' => $tag,
];
break;
default: // Default: returns empty array on any other archive or homepage
$add_query_args_to_args = [];
break;
}
return $add_query_args_to_args;
}
/**
* @access private
* This function is marked private and should not be used in any other functions
*
* This is a helper function for the main pagination function. This function
* checks if the defined query variables has been set in the URL of a single
* post
*
* If any of the query variables are found on any given single post page, then
* these query variables will be set to the next and previous post links according
* to the single post's query variables
*
* This way, next and previous posts will be shown from the same category, term,
* search query or author archive from which the original single post was referred
* from.
*
* If a single post was referred from any other archive or main page, these query
* variables will not be set, and function will default to an empty array and no
* query variables will be set to the next and previous post links
*
* @uses has_query_var()
* @return (array) $qv Query variable to add to next/previous post links
* @see http://codex.wordpress.org/Function_Reference/add_query_arg
*
* @todo Other archives can be added later
*/
function _add_query_vars_to_nav_links() {
switch ( true ) {
case ( has_query_var( 'cq' ) ): // For category referrer
$category = get_query_var( 'cq' );
$qv = [
'cq' => $category,
];
break;
case ( has_query_var( 'tq' ) && has_query_var( 'ttq' ) ): // For taxonomy term referrer
$taxonomy = get_query_var( 'tq' );
$term = get_query_var( 'ttq' );
$qv = [
'tq' => $term->taxonomy,
'ttq' => $term->slug
];
break;
case ( has_query_var( 'sq' ) ): // For search referrer
$search = get_query_var( 'sq' );
$qv = [
'sq' => $search,
];
break;
case ( has_query_var( 'aq' ) ): // For author referrer
$author = get_query_var( 'aq' );
$qv = [
'aq' => $author,
];
break;
case ( has_query_var( 'taq' ) ): // For tag referrer
$tag = get_query_var( 'taq' );
$qv = [
'taq' => $tag,
];
break;
default: // Default: returns empty array on any other archive or homepage
$qv = [];
break;
}
return $qv;
}
/**
* This function returns navigation links to the next/previous single post
* There are choices to which taxonomy to use, and whether adjacent posts should
* be of the same term or not
*
* When in_same_term is set to true, you have a choice to use the parent term or
* child term if a post belongs to both. If the parent term is not available, the child term
* is automatically used
*
* @param array $defaults An array of key => value arguments. Defaults below
* - bool in_same_term Whether or not next/previous post should be in the same term Default true
* - bool parent_term If in_same_term is true, should the parent or child terms be used Default true
* - string/array taxonomy The taxonomy from which terms to use Default category
* - string previous_text Text to display with previous post Default 'Previous post'
* - string next_text Text to display with next post Default 'Next post'
*
* @return string $links
*/
function get_single_post_navigation( $args = [] ) {
// Sets the default arguments for default usage
$defaults = [
'in_same_term' => true,
'parent_term' => true,
'post_types' => '',
'taxonomy' => 'category',
'previous_text' => __( 'Previous post' ),
'next_text' => __( 'Next post' ),
];
// Merges the default arguments with user defined variables
$args = wp_parse_args( $args, $defaults );
/**
* Get the currently displayed single post. For this use
* get_queried_object() as this is more safe than the global $post
*
* The $post global is very easily changed by any poorly written custom query
* or function, and is there for not reliable
*
* @see Post below on WPSE for explanation
* @link https://wordpress.stackexchange.com/q/167706/31545
*/
$single_post = get_queried_object();
/**
* Use the post type of the current post or post types entered in args
*
*/
$post_type = ( empty( $args['post_types'] ) ) ? $single_post->post_type : $args['post_types'];
// Set the variable query variables according to condition
if( !empty( _query_vars_to_query_args() ) ) {
$query_args = _query_vars_to_query_args();
}elseif( true === $args['in_same_term'] ) {
$terms = wp_get_post_terms( $single_post->ID, $args['taxonomy'] );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
foreach ( $terms as $term ) {
if( $term->parent === 0 ) {
$parent[] = $term;
}else{
$child[] = $term;
}
}
$term_id = ( $args['parent_term'] === true && isset( $parent ) ) ? $parent[0]->term_id : $child[0]->term_id;
$query_args = [
'tax_query' => [
[
'taxonomy' => $args['taxonomy'],
'field' => 'term_id',
'terms' => $term_id,
'include_children' => false,
],
],
];
}
}else{
$query_args = [];
}
// Default arguments to use with all the conditional statements above
$default_query_args = [
'post_type' => $post_type,
'fields' => 'ids',
'posts_per_page' => -1,
];
// Merges the default arguments with the arguments from the conditional statement
$combined_args = wp_parse_args( $query_args, $default_query_args );
$q = new WP_Query( $combined_args );
// Get the current post position. Will be used to determine adjacent posts
$current_post_position = array_search( $single_post->ID, $q->posts );
// Get the returned values from '_add_query_vars_to_nav_links()' to build links
$get_qv = _add_query_vars_to_nav_links();
// Get the next/older post ID
if ( array_key_exists( $current_post_position + 1 , $q->posts ) ) {
$next = $q->posts[$current_post_position + 1];
}
// Get post title link to the next post
if( isset( $next ) ) {
$next_post = get_post( $next );
$next_post_link = ( !empty( $get_qv ) ) ? add_query_arg( $get_qv, get_permalink( $next ) ) : get_permalink( $next );
$next_title = '<span class="meta-nav">' . $args['next_text'] . ': </span><a href="' . $next_post_link . '">' . $next_post->post_title . '</a></br>';
}else{
$next_title = '';
}
// Get the previous/newer post ID
if ( array_key_exists( $current_post_position - 1 , $q->posts ) ) {
$previous = $q->posts[$current_post_position - 1];
}
// Get post title link to the previous post
if( isset( $previous ) ) {
$previous_post = get_post( $previous );
$previous_post_link = ( !empty( $get_qv ) ) ? add_query_arg( $get_qv, get_permalink( $previous ) ) : get_permalink( $previous );
$previous_title = '<span class="meta-nav">' . $args['previous_text'] . ': </span><a href="' . $previous_post_link . '">' . $previous_post->post_title . '</a></br>';
}else{
$previous_title = '';
}
// Create the next/previous post links
$links = '<nav class="navigation post-navigation" role="navigation">';
$links .= '<div class="nav-links">';
$links .= $previous_title;
$links .= $next_title;
$links .= '</div><!-- .nav-links -->';
$links .= '</nav><!-- .navigation -->';
// Returns the post links with HTML mark-up
return $links;
}
/**
* This function is simply just a wrapper for the main navigation
* function and echo's the returned values from the main navigation
* function
*/
function single_post_navigation( $args = [] ) {
echo get_single_post_navigation( $args );
}
$args = [
'post_types' => ['post', 'my_cpt'],
'in_same_term' => false,
'previous_text' => __( 'Vorige Pos' ),
'next_text' => __( 'Volgende Pos' ),
];
single_post_navigation( $args );