Add and in the header while looping over custom query in page template

The question:

I have a custom page template defined and working properly.
On this specific page, I want to list a lot of links, and paginate them, to display 100 links per page.

Here is the code in my template file, working exactly like I want

<div class="container">
<ul class="row listing-items">
    <?php
        $paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
        $custom_args = array(
            'post_type' => 'page',
            'posts_per_page' => 90,
            'paged' => $paged,
            'order' => 'ASC',
            'orderby' => 'title',
            'post__not_in' => array('6','6371','9522','5038','6380','9521','6385','9276','4159','4087','4085','4082'),
            'post_parent__in' => array('13', '154', '127', '162', '123', '167', '159', '121','18675','18676','18677','18678','18679','18680','18681','18682','18683','18684','18685','18687','18688','18689','18690','18691','18692','18693','18695','18696','18697','18699','18700','18701','18702','18703','18704','18694','18709','18705','18710','18706','18707','18718','18719','18720','18721','18722','18723','18724','18725','18726','18711','18727','18728','18729','18730','18731','18732','18716','18733','18734','18712','18735','18736','18737','18738','18739','18740','18741','18742','18743','18744','18745','18746','18717','18747','18686','18708','18748','18713','18749','18750','18751','18714','18752','18698','18753','18754','18755','18757','18758','18759','18760','18715','18761','18762','18756'),
        );
        $wp_query = new WP_Query( $custom_args );
        if ( $wp_query->have_posts() ) {
            while ( $wp_query->have_posts() ) : $wp_query->the_post();
                echo '<li class="listing-item col-12 col-sm-12 col-md-12 col-lg-6 col-xl-6">';
                echo '<a href="'.get_the_permalink().'" rel="nofollow noreferrer noopener">Voiture '.get_the_title().'</a></li>';
            endwhile;
            wp_reset_postdata();
        }
    ?>
</ul>

Now, for SEO purposes, I want to add in my header rel Next and Prev, so Google understand the pagination and can understand which page is the current one, and which page is next and prev.

Here is my code in functions.php

function rel_next_prev() {
global $paged;

if ( get_previous_posts_link() ) {
    echo '<link rel="prev" href="'.get_pagenum_link( $paged - 1 ).'" rel="nofollow noreferrer noopener" />';
}
if ( get_next_posts_link() ) {
    echo '<link rel="next" href="'.get_pagenum_link( $paged + 1 ).'" rel="nofollow noreferrer noopener" />';
}
}
add_action( 'wp_head', 'rel_next_prev' );

Unfortunately, this is partially working. I always get the Rel Prev link in the header, but is not currently based on the query I did.
Let me explain:

When my query is set, I have 19 pages, under this format:

http://localhost:3000/villes/page/2/

So If I change the URL to be (404)

    http://localhost:3000/villes/page/222/

I still get rel Prev with 221 in the header.

So to resume:

How do I properly set rel next/prev in the header based on the current query I’m doing?

Thanks!

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

After a huge night overthinking this, and thanks to Joost de Valk (Yoast SEO plugin author), I found the solution.

As per this thread: https://github.com/Yoast/wordpress-seo/issues/437 , what I want to achieve the way I do, is undoable, or at least, a very bad practice.

If you want your custom query to have the default pagination and rel next prev in the header, you need to call it before get_header();

THEORIC SOLUTION

To make your custom query work with default WP and Yoast functions, you need to:

  1. Put your query BEFORE get_header();
  2. Be sure your query has the default name provided by WP, which is $wp_query
  3. That being said, you will need to create a specific page template for your query, so you can set your query before getting the header.

PRACTIC SOLUTION

For the previous code I had, which was working with get_template_part();.

  1. Create a custom page-template, refering to the page ID or the page slug. More on this here: https://developer.wordpress.org/themes/template-files-section/page-template-files/

  2. Set your custom query before the get_header(); function.

  3. Be sure to re-adapt your code, so it displays the way you want.

Here is my code, which is working as expected. Be sure to keep the rel_next_prev(); function I placed in my functions.php

Final Result:

<?php
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$custom_args = array(
    'post_type' => 'page',
    'posts_per_page' => 90,
    'paged' => $paged,
    'order' => 'ASC',
    'orderby' => 'title',
    'post__not_in' => array('6','6371','9522','5038','6380','9521','6385','9276','4159','4087','4085','4082'),
    'post_parent__in' => array('13', '154', '127', '162', '123', '167', '159', '121','18675','18676','18677','18678','18679','18680','18681','18682','18683','18684','18685','18687','18688','18689','18690','18691','18692','18693','18695','18696','18697','18699','18700','18701','18702','18703','18704','18694','18709','18705','18710','18706','18707','18718','18719','18720','18721','18722','18723','18724','18725','18726','18711','18727','18728','18729','18730','18731','18732','18716','18733','18734','18712','18735','18736','18737','18738','18739','18740','18741','18742','18743','18744','18745','18746','18717','18747','18686','18708','18748','18713','18749','18750','18751','18714','18752','18698','18753','18754','18755','18757','18758','18759','18760','18715','18761','18762','18756'),
);
$wp_query = new WP_Query( $custom_args );
get_header();
get_template_part('template-parts/headers/header', 'listing');
?>

<div class="container">
    <ul class="row listing-items">
        <?php
        if ( $wp_query->have_posts() ) {
            while ( $wp_query->have_posts() ) :
                $wp_query->the_post();
                ?>
                <li class="listing-item col-12 col-sm-12 col-md-12 col-lg-6 col-xl-6">
                    <a href="<?php get_the_permalink(); ?>" rel="nofollow noreferrer noopener">Serrurier <?php the_title();?></a></li>
            <?php
            endwhile;
            wp_reset_postdata(); // reset the query
        }
        ?>
    </ul>

    <div class="row pagination">
        <?php $paginationArgs = array(
            'base'            => get_pagenum_link(1) . '%_%',
            'format'          => 'page/%#%/',
            'total'           => $wp_query->max_num_pages,
            'current'         => $paged,
            'show_all'        => true,
            'end_size'        => 1,
            'mid_size'        => 1,
            'prev_next'       => True,
            'prev_text'       => __('&laquo;'),
            'next_text'       => __('&raquo;'),
            'type'            => 'plain',
            'add_args'        => false,
            'add_fragment'    => ''
        );
        ?>
        <div class="col-12 heading">
            <span>Page <?php echo $paged; ?> sur <?php echo $wp_query->max_num_pages; ?></span>
        </div>

        <div class="col-12 items">
            <?php echo paginate_links($paginationArgs); ?>
        </div>
    </div>


</div>

<?php
get_footer();
?>


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment