0

I'm fairly new to WP development, however as far as I can see I've followed the correct procedure in my custom archive page (below). If I remove the check for is_main_query() it wipes the menus out and likely a lot of other data is lost due to the filter being applied.

Adding debug code shows that is_main_query() is never returned as true? What am I doing wrong?

My build is WP 4.4 with the "Avada" theme and I'm also making use of the ACF Advanced Custom Fields to add custom meta data to my posts.

Any help is really appreciated, thanks!

<?php
    $has_searchform = true; 
    get_header();
?>
<div id="content" <?php Avada()->layout->add_class( 'content_class' ); ?> <?php Avada()->layout->add_style( 'content_style' ); ?>>
<?php 

function my_pre_get_posts( $query ) {
    //* if within admin, return
    if ( is_admin() ) {
        echo "Admin returning";
        return;
    }
    //* if not main query, return
    else if ( ! $query->is_main_query() ) {
        echo "Not main query";
        return;
    }
    else if ( $query->is_main_query() ) {

        echo "Main query called";

        if( (isset($_GET['fs_date_from']) && $_GET['fs_date_from'] != '')       || 
            (isset($_GET['fs_date_to']) && $_GET['fs_date_to'] != '')           || 
            (isset($_GET['fs_music_genre']) && $_GET['fs_music_genre'] != '')   ||
            (isset($_GET['fs_keyword']) && $_GET['fs_keyword'] != '')           ||
            (isset($_GET['fs_country']) && $_GET['fs_country'] != '')           ||
            (isset($_GET['fs_festival_category']) && $_GET['fs_festival_category'] != '')) {

            if(isset($_GET['fs_date_from']) && $_GET['fs_date_from'] != '') {
                $date_from      = date('Ymd',strtotime(sanitize_text_field($_GET['fs_date_from'])));
                $search_array['fs_date_from'] = array(  'key'       => 'start_date',
                                                        'value'     => $date_from,
                                                        'compare'   => '>='
                                                        );
            }
            if(isset($_GET['fs_date_to']) && $_GET['fs_date_to'] != '') {
                $date_to        = date('Ymd',strtotime(sanitize_text_field($_GET['fs_date_to'])));
                $search_array['fs_date_to'] = array('key'       => 'end_date',
                                                    'value'     => $date_to,
                                                    'compare'   => '<=');
            }
            $keyword        = sanitize_text_field($_GET['fs_keyword']);
            if($keyword != '') {
                $query->set('s',$keyword);
            }
            if(isset($_GET['fs_country']) && $_GET['fs_country'] != '') {
                $country = sanitize_text_field($_GET['fs_country']);
                $search_array['fs_country'] = array('key'       => 'fs_country',
                                                    'value'     => $country,
                                                    'compare'   => '=');
            }
            $music_genre    = sanitize_text_field($_GET['fs_music_genre']);
            if($music_genre != '') {
                $tax_query['music_genre'] = array(  'taxonomy'  => 'music_genre',
                                                    'field'     => 'id',
                                                    'terms'     => array($music_genre),
                                                    'operator'  => 'IN');
            }
            $festival_category  = sanitize_text_field($_GET['fs_festival_category']);
            if($festival_category != '') {
                $tax_query['fs_festival_category'] = array( 'taxonomy'  => 'festival_category',
                                                            'field'     => 'id',
                                                            'terms'     => array($festival_category),
                                                            'operator'  => 'IN');
            }
            print_r($search_array);
            $search_array['relation']   = (($date_from != '' && $date_to != '')? "AND" : "");
            $query->set('posts_per_page', 10);
            $query->set('post_type'     , 'festival');
            $query->set('meta_query'    , $search_array);
            $query->set('tax_query'     , $tax_query);
        }   
        else {
            echo "Woop";
            $query->set('posts_per_page', 10);
            $query->set('post_type'     , 'festival');
        } 
    }
}
add_action('pre_get_posts', 'my_pre_get_posts');

