WordPress

pole niestandardowe — Jak mogę utworzyć przycisk, który po kliknięciu wypełnia element div listą produktów spożywczych, które są sprawdzane jako określony typ ACF?

  • 12 marca, 2020
  • 6 min read
pole niestandardowe — Jak mogę utworzyć przycisk, który po kliknięciu wypełnia element div listą produktów spożywczych, które są sprawdzane jako określony typ ACF?


Najpierw radzę się upewnić $meal_type = get_field('meal_type'); zwraca tablicę ciągów znaków – w tym celu wystarczy zadzwonić var_dumb($meal_type) po uzyskaniu tej wartości pola. Na przykład, jeśli użyłeś pola Repeater dla typ_posiłku, zobaczysz tablicę tablic, a nie tablicę ciągów.

To też trochę dziwne z ACF, ale kiedy jesteś w niestandardowej pętli WP_Query, a nawet zrobiłeś to dobrze przez $meal->the_post() do konfiguracji globalnej $post obiekt może czasami zignorować ten, który właśnie ustawiłeś, więc oto bardziej kuloodporny sposób dzwonienia 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=" 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; ?>

Aby upewnić się, że pobiera dane z właściwego miejsca, możesz przekazać drugi argument jako obiekt $post, którego chcesz użyć do pobrania danych ACF.

Również w przypadku, gdy chcesz, aby był to kod o bardziej ogólnym przeznaczeniu, działający dla wszystkich rodzajów posiłków.

  1. Zmień znaczniki listy typów posiłków na

    <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=" class="meal-icon lazyloaded" src=" loading="lazy">
        <noscript>
          <img src=" width="75" height="auto" alt="Emergency" class="meal-icon" id="emergency-icon">
        </noscript>
        <span class="meal-icon-caption"> Emergency</span>
      </a>
    </div>
    
  2. Zmień kod JS na

    <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>
    
    1. Następnie w PHP otrzymamy to mealType zmienny

      $requested_meal_type = sanitize_text_field( isset( $_GET['mealType'] ) ? $_GET['mealType'] : '' );

      Ważne jest, aby oczyścić wszelkie dane wejściowe użytkownika, które czytasz z żądań, w przeciwnym razie może dojść do naruszenia bezpieczeństwa.

      Więc mając tę ​​zmienną odczytaną, możemy zmienić warunek na if ( $meal_type && in_array($requested_meal_type , $meal_type)) być w stanie poradzić sobie z różnymi rodzajami posiłków.

      Możesz także sprawdzić przypadek, jeśli mealType $_GET var jest pusta i pokazuje – no meals found message tak jak
      if ( empty( $requested_meal_type ) ) { echo 'no meals found' } else { // do wp query and other logic as it should be. }

/// UPD

Warto przeczytać!  metabox - W razie potrzeby utwórz więcej Meta Boxów

Myślę, że to, co może się wydarzyć, to to, że dzwonisz my-url.php Myślałem, że to tylko przykład i przegapiłem to. W WordPress, gdy trzeba obsłużyć coś wygenerowanego przez php przez ajax, działa nieco inaczej niż po prostu tworzenie jakiegoś pliku my-url.php w katalogu głównym dokumentu witryny.

Sposób WordPressa na wywołanie ajax to:

  1. dzwonić /wp-admin/admin-ajax.php zamiast niestandardowego pliku php, z js w ajax,

  2. przejść w a action zmiennej do js, ​​ta nazwa akcji będzie akcją, którą zdefiniowaliśmy w PHP do obsługi tego typu żądań ajax. Więc ajaxowa część kodu JS zmieni się w.

                $.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);
                });
    
  3. w twoim temacie functions.php stworzymy program obsługi php ajax, który wygeneruje żądany znacznik html i odeśle go z powrotem do js. Więc część kodu php umieściliśmy w functions.php będzie wyglądać tak.

    // 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=" 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');
    


Źródło

Warto przeczytać!  Jak uzyskać rekomendacje Google dotyczące szybkości strony graficznej za pomocą Smush