2

after hours and dozen of tests and messes... i'm face to the wall and fed up searching (mainly cuz my google's answers are already all clicked !)

I'm trying to display paginate_link with a filters taxonomy form (AGAIN ????? ;).

With all solutions here, I've found how to get the right numbered pagination in a result of my form only on the first page of the results.

The main problem, is in the pagination links, they are using the wrong "$paged" and my filter are remove of the query (via tax_query=>....) on page/2 and the others following.

// In "archive-myCptSlug.php"
// Basicaly my genarated array of args (copy/paste of its var_dump() just before the query): 
//   $custom_query_args {
//     ["paged"]             => int(1)
//     ["posts_per_page"]    => int(3)
//     ["post_type"]         => array(1) { [0]=>string(7) "outings" }
//     ["relation"]          => string(3) "AND"
//     ["tax_query"]         => array(1) {
//                                [0]=> array(3) {
//                                   ["taxonomy"]    => string(16) "outings-category"
//                                   ["field"]       => string(4) "slug"
//                                   ["terms"]       => array(1) { [0]=> string(6) "cinema" }
//                                }
//                              }
//   }

    $custom_query_args = array( /* Parameters go here */ );
    $custom_query_args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
    $custom_query_args['posts_per_page'] = 3;
    $custom_query_args['post_type'] = array( 'outings');
    $custom_query_args['relation'] = 'AND';
    $custom_query_args_tax = array(); // filled with form

    $custom_query = new WP_Query( $custom_query_args );

    // A part of a solution seems to "assimilate" the custom query to the main one, so let's try
    // Backup -> Null -> replace
    $temp_query = $wp_query;
    $wp_query = null;
    $wp_query = $custom_query;

    //then some stuff
    if ( $custom_query->have_posts() ) :
        while ( $custom_query->have_posts() ) :
            $custom_query->the_post();
               // "Hello world"
        endwhile;
    endif;
    wp_reset_postdata();

    // PAGINATE LINKS
    $big = 999999999; // need an unlikely integer
    echo paginate_links( array(
        'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
        'format' => '?paged=%#%',
        'current' => max( 1, get_query_var('paged') ),
        'total' => $custom_query->max_num_pages
    ) );

    // RESTORE WP QUERY
    $wp_query = NULL;
    $wp_query = $temp_query;
  • It's a lot based on WPSE 120407 How to fix pagination for custom loops?
  • The filename used is "archive-outings.php"
  • Permalinks are saved each time
  • Settings > reading > numbers of posts > "10"
  • The 'outings-category' is use as taxonomy instead of WP category, it's on purpose.

Result ?

  • The first page is looking good with filtered items from "cinema".
  • There is 3 elements on the page as asked in custom query
  • The numbered pagination is good with the right "max-pages" number

The problem

  • If, for example, I click on the "2", the page loaded as removed my taxonomy filter(s) and paginate navigation "max-page" looks like (seems to be) the number of pages non filtered by taxonomy (probably due to the use of the "archives-myCptSlug.php" template).

Solution(s) ?

  • I've tryed so much solutions...
  • I don't want use a Settings > reading > numbers of posts set to 1 (I've made it works once) mainly because i will never remeber why I've done this in the future.
  • This doesn't looks to works for me (or i don't know how to use it, because I don't use category - sorties was the wrewrite term but I've tried outings which is the name of my CPT):
    function my_pagination_rewrite() {
        add_rewrite_rule('sorties/page/?([0-9]{1,})/?$', 'index.php?category_name=blog&paged=$matches[1]', 'top');
    }
    add_action('init', 'my_pagination_rewrite');
  • This neither :
    function wpse120407_pre_get_posts( $query ) {
        // Test for category archive index
        // and ensure that the query is the main query
        // and not a secondary query (such as a nav menu
        // or recent posts widget output, etc.
        if ( is_archive() && $query->is_main_query() ) {
            // Modify posts per page
            $query->set( 'posts_per_page', 5 ); 
        }
    }
    add_action( 'pre_get_posts', 'wpse120407_pre_get_posts' );

