Les cours sont classés par ordre où ils ont été donnés, du plus récent au plus ancien.

Code snippets dans VSCode

Code snippets dans VSCode

Les snippets sur VSCode permettent de gagner un temps précieux, et surtout, dans mon cas, d’éviter des fautes de frappe.

Le tuto complet se trouve dans la vidéo ci-jointe. Une fois que j’ai compris le principe, je passe par ChatGPT pour créer les snippets dont j’ai besoin. Voici un exemple de Prompt. Les placeholders sont des éléments sur lequel le focus sera placé à chaque pression du TAB, 1:placeholder à la première pression, 2:placeholder à la 2e etc.

Create a vscode snippet to generate jquery on click function. click the .element targets the .target and shows it with .show() .element and .target are placeholders.

 

Création du snippet dans le fichier JSON de VSCode

				
					// ce snippet affiche le JS ci-dessus. 
// les placeholders 
// 1:element
// 2:target
// 3:functionName
// seront éditables à chaque pression de TAB
{
	"jQuery on click show event": {
	  "prefix": "click",
	  "body": [
		"$('.${1:element}').click(function() {",
		"  $('.${2:target}').show();",
		"});"
	  ],
	  "description": "Create jQuery on click show event"
	},
	"jQuery on ready show event": {
	  "prefix": "ready",
	  "body": [
		"$(document).ready(function() {",
		"\t  ${3:functionName} ",
		"});"
	  ],
	  "description": "Create jQuery on ready show event"
	}
  }
  


				
			

Génération de la fonction suivante après avoir écrit click. au premier TAB le focus est mis sur .element, au deuxième TAB il est mis sur .target

				
					$(document).ready(function() {
      $('.element').click(function() {
        $('.target').show();
      }); 
});
				
			

Introduction à Git & Github

Totalement désactiver les commentaires dans WordPress

Totalement désactiver les commentaires dans WordPress

Vous trouverez ici toutes les fonctions à introduire dans functions.php afin de totalement désactiver les fonctionnalités liées aux commentaires dans WordPress.
				
					add_action('admin_init', function () {
    // Redirect any user trying to access comments page
    global $pagenow;
     
    if ($pagenow === 'edit-comments.php') {
        wp_safe_redirect(admin_url());
        exit;
    }
 
    // Remove comments metabox from dashboard
    remove_meta_box('dashboard_recent_comments', 'dashboard', 'normal');
 
    // Disable support for comments and trackbacks in post types
    foreach (get_post_types() as $post_type) {
        if (post_type_supports($post_type, 'comments')) {
            remove_post_type_support($post_type, 'comments');
            remove_post_type_support($post_type, 'trackbacks');
        }
    }
});
 
// Close comments on the front-end
add_filter('comments_open', '__return_false', 20, 2);
add_filter('pings_open', '__return_false', 20, 2);
 
// Hide existing comments
add_filter('comments_array', '__return_empty_array', 10, 2);
 
// Remove comments page in menu
add_action('admin_menu', function () {
    remove_menu_page('edit-comments.php');
});
 
// Remove comments links from admin bar
add_action('init', function () {
    if (is_admin_bar_showing()) {
        remove_action('admin_bar_menu', 'wp_admin_bar_comments_menu', 60);
    }
});


				
			

Condition if exists sur shortcode ACF

Condition if exists sur shortcode ACF

Je trouve très utile avec les ACF de pouvoir facilement vérifier si une variable existe avant de l'afficher, seule ou englobée dans du code. Cette fonction PHP permet d'utiliser cette condition au moyen de [shortcodes]
				
					// mettre des conditions sur les shortcodes ACF https://support.advancedcustomfields.com/forums/topic/conditional-shortcodes/
// [acfcond field='']foobar[/acfcond]
function acfcond($atts = [], $content = null)
{
    $atts = array_change_key_case((array)$atts, CASE_LOWER);

    if(get_field($atts['field']))
    {
        $content = do_shortcode($content);
    }
    else
    {
        $content = '';
    }

    return $content;
}
add_shortcode('acfcond', 'acfcond');
				
			

Du coup dans Elementor on peut faire

				
					[acfcond field='le_mot_du_directeur']
<h2>Le mot du directeur (shortcode)</h2>

[/acfcond]

				
			

Updates to ACF Field Functions in 5.11 & Registering Fields via PHP

Faire des requêtes personnalisées dans des Custom Post Types (CPT) contenant des Advanced Custom Fields (ACF)

Faire des requêtes personnalisées dans des Custom Post Types (CPT) contenant des Advanced Custom Fields (ACF)

Cet article fournit un exemple complet sur la manière dont je filtre les utilisateurs sur base de valeurs introduites via ACF (âge, genre…)

Etude cas d’une requête dans les Users

