Contenu principal
Aide contextuelle de WordPress 3.3

La nouvelle aide contextuelle de WordPress 3.3

WordPress 3.3 se prépare, apportant son lot de nouveautés. Ces nouveautés, pour le peu que j’ai vu, amènent pas mal de changements au niveau de la façon de coder nos plugins. Je pense notamment à de nouvelles classes php faisant leur apparition, comme par exemple celles de l’éditeur (TinyMCE et quicktags) et de l’aide contextuelle. Aujourd’hui je vais vous exposer le résultat de mes recherches sur l’aide contextuelle, afin de définir une « méthode » compatible post et pré-WP3.3.

Travaillant depuis un moment sur un plugin (ouais, ça fait 2 mois que j’ai pas fait d’article, je suis occupé môa môssieur xD), je me suis décidé pour la première fois à fouiner dans une bêta de WordPress (la 3.3 b3 actuellement) afin de prévoir une compatibilité avec la future nouvelle version (grand bien m’en a fait puisque j’ai eu des soucis avec l’éditeur, mais c’est une autre histoire). Les bêtas étant amenées à évoluer, cet article sera mis à jour si besoin jusqu’à la sortie de la version 3.3 finale de WordPress.

Comme dit dans l’introduction, le sujet du jour sera l’aide contextuelle. Cet article s’adresse donc plutôt aux développeurs de plugins.
Bon, trêve de bavardages. WordPress introduit la nouvelle classe php WP_Screen (wp-admin/includes/screen.php), relative entre autres à l’aide contextuelle (mais aussi relative à beaucoup d’autres choses en fait).
Visuellement, on remarque une liste d’onglets sur la gauche de l’aide, et une sidebar sur la droite.
Ce que je souhaite faire aujourd’hui, c’est créer une « méthode » qui fonctionnera tout aussi bien avec la future version 3.3 et avec la 3.2.1 actuelle et inférieures, tout en profitant des nouvelles fonctionnalités.

Ancienne méthode

Jusque là, nous faisions donc comme ça :

123456

add_action('contextual_help', 'my_plugin_help',10,3);	// Trinity! Help me!
function my_plugin_help($help, $screen_id, $screen) {
	$help .= "<h5>Mon titre d'aide</h5>";
	$help .= "<p>Mon texte pour vous expliquer comment ça marche, bande de noobs!</p>";
	return $help;
}

Bien sûr, la compatibilité avec l’ancienne méthode est assurée dans la nouvelle, ainsi, un nouvel onglet « Screen Info » sera crée, laissant apparaitre mon texte explicatif. Mais à choisir, je préfèrerais avoir « Mon titre d’aide » dans l’onglet.

Et maintenant

Pour ajouter une aide avec onglet, voici comment on doit faire maintenant :

123456

$helpItem = array(
	'id'		=> 'mon-plugin',
	'title'		=> "Mon titre d'aide",
	'content'	=> "<p>Mon texte pour vous expliquer comment ça marche, bande de noobs!</p>"
);
get_current_screen()->add_help_tab($helpItem);

Puis, ajouter la sidebar à droite, proposant des liens pour trouver plus d’aide :

080910

$helpSide = '<p><strong>' . __('For more information:') . '</strong></p>' .
	'<p><a title='Screenfeed' target='_blank' href='https://scri.in/blog'>Mon blog</a></p>';
get_current_screen()->set_help_sidebar( $helpSide );

Plutôt simple non? Mais bien sûr ça ne marchera pas avec un WP < 3.3.

On mélange tout

Pour avoir cette aide optimisée pour WP 3.3 et fonctionnelle pour les versions inférieures, voici ce que je propose :
D’abord nous créons un hook sur ‘contextual_help’ comme avant.

123456

add_action('contextual_help', 'my_plugin_help',10,3);	// Trinity! Help me!
function my_plugin_help($help, $screen_id, $screen) {

	//...

}

La première chose à faire est de vérifier que nous sommes bien sur la bonne page : si je veux montrer l’aide seulement sur la page de réglages de mon plugin par exemple, il va falloir faire un test sur $screen_id.

12345678

add_action('contextual_help', 'my_plugin_help',10,3);	// Trinity! Help me!
function my_plugin_help($help, $screen_id, $screen) {
	if ($screen_id != 'settings_page_mon_plugin_config')
		return $help;

	//...

}

Ici, ‘mon_plugin_config’ correspondra à l’ID donné dans add_submenu_page(). Par exemple (l’avant dernier paramètre) :

1

add_submenu_page('options-general.php', 'Mon plugin', 'Mon plugin', 'manage_options', 'mon_plugin_config', 'mon_plugin_settings_page');

Maintenant, créons un tableau contenant l’aide. Il pourra contenir plusieurs aides, donc plusieurs onglets :

0102030405060708091011121314151617181920

