我如何创建一个按钮,当被点击时,它会用被检查为特定类型的ACF的食物列表填充div?

时间:2020-03-12 作者:Dawn Summerall

我以前没有在这里问过任何问题,所以如果我做错了,我很抱歉。我不熟悉自定义主题模板文件。我对wordpress和php也是新手。这对我来说是一个学习练习。我正在做一个页面,里面有不同类型的食物,都在一定的卡路里水平下。我希望有一个按钮,当按下时,将列出所有被检查为特定类型的食物。我正在使用自定义的post-type Founds和ACF来创建自定义字段。页面如下:https://blog.unicornpoint.net/wp/safe-foods-meal-generator-diet-assistant/

我有一个按钮,它有一个jquery click事件。

<script>
            jQuery(document).ready(function($){
                $(\'#emergency-icon\').click(function(){
                    $.ajax({
                        method: \'GET\',
                        url: \'my-url.php\'
                    }).done(function(data){
                        $("#meal-results").html(data);
                    });
                });
            });
        </script>
单击按钮时,返回“您已到达文件”这是在小ajax块中调用的php文件中的代码。它可以自己工作,并显示在页面上的一个框中,以表明它可以工作。

<?php echo "You have reached the file.";  ?>
<div class="d-inline-flex flex-wrap text-center p-2">
    <?php
    $args = array(\'post_type\' => \'meal\');
    $meals = new WP_Query($args);

    if($meals->have_posts()) : while($meals->have_posts()) : $meals->the_post();
        $meal_type = get_field(\'meal_type\');
        if ( $meal_type && in_array(\'emergency\', $meal_type)){?>
            <div class="text-center p-2 meal-size-posts">
                <h4><?php the_field(\'meal_name\'); ?></h4>
                <img src="<?php echo get_field(\'meal_icon\'); ?>" class="meal-icon">
                <p class="meal-description"><?php the_field(\'meal_description\'); ?></p>
                <h4><?php the_field(\'meal_calories\'); ?> calories</h4>
            </div>
        <?php } ?>
    <?php endwhile; endif; ?>
</div>
你能帮我让这个家伙工作吗?或者告诉我一些容易理解的资源,这样我就能更好地理解如何做?非常感谢。

1 个回复
SO网友:Mikhail

首先我建议你确保$meal_type = get_field(\'meal_type\'); 返回字符串数组-为此,只需调用var_dumb($meal_type) 获取此字段值后。因此,例如,如果您对MEIN\\U类型使用了一个Repeater字段,您将看到数组的数组,而不是字符串的数组。

对于ACF来说,这也是一件奇怪的事情,但当您处于自定义WP\\U查询循环中时,即使您通过$meal->the_post() 设置全局$post 对象它有时可能会忽略您刚刚设置的对象,因此这里有一种更可靠的调用方式get_field()

 <?php if( $meals->have_posts() ) :
    $meal_posts = $meals->get_posts();
    foreach( $meal_posts as $meal_post) :
      $meal_type = get_field(\'meal_type\', $meal_post);
      if ( $meal_type && in_array(\'emergency\', $meal_type)): ?>
          <div class="text-center p-2 meal-size-posts">
              <h4><?php the_field(\'meal_name\', $meal_post); ?></h4>
              <img src="<?php echo get_field(\'meal_icon\', $meal_post); ?>" class="meal-icon">
              <p class="meal-description"><?php the_field(\'meal_description\', $meal_post); ?></p>
              <h4><?php the_field(\'meal_calories\', $meal_post); ?> calories</h4>
          </div>
      <?php endif; ?>
   <?php endforeach; ?>
<?php endif; ?>
为了确保它从正确的位置获取数据,您可以将第二个参数作为$post对象传入,您要使用它来获取ACF数据。

此外,如果您希望它生成一个更通用的代码,适用于所有用餐类型。

将膳食类型列表的标记更改为

<div class="col-6 col-md-3">
  <a href="#emergency" class="load-meal-by-type">
    <img width="75" height="auto" alt="Emergency" id="emergency-icon" data-src="https://blog.unicornpoint.net/wp/wp-content/uploads/2020/02/panic.png" class="meal-icon lazyloaded" src="https://blog.unicornpoint.net/wp/wp-content/uploads/2020/02/panic.png" loading="lazy">
    <noscript>
      <img src="https://blog.unicornpoint.net/wp/wp-content/uploads/2020/02/panic.png" width="75" height="auto" alt="Emergency" class="meal-icon" id="emergency-icon">
    </noscript>
    <span class="meal-icon-caption"> Emergency</span>
  </a>
</div>
将JS代码更改为

<script>
    jQuery(document).ready(function($){
        $(\'a.load-meal-by-type\').click(function(event){
            event.preventDefault(); // to prevent browser from trying to navigate via #link
            var $btn = $(this); // quick way to get current clicked link inside handler function
            var mealType = $btn.attr(\'href\'); // we\'ll pass meal type as variable to ajax
            mealType = mealType.replace(\'#\', \'\'); // remove # as we don\'t need it- we keep it in href originally to make link valid and at the same time - if you\'d like to have a step further you can make a thing called deeplinking, being able to have shared link which will load exact content as you would click on a link.

            $.ajax({
                method: \'GET\',
                url: \'my-url.php\',
                data: {
                  mealType: mealType // we pass in our mealType string to php as GET parameter.
                }
            }).done(function(data){
                $("#meal-results").html(data);
            });
        });
    });
</script>
然后在PHP中,我们将得到mealType 变量

$requested_meal_type = sanitize_text_field( isset( $_GET[\'mealType\'] ) ? $_GET[\'mealType\'] : \'\' );清理从请求中读取的任何用户输入都很重要,否则可能存在安全漏洞。

所以读取这个变量后,我们可以将条件更改为if ( $meal_type && in_array($requested_meal_type , $meal_type)) 能够处理不同的膳食类型。

您还可以在以下情况下检查案例mealType $_GET var为空,并显示-no meals found message 喜欢if ( empty( $requested_meal_type ) ) { echo \'no meals found\' } else { // do wp query and other logic as it should be. }

///UPD

我认为可能发生的事情是,你在打电话my-url.php 我认为这只是一个例子,但我错过了。在Wordpress中,当您需要通过ajax处理通过php生成的内容时,其工作方式与创建一些文件略有不同my-url.php 在站点的文档根目录中。

Wordpress调用ajax的方式是:

呼叫/wp-admin/admin-ajax.php 而不是来自ajax中js的自定义php文件,

通过aaction 在js中,这个动作名称将是我们在PHP中定义的一个动作,用于处理这种ajax请求。因此JS代码的ajax部分将变成。

            $.ajax({
                method: \'GET\',
                url: \'/wp-admin/admin-ajax.php\', // we send all WP ajax requests to this file, it will load all WP\'s files, plugins. It\'s WP Ajax approach.
                data: {
                  action: \'load_meals\', // you can name it whatever just use the same in PHP binding ajax action.
                  mealType: mealType // we pass in our mealType string to php as GET parameter.
                }
            }).done(function(data){
                $("#meal-results").html(data);
            });
在您的主题中functions.php 我们将创建php ajax处理程序,该处理程序将生成所需的html标记并将其发送回js。所以我们在functions.php 看起来像这样。

// this function will render our html and send it back to js, upon ajax request.
function my_ajax_load_meals() {
  $requested_meal_type = sanitize_text_field( isset( $_GET[\'mealType\'] ) ? $_GET[\'mealType\'] : \'\' );
  echo \'You have reached the file.\'; ?>

?>
<div class="d-inline-flex flex-wrap text-center p-2">
    <?php
    $args  = array( \'post_type\' => \'meal\' );
    $meals = new WP_Query( $args );

    if ( $meals->have_posts() ) :
        $meals_posts = $meals->get_posts();
        foreach ( $meals_posts as $meal_post ) :
            $meal_type = get_field( \'meal_type\', $meal_post );
            if ( $meal_type && in_array( $requested_meal_type, $meal_type ) ): ?>
                <div class="text-center p-2 meal-size-posts">
                    <h4><?php the_field( \'meal_name\', $meal_post ); ?></h4>
                    <img src="<?php echo get_field( \'meal_icon\', $meal_post ); ?>" class="meal-icon">
                    <p class="meal-description"><?php the_field( \'meal_description\', $meal_post ); ?></p>
                    <h4><?php the_field( \'meal_calories\', $meal_post ); ?> calories</h4>
                </div>
            <?php endif; ?>
        <?php endforeach; ?>
    <?php endif; ?>
</div>
<?php
  exit(); // important to exit to close output and let js know it has loaded everything already.
}

 // this is where we bind our function to `load_meals` action name.
 // the one with `_nopriv` prefix in wp action name is for not logged in users, and without it for logged in users.
add_action(\'wp_ajax_load_meals\', \'my_ajax_load_meals\');
add_action(\'wp_ajax_nopriv_load_meals\', \'my_ajax_load_meals\');

相关推荐

使用AJAX向WooCommerce产品循环添加参数

我正在尝试为我的WooCommerce商店页面制作一个AJAX产品过滤器。之前,我自己创建了查询,没有使用商店页面。然而,我想让我的代码现在更兼容WC。目前,我可以从查询字符串中设置变量来过滤WooCommerce产品循环。我使用以下代码执行此操作: add_action(\'pre_get_posts\', \'filter_pre_get_posts\' ); function filter_pre_get_posts( $wp_query ) { if(