为所有页面模板创建一个回调,发布过滤器查询+分页页面,通过AJAX触发分页

时间:2022-01-07 作者:DevelJoe

我正在使用以下wp查询查询帖子:

function custom_retrieve_posts_function() {

$paged = get_query_var( "paged" ) ? get_query_var( "paged" ) : 1;
$args = array(
        \'post_type\' => \'my_post_type\',
        \'posts_per_page\' => 7,
        \'paged\' => $paged
);
$query = new \\WP_Query( $args );
$output = "";
if ( $query->have_posts() ) {

  while ( $query->have_posts() ) {

    // Iterate next post of query result
    $query->the_post();

    $output .= get_the_content();

  }

  // Only display arrows if links have been obtained, so do it in this way
  $previous_link = get_previous_posts_link(
    esc_html__( \'Zurück\', \'custom-text-domain\' )
  );
  
  $next_link = get_next_posts_link(
    esc_html__( \'Weiter\', \'custom-text-domain\' ),
    $query->max_num_pages
  );

  $nav_links = "<div id=\\"navigation-links\\">".

    "<span id=\\"previous-link\\">".
    ( $previous_link ? "&#8678 {$previous_link}" : "" ).
    "</span>".

    "<span id=\\"next-link\\">".
    ( $next_link ? "{$next_link} &#8680" : "" ).
    "</span>".

  "</div>";

  $output .= $nav_links;

  // Reset the wp_query loop
  wp_reset_postdata();
      
 } else {

   $output = "<p class=\\"no-results\\">Oops!</p>";

}

echo $output;

}
问题是,n页的某些帖子似乎在m页上随机重复,m>;n

feed和blog中显示的帖子数量/限制是7,我在wp admin选项中设置了这一点。不过,同样的问题依然存在。

知道为什么会这样吗?

UPDATE

功能custom_retrieve_posts_function() (在类等的名称空间中定义,但为了简单起见,这里省略了所有这些)在绑定到AJAX挂钩的PHP脚本中调用,该挂钩负责通过AJAX执行自定义过滤查询。

因此,脚本的名称如下:

主插件文件包含以下内容:

add_action(
  \'wp_ajax_myplugin_search_custom\',
  function() {
    require MYPLUGIN_AJAX_DIR.\'/custom_search.php\';
    wp_die();
  }
);

add_action(
  \'wp_ajax_nopriv_myplugin_search_custom\',
  function() {
    require MYPLUGIN_AJAX_DIR.\'/custom_search.php\';
    wp_die();
  }
);
内容为AJAX_DIR.\'/custom_search.php\' 被(再次简化,所有命名冲突都被100%避免,因此所有类名/名称空间都被再次省略):

check_ajax_referer( \'ajax-nonce-content\' );
require MYPLUGIN.\'/custom_search_function.php\';
custom_retrieve_posts_function();
然后,在我的themes/mycustomtheme/templates 目录,在该页面模板中,我只需调用

require MYPLUGIN.\'/custom_search_function.php\';
custom_retrieve_posts_function();
请注意,除了已经显示的帖子被重新显示在随后分页的页面上的问题之外,所有这些都非常有效。

UPDATE 2

遗憾的是,在通过js进行了评论修改后,我无法使其工作(另外将分页的页码传递给查询)。例如,当我通过AJAX执行此查询时:

$args = array(
        \'post_type\' => \'my_post_type\',
        \'tax_query\' => $tax_query_array,
        \'orderby\' => \'meta_value_num\',
        \'meta_key\' => \'my_metas_key\',
        \'order\' => \'ASC\',
        \'posts_per_page\' => 7,
        \'paged\' => 2
);
我仍然收到一篇已经在第1页上显示的帖子(随机的)。

如果我添加,则相同$args[\'offset\'] = 7 和/或$args[\'page\'] = 2, 所以我很困惑;我在这里还没有完全理解什么??

2 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

因为这条线:

$paged = get_query_var( "paged" ) ? get_query_var( "paged" ) : 1;
这是在一个用于AJAX处理程序和页面请求的函数中实现的。get_query_var 从主查询中提取参数(也称为主查询WP_Query 其功能如下the_post, have_posts() 等等)。但这会never 处理AJAX请求。

因此,当您从AJAX请求下一个页面时,它将始终导致1. 如果您想要的不是第1页,那么您需要在发送AJAX请求的javascript中包含所需的页面编号,将其传递,然后阅读并将其放入WP_Query 直接输入参数。即使有一个主查询,它也不会是相同的主查询。

记住,对服务器的每一个请求都会从一块空白的石板上加载WordPress,AJAX请求处理程序不会与浏览器打开的页面共享任何内容,除非您明确地将要与请求一起共享的数据作为POST/GET变量发送给它们。幕后没有共享分页状态,也没有将其粘合在一起的魔法。

此外,由于您在AJAX响应中包含了分页HTML,因此现在将有一个指向第2页的下一页链接,但会触发加载第1页的AJAX(为什么它会知道加载第2页?get_query_var 不会工作,没有主查询可以从中获取查询变量!)。

更重要的是,我很怀疑你archive-mycustompost.php, 这个pre_get_posts 过滤器,或在注册CPT时更改CPT存档URL的功能,或主查询的查询参数来自URL,您可以添加额外的参数,例如:。example.com/?s=test&posts_per_page=7&paged=2 获取“的搜索查询的第二页”;“测试”;每页有7篇文章。在大多数情况下,完全不需要二次查询和自定义页面模板。

SO网友:DevelJoe

好了,终于成功了。出于不在这里详述的原因,我更喜欢使用一个单独回调的分页解决方案,我在需要分页的任何地方都使用这个回调。换句话说,在需要查询的模板页面的页面加载时,以及在单击分页链接或应用任何搜索过滤器来查询帖子时,我都会调用回调调用。

在不需要您这样做的情况下,您当然可以参考@TomJ Nowell和我之间的讨论(在上面的回答中,再次使用thx!)。因此,如果您的设计可行,您可以使用WP REST API(而不是使用AP AJAX API)来创建请求、归档页面+WP的主查询循环+与该主查询关联的相关分页功能。

如果您希望创建一个专门使用WP AJAX的WP分页解决方案,请通过$_POST, 您可以通过JS向ajax处理程序提供所请求的额外页面数量来轻松做到这一点,如果没有提供,只需使用1即可。因此,我的上述功能变成:

function custom_retrieve_posts_function( $paged = 1 ) {

if ( isset($_POST[\'page_to_request\'] ) ) {
  $paged = intval( sanitize_text_field( isset( $_POST[\'page_to_request\'] ) ) );
}

$args = array(
  \'post_type\' => \'my_custom_post_type\',
  \'tax_query\' => $tax_query_array,
  \'orderby\' => array(
    \'meta_value_num\' => \'ASC\',
    \'date\' => \'DESC\'
   ),
   \'meta_key\' => \'my_custom_meta_key\',
   \'posts_per_page\' => 7,
   \'paged\' => $paged
);

$query = new \\WP_Query( $args );
$output = "";
if ( $query->have_posts() ) {

  while ( $query->have_posts() ) {

    // Iterate next post of query result
    $query->the_post();

    $output .= get_the_content();

  }

  // Only display arrows if links have been obtained, so do it in this way
  $max_num_pages = $query->max_num_pages;

  $nav_links = "<div id=\\"navigation-links\\">".

    // If we\'re not on the first page, add a link allowing to go back to
    // the one previous to the one currently requested
    "<span id=\\"previous-link\\"".(
      ( $max_num_pages !== 1 ) ?
      " data-previous-page=\'".( $paged - 1 )."\'>&#8678 Back" :
      ">"
    ).
    "</span>".

    // If we\'re not on the last page, add a link allowing to go forward to
    // the page subsequent to the one currently requested 
    "<span id=\\"next-link\\"".(
      ( $max_num_pages > $paged ) ?
      " data-next-page=\'".( $paged + 1 )."\'>Next &#8680" :
      ">"
    ).
    "</span>".

  "</div>";

  $output .= $nav_links;

  // Reset the wp_query loop
  wp_reset_postdata();
      
 } else {

   $output = "<p class=\\"no-results\\">Oops!</p>";

}

echo $output;

}
注意,我添加了date 进入我的order 条款,除我在上述问题中指定的内容外。这是因为我发现您分页的第n页可能会显示以前m页的帖子,其中m<;n、 如果你有很多帖子都有相同的元价值。即使使用wp query等的offset参数,也无法消除此问题。因此,我想首先在我的案例中使用我需要的排序(元键),然后根据帖子特有的另一个值,例如帖子的日期。我的想法是这样的,我可以保证帖子总是以完全相同的顺序检索,即使它们的元值是相同的。而且,无论调用函数的上下文如何,具有相同的顺序对于正确分页都至关重要。

正如我想象的那样,WP将此WP\\u查询数组转换为SQL查询,以查询相应的数据。因此,当使用post独有的数据字段,而不是日期,而是DB中的主键时,这可能会导致更快的查询时间。因此date 订单键,您可以使用ID.

相关推荐

查询字符串值的最佳实践-对于查询字符串中提供的值,GET_QUERY_var始终为空

我正在我的WP插件中构建一个表单。我需要通过在URL中提供如下值来指定要修改的记录:https://example.com/wp-admin/admin.php?page=my_plugin-event-video-assoc&event_post_id=123我已经正确设置了代码,以便运行所需的代码来处理url请求,但是get_query_var 始终返回NULL:$event_post_id = get_query_var(\'event_post_id\', NULL); var_d