UPDATE

My form is include with get_template_part :

    <form class="categorie-form" id="outingsFilterForm" role="categorie" action="http://thela.local:8888/eventspage" method="post" accept-charset="UTF-8" target="_self">
    
                <fieldset>
    
                    <legend>Filtres</legend>
    
            <!-- FILTERS ITEM : CATEGORIES -->
    
                    <div class="filterCategorie">
    
                <?php foreach ($termsAllForCategory as $keyCat => $valueCat) : ?>
    
                        <label>
                            <span><?php echo $valueCat->name . " (" . $valueCat->count . ")"; ?></span>
    
                    <?php if ( isset( $postedCategory ) && $postedCategory != "" ) : ?>
    
                        <?php if ( in_array($valueCat->slug, $postedCategory) ) : ?>
                            <input type="checkbox" name="categorie[]" value="<?php echo esc_attr($valueCat->slug); ?>" checked />
                        <?php else: ?>
                            <input type="checkbox" name="categorie[]" value="<?php echo esc_attr($valueCat->slug); ?>" />
                        <?php endif; ?>
    
                    <?php else: ?>
                            <input type="checkbox" name="categorie[]" value="<?php echo esc_attr($valueCat->slug); ?>" checked />
                    <?php endif; ?>
    
                        </label>
    
                <?php endforeach; ?>
    
                    </div>
    
            <!-- FILTERS ITEM : VILLE -->
    
    
                    <div class="filterCategorie">
    
                        <label>
                            <select name="city" id="city" class="select-css">
                        <?php if ( (isset($postedCity) && $postedCity != "") || (isset($favoriteCity) && $favoriteCity != "") ) : ?>
                                <option value="" ><?php _e('All outings cities', 'thela'); ?></option>
                        <?php else : ?>
                                <option value="" selected="selected"><?php _e('All outings cities', 'thela'); ?></option>
                        <?php endif; ?>
    
                        <?php $onceIsHere = ""; ?>
    
                        <?php foreach ($termsAllForCity as $key => $value) : ?>
    
                            <?php if ( $postedCity == $value->slug || $favoriteCity == $value->slug) : ?>
                                <?php $onceIsHere = ( isset($favoriteCity) )? "checked" : "" ?>
                                <option value="<?php echo esc_attr($value->slug); ?>" selected="selected"><?php echo esc_html($value->name); ?> (<?php echo esc_html($value->count); ?>)</option>
                            <?php else : ?>
                                <option value="<?php echo esc_attr($value->slug); ?>"><?php echo esc_html($value->name); ?> (<?php echo esc_html($value->count); ?>)</option>
                            <?php endif; ?>
    
                        <?php endforeach; ?>
                            </select>
                        </label>
    
                    </div>
    
                    <button type="submit"><?php esc_html_e("Display result(s)", "thela"); ?><span></span></button>
    
                </fieldset>
    
                </form>

The actual outings-archive.php is like so :

  • Header

  • Custom code for $_POST vars (obviously to feed Query args Array)

  • get_template_part('outings', 'filters', $getTemplateVars ); (here is loaded the filters form with inside)

  • get_template_part('outings', 'header', $getTemplateVars ); (here is loaded the "resume of the query")

  • wp_query request

  • if / while / $the_post

  • enfwhile / endif

  • wp_reset_postdata;

  • paginate_links

  • $wp_query = NULL;

  • $wp_query = $temp_query;

  • Footer

In order to help -or not-, i've found this thread where he could make it works by calling paginate_links in "success" of its ajax function. (he try the same but in ajax).

https://grafikart.fr/forum/23564

JSFIDDLE

FINALY (or close to)

Thanks Sally-CJ https://wordpress.stackexchange.com/users/137402/sally-cj As soon as can vote, i do it one for you.

