Я хотел бы разместить нумерацию страниц на каждой странице продукта в WooCommerce, чтобы пользователь мог легче перемещаться между продуктами этой категории, чем каждый раз возвращаться на главную страницу категории.
Я знаю, что можно использовать стандартные нумерационные ссылки WordPress, такие как…
<?php previous_post_link('« %link'); ?>
<?php next_post_link('%link »'); ?>
Это работает, если я хочу просмотреть все продукты, но я хочу только просмотреть продукты, относящиеся к той категории, в которой я нахожусь. Кто-нибудь знает, как я могу ограничить это, чтобы продукты за пределами этой категории не включались?
Я попытался использовать параметр in_same_term, как упомянуто в кодексе WordPress, чтобы получить ссылки, показывающие только, если следующий / предыдущий продукт находится в той же категории, но по какой-то причине он возвращает целое число. Вот код, который я использую …
<?php next_post_link( '%link', '%title', TRUE, '' ); ?>
Это ничего не возвращает вообще, хотя и следует структуре Кодекса. Я также пытался …
<?php next_post_link( '%link %title', TRUE, '' ); ?>
И это то, что я получаю взамен …
1 %title
Я в тупик, куда идти дальше.
Вот функция, которую я недавно написал, которая также выполняет свою работу и является достаточно гибкой
Сначала нужно получить идентификатор текущей записи, через который я получаю get_queried_object_id()
. Идентификатор сообщения будет использоваться для получения:
Условия сообщения, к которому принадлежит сообщение wp_get_post_terms()
. Чтобы ускорить процесс, будут возвращены только идентификаторы условий. Первый идентификатор будет использоваться (Вы можете изменить код здесь, чтобы решить, какой термин будет использоваться, если сообщение содержит более одного термина), и это будет использоваться для получения всех сообщений, которые имеют этот определенный термин
Идентификаторы постов, которые находятся непосредственно рядом с этим постом, чтобы определить и извлечь следующий и предыдущий пост из этого поста.
Вся информация выше будет использована в tax_query
с get_posts
чтобы получить все сообщения, которые разделяют термин из текущего сообщения. В функции таксономия по умолчанию category
и post_type
установлен на любой, чтобы получить все сообщения, которые имеют этот конкретный термин
Опять же, чтобы сделать код быстрее и безопаснее для ресурсов, мы собираемся получить только идентификаторы постов, так как это все, что нужно
Теперь перейдем к важным частям кода. Теперь нам нужно определить следующее:
Текущая позиция текущего сообщения в возвращенном массиве идентификаторов сообщений из пользовательского get_posts
запрос. Используемая здесь функция array_search
Если есть пост до или после этого поста (следующие или предыдущие посты, определения те же, что и для встроенных функций next_post_link()
а также previous_post_link()
), получить идентификаторы этих сообщений
Используйте идентификаторы с get_post
извлечь заголовки следующего и предыдущего поста из текущего поста
Наконец будет возвращать ссылки. Я установил сообщения, если текущее сообщение является первым или последним сообщением в массиве, и нет следующего или предыдущего сообщения. Вы можете решить, что вы хотите сделать здесь, и для всего, что имеет значение, остальная часть кода
Чтобы сделать код еще быстрее и эффективнее, я использовал Переходный API который вы можете прочитать дальше. Я также использовал transition_post_status
Действие ловушка, чтобы подключить функцию, чтобы удалить эти переходные процессы всякий раз, когда статус публикации изменяется. Это включает в себя новые публикации публикуемые, сообщение обновляется и сообщение удалено / восстановлено
Вот код Это входит в ваши functions.php
function get_post_link( $taxonomy = 'category', $post_type = [ 'any' ] ) {
$id = get_queried_object_id(); // Get the current post ID
$transient_id = 'post_number_' . md5( $id . $taxonomy . implode( ',', $post_type ) ); //Create a unique transient id
if ( false === ( $links = get_transient( $transient_id ) ) ) {
// Get the terms a post belongs to
$terms = wp_get_post_terms( $id, $taxonomy, array( 'fields' => 'ids' ) );
// Use a tax_query to get all posts from the given term
// Just retrieve the ids to speed up the query
$post_args = [
'post_type' => $post_type,
'fields' => 'ids',
'posts_per_page' => -1,
'tax_query' => [
[
'taxonomy' => $taxonomy,
'field' => 'term_id',
'terms' => $terms[0],
'include_children' => false,
],
],
];
// Get all the posts having the given term from all post types
$q = get_posts( $post_args );
//Get the current post position. Will be used to determine next/previous post
$current_post_position = array_search( $id, $q );
// Get the previous/older post ID
if ( array_key_exists( $current_post_position + 1 , $q ) ) {
$previous = $q[$current_post_position + 1];
}
// Get post title link to the previous post
if( isset( $previous ) ) {
$previous_post = get_post( $previous );
$previous_post_link = get_permalink( $previous );
$previous_title = '<a href="' . $previous_post_link . '">' . $previous_post->post_title . '</a></br>';
}
// Get the next/newer post ID
if ( array_key_exists( $current_post_position - 1 , $q ) ) {
$next = $q[$current_post_position - 1];
}
// Get post title link to the next post
if( isset( $next ) ) {
$next_post = get_post( $next );
$next_post_link = get_permalink( $next );
$next_title = '<a href="' . $next_post_link . '">' . $next_post->post_title . '</a></br>';?><pre><?php var_dump($next_title); ?></pre><?php
}
// The returned post links
if( isset( $previous_title, $next_title ) ) {
$links = [
'previous_post' => $previous_title,
'next_post' => $next_title,
];
}elseif( !isset( $previous_title ) && $next_title ) {
$links = [
'previous_post' => 'You are currently viewing the newest post',
'next_post' => $next_title,
];
}elseif( $previous_title && !isset( $next_title ) ) {
$links = [
'previous_post' => $previous_title,
'next_post' => 'You are currently viewing the last post',
];
}
set_transient( $transient_id, $links, 7 * DAY_IN_SECONDS );
}
return (object)$links;
}
add_action( 'transition_post_status', function ( $new_status, $old_status, $post )
{
global $wpdb;
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE ('_transient%_post_number_%')" );
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE ('_transient_timeout%_post_number_%')" );
}, 10, 3 );
Теперь вы можете использовать следующий код в файле single.php. Таксономия по умолчанию category
и тип сообщения any
, Если ваша пользовательская таксономия называется mytax
, вы можете использовать код, как это
if( function_exists( 'get_post_link' ) ) {
$post_links = get_post_link( 'mytax' );
echo $post_links->previous_post . '</br>' . $post_links->next_post;
}
Других решений пока нет …