[РЕШЕНО] Реверсивная пагинация — Reverse ordered pagination on home, search and archive pages
(за качество кода ответить не могу )
РЕШЕНИЕ только для домашней страницы, на архивах не срабатывает вывод, но работает логика, нужно дорабатывать код : https://github.com/kingkool68/reverse-pagination
код подправил для работы на архивах , в конструкции отсутствовал total count для архивов
<?php /* Plugin Name: WP Reverse Pagination Description: Pagination starts higher and goes lower for more consistent archive page numbering. Author: Russell Heimlich Version: 0.4 */ /** * Logic to make WordPress work with reverse pagination */ class WP_Reverse_Pagination { /** * Once we figure out what the new paged value should be we can store it here for future uses * * @var integer */ private $new_paged = 0; /** * Stores the original paged value of the current request * * @var integer */ private $original_paged = 0; /** * Store the maximum number of pages value once it has been calculated * * @var integer */ private $max_num_pages = 0; /** * Empty constructor */ public function construct() {} /** * Get an instance of this class */ public static function get_instance() { static $instance = null; if ( null === $instance ) { $instance = new static(); $instance->setup_actions(); $instance->setup_filters(); } return $instance; } /** * Hook into WordPress via actions */ public function setup_actions() { add_action( 'template_redirect', array( $this, 'action_template_redirect' ) ); } /** * Hook into WordPress via filters */ public function setup_filters() { add_filter( 'redirect_canonical', array( $this, 'filter_redirect_canonical' ), 10, 2 ); add_filter( 'posts_clauses_request', array( $this, 'filter_posts_clauses_request' ), 10, 2 ); } /** * Redirect to the non /page/ URL if the current $paged value === the max num pages value */ public function action_template_redirect() { global $wp; // When the requested paged value == the max_num_pages value then perform // a redirect to the non /page/ version of the URL for SEO reasons. if ( intval( $this->original_paged ) === intval( $this->max_num_pages ) ) { // Get the URL of the current request. $url = home_url( $wp->request ); $url = add_query_arg( array( $_GET ), trailingslashit( $url ) ); if ( ! $url ) { return; } $redirect = str_replace( '/page/' . $this->original_paged . '/', '', $url ); if ( $url !== $redirect ) { wp_safe_redirect( $redirect, 302 ); exit; } } } /** * Undo some default redirects that WordPress provides * * @param string $redirect_url The URL to be redirected to. * @param string $requested_url The URL being requested. */ public function filter_redirect_canonical( $redirect_url = '', $requested_url = '' ) { if ( is_admin() ) { return; } if ( stristr( $requested_url, '/page/1/' ) ) { return $requested_url; } if ( stristr( $redirect_url, '/page/' . $this->new_paged . '/' ) ) { return $requested_url; } return $redirect_url; } /** * Figure out the proper pagination values and modify SQL clauses to make everything work. * * @param array $clauses The SQL clauses being modified. * @param WP_Query $wp_query The WP_Query being processed. */ public function filter_posts_clauses_request( $clauses = array(), $wp_query ) { global $wpdb; if ( is_admin() || ! $wp_query->is_main_query() ) { return $clauses; } // Setup variables. $q = $wp_query->query_vars; $where = $clauses['where']; $groupby = $clauses['groupby']; if ( ! empty( $groupby ) ) { $groupby = 'GROUP BY ' . $groupby; } $join = $clauses['join']; $orderby = $clauses['orderby']; $distinct = $clauses['distinct']; $fields = $clauses['fields']; $limits = $clauses['limits']; // Figure out how many rows we have. $found_posts = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->posts} $join WHERE 1=1 $where $groupby ORDER BY $orderby" ); if ( is_home() || is_front_page() ){ $found_posts = $wpdb->get_var( "SELECT COUNT(ID) FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish'" ); } // Set how many found posts there are since we know it now. $wp_query->found_posts = intval( $found_posts ); $wp_query->found_posts = apply_filters_ref_array( 'found_posts', array( $wp_query->found_posts, &$wp_query ) ); if ( get_queried_object()->term_id > 0 ){ $wp_query->found_posts = get_term( get_queried_object()->term_id )->count; } // Set the max number of pages. $posts_per_page = intval( $q['posts_per_page'] ); if ( ! $posts_per_page ) { $posts_per_page = get_option( 'posts_per_page' ); } $wp_query->max_num_pages = ceil( $wp_query->found_posts / $posts_per_page ); $this->max_num_pages = $wp_query->max_num_pages; // Save a database query. $wp_query->query_vars['no_found_rows'] = true; // Get the current page being paginated. $paged = $q['paged']; $new_paged = intval( $wp_query->max_num_pages - $paged ) + 1; if ( 0 === $paged ) { $new_paged = intval( $wp_query->max_num_pages ); } $this->original_paged = $paged; $this->new_paged = $new_paged; // Calculate the new offset. $new_offset = ( $wp_query->max_num_pages - $paged ) * $posts_per_page; if ( 0 === $paged ) { $new_offset = 0; } // Set the new limit clause if it is a positive number (otherwise a negative number indicates a 404). if ( $new_offset >= 0 ) { $clauses['limits'] = 'LIMIT ' . $new_offset . ', ' . $posts_per_page; } return $clauses; } } // Kick things off! WP_Reverse_Pagination::get_instance(); /** * Display a list of pagination links based on the current query * * @see paginate_links() * * @param string $args Args to modify the output. */ function reverse_paginate_links( $args = '' ) { global $wp_query, $wp_rewrite; // Setting up default values based on the current URL. $pagenum_link = html_entity_decode( get_pagenum_link() ); $url_parts = explode( '?', $pagenum_link ); // Get max pages and current page out of the current query, if available. $total = isset( $wp_query->max_num_pages ) ? $wp_query->max_num_pages : 1; $current = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : $total; // Append the format placeholder to the base URL. $pagenum_link = trailingslashit( $url_parts[0] ) . '%_%'; // URL base depends on permalink settings. $format = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : ''; $format .= $wp_rewrite->using_permalinks() ? user_trailingslashit( $wp_rewrite->pagination_base . '/%#%', 'paged' ) : '?paged=%#%'; $defaults = array( 'base' => $pagenum_link, // http://example.com/all_posts.php%_% : %_% is replaced by format (below). 'format' => $format, // ?page=%#% : %#% is replaced by the page number 'total' => $total, 'current' => $current, 'aria_current' => 'page', 'show_all' => false, 'prev_next' => true, 'prev_text' => __( 'Previous »' ), 'next_text' => __( '« Next' ), 'end_size' => 1, 'mid_size' => 2, 'type' => 'plain', 'add_args' => array(), // array of query args to add. 'add_fragment' => '', 'before_page_number' => '', 'after_page_number' => '', ); $args = wp_parse_args( $args, $defaults ); if ( ! is_array( $args['add_args'] ) ) { $args['add_args'] = array(); } // Merge additional query vars found in the original URL into 'add_args' array. if ( isset( $url_parts[1] ) ) { // Find the format argument. $format = explode( '?', str_replace( '%_%', $args['format'], $args['base'] ) ); $format_query = isset( $format[1] ) ? $format[1] : ''; wp_parse_str( $format_query, $format_args ); // Find the query args of the requested URL. wp_parse_str( $url_parts[1], $url_query_args ); // Remove the format argument from the array of query arguments, to avoid overwriting custom format. foreach ( $format_args as $format_arg => $format_arg_value ) { unset( $url_query_args[ $format_arg ] ); } $args['add_args'] = array_merge( $args['add_args'], urlencode_deep( $url_query_args ) ); } // Who knows what else people pass in $args. $total = (int) $args['total']; if ( $total < 2 ) { return; } $current = (int) $args['current']; $end_size = (int) $args['end_size']; // Out of bounds? Make it the default. if ( $end_size < 1 ) { $end_size = 1; } $mid_size = (int) $args['mid_size']; if ( $mid_size < 0 ) { $mid_size = 2; } $add_args = $args['add_args']; $r = ''; $page_links = array(); $dots = false; if ( $args['prev_next'] && $current && $current < $total ) : $link = str_replace( '%_%', $total - 1 === $current ? '' : $args['format'], $args['base'] ); $link = str_replace( '%#%', $current + 1, $link ); if ( $add_args ) { $link = add_query_arg( $add_args, $link ); } $link .= $args['add_fragment']; /** * Filters the paginated links for the given archive pages. * * @since 3.0.0 * * @param string $link The paginated link URL. */ $page_links[] = '<a class="prev page-numbers" href="' . esc_url( apply_filters( 'paginate_links', $link ) ) . '">' . $args['next_text'] . '</a>'; endif; for ( $n = $total; $n >= 1; $n-- ) : if ( $n === $current ) : $page_links[] = "<span aria-current='" . esc_attr( $args['aria_current'] ) . "' class='page-numbers current'>" . $args['before_page_number'] . number_format_i18n( $n ) . $args['after_page_number'] . '</span>'; $dots = true; else : // This logic is weird and needs reworking. if ( $args['show_all'] || ( $n <= $end_size || ( $current && $n > $current - $mid_size && $n < $current + $mid_size ) || $n > $total - $end_size ) ) : $link = str_replace( '%_%', $total === $n ? '' : $args['format'], $args['base'] ); $link = str_replace( '%#%', $n, $link ); if ( $add_args ) { $link = add_query_arg( $add_args, $link ); } $link .= $args['add_fragment']; /** This filter is documented in wp-includes/general-template.php */ $page_links[] = "<a class='page-numbers' href='" . esc_url( apply_filters( 'paginate_links', $link ) ) . "'>" . $args['before_page_number'] . number_format_i18n( $n ) . $args['after_page_number'] . '</a>'; $dots = true; elseif ( $dots && ! $args['show_all'] ) : $page_links[] = '<span class="page-numbers dots">' . __( '…' ) . '</span>'; $dots = false; endif; endif; endfor; if ( $args['prev_next'] && $current && 1 < $current ) : $link = str_replace( '%_%', $args['format'], $args['base'] ); $link = str_replace( '%#%', $current - 1, $link ); if ( $add_args ) { $link = add_query_arg( $add_args, $link ); } $link .= $args['add_fragment']; /** This filter is documented in wp-includes/general-template.php */ $page_links[] = '<a class="next page-numbers" href="' . esc_url( apply_filters( 'paginate_links', $link ) ) . '">' . $args['prev_text'] . '</a>'; endif; switch ( $args['type'] ) { case 'array': return $page_links; case 'list': $r .= "<ul class='page-numbers'>\n\t<li>"; $r .= join( "</li>\n\t<li>", $page_links ); $r .= "</li>\n</ul>\n"; break; default: $r = join( "\n", $page_links ); break; } return $r; }
Как сделать такое? Пример:
https://izismile.com/ в данном примере, автор смог развернуть пагинацию в обратную сторону для домашней страницы , а вот для таксономий не справился или пропустил https://izismile.com/tags/wins/
1 Нужно перевернуть пагинацию
из [HOME или 1].2.3...8.9.10 - сейчас на [10] самые первые\старые посты
в- [HOME или 10].9.8...3.2.1 - тут на [10] и [HOME] домашняя\главная страница
2 Главную страницу и архивы нужно сохранить на чистом домене без пагинации (https://site.com/ или https://site.com/category/test/)
3 Чтоб при нажатии на [10] открывалась главная (домашняя страница) https://site.com/, а на [1] открывались самые первые посты https://site.com/category/test/page/1/
4 простыми словами, текущие стандартная сортировка и вывод постов по дате публикации не должны быть затронуты
Зачем сие мудрение? Часто клиенты (я тоже) пользуются поиском по картинкам (к фразам тоже относится) - Когда идет поиск необычной темы, гугл и яндекс выводит в поиске ссылки на страницы архивов с пагинацией
https://site.com/korm/page/25/
сами понимаете, пост при добавлении новых записей смещается в новые номера страниц архивов - в итоге пользователь шуршит по поиску и архивам - обычно 3-5 страниц в разные стороны и в итоге пост теряется для пользователя и сайт теряет посетителя.еще, бывает в поиске, один и тот же запрос ссылается на 3-6 страниц архивов с пагинацией - но не на одной из страниц поста уже нет.
для продажников плохо что пользователь не находит нужное, для сайтов с рекламой наоборот хорошо так как пользователь просматривает банеры.
/****[000] Pagination */ function my_pagenavi() { global $wp_query; $big = 123456789; $page_format = paginate_links( array( 'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ), 'format' => '?paged=%#%', 'current' => max( 1, get_query_var('paged') ), 'total' => $wp_query->max_num_pages, 'mid_size' => 3, 'end_size' => 1, // 'show_all' => true, 'type' => 'array', 'prev_text' => __(' ⋘ '), 'next_text' => __(' ⋙ ') ) ); $navi = ''; if( is_array($page_format) ) { $paged = ( get_query_var('paged') == 0 ) ? 1 : get_query_var('paged'); $navi = '<table class="pg_nav" ><tbody><tr>'; if ($paged == 1 || $paged == '' ){ $navi .= '<td><a class="prev page-numbers disabled" href="#"> ⋘ </a></td>'; } foreach ( $page_format as $page ) { $navi .= '<td>'; $navi .= "$page"; $navi .= '</td>'; } if ($paged == $wp_query->max_num_pages ){ $navi .= '<td><a href="#" class="disabled"> ⋙ </a></td>'; } $navi .= '</tr></tbody></table>'; } return $navi; }
Такой манипуляции не достаточно?
if( is_array($page_format) ) { $page_format = array_reverse( $page_format );
Ну и немного подкрутить параметры...
1 Переворот пагинации сработал
![](/wp-content/uploads/2021/02/2021-02-15_17-36-34.png)
2 Осталась проблема вывода\сортировки записи - перевернул
add_filter('pre_get_posts', 'pre_get_posts_hook' ); // function pre_get_posts_hook($wp_query) { $wp_query->set( 'order', 'ASC' ); // set query order ascending return $wp_query; }
3 теперь вопрос с главной\первой и страницами архивов. Чтоб ссылки вели на последние добавленные записи - сейчас открываю home, открывается https://site.com/page/1
, a нужно https://site.com/page/58/
или без "page/58/"
- но с последними добавленными записями - как в примере в вопросе
https://site.com/58/ == https://site.com/ https://site.com/category/test/page/10/ == https://site.com/category/test/
А какой функцией сейчас выводится пагинация?