Développer avec et sans Ajax : Compatibilité NOJS avec admin-post.php

Développer avec et sans Ajax : Compatibilité NOJS avec admin-post.php

Ajax, sujet toujours discuté à droite à gauche, ici même encore la semaine dernière avec un article sur la navigation ajax made in wabeo par notre ami Willy.

À mon tour de vous parler d’Ajax, plus précisément de la façon d’utiliser Ajax dans WordPress afin de rendre vos développements compatible NOJS, ou si vous préférez « Sans JavaScript« .

Dans le même temps je vais devoir vous parler d’un fichier un peu plus méconnu que le admin-ajax.php, il s’agit de admin-post.php, son jumeau synchrone.

JavaScript Head

Vous avez développé un plugin, avec une belle interface, des actions bien stylées, les pages n’ont même pas besoin de se recharger. Que ce soit en back-end ou en front-end, l’administrateur et l’utilisateur final gagnent en confort de navigation. Félicitations.

Vous désactivez le JavaScript afin de tester le site, puisqu’avant le développement de ce plugin, le site était bel et bien fonctionnel. Même chose pour le back-end, WordPress a géré pour toutes les pages, toutes les options, tous les cas que tout fonctionne même sans le JavaScript. Vous rafraîchissez et …

drama

Peinard dans votre fauteuil, vous regardez flambez le site, plus rien ne fonctionne, vous qui aviez déjà le champagne à la main, en train de vous auto-congratuler de votre chef-d’oeuvre JavaScripto-contemporaino-2013, c’est raté.

HEY ! Pourquoi désactiver JavaScript ? Qui navigue sans JavaScript ? Quel pourcentage de personnes cela représente ? Je vous laisse lire l’article chez AlsaCreations qui s’est demandé Pourquoi certains naviguent sans JavaScript.

y-u-no-have-javascript-enabled
C’est vrai quoi …. y ?

Convaincus ? J’espère !

JavaScript Heat

En fait, la vraie bonne solution n’est pas de développer en pensant JavaScript en premier lieu, même si c’est le besoin recherché, il ne faut donc pas le faire basé sur admin-ajax.php avec un envoi de donnée arbitraire comme « id=123,action=like » etc.

Vous devez faire en sorte que le développement fonctionne sans JavaScript, basé sur admin-post.php, puis ensuite, nous pourrons ajouter la couche Ajax, ce qui ne prendra certainement pas le double de temps.

JavaScript Junkie

Exit admin-ajax.php, hello admin-post.php. Ces 2 fichiers fonctionnent quasiment de la même façon à la différence que Ajax sera asynchrone comme son nom l’indique, et Post sera synchrone, un rechargement de la page sera nécessaire, c’est le but : ne pas gérer de suite le JavaScript.

Nous allons voir le plus simplement possible comment faire. Prenons l’exemple d’un lien à cliquer qui serait sous la forme :

<a href="#" data-ID="<?php get_the_ID(); ?>" class="clicme">Like</a>

Puis vous avez certainement un code JavaScript du genre :

$('.clicme').on('click', function(e){
	e.preventDefault();
	$.get( '<?php echo admin_url( 'admin-ajax.php' ); ?>', { id: $(this).data('ID'), action:'like' } )
		.done( function(){ alert('Merci d\'avoir liké'); } );
});

Et côté PHP vous avez (j’espère) utilisé les hooks wp_ajax_nopriv_like et wp_ajax_like pour gérer ce like.

Code PHP du like très simplifié :

add_action( 'wp_ajax_nopriv_like', 'manage_callback_like' );
add_action( 'wp_ajax_like', 'manage_callback_like' );
function manage_callback_like() {
	if ( isset( $_GET['id'] ) && $id=$_GET['id'] && $post == get_post( $id ) ) {
		$nb = (int)get_post_meta( $id, '_likes', true );
		update_post_meta( $id, '_likes', ++$nb );
		wp_send_json_success();
	}
}

Hot JavaScript

« Ça devient chaud ! » Mais nooon … il faut d’abord penser à le faire de suite sans JS, voici comment procéder :

<a href="<?php echo admin_url( 'admin-post.php?action=like&id=' . get_the_ID() ); ?>">Like</a>

Plus besoin du data-ID. Et côté PHP j’utilise maintenant en plus les hooks admin_post_nopriv_like et admin_post_like.

Je modifie un peu la fonction de callback en prime :

add_action( 'wp_ajax_nopriv_like', 'manage_callback_like' );
add_action( 'wp_ajax_like', 'manage_callback_like' );
add_action( 'admin_post_nopriv_like', 'manage_callback_like' );
add_action( 'admin_post_like', 'manage_callback_like' );
function manage_callback_like() {
	if ( isset( $_GET['id'] ) && $id=$_GET['id'] && $post == get_post( $id ) ) {
		$nb = (int)get_post_meta( $id, '_likes', true );
		update_post_meta( $id, '_likes', ++$nb );
		// pas d'Ajax = redirection sur la page de provenance
		if ( !defined( 'DOING_AJAX' ) ) {
			wp_safe_redirect( wp_get_referer() );
			die();
		}
		wp_send_json_success();
	}
}

Et mon JavaScript se simplifie :

$('.clicme').on('click', function(e){
	e.preventDefault();
	$.get( $(this).attr('href').replace('admin-post.php', 'admin-ajax.php') )
		.done( function(){ alert('Merci d\'avoir liké'); } );
});

Je prends l’url du lien et remplace le nom du fichier post par celui de l’Ajax ! Plus besoin des data.

Franchement, c’est plus difficile là ? Plus long à coder ? Non. Si je clic sur le lien sans JavaScript je vais déclencher l’action de admin-post.php, mettre à jour un compteur de like, et être redirigé sur ma page.

Si le JavaScript est possible, le preventDefault empêchera alors le clic et lancera à la place la requête Ajax sur admin-ajax.php. Libre à vous d’ajouter un loader/spinner pour indiquer qu’une requête est en cours, si vous souhaitez mettre à jour le compteur en live, je vous laisse faire un wp_send_json() avec la valeur à retourner, valeur que vous remplacerez, ça, c’est aussi un autre sujet, je vous laisse faire :D

Epic JavaScript

Vous venez de faire du développement Ajax compatible NOJS en 3 lignes de code de plus et en modifiant un lien href.

Boy-That-Escalated-Quickly-Anchorman

Cette solution fonctionne aussi avec les formulaires qui seraient sérialisés puis envoyés en Ajax, si vous l’utilisez dans le back-end, n’oubliez pas d’ajouter un nonce !

Aussi elle est simple à mettre en place et respecte les bonnes pratiques en termes d’accessibilité, en auriez-vous déjà eu besoin ?

Julio Potier

Consultant en Sécurité, Expert WordPress, Formateur, Marketeur et créateur du plugin de sécurité WordPress SecuPress.
Julio développe et sécurise du contenu web tous les jours. La création de plugins WordPress et la vente de produits WordPress font partie de son quotidien.

Lire la suite

Vous aimez ? Partagez !


Réagir à cet article

120 caractères maximum