Dans quasiment tous les projets que je réalise en WordPress j’utilise des CPT combinés à des ACF. Dans mes pages j’utilise également régulièrement des filtres avec lesquels je charge en AJAX des contenus sur base de requêtes personnalisées. Ces requêtes sont basées sur des arrays qui contiennent:

  • le champ à comparer
  • la valeur à comparer avec la valeur contenue dans le champ de la DB
  • le type de comparaison « > = <« 

Il est ensuite possible d’inclure tous ces arrays dans la requête.

Dans l’exemple ci-dessous je charge des utilisateurs sur base de critères comme l’âge, la région, le genre etc. au moyen de la fonction get_users()

Dans cette fonction je passe les arrays que j’ai définis préalablement et que je décrirai plus bas

Requête au moyen de la fonction get_users() et meta_query

				
					$blogusers = get_users( array( 
    'role__in' => array(  'subscriber' ),
    //  'meta_key' => "genre",
     'meta_query' => array($arraygenre,$arrayage,$arrayregion,$arrayetudes,$arrayenfants),
     
     ) ); // recuperation des users sur base des filtres

				
			

Définition des arrays (que j’annule si une valeur vide est passée

				
					// filtre GENRE
// si pas de valeur dans ce filtre, on en fait un array vide comme ça pas pris en compte dans la requête
if ($genre == "tous") {
    $arraygenre = array();
} else {
    $arraygenre =  array(
        'key' => 'genre',
        'value' => $genre,
        'compare' => '='
    );
}


// filtre REGION
// si pas de valeur dans ce filtre, on en fait un array vide comme ça pas pris en compte dans la requête
if ($region == "tous") {
    $arrayregion = array();
} else {
    $arrayregion =  array(
        'key' => 'region',
        'value' => $region,
        'compare' => '='
    );
}


// filtre ETUDES
// si pas de valeur dans ce filtre, on en fait un array vide comme ça pas pris en compte dans la requête
if ($etudes == "tous") {
    $arrayetudes= array();
} else {
    $arrayetudes =  array(
        'key' => 'niveau_detudes',
        'value' => $etudes,
        'compare' => '='
    );
}


// filtre ENFANTS
// si pas de valeur dans ce filtre, on en fait un array vide comme ça pas pris en compte dans la requête
if ($enfants == "tous") {
    $arrayenfants= array();
} else {
    $arrayenfants =  array(
        'key' => 'enfants',
        'value' => $enfants,
        'compare' => '='
    );
}



// filtre AGE MIN ET MAX
$arrayage = array(
    array(
    'key' => 'age',
    'value' => $agemax,
    'compare' => '<='
    ),
        array(
            'key' => 'age',
            'value' => $agemin,
            'compare' => '>='
        )
);
				
			

Boucle à travers les résultats.

En suite je récupère toutes les valeurs dans une boucle while

				
					foreach ( $blogusers as $user ) {

    $author_id = $user->ID;
    $image = get_field('tsm_local_avatar', 'user_'.$author_id );
    $genre = get_field('genre', 'user_'.$author_id );
    $age = get_field('age', 'user_'.$author_id );
    $celibataire_depuis= get_field('celibataire_depuis', 'user_'.$author_id ); 

}
				
			

Comment détecter qu’il s’agit d’un device mobile

Comment détecter qu’il s’agit d’un device mobile

Lorsque je développe des sites web, je m’assure qu’ils rendent bien sur tous les types d’écrans, dont les mobiles. En général les mediaqueries en CSS sont suffisantes. Mais récemment j’ai développé un site où la version mobile était assez différente de la version desktop. Il me fallait donc une redirection sur base de… la taille de l’écran. En tout cas c’est ce que je pensais dans un premier temps. Car après quelques tests je me suis aperçu que certains smartphones avaient des résolutions d’écran parfois supérieures à des laptops. Ce guide sur les résolutions d’écran iPhone l’illustre fort bien.

J’ai donc cherché un peu et trouvé qu’il y a moyen de détecter le userAgent (çad le navigateur). Cela fonctionne très bien mais comme un utilisateur peut manipuler le userAgent utilisé cette méthode n’est pas trop recommandée. Mon avis perso p/r à cela est qu’un utiliser qui manipule son userAgent est un utilisateur avancé et s’il se rend compte que le site ne fonctionne pas bien à cause de cela il saura quoi faire.

La dernière solution que j’ai trouvée et qui est pour la moi la meilleure, c’est de détecter en JS si le device à une fonction Hover. On sait que cela n’est pas possible sur un device mobile et donc détecter cette fonctionnalité permet de savoir à coup sur si on a à faire à un device mobile ou non. Seul bémol, cette façon ne permet pas d’exclure les iPads du choix. Or dans le site qui m’a posé ce problème je devais avoir une version iPad identique à la version desktop. Il faudra donc combiner  les solutions entr’elles pour obtenir le résultat désiré.

Détection de la taille

				
					$(window).on('load resize',function(){

 if($(window).width() < 769){
// redirection ou autre action
	 }
    });
				
			

Détection du userAgent

				
					$(window).on('load resize',function(){

if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)){
   
        // redirection ou autre action

        }
    });
				
			

