Rechercher

Affichage et MAJ d’un élément en AJAX

Placeholder image

Dans le JS l’action doit renvoyer vers la fonction qu’on active.

document.addEventListener("DOMContentLoaded", function () {
    if (typeof mnky_ajax === "undefined") {
        console.error("Erreur: mnky_ajax n'est pas défini !");
        return;
    }
    // Utilisation de event delegation pour s'assurer que l'événement est attaché une seule fois
    document.body.addEventListener("click", function (event) {
        if (event.target && event.target.matches(".mnky-like-btn")) {
            let postId = event.target.getAttribute("data-post-id");

            fetch(mnky_ajax.ajax_url, {
                method: "POST",
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded",
                },
                body: new URLSearchParams({
                    action: "increment_like",
                    post_id: postId,
                }),
            })
            .then(response => response.json())  // Convertir la réponse en JSON
            .then(data => {

                if (data.success && data.data && data.data.new_count !== undefined) {
                    event.target.querySelector('span').innerHTML = `${data.data.new_count}`;
                }
            })
            .catch(error => console.error("Erreur AJAX:", error));
        }
    });
});
function mnky_increment_like() {
    if (!isset($_POST['post_id'])) {
        wp_send_json_error(['message' => 'Post ID manquant']);
        wp_die();
    }

    $post_id = intval($_POST['post_id']);

    // Vérifier si la méta existe déjà
    $current_likes = get_post_meta($post_id, 'mnky_post_views_like', true);
    if (!$current_likes || !is_numeric($current_likes)) {
        $current_likes = 0; // Si la méta n'existe pas, initialiser à 0
    }

    // Incrémenter
    $new_likes = $current_likes + 1;

    // Mettre à jour la base de données
    update_post_meta($post_id, 'mnky_post_views_like', $new_likes);

    // Retourner la réponse au format JSON
    $response = ['success' => true, 'new_count' => $new_likes];
    wp_send_json_success($response);

    wp_die();
}
add_action('wp_ajax_increment_like', 'mnky_increment_like');
add_action('wp_ajax_nopriv_increment_like', 'mnky_increment_like');
function mnky_enqueue_scripts() {
    // Enregistrer main.js
    wp_register_script('like-js', get_template_directory_uri() . '/js/like.js', ['jquery'], null, true);

    // Injecter mnky_ajax après avoir enregistré le script
    wp_localize_script('like-js', 'mnky_ajax', [
        'ajax_url' => admin_url('admin-ajax.php'),
    ]);

    // Charger main.js après l’injection de mnky_ajax
    wp_enqueue_script('like-js');
}
add_action('wp_enqueue_scripts', 'mnky_enqueue_scripts');

Commander à nouveau une ancienne commande woocommerce

Placeholder image
<?php

/**
 *  Order Again 
 */
add_filter( 'woocommerce_my_account_my_orders_actions', 'mahii_order_again_action', 9999, 2 ); 
function mahii_order_again_action( $actions, $order ) {
   if ( $order->has_status( 'completed' ) ) {
      $actions['order-again'] = array(
         'url' => wp_nonce_url( add_query_arg( 'order_again', $order->get_id(), wc_get_cart_url() ), 'woocommerce-order_again' ),
         'name' => __( 'Order again', 'woocommerce' ),
      );
   }
   return $actions;
}


/**
 * @snippet       Add popup after re-order
 * @author        Mahii
 * @compatible    WooCommerce 6
 */
add_action('woocommerce_account_content', 'order_again_popup_code', 10, 2);
function order_again_popup_code() {
?>
<div id="order-again-popup" class="order-again-popup" style="display: none">
   <div id="closeButton" class="close"></div>
    <p><?php _e('Attention, les prix seront actualisés dans cette nouvelle commandes', 'hello-elementor-child'); ?></p>
    <div class="order-again-popup-actions">
      <button id="continueButton"><?php _e('Continuer',  'hello-elementor-child'); ?></button>
      <button id="cancelButton"><?php _e('Annuler',  'hello-elementor-child'); ?></button>
    </div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
    var popup = document.getElementById('order-again-popup');
    function showPopup() {
      popup.style.display = 'block';
    }
    function hidePopup() {
      popup.style.display = 'none';
    }

    document.getElementById('continueButton').addEventListener('click', function() {
      window.location.href = originalOrderURL;
    });

    document.getElementById('cancelButton').addEventListener('click', function() {
      hidePopup();
    });
    document.getElementById('closeButton').addEventListener('click', function() {
      hidePopup();
    });

   let reordersButtons = document.querySelectorAll('.woocommerce-button.order-again');
   reordersButtons.forEach(button => {
      button.addEventListener('click', reorder);
   });

    function reorder(e) {
      e.preventDefault();
      originalOrderURL = this.href;
      showPopup();
    }
});