if( have_posts() ) {
    echo 
"<div class='row fusion-row'>
    <div class='col-sm-12'>
";
    fusion_pagination($pages = '', $range = 2);
echo 
"   </div>
</div>";
    while(have_posts()) {
        the_post();
        //setup_postdata( $post );
        $image      = get_field('header_image');
        $image_url  = $image['sizes']['medium_large'];
        $date_format = 'dS \o\f F Y';
        /*if(get_field('start_date') != '') {
            $start_date = DateTime::createFromFormat('Ymd', get_field('start_date'));
        }
        else {
            $start_date = '';
        }
        if(get_field('end_date') != '') {
            $end_date = DateTime::createFromFormat('Ymd', get_field('end_date'));   
        }
        else {
            $end_date = '';
        }*/
        $start_date = get_field('start_date');
        $end_date   = get_field('end_date');
        $vibe       = substr(get_field('vibe'), 0,250)."...";
        $location   = get_field('location');
        $country    = get_field('country');
        //print_r($post);
        $price      = get_min_price(get_the_ID());
        echo 
"<div class='row fusion-row result_row' onclick=\"javascript:window.location.href='". get_permalink() ."'; return false;\">
    <div class='col-sm-5 result_thumbnail' style='background: url(\"". $image_url ."\") center center no-repeat;'>

    </div>
    <div class='col-sm-7'>
        <h3 class='result_title'><a href='". get_permalink() ."'>".get_the_title()."</a></h3>
        <h4 class='result_location'>$location" . (($location != '' && $country != '')? "," : "") . " $country</h4>
        <div class='result_vibe'>
        ". $vibe ."
        </div>
    </div>
    <div class='result_bottom_row col-sm-7'>
        <div class='result_dates'>
";
        if($start_date != '') {
            echo $start_date;
        }
        echo  ((get_field('start_date') != '' && get_field('end_date') != '')? " - " : "");
        if($end_date != '') {
            echo $end_date;
        }
        echo 
"       </div>
        <div class='result_price'>
            $price
        </div>
    </div>
</div>
";
    }       
    fusion_pagination($pages = '', $range = 2);
} 

else {
    echo 
"<p>Sorry, no Festivals match your search.</p>";
}


?>
</div>
<?php do_action( 'fusion_after_content' ); ?>
<?php get_footer();

// Omit closing PHP tag to avoid "Headers already sent" issues.
  • Try put your function with debug code in functions.php – Jevuska Mar 23 '16 at 23:19
1

The action hook pre_get_posts is called well before the page template is rendered. Move add_action('pre_get_posts', 'my_pre_get_posts'); and your my_pre_get_posts() function to your theme's functions.php file.

| improve this answer | |
  • I have done this, now while the query does filter the posts on the archive page, every other page returns a 404. Ill look into how do specifically call it on one page. What is the best practice for this? – Paul Cullen Mar 24 '16 at 10:16
0

A few notes on your code here:

  • Never add business logic in templates. Templates should never be used to compute any kind of logic, templates should only display the results from that logic. In short, templates should know function names, that's it. The function itself should be defined in a plugin or in your theme's functions files

  • By the time the template is set (via template_include), the main query has already executed and just a distant memory. By now, the main query cannot be altered. That is why your action has no affect on the main query. As I stated, functions, including filters and actions should be in a plugin or functions file

  • Instead of doing isset($_GET['fs_date_from']) && $_GET['fs_date_from'] != '') every time you need it, you can simply do the following with filter_input, which will take care of checking if the var is set and will return the value if it is. You can additionally set a filter which will take care of sanitation for you

    $fs_date_from = filter_input( 
        INPUT_GET,             // $_GET Global , for $_POST it will be INPUT_POST
        'fs_date_from',        // Name of the variable
        FILTER_SANITIZE_STRING // Type of filter to use to validate/sanitize
    );
    

    You can now just check if $fs_date_from has a value

    if ( $fs_date_from ) {
        // Do something
    }
    

    You can also look into filter_input_array to handle multiple $_GET variable values

| improve this answer | |
0

Thanks for all your help.

The key issues where that i needed to post the code in the functions.php file and needed to amend the if statement to read:

$query->is_main_query() && is_post_type_archive( 'festival' )

So that it would only effect my custom post type.

Thanks!

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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