Détection de la fonctionnalité :hover

				
					 $(window).on('load resize',function(){

 if(window.matchMedia("(any-hover: none)").matches) {
           
// redirection ou autre action

        }
    });
				
			

WordPress pagination post suivant et précédent avec image mise en avant

WordPress pagination post suivant et précédent avec image mise en avant

Pour les besoins d’un site qui présente des portraits, je devais pouvoir passer au post précédent et suivant au moyen d’un lient contenant le titre du post mais aussi l’image en avant. Voici le script complet.

J’ai ajouté une condition pour ne pas afficher précédent sur le premier post ni suivant sur le dernier

				
					<?php
// https://njengah.com/wordpress-next-previous-post-with-thumbnail-pagination/
$prev = get_previous_post();
$next = get_next_post();
?>

<?php if(!empty($prev->ID)) {   ?>
<a href="<?php echo get_permalink( $prev->ID ); ?>">
<?php _e("Portrait pécédent", "thisishomemade"); ?><br>
<?php echo apply_filters( 'the_title', $prev->post_title ); ?>
<?php echo get_the_post_thumbnail($prev->ID, 'thumbnail'); ?>
</a>
<?php } ?>

<?php if(!empty($next->ID)){ ?>
<a href="<?php echo get_permalink( $next->ID ); ?>">
<?php _e("Portrait suivant", "thisishomemade"); ?><br>
<?php echo apply_filters( 'the_title', $next->post_title ); ?>
<?php echo get_the_post_thumbnail($next->ID, 'thumbnail'); ?>
</a>
<?php } ?>
				
			

Une boucle est néanmoins possible au moyen de ce script.

merci à https://gist.github.com/banago/5603826 !

				
					<?php 
/**
 *  Infinite next and previous post looping in WordPress
 */
if( get_adjacent_post(false, '', true) ) { 
	previous_post_link('%link', '&larr; Previous Post');
} else { 
    $first = new WP_Query('posts_per_page=1&order=DESC'); $first->the_post();
    	echo '<a href="' . get_permalink() . '">&larr; Previous Post</a>';
  	wp_reset_query();
}; 
    
if( get_adjacent_post(false, '', false) ) { 
	next_post_link('%link', 'Next Post &rarr;');
} else { 
	$last = new WP_Query('posts_per_page=1&order=ASC'); $last->the_post();
    	echo '<a href="' . get_permalink() . '">Next Post &rarr;</a>';
    wp_reset_query();
}; 

?>
				
			

Uploader en FTP uniquement les derniers fichiers modifiés au moyen de Git-Ftp

Je développe beaucoup de sites en WordPress en local que je dois ensuite déployer sur le serveur de production (ça vaut également pour le passage de local vers dev ou de dev vers prod)

Pendant tout un temps j’ai utilisé Duplicator et j’en étais très satisfait. Il faut par contre à chaque fois faire un paquet du site entier (personnellement j’ai toujours exclu de dossier uploads du à la limitation à 500MB de la version gratuite), l’uploader en FTP puis refaire une install sur base des fichiers Duplicator. ça prend pas mal de temps.

J’ai ensuite découvert WP Migrate Pro qui me permet d’un simple click de synchroniser tout le contenu de la BDD de Local vers Dev, ou Dev vers Prod, ou même souvent de prod vers local car comme mes clients ajoutent du contenu sur le site, ça me permet de rapatrier tout ce contenu en local ou sur le dev. Le gros avantage de ce plugin est qu’il remplace tous les chemins des fichiers et les url du site automatiquement! un vrai régal. en 30″ les sites sont synchros.

Restait encore à régler le problème des fichiers modifiés en local. Pour cela j’ai configuré mon Filezilla afin qu’il n’upload que les fichiers qui ont une date de modification différente et je balance donc à chaque fois tout le dossier du thème et ne sont effectivement transférés que les fichiers sur lesquels j’ai travaillé.

Mais récemment, on me sollicite de plus en plus pour reprendre la maintenance de sites fait avec Elementor. Ce plugin crée des fichiers un peu partout. Il créée par exemple 1 fichier CSS par post qu’il stocke dans uploads/elementor/css. Il m’est donc très pénible de rentrer chaque fois dans les dossiers en question pour les uploader. Je travaille également beaucoup avec WPML qui lui aussi crée des fichiers un peu partout.

J’ai donc trouvé la solution optimale pour synchroniser cela d’une ligne de commande grâce à Git-FTP (installation de Git-Ftp). Grâce à cela, une fois commité mes derniers changements, je fais un petit git ftp push qui m’upload tous les fichiers de mon système qui ont été modifiés !