我有一系列帖子,它们是按meta\\u键值排序的。如有必要,也可以按菜单顺序排列。
下一个/上一个帖子链接(由next_post_link
, previous_post_link
, 或posts_nav_link
全部按时间顺序导航。虽然我理解这种默认行为,但我不知道如何改变它。我发现它映射到链接模板中相邻的\\u post\\u链接。php,但之后它似乎开始相当硬编码。是否建议从头开始重新编写以替换它,或者是否有更好的解决方案。
我有一系列帖子,它们是按meta\\u键值排序的。如有必要,也可以按菜单顺序排列。
下一个/上一个帖子链接(由next_post_link
, previous_post_link
, 或posts_nav_link
全部按时间顺序导航。虽然我理解这种默认行为,但我不知道如何改变它。我发现它映射到链接模板中相邻的\\u post\\u链接。php,但之后它似乎开始相当硬编码。是否建议从头开始重新编写以替换它,或者是否有更好的解决方案。
post_date
- 或者,如果您将分级帖子作为当前显示的对象,则为帖子父级。当您查看next_post_link()
, 然后您会看到它基本上是adjacent_post_link()
. 后面的函数调用get_adjacent_post()
内部使用$previous
参数/标志设置为bool(true|false)
获取下一个或上一个帖子链接。
get_adjacent_post()
Source link 为其输出提供了一些很好的过滤器(也称为查询结果):(过滤器名称/参数)"get_{$adjacent}_post_join"
$join
// Only if `$in_same_cat`
// or: ! empty( $excluded_categories`
// and then:
// " INNER JOIN $wpdb->term_relationships AS tr
// ON p.ID = tr.object_id
// INNER JOIN $wpdb->term_taxonomy tt
// ON tr.term_taxonomy_id = tt.term_taxonomy_id";
// and if $in_same_cat then it APPENDS:
// " AND tt.taxonomy = \'category\'
// AND tt.term_id IN (" . implode(\',\', $cat_array) . ")";
$in_same_cat
$excluded_categories
"get_{$adjacent}_post_where"
$wpdb->prepare(
// $op = $previous ? \'<\' : \'>\'; | $current_post_date
"WHERE p.post_date $op %s "
// $post->post_type
."AND p.post_type = %s "
// $posts_in_ex_cats_sql = " AND tt.taxonomy = \'category\'
// AND tt.term_id NOT IN (" . implode($excluded_categories, \',\') . \')\';
// OR empty string if $in_same_cat || ! empty( $excluded_categories
."AND p.post_status = \'publish\' $posts_in_ex_cats_sql "
",
$current_post_date,
$post->post_type
)
$in_same_cat
$excluded_categories
"get_{$adjacent}_post_sort"
"ORDER BY p.post_date $order LIMIT 1"`
所以你可以用它做很多事情。首先要过滤WHERE
条款,以及JOIN
ed表格和ORDER BY
陈述结果缓存在当前请求的内存中,因此如果在单个页面上多次调用该函数,则不会添加额外的查询。
get_meta_sql()
- 示例in Codex. 基本上,此函数只用于构建在中使用的元SQL语句WP_Query
, 但您也可以在这种情况下(或其他情况下)使用它。您在其中输入的参数是一个数组,与添加到WP_Query
.$meta_sql = get_meta_sql(
$meta_query,
\'post\',
$wpdb->posts,
\'ID\'
);
返回值是一个数组:$sql => (array) \'join\' => array(),
(array) \'where\' => array()
所以你可以使用$sql[\'join\']
和$sql[\'where\']
在您的回拨中。$adjacent = $previous ? \'previous\' : \'next\';
变量和$order = $previous ? \'DESC\' : \'ASC\';
变量:get_previous_post_join
, get_next_post_join
get_previous_post_where
, get_next_post_where
get_previous_post_sort
, get_next_post_sort
<?php
/** Plugin Name: (#73190) Alter adjacent post link sort order */
function wpse73190_adjacent_post_sort( $orderby )
{
return "ORDER BY p.menu_order DESC LIMIT 1";
}
add_filter( \'get_previous_post_sort\', \'wpse73190_adjacent_post_sort\' );
add_filter( \'get_next_post_sort\', \'wpse73190_adjacent_post_sort\' );
Kaiser\'s answer 是非常棒和彻底的,但是仅仅更改ORDER BY子句是不够的,除非您的menu_order
符合您的时间顺序。
我不能对此负责,但我在中发现了以下代码this gist:
<?php
/**
* Customize Adjacent Post Link Order
*/
function wpse73190_gist_adjacent_post_where($sql) {
if ( !is_main_query() || !is_singular() )
return $sql;
$the_post = get_post( get_the_ID() );
$patterns = array();
$patterns[] = \'/post_date/\';
$patterns[] = \'/\\\'[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\\\'/\';
$replacements = array();
$replacements[] = \'menu_order\';
$replacements[] = $the_post->menu_order;
return preg_replace( $patterns, $replacements, $sql );
}
add_filter( \'get_next_post_where\', \'wpse73190_gist_adjacent_post_where\' );
add_filter( \'get_previous_post_where\', \'wpse73190_gist_adjacent_post_where\' );
function wpse73190_gist_adjacent_post_sort($sql) {
if ( !is_main_query() || !is_singular() )
return $sql;
$pattern = \'/post_date/\';
$replacement = \'menu_order\';
return preg_replace( $pattern, $replacement, $sql );
}
add_filter( \'get_next_post_sort\', \'wpse73190_gist_adjacent_post_sort\' );
add_filter( \'get_previous_post_sort\', \'wpse73190_gist_adjacent_post_sort\' );
我已经修改了WP的函数名。东南部如果只更改ORDER BY子句,查询仍会查找大于或小于当前发布日期的发布。如果你的帖子不按时间顺序排列,你就不会得到正确的帖子。
除了修改orderby子句外,这将更改where子句以查找menu\\u顺序大于或小于当前帖子menu\\u顺序的帖子。
orderby子句也不应该硬编码为使用DESC,因为它需要根据您是获得下一个还是上一个post链接进行切换。
试图勾搭但没有成功。这可能只是我的配置问题,但对于那些无法使挂钩工作的人,这里有一个最简单的解决方案:
<?php
$all_posts = new WP_Query(array(
\'orderby\' => \'menu_order\',
\'order\' => \'ASC\',
\'posts_per_page\' => -1
));
foreach($all_posts->posts as $key => $value) {
if($value->ID == $post->ID){
$nextID = $all_posts->posts[$key + 1]->ID;
$prevID = $all_posts->posts[$key - 1]->ID;
break;
}
}
?>
<?php if($prevID): ?>
<span class="prev">
<a href="<?= get_the_permalink($prevID) ?>" rel="prev"><?= get_the_title($prevID) ?></a>
</span>
<?php endif; ?>
<?php if($nextID): ?>
<span class="next">
<a href="<?= get_the_permalink($nextID) ?>" rel="next"><?= get_the_title($nextID) ?></a>
</span>
<?php endif; ?>
function wpse73190_gist_adjacent_post_sort( $sql ) {
$pattern = \'/post_date/\';
$replacement = \'menu_order\';
return preg_replace( $pattern, $replacement, $sql );
}
add_filter( \'get_next_post_sort\', \'wpse73190_gist_adjacent_post_sort\' );
add_filter( \'get_previous_post_sort\', \'wpse73190_gist_adjacent_post_sort\' );
基于@Szabolcs Páll\'sanswer 我用助手方法创建了这个实用程序类,可以按菜单顺序获取类型的帖子,也可以按菜单顺序获取下一篇和上一篇帖子。我还添加了一些条件,以检查当前帖子是否是分别获得最后一篇或第一篇帖子的第一篇或最后一篇帖子。
例如:
// $currentPost is first by menu order
getPreviousPostByMenuOrder($postType, $$currentPost->ID)
// returns => last post by menu order
// $currentPost is last by menu order
getPreviousPostByMenuOrder($postType, $$currentPost->ID)
// returns => first post by menu order
完整类别:class PostMenuOrderUtils {
public static function getPostsByMenuOrder($postType){
$args =[
\'post_type\' => $postType,
\'orderby\' => \'menu_order\',
\'order\' => \'ASC\',
\'posts_per_page\' => -1
];
$posts = get_posts($args);
return $posts;
}
public static function getNextPostByMenuOrder($postType, $postID){
$posts = self::getPostsByMenuOrder($postType);
$nextPost = null;
foreach($posts as $key => $value) {
if($value->ID == $postID){
$nextPost = $posts[$key] !== end($posts) ? $posts[$key + 1] : $posts[0];
break;
}
}
return $nextPost;
}
public static function getPreviousPostByMenuOrder($postType, $postID){
$posts = self::getPostsByMenuOrder($postType);
$prevPost = null;
foreach($posts as $key => $value) {
if($value->ID == $postID){
$prevPost = $key !== 0 ? $posts[$key - 1] : end($posts);
break;
}
}
return $prevPost;
}
}
FWIW以下是您可以订购的方式menu_order
对于特定的自定义帖子类型:
/**
* Customize adjacent post order
*/
add_filter(\'get_next_post_sort\', function($order) {
if (is_singular(\'my_custom_post_type\')) {
return \'ORDER BY p.menu_order ASC LIMIT 1\';
}
return $order;
}, 10);
add_filter(\'get_previous_post_sort\', function($order) {
if (is_singular(\'my_custom_post_type\')) {
return \'ORDER BY p.menu_order DESC LIMIT 1\';
}
return $order;
}, 10);
add_filter(\'get_next_post_where\', function() {
if (is_singular(\'my_custom_post_type\')) {
global $post, $wpdb;
return $wpdb->prepare("WHERE p.menu_order > %s AND p.post_type = %s AND p.post_status = \'publish\'", $post->menu_order, $post->post_type);
}
}, 10);
add_filter(\'get_previous_post_where\', function() {
if (is_singular(\'my_custom_post_type\')) {
global $post, $wpdb;
return $wpdb->prepare("WHERE p.menu_order < %s AND p.post_type = %s AND p.post_status = \'publish\'", $post->menu_order, $post->post_type);
}
}, 10);
希望这对其他人有帮助!基于@Szabolcs Páll\'sanswer 和bbloomer的职位adding next/prev buttons in WooCommerce Single Product Page, 我创建了此代码。
It sorts all products by meta key and adding prev/next buttons above + below the product.
(The meta key can be an ACF field too!)
/**
* @snippet Add next/prev buttons sorted by meta key or ACF field @ WooCommerce Single Product Page
* @testedwith WooCommerce 4.8.0
* @source Elron : https://wordpress.stackexchange.com/a/365334/98773
* @thanks bbloomer : https://businessbloomer.com/?p=20567
* @thanks Szabolcs Páll : https://wordpress.stackexchange.com/a/284045/98773
*/
add_action(\'woocommerce_before_single_product\', \'elron_prev_next_product\');
// and if you also want them at the bottom...
add_action(\'woocommerce_after_single_product\', \'elron_prev_next_product\');
function elron_prev_next_product()
{
global $post;
echo \'<div class="prev-next-buttons">\';
$all_posts = new WP_Query(
array(
\'post_type\' => \'product\',
\'meta_key\' => \'the_meta_key_or_acf_field\', // <-- CHANGE THIS
\'orderby\' => \'meta_value\',
\'order\' => \'DESC\',
\'posts_per_page\' => -1
)
);
foreach ($all_posts->posts as $key => $value) {
if ($value->ID == $post->ID) {
$nextID = $all_posts->posts[$key + 1]->ID;
$prevID = $all_posts->posts[$key - 1]->ID;
break;
}
}
if ($prevID) : ?>
<a href="<?= get_the_permalink($prevID) ?>" rel="prev" class="prev" title="<?= get_the_title($prevID) ?>"><?= esc_attr__(\'Previous product\') ?></a>
<?php endif; ?>
<?php if ($nextID) : ?>
<a href="<?= get_the_permalink($nextID) ?>" rel="next" class="next" title="<?= get_the_title($nextID) ?>"><?= esc_attr__(\'Next product\') ?></a>
<?php endif; ?>
<?php
echo \'</div>\';
}
如果您想要我使用的额外scss文件:_prev-next-buttons.scss
.prev-next-buttons {
background: $lightpurple;
padding: 2em;
text-align: center;
a {
opacity: 0.7;
border-radius: 0.5em;
border: $white 1px solid;
color: $white;
display: inline-block;
padding: 0.5em 0.8em;
text-decoration: none;
margin: 0 0.1em;
&:hover, &:focus {
opacity: 1;
}
}
.prev {
&:before {
content: " ";
}
}
.next {
&:after {
content: " ";
}
}
}
.rtl {
.prev-next-buttons {
.prev {
&:before {
content: " ";
}
}
.next {
&:after {
content: " ";
}
}
}
}
我发现这个小插件非常方便:http://wordpress.org/plugins/wp-query-powered-adjacent-post-link/
WP\\u Query-Powered nextual-Post-Link是一个面向开发人员的插件。它添加了函数wpqpapl();
到WordPress,它可以将上一篇文章和下一篇文章的信息返回到当前。它接受用于WP_Query
班
这对我很有用:
add_filter( \'get_previous_post_where\', \'so16495117_mod_adjacent_bis\' );
add_filter( \'get_next_post_where\', \'so16495117_mod_adjacent_bis\' );
function so16495117_mod_adjacent_bis( $where ) {
global $wpdb;
return $where . " AND p.ID NOT IN ( SELECT post_id FROM $wpdb->postmeta WHERE ($wpdb->postmeta.post_id = p.ID ) AND $wpdb->postmeta.meta_key = \'archive\' AND $wpdb->postmeta.meta_value = 1 )";
}
摘自:https://stackoverflow.com/questions/16495117/how-to-skip-certain-links-on-adjacent-posts-in-wordpress我对此也有意见。我神奇地让它像这样工作:
确保您的帖子类型设置为具有层次式帖子https://wordpress.org/plugins/simple-custom-post-order/
除了可以通过拖放轻松排序外,该插件还可以通过菜单顺序确保上一步和下一步的工作。不幸的是,它可能以错误的顺序使用DSC而不是ASC。为了解决这个问题,我们可以创建一个反向后期导航功能https://gist.github.com/jaredchu/3e3bcb866240d1d32a3b4ae55905b135#file-the_reverse_post_navigation而且我自己也不必写一个字的代码:)
我发现了一种更容易实现基于元键的帖子导航的方法,无需修改函数。php。
我的例子:你有一个产品。php和您想要在产品之间切换。上一个产品是下一个更便宜的,下一个产品是下一个更贵的。
下面是我的解决方案single.php:
<div class="post_navigation">
<?php
// Prepare loop
$args = (
\'post_type\' => \'products\',
\'post_status\' => \'publish\',
\'meta_key\' => \'price\',
\'orderby\' => \'meta_value_num\',
\'order\' => \'ASC\',
\'posts_per_page\' => -1
);
query_posts($args);
// Initialize array in which the IDs of ALL products posts will be stored
$posts = array();
// ... and now let\'s start the loop
while ( have_posts() ) : the_post();
$posts[] += $post->ID;
endwhile;
// Reset Query
wp_reset_query();
// Identify the position of the current product within the $posts-array
$current = array_search(get_the_ID(), $posts);
// Identify ID of previous product
$prevID = $posts[$current-1];
// Identify ID of next product
$nextID = $posts[$current+1];
// Link "previous product"
if (!empty($prevID)) { ?>
<a href="/?p=<?php echo $prevID; ?>">previous product</a>
<?php }
// Link "next product"
if (!empty($nextID)) { ?>
<a href="/?p=<?php echo $nextID; ?>">next product</a>
<?php } ?>
我正在使用以下查询:<?php $postslist = new WP_Query(\'meta_key=Ordermetakey&orderby=meta_value_num&order=ASC&posts_per_page=5\'); 对frontpage上的小帖子列表进行排序,以显示最新的帖子。它需要通过一个元键对它们进行排序并进行描述。奇怪的是,它显示了帖子的ASC,尽管我已经将ASC放在了这个查询中。元键的值是日期-时间戳:例如:120403=03-04-