add_action('contextual_help', 'my_plugin_help',10,3);	// Trinity! Help me!
function my_plugin_help($help, $screen_id, $screen) {
	if ($screen_id != 'settings_page_mon_plugin_config')
		return $help;

	$helpArr = array();
	$helpArr[] = array(
		'id'		=> 'mon-plugin',
		'title'		=> "Mon titre d'aide",
		'content'	=> "<p>Mon texte pour vous expliquer comment ça marche, bande de noobs!</p>"
	);
	$helpArr[] = array(
		'id'		=> 'credits',
		'title'		=> "Credits",
		'content'	=> "<p>Merci à Greg pour cette bonne méthode.</p>"
	);

	//...

}

On ajoute la sidebar et une fonction qui va traiter tout ça en suivant.

0102030405060708091011121314151617181920212223

add_action('contextual_help', 'my_plugin_help',10,3);	// Trinity! Help me!
function my_plugin_help($help, $screen_id, $screen) {
	if ($screen_id != 'settings_page_mon_plugin_config')
		return $help;

	$helpArr = array();
	$helpArr[] = array(
		'id'		=> 'mon-plugin',
		'title'		=> "Mon titre d'aide",
		'content'	=> "<p>Mon texte pour vous expliquer comment ça marche, bande de noobs!</p>"
	);
	$helpArr[] = array(
		'id'		=> 'credits',
		'title'		=> "Credits",
		'content'	=> "<p>Merci à Greg pour cette bonne méthode.</p>"
	);

	$helpSide = '<p><strong>' . __('For more information:') . '</strong></p>' .
		'<p><a title='Screenfeed' target='_blank' href='https://scri.in/blog'>Mon blog</a></p>';

	sf_contextual_help($helpArr, $help, $helpSide);

}

Cette partie là est finie, il nous reste qu’à créer la fonction sf_contextual_help().
On va donner à cette fonction 4 paramètres :

  • $helpArr = array() : contiendra le tableau de nos onglets.
  • $help = '' : contiendra le $help qu’on avait plus haut, transmis par notre hook sur ‘contextual_help’. A noter que $help sera vide pour WP 3.3.
  • $helpSide = '' : le contenu de la sidebar.
  • $keep_previous = true : indiquera si on veut garder les onglets déjà existants ou si on les supprime.

On déclare notre fonction et on la sépare en deux avec un class_exists() :

2526272829303132333435

function sf_contextual_help($helpArr = array(), $help = '', $helpSide = '', $keep_previous = true) {
	if (class_exists('WP_Screen')) {

		// WP 3.3+

	} else {

		// WP < 3.3

	}
}

D’abord on s’occupe de $keep_previous. La classe WP_Screen dispose d’une méthode remove_help_tabs() qui supprime les onglets existants. De la même manière il existe remove_help_tab($id) qui supprime un onglet en particulier.

25262728293031323334353637383940

function sf_contextual_help($helpArr = array(), $help = '', $helpSide = '', $keep_previous = true) {
	if (class_exists('WP_Screen')) {
		$screen = get_current_screen();
		if (!$keep_previous)
			$screen->remove_help_tabs();

		// WP 3.3+

	} else {
		if (!$keep_previous)
			$help = '';

		// WP < 3.3

	}
}

Maintenant on ajoute les onglets.

25262728293031323334353637383940414243444546474849505152

function sf_contextual_help($helpArr = array(), $help = '', $helpSide = '', $keep_previous = true) {
	if (class_exists('WP_Screen')) {
		$screen = get_current_screen();
		if (!$keep_previous)
			$screen->remove_help_tabs();
		if (is_array($helpArr) && count($helpArr)) {
			foreach($helpArr as $helpItem) {
				$screen->add_help_tab($helpItem);
			}
		}

		// WP 3.3+

	} else {
		if (!$keep_previous)
			$help = '';
		if (is_array($helpArr) && count($helpArr)) {
			$nhelp = '';
			foreach($helpArr as $helpItem) {
				$nhelp .= '<h5>'.$helpItem['title'].'</h5>'."n";
				$nhelp .= $helpItem['content']."n";
			}
		}

		// WP < 3.3

	}
}

Et on finit en ajoutant la sidebar.

2526272829303132333435363738394041424344454647484950

function sf_contextual_help($helpArr = array(), $help = '', $helpSide = '', $keep_previous = true) {
	if (class_exists('WP_Screen')) {
		$screen = get_current_screen();
		if (!$keep_previous)
			$screen->remove_help_tabs();
		if (is_array($helpArr) && count($helpArr)) {
			foreach($helpArr as $helpItem) {
				$screen->add_help_tab($helpItem);
			}
		}
		if (isset($helpSide) && $helpSide)
			$screen->set_help_sidebar( $helpSide );
	} else {
		if (!$keep_previous)
			$help = '';
		if (is_array($helpArr) && count($helpArr)) {
			$nhelp = '';
			foreach($helpArr as $helpItem) {
				$nhelp .= '<h5>'.$helpItem['title'].'</h5>'."n";
				$nhelp .= $helpItem['content']."n";
			}
		}
		$nhelp .= isset($helpSide) && $helpSide ? '<div style="border-top:solid 1px #dfdfdf">'.$helpSide.'</div>'."n" : '';
		echo $help . $nhelp;
	}
}

Le code complet

0102030405060708091011121314151617181920212223242526272829303132333435363738394041424344454647484950