</script>
<?php 
}

Créer un bloc Gutenberg avec ACF

Placeholder image
function mahii_register_acf_block_types() {
    acf_register_block_type( array(
        'name'              => 'mobile-carousel',
        'title'             => 'Carousel en mobile',
        'description'       => "Contenu qui s'affiche en carousel en mobile",
        'render_template'   => 'blocks/mobile-carousel.php',
        'category'          => 'imogis', 
        'icon'              => 'slides', 
        'keywords'          => array( 'carousel' ),
        'enqueue_assets'    => function() {
        	wp_enqueue_style( 
              'glide-core-style', 
              get_template_directory_uri() . '/css/glide.core.min.css' 
          );
        	wp_enqueue_style( 
              'mobile-carousel-block', 
              get_template_directory_uri() . '/css/block-carousel.css' 
          );

          wp_enqueue_script(
            'glide-carousel',
            get_template_directory_uri() . '/js/glide.min.js',
            array(),
            '3.6.1',
            true
          );
          wp_enqueue_script(
            'glide-carousel-block',
            get_template_directory_uri() . '/js/block-mobile-carousel.js',
            array( 'glide-carousel' ),
            '1.0',
            true
          );
        }
    ) );
}
add_action( 'acf/init', 'mahii_register_acf_block_types' );

Ajouter les couleurs dans gutenberg

Placeholder image
// Editor color palette.
add_theme_support(
	'editor-color-palette',
	array(
		array(
			'name'  => 'Beige',
			'slug'  => 'mahii-beige',
			'color' => '#eee0d0',
		),
		array(
			'name'  => 'Orange',
			'slug'  => 'mahii-orange',
			'color' => '#f37646',
		),
		array(
			'name'  => 'Blanc',
			'slug'  => 'mahii-blanc',
			'color' => '#fff',
		),
		array(
			'name'  => 'Noir',
			'slug'  => 'mahii-noir',
			'color' => '#141819',
		),
	)
);

Utiliser un champs ACF répéteur dans un widget Unlimited Elements

Placeholder image

Créer un nouveau Widget dans Unlimited Elements. Voici la configuration à appliquer :

Onglet « Général »

Onglet « Attribute »

Choisir le type : « Dynamic Grouped Settings »

Donner un titre, un nom et dans le cadre gris, choisir « Use For: Items »

Dans « Included Attributes: » ajouter l’identifiant des attributs ACF de votre champs répéteur.

Exemple :

Si un de vos champs est une image, vous devez ajouter un attribut avec le titre : Image size, le name image_size. Son « type »Attribute Type » est « Special Attribute » et son « Spécial Attribute Type » est Items Image Size.

Exemple :

Dans onglet « Items attributes »

Activez les items et pour chaque sous-champs ACF du répéteur, créer un item attribute correspondant (un texte pour du texte, une image pour une image…)

Exemple :

Onglet HTML :

Utilisez la fonction put_items() et utilisez vos items attribute comme d’habitude.

Dans Elementor :

Ajouter votre nouveau widget. Il va falloir le configurer pour qu’il utilise les bonnes sources de donées.

  • Dans item source, choisir ACF Custom FIeld
  • Dans ACF field name, mettez l’identifiant de votre champs répéteur
  • Dans ACF field location, choisissez le localistation de votre champs (en général Current Post)
  • Vous devez ensuite associer chacun de vos « Item attribute » avec le bon sous-champs :
    • Choisissez Item Field name
    • Insérer l’identifiant du sous-champs dans « Item Field Name »

Exemple :

Ajouter des colonnes dans les listes de posts de l’admin de WordPress

Placeholder image
/* =============================================
===============. ADMIN COLUMN .=================
============================================= */
// Ajouter les colonnes "Statut" et "Slug" dans le tableau des articles
function ajouter_custom_colonnes_posts($columns) {
	$new_columns = array(
        'thumbnail'   => __('Miniature'),
    );
	$new_after_columns = array(
        'post_status' => __('Statut'),
        'post_slug'   => __('Slug'),
    );
    
    // Insérer les nouvelles colonnes au début du tableau
    return array_merge($new_columns, $columns, $new_after_columns);
}
add_filter('manage_posts_columns', 'ajouter_custom_colonnes_posts');
add_filter('manage_pages_columns', 'ajouter_custom_colonnes_posts');

