'is_page() conditional not working inside an AJAX function

I am doing filtering posts using ajax.

I wish $ array was different for pages "Products" and "Faq"

If this is executed within an ajax request, is_page() won't be set. the page you're making the request from was a previous request. you need to set something on the originating page to pass with your ajax request to let it know it's for your special case page.

functions.php

function load_scripts() {
    
  wp_enqueue_script( 'ajax', get_template_directory_uri() . '/vendor/jquery/main.js', array( 'jquery' ), NULL, true );
  
  wp_localize_script( 'ajax', 'wp_ajax',
      array( 
          'ajax_url' => admin_url( 'admin-ajax.php' ),
          'is_page'  => is_page( 420 ), // Whatever you want to pass. Add as many key pairs as needed.
          )
  );
  
}
add_action( 'wp_enqueue_scripts', 'load_scripts');

add_action( 'wp_ajax_nopriv_filter', 'filter_ajax' );
add_action( 'wp_ajax_filter', 'filter_ajax' );


function filter_ajax() {
  
$category = $_POST['category'];

if(isset($_POST['is_page']) && $_POST['is_page'] === 'faq'){
      $cat__in = 10;
      print_r(  $_POST );
      echo "FAQ";

  } else{
    $cat__in = 4;
    print_r(  $_POST );
    echo "Products";
  }
  
$args = array(
'post_type' => 'post',
'posts_per_page' => 50,
'category__in' => $cat__in,
);

if(isset($category)) {

  $args['category__in'] = array($category);
}


      $query = new WP_Query($args);

      if($query->have_posts()) :
          while($query->have_posts()) : $query->the_post();
              the_title('<h2>', '</h2>');
              the_content('<p>', '</p>');
          endwhile;
      endif;
          wp_reset_postdata(); 
  die();
}

faq.php

<div class="js-filter">
    <?php
    $args = array(
    'post_type' => 'post',
    'posts_per_page' => 100,
    'child_of' => 10,
    'exclude' => array(1),
    );
    $query = new WP_Query(array( 'cat' => 10 ));

    if($query->have_posts()) :
        while($query->have_posts()) : $query->the_post();
            the_title('<h2>', '</h2>');
            the_content('<p>', '</p>');
        endwhile;
        endif;
    wp_reset_postdata(); ?>
</div>
<div class="categories">

<ul>
    <?php 
        $cat_args = array(
            'exclude' => array(1),
            'child_of' => 10
        );
        ?>

<?php 
global $post;
$category = reset(get_the_category($post->ID));
$category_id = $category->cat_ID;
?>

        <li class="js-filter-item"><a href="#">All</a></li>

        <?php $categories = get_categories($cat_args); foreach($categories as $cat) : ?>
        <li class="js-filter-item"><a data-category="<?= $cat->term_id; ?>" href="<?= get_category_link($cat->term_id); ?>"><?= $cat->name; ?></a></li>
    <?php endforeach; ?>
</ul>
</div>

products.php

<div class="js-filter">
    <?php
    $args = array(
    'post_type' => 'post',
    'posts_per_page' => 100,
    'child_of' => 6,
    'exclude' => array(1,10),
    );

    $query = new WP_Query(array( 'cat' => 6 ));

    if($query->have_posts()) :
        while($query->have_posts()) : $query->the_post();
            the_title('<h2>', '</h2>');
            the_content('<p>', '</p>');
        endwhile;
        endif;
    wp_reset_postdata(); ?>
</div>
<div class="categories">

<ul>
    <?php 
        $cat_args = array(
            'exclude' => array(1,10),
            'child_of' => 6
        );
        ?>

<?php 
global $post;
$category = reset(get_the_category($post->ID));
$category_id = $category->cat_ID;
?>

        <li class="js-filter-item"><a href="#">All</a></li>

        <?php $categories = get_categories($cat_args); foreach($categories as $cat) : ?>
        <li class="js-filter-item"><a data-category="<?= $cat->term_id; ?>" href="<?= get_category_link($cat->term_id); ?>"><?= $cat->name; ?></a></li>
    <?php endforeach; ?>
</ul>
</div>

main.js

 jQuery(function($){
    $(document).on('click', '.js-filter-item > a', function(e){
        e.preventDefault();

        var category = $(this).data('category');

        $.ajax({
            url: wp_ajax.ajax_url,
            data: {
                action: 'filter',
                is_page: wp_ajax.is_page, // This param will be passed to your ajax function.
                category: category,
                pageslug: location.pathname.replace(/\//g,'')
            },
            type: 'post',
            success: function(result) {
                $('.js-filter').html(result);
            },
            error: function(result) {
                console.warn(result);
            }
        });
    });
});

do you have any idea how to solve it? After clicking on the "All" button, it displays posts from the "ID = 6" category



Solution 1:[1]

is_page() is not supposed to work in wp_ajax_ functions. Check this answer: Why doesn't is_page(id) work in functions.php?

is_page() relies on a complete global $wp_query object. If you call it before the action template_redirect has been fired, it might be impossible to get that data.

Instead of using is_page(), you can pass the slug as ajax data array value.

To pass as slug, edit main.js to replace

data: { action: 'filter', category: category },

with

data: { 
  action: 'filter', 
  category: category, 
  pageslug: location.pathname.replace(/\//g,'') 
},

Then, in functions.php in filter_ajax() function, replace

if (is_page('faq'))

with

if(isset($_POST['pageslug']) && $_POST['pageslug'] === 'faq')

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1