Jouez avec l’ajout des liens avec wpLink JS

Jouez avec l’ajout des liens avec wpLink JS

ink est une fenêtre qui permet d’ajouter des liens, cette fonctionnalité est incluse dans WordPress nativement. Nous allons ici découvrir comment l’utiliser dans nos développements afin d’éviter de réinventer la roue carrée.

Alors déjà pour ceux qui veulent voir du code, vous trouverez le fichier du code dans /wp-includes/js/wplink.js et aussi le plugin TinyMCE dans /wp-includes/js/tinymce/plugins/wplink/plugin.js.

Pour ceux qui veulent voir de quoi on parle, c’est cette boite de dialogue là :

wplink preview

L’idée est de réutiliser cette boite dans nos développements afin de profiter de l’interface, du code et du fait que les utilisateurs n’auront pas à apprendre une nouvelle mauvaise façon de faire la même chose qu’avant alors que c’est très bien (l’effet Gutenberg quoi…).

Voici une démo de ce que j’en ai fait pour SecuPress v1.4.9 dans le module de déplacement de la page de connexion (Move Login Page) :

input type=url
Démo vidéo

teaxtarea

De base, ce wpLink est lié au textarea de votre article. Pour lancer cette fenêtre, vous devez sélectionnez un mot dans votre contenu puis cliquer sur « Insert/edit link », puis encore sur la roue (cog), elle apparait alors en tant que « réglages avancés » de ce lien finalement, une aide aussi à linker des pages de votre site.

Nous allons lier cette boite à autre chose qu’un textarea, je l’ai mise sur un bouton qui rempli ensuite un input text/url, je pense qu’on peut finalement le lier à ce qu’on veut.

html

Vous vous attendiez à un DOM de fou ? Vous allez être déçu car le html est ultra simple et tout à fait commun :

<input type="url" name="secupress['my-field']" class="wp_link_dialog">

Cela fonctionnera sur ce que vous voulez, vous verrez dans le code, vous pourrez même changer le nom (ouf !). Donc je mets cette classe pour indiquer que ce champ dois déclencher l’ouverture de la boite wpLink.

PHP#1

Un peu de PHP pour préparer la boite et la trad en JS qu’on voit après :

function secupress_enqueue_wplink_dialog() {
	// We need the editor buttons styles
	wp_enqueue_style( 'editor-buttons' );
	// and native wplink script here
	wp_enqueue_script( 'wplink' );
	// and native wplink script here
	$suffix  = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
	$version = $suffix ? '1.0' : time();
	// Our wplink JS code
	wp_enqueue_script( 'secupress-wplink', SECUPRESS_ADMIN_JS_URL . 'secupress-wplink' . $suffix . '.js', 'jQuery', $version, true );
	// some i18n
	wp_localize_script( 'secupress-wplink', 'secupresswplink', [ 'insert' => __( 'Insert/edit link' ), 'home_url' => esc_url( home_url() ) ] );
}

J’enqueue le style CSS de editor-buttons nécessaire, le script de wpLink aussi. Puis mon JS qu’on voit juste après (toujours un .min hein !) et enfin je fais un wp_localize_script() pour traduire le bouton « Insert/edit link ».

JavaScript

Même là, vous allez voir que ça se fait en peu de lignes, déception ! OU PAS !

/**
 * @version 1.0
 * @author Julio Potier
 */
jQuery(document).ready(function ($){
	$('[type=url][name^=secupress].wp_link_dialog').prop('readonly', true)
		.after( ' <button type="button" class="wp_link_dialog_open secupress-button">' + secupresswplink.insert + '</button>' +
				' <input type="reset" class="wp_link_dialog_reset secupress-button-mini" />' );
	$('[type=reset].wp_link_dialog_reset').click(function (e){
		e.preventDefault();
		var $t = $(this).parent().find('[type=url][name^=secupress].wp_link_dialog');
		$($t).val(secupresswplink.home_url);
	});
	$('button.wp_link_dialog_open').click(function (e){
		$('#link-options, #wplink-link-existing-content').hide();
		var $t = $(this).prev('[type=url][name^=secupress].wp_link_dialog');
		wpLink.open($($t).attr('id'), '', '' );
		wpLink.htmlUpdate = function() {
			var attrs = wpLink.getAttrs();
			var parser = document.createElement( 'a' );
			parser.href = attrs.href;
			if ( 'javascript:' === parser.protocol || 'data:' === parser.protocol ) { // jshint ignore:line
				$($t).val('');
				wpLink.close();
			}
			$($t).val(attrs.href);
			wpLink.close();
		}
	});
})
wpLink from SecuPress