I could get rid of My problem Because of 2 main things :

  • Using $_POST instead of $_GET for my filters form
  • Using pre_get_posts to modify WP_Query looks better than making a custom query

Thanks for help ! Nicolas.

11
  • Note that taxonomy archive for specific term have their template name in the form of taxonomy-<taxonomy>-<term slug>.php and not archive-<term slug>.php. And 1) Can you include the code for your filter form? 2) Did you put the form in your post type archive template (archive-<your post type>.php)? 3) You shouldn't be making secondary WP_Query (i.e. new WP_Query()) calls in your taxonomy (and archive) templates - just use the pre_get_posts hook to alter the main query. :)
    – Sally CJ
    Commented Feb 8, 2021 at 5:49
  • You didn't answer my second question - in what template you displayed the form, or in what template you called the get_template_part() which loads the form code? And your form submits to thela.local:8888/eventspage - is that a Page (post of the page type)?
    – Sally CJ
    Commented Feb 8, 2021 at 11:53
  • thela.local:8888/eventspage is a page witth this template (since this morning when i tried again). But I have both now working and bugging the same so I can tes the 2. One is "category-outings.php" the other is "outings.php", a page with this code as template & with a different slug name : "eventspage"
    – nico
    Commented Feb 8, 2021 at 13:24
  • 1
    Ok I quiclky read and you teach me a lot on skills i never used. I started to use pre_get_posts, which seems a good start. I will read right now with attention your post and let you inform. Thanks Thanks 3 times Thanks
    – nico
    Commented Feb 9, 2021 at 11:14
  • 1
    I quickly changed things .... It's seems working great. You help me a lot, thank you a lot !
    – nico
    Commented Feb 9, 2021 at 11:31

1 Answer 1

1

If, for example, I click on the "2", the page loaded as removed my taxonomy filter(s) and paginate navigation "max-page" looks like (seems to be) the number of pages non filtered by taxonomy

It's not that the (taxonomy) filters are removed from the pagination links, but instead, the filters are actually never added because the form data is being submitted using the (HTTP) POST method, hence paginate_links() does not read the data (the function only parses data in the URL query string) and therefore does not add the filters into the pagination links.

And you could manually add the filters by using the add_args argument in the first (and the only) parameter for paginate_links(), but instead of having to set that argument, it's actually simpler if you just set your form's method to get — that way, the browser will automatically add the filters as query string in the form's action URL and so paginate_links() will also then add the filters into the pagination links.

<form class="categorie-form" id="outingsFilterForm" role="categorie"
    action="http://thela.local:8888/eventspage" method="get"
    accept-charset="UTF-8" target="_self">

However, if the form uses the GET method, then in your outings-archive.php (post type archive) template, you'll need to make sure the filters are read from $_GET. E.g.

// Note: Here I'm using the PHP 7's null coalescing operator (the "??" symbol).
$getTemplateVars['postedCategory'] = (array) ( $_GET['categorie'] ?? array() );
$getTemplateVars['postedCity']     = $_GET['city'] ?? '';

So apply those two changes (set the form's method to get and use the above PHP code to read the submitted data) and check if the pagination links now includes the filters from your form.

The actual outings-archive.php is like so :

If you use the same code in a page template, then the "wp_query request" part in your code is fine.

However, on the post type archive page (e.g. the one you've got at /sorties), you shouldn't be making the secondary WP_Query request because pagination will conflict with the one for the main WordPress query which runs on page load (before the archive template is loaded).

  • E.g. If your custom/secondary WordPress query had 3 (max number of) pages, yet the main query had only 2 pages, then going to page 3 would result in the error 404 ("not/nothing found").

  • Therefore, your archive template should just display the posts in the main loop/query. I.e. Without the "wp_query request", "$wp_query = NULL;" and "$wp_query = $temp_query;" parts..

Nonetheless, for now, just apply the two changes I said earlier above and see how things goes. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.