// Afficher le contenu des colonnes "Statut" et "Slug"
function afficher_contenu_custom_colonnes($column, $post_id) {
    switch ($column) {
        case 'post_status':
			$color = "#000";
			if(get_post_status($post_id) == "publish") {
				$color = "green";
			}
			if(get_post_status($post_id) == "draft") {
				$color = "grey";
			}
            echo '<b style="color: '.$color.'">' . get_post_status($post_id) . '</b>';
            break;
        case 'post_slug':
            $post = get_post($post_id);
            echo $post->post_name;
            break;
        case 'thumbnail':
            $thumbnail = get_the_post_thumbnail($post_id, array(50, 50));
        	echo $thumbnail;
            break;
    }
}
add_action('manage_posts_custom_column', 'afficher_contenu_custom_colonnes', 10, 2);
add_action('manage_pages_custom_column', 'afficher_contenu_custom_colonnes', 10, 2);

Ajouter une classe ACF au body dans WordPress

Placeholder image
/* =============================================
=================. BODY CLASS .==================
============================================= */
add_filter('body_class', 'ajouter_classe_acf_selecteur_body');
function ajouter_classe_acf_selecteur_body($classes) {
    if (function_exists('get_field') && get_field('classe')) {
        $valeur_champ_acf = get_field('logo_mode');
        if (!empty($valeur_champ_acf)) {
            $classes[] = sanitize_html_class($valeur_champ_acf);
        }
    }
    return $classes;
}

Chercher en AJAX dans WordPress

Placeholder image
function mahiiro_ajax_search() {
    wp_register_script( 'mahii_ajax_search', get_template_directory_uri() . '/js/mahii-ajax-search.js', array() );
    wp_localize_script( 'mahii_ajax_search', 'mahii_ajax_search_params', array(
        'ajaxurl' => admin_url('admin-ajax.php')
    ) );
    wp_enqueue_script( 'mahii_ajax_search' );
}
add_action( 'wp_enqueue_scripts', 'mahiiro_ajax_search', 999 );

function mahii_ajax_search_ajax_handler(){
    // Sanitize the search query to prevent security issues
    $search_query = sanitize_text_field( $_POST['search'] );

    $args = array(
        's'                   => $search_query,
        'post_type'           => array( 'page', 'post', 'ressources', 'definitions' ),
        'post_status'         => 'publish',
        'posts_per_page'      => 5
    );

    $query = new WP_Query( $args ); 

    if( $query->have_posts() ) :
        while( $query->have_posts() ): $query->the_post(); 
            echo '<a href="'.get_the_permalink().'">';
            if( has_post_thumbnail() ) {
                the_post_thumbnail('thumbnail');
            } else {
                echo 'Image par défaut';
            }
            the_title('<span>', '</span>');
            echo '</a>';
        endwhile;
        wp_reset_postdata(); // Always reset the post data after a custom query
    else: 
        echo "<p>Il n'y a pas de résultats pour votre recherche</p>";
    endif;

    wp_die();
}
// Contenu du fichier /js/mahii-ajax-search.js (dans l'exemple)
const ajaxSearch = document.getElementById('ajax-search');
const ajaxResults = document.getElementById('ajax-search-results');
let searchTimeout;

if (ajaxSearch !== null) {
    ajaxSearch.addEventListener('input', event => {
        const formData = new FormData();
        formData.append('action', 'ajaxsearch');
        clearTimeout(searchTimeout);

        if (ajaxSearch.value.length >= 3) {
            searchTimeout = setTimeout(() => {
                ajaxResults.innerHTML = "";
                formData.append('search', ajaxSearch.value); // No need for JSON.stringify()

                if (ajaxResults !== null) {
                    ajaxResults.classList.add('loading');
                    fetch(mahii_ajax_search_params.ajaxurl, {
                        method: "POST",
                        body: formData, // FormData automatically handles multipart data
                    }).then(response => {
                        return response.text();
                    }).then(response => {
                        if (response) {
                            ajaxResults.innerHTML = response;
                            ajaxResults.classList.remove('loading');
                        }
                    }).catch(error => {
                        console.log(error);
                    });
                }
            }, 300);
        }
    });

    ajaxSearch.addEventListener('blur', () => {
        if (ajaxResults !== null && ajaxSearch.value === '') {
            ajaxResults.classList.remove('loading');
        }
    });

    ajaxSearch.addEventListener('search', () => {
        if (ajaxSearch.value === '') {
            if (ajaxResults !== null) {
                ajaxResults.classList.remove('loading');
            }
        }
    });
}