add_action('contextual_help', 'my_plugin_help',10,3);	// Trinity! Help me!
function my_plugin_help($help, $screen_id, $screen) {
	if ($screen_id != 'settings_page_mon_plugin_config')
		return $help;

	$helpArr = array();
	$helpArr[] = array(
		'id'		=> 'mon-plugin',
		'title'		=> "Mon titre d'aide",
		'content'	=> "<p>Mon texte pour vous expliquer comment ça marche, bande de noobs!</p>"
	);
	$helpArr[] = array(
		'id'		=> 'credits',
		'title'		=> "Credits",
		'content'	=> "<p>Merci à Greg pour cette bonne méthode.</p>"
	);

	$helpSide = '<p><strong>' . __('For more information:') . '</strong></p>' .
		'<p><a title='Screenfeed' target='_blank' href='https://scri.in/blog'>Mon blog</a></p>';

	sf_contextual_help($helpArr, $help, $helpSide);

}

function sf_contextual_help($helpArr = array(), $help = '', $helpSide = '', $keep_previous = true) {
	if (class_exists('WP_Screen')) {
		$screen = get_current_screen();
		if (!$keep_previous)
			$screen->remove_help_tabs();
		if (is_array($helpArr) && count($helpArr)) {
			foreach($helpArr as $helpItem) {
				$screen->add_help_tab($helpItem);
			}
		}
		if (isset($helpSide) && $helpSide)
			$screen->set_help_sidebar( $helpSide );
	} else {
		if (!$keep_previous)
			$help = '';
		if (is_array($helpArr) && count($helpArr)) {
			$nhelp = '';
			foreach($helpArr as $helpItem) {
				$nhelp .= '<h5>'.$helpItem['title'].'</h5>'."n";
				$nhelp .= $helpItem['content']."n";
			}
		}
		$nhelp .= isset($helpSide) && $helpSide ? '<div style="border-top:solid 1px #dfdfdf">'.$helpSide.'</div>'."n" : '';
		echo $help . $nhelp;
	}
}

Conclusion

La seule chose que je trouve dommage dans cette nouvelle classe c’est que nous n’avons pas accès aux onglets déjà existants : on peut les supprimer, mais pas les récupérer. En effet, ils sont stockés dans une variable Private au sein de la classe. On ne peut donc pas modifier un onglet, ou créer un onglet en fonction d’un autre pré-existant. Dommage.
Pour la version WP < 3.3, le titre est affiché dans une balise <h5> plutôt que dans un onglet, et le contenu de la sidebar sera affiché à la fin de l’aide, avec un trait horizontal pour délimiter.

Voilà comment profiter pleinement de cette nouvelle aide contextuelle tant en gardant la compatibilité avec l’ancienne :)

Le petit truc en plus

Comme je suis un mec sympa (hey, pourquoi tu souris?!), je vous donne une petite astuce supplémentaire. Je me suis dit qu’il serait de bon ton de rajouter sur la page de réglages de mon plugin des petits liens renvoyant vers l’aide, et vers le bon onglet en plus :)

Allez, je fais rapide.
Le code HTML du lien :

1

<a class="help-link" href="#tab-panel-credits"><span>?</span></a>

Ici, « credits » correspond à l’ID de mon 2ème onglet, il suffit de rajouter « #tab-panel- » devant pour avoir le href complet (ce qui correspond à l’attribut id html de l’onglet).
On ajoute un peu de CSS :

010203040506070809101112131415161718192021222324252627282930

.help-link {
	position: relative;
	display: inline-block;
	background: #21759b;
	color: #fff;
	text-decoration: none;
	font-size: 10px;
	font-family: sans-serif;
	line-height: 16px;
	width: 15px;
	height: 15px;
	top: -1px;
	-webkit-border-radius: 10px;
	   -moz-border-radius: 10px;
	    -ms-border-radius: 10px;
	     -o-border-radius: 10px;
		border-radius: 10px;
}
.help-link span {
	display: inline-block;
	padding: 0 5px;
	height: 15px;
}
.help-link:hover, .help-link:active {
	background: #d54e21;
	color: #fff;
}
.no-js .help-link {
	display: none;
}

A noter que le bouton ne sera pas visible si javascript est désactivé (l’aide ne sera pas visible de toute façon).
Et un peu de jQuery :

01020304050607080910111213

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

	$('a.help-link').click(function(e) {
		tabid = $(this).attr('href');
		$hlpbtn = $('#contextual-help-link');
		if ( !$hlpbtn.parent().andSelf().hasClass('screen-meta-active') )
			$hlpbtn.trigger('click');
		$('#contextual-help-wrap').find('a[href="'+tabid+'"]').trigger('click');
		$("html, body").animate({ scrollTop: 0 }, "slow");
		e.preventDefault();
	});

});

Et voilà. Au clic, l’écran remonte en haut de page, l’aide s’ouvre, le bon onglet s’ouvre aussi :)

See ya!

PS : comme je le dis toujours, je ne me prétends pas développeur donc si vous avez des améliorations à amener ou des critiques à faire, les commentaires sont ouverts.