Hi Mike,
A small update on this. What I want to achieve is not to change the URL structure, but rather that each paginated is pointing towards itself as a canonical page. Then, the Yoast plug-in also advises to add rel=next and rel=prev tags to the pagination buttons.
You can read more about that here: https://yoast.com/help/is-the-plugin-compatible-with-paginated-content/
And here is a Github link to the implementation: https://gist.github.com/amboutwe/66c583d2ef4015a8a244ee3e0e8cd1a0
There is also another ticket that links to this: https://kriesi.at/support/topic/alternate-page-with-correct-canonical-tag/.
I tried, based on the documentation, to alter the Yoast plug-in to take the avia-pagination into account when adding it’s logic, both canonical wise and with the prev/next rel’s.
Could you guide me in the right direction with this:
<?php
/**
* Fix Yoast SEO pagination compatibility with Enfold theme using avia-element-paging.
*
* This will:
* - Override the canonical URL to point to the current paginated URL
* - Add correct rel="next" and rel="prev" links for Yoast SEO
* - Handle first page navigation properly
* - Work with multiple Enfold paginated pages
*/
// Store max pages in a more efficient way
global $avia_pagination_data;
$avia_pagination_data = [];
// More efficient way to store max pages without creating duplicate queries
add_filter('avia_blog_post_query', function($query, $params) {
global $avia_pagination_data;
// Store the page ID so we can track pagination for multiple pages
$page_id = get_the_ID();
if (!isset($avia_pagination_data[$page_id])) {
$avia_pagination_data[$page_id] = [];
}
// We don't need to create a new query object here
// Just extract the pagination data from the query args
if (isset($query['posts_per_page']) && isset($params['items'])) {
$posts_per_page = intval($query['posts_per_page']);
$total_items = intval($params['items']);
if ($posts_per_page > 0) {
$max_pages = ceil($total_items / $posts_per_page);
$avia_pagination_data[$page_id]['max_pages'] = $max_pages;
}
}
return $query;
}, 20, 2);
/**
* Helper function to check if we're on an Enfold paginated page
*/
function is_enfold_paginated_page() {
// Check if we're on a singular page that might have pagination
if (!is_singular()) {
return false;
}
// Check for the pagination parameter
$has_param = isset($_GET['avia-element-paging']);
// Also check if the page content contains Enfold pagination elements
$content = get_post_field('post_content', get_the_ID());
$has_pagination_element = (
strpos($content, 'blog') !== false ||
strpos($content, 'portfolio') !== false ||
strpos($content, 'av_masonry_entries') !== false
);
return $has_param || $has_pagination_element;
}
/**
* Get current page and max pages for the current Enfold page
*/
function get_enfold_pagination_data() {
global $avia_pagination_data;
$page_id = get_the_ID();
$current_page = isset($_GET['avia-element-paging']) ? intval($_GET['avia-element-paging']) : 1;
$max_pages = isset($avia_pagination_data[$page_id]['max_pages']) ?
$avia_pagination_data[$page_id]['max_pages'] :
10; // Fallback value
return [
'current' => $current_page,
'max' => $max_pages
];
}
/**
* Fix canonical URL for Enfold pagination
*/
add_filter('wpseo_canonical', function($canonical) {
if (!is_enfold_paginated_page()) {
return $canonical;
}
$data = get_enfold_pagination_data();
$current_page = $data['current'];
// Only modify if we're on a paginated page
if ($current_page > 1) {
return add_query_arg('avia-element-paging', $current_page, get_permalink());
}
return $canonical;
});
/**
* Fix prev link for Enfold pagination
*/
add_filter('wpseo_prev_rel_link', function($link) {
if (!is_enfold_paginated_page()) {
return $link;
}
$data = get_enfold_pagination_data();
$current_page = $data['current'];
if ($current_page > 1) {
$prev_page = $current_page - 1;
$prev_url = ($prev_page === 1) ?
get_permalink() :
add_query_arg('avia-element-paging', $prev_page, get_permalink());
return '<link rel="prev" href="' . esc_url($prev_url) . '" />' . PHP_EOL;
}
return false;
});
/**
* Fix next link for Enfold pagination
*/
add_filter('wpseo_next_rel_link', function($link) {
if (!is_enfold_paginated_page()) {
return $link;
}
$data = get_enfold_pagination_data();
$current_page = $data['current'];
$max_pages = $data['max'];
if ($current_page < $max_pages) {
$next_page = $current_page + 1;
$next_url = add_query_arg('avia-element-paging', $next_page, get_permalink());
return '<link rel="next" href="' . esc_url($next_url) . '" />' . PHP_EOL;
}
return false;
});
/**
* Also fix first page navigation (when no pagination parameter is present)
*/
add_action('wp_head', function() {
// Only run on first page (no pagination parameter)
if (is_enfold_paginated_page() && !isset($_GET['avia-element-paging'])) {
$data = get_enfold_pagination_data();
$max_pages = $data['max'];
// Only add next link if we have more than one page
if ($max_pages > 1) {
$next_url = add_query_arg('avia-element-paging', 2, get_permalink());
echo '<link rel="next" href="' . esc_url($next_url) . '" />' . PHP_EOL;
}
}
}, 999); // Run late to ensure it doesn't get overridden
Would be greatly appreciated, as this would solve the GSC notifications and let the pagination target to itself.
Kind regards,
Joost