Allez, un ligne par ligne.

5. jQuery(document).ready(function ($){

Je suis en back-office donc j’utilise jQuery qui est nativement inclus et enqueue partout.

6. $('[type=url][name^=secupress].wp_link_dialog').prop('readonly', true)`

Je vais ensuite ajouter la propriété readonly afin qu’on ne puisse pas écrire manuellement une URL.

Alors bien sûr vous pouvez mettre un autre nom de champ et pas secupress, vous pouvez même retirer ce sélecteur. La classe est utilisée pour ça.

Aussi vous me direz « mais Julio, avec l’inspecteur d’object/firebug je peux modifier ton readonly et mettre ce que je veux, c’est pas secure ! », non mais je sais, j’ai prévu le cas dans le PHP, je filtre tout bien 🙂 #autohacking.

7. .after( ' <button type="button" class="wp_link_dialog_open secupress-button">' + secupresswplink.insert + '</button>' +
8. ' <input type="reset" class="wp_link_dialog_reset secupress-button-mini" />' );

Je fais ensuite un .after pour ajouter du html à la suite, j’y ajoute alors 2 boutons, un <button> qui servira à déclencher la popup et un <input type="reset">. Je leur mets mes ptites classes CSS pour faire joli !

J’utilise donc la traduction précédente avec secupresswplink.insert native de WordPress, « Insert/edit link ». Comme j’utilise la trad WP, rien à traduire dans mon dev. Je mets aussi un home_url() car étonnamment on a pas cette info, je pensais …

Pour le bouton reset, je mets ce type juste pour que le bouton soir traduit par mon navigateur, encore rien à traduire (flemmmmmmme).
Remarquez que « secupresswplink » vient de la traduction du JS.

9. $('[type=reset].wp_link_dialog_reset').click(function (e){

Je pose ensuite un évènement pour pouvoir remettre la home de notre site car la boite ne permet pas de le faire, aussi, il s’agit de la valeur par défaut de mon champ.

10. e.preventDefault();

Je fais un preventDefault() car je ne veut PAS reset mon formulaire.

11. var $t = $(this).parent().find('[type=url][name^=secupress].wp_link_dialog');

12. $($t).val(secupresswplink.home_url);

Puis je mets alors ma home dans le input trouvé via .parent().find().

14. $('button.wp_link_dialog_open').click(function (e){

On s’occupe enfin de notre bouton qui ouvre la popup.

15. $('#link-options, #wplink-link-existing-content').hide();

Je cache les élements du haut car je ne souhaite pas laisser la liberté de toute URL.

16. var $t = $(this).prev('[type=url][name^=secupress].wp_link_dialog');

Ici je récupère la cible qui va recevoir le lien choisi, je prends donc le type=url précédent avec .prev().

17. wpLink.open($($t).attr('id'), '', '' );

Voilà on l’ouvre enfin ce wpLink ! On lui donne l’ID du champ en premier param, oubliez les autres (ou RTFM).

		wpLink.htmlUpdate = function() {
			var attrs = wpLink.getAttrs();
			var parser = document.createElement( 'a' );
			parser.href = attrs.href;
			if ( 'javascript:' === parser.protocol || 'data:' === parser.protocol ) { // jshint ignore:line
				$($t).val('');
				wpLink.close();
			}
			$($t).val(attrs.href);
			wpLink.close();
		}

18 à 28 c’est un morceau de wplink.js dans lequel je n’ai gardé que ce que je veux. En fait il existe la fonction buildHtml qui crée une balise <a> mais sans le contenu ni le </a>, étrange. J’ai donc utilisé htmlUpdate qui mets à jour la champ, et au lieu d’envoyer une balise complète, je n’envoie que le href ! BOUM !

Et BIM, c’est déjà la fin, et PAON, avec ce peu de code suffit à réutiliser cette boite wpLink dans vos développements !

Je vous relire et inclure ça dans vos devs 😉

Vous aimez ? Partagez !


Réagir à cet article

220 caractères maximum