WordPress est passé hier en version 3.1, une version très attendue car elle apporte quelques nouveautés que les utilisateurs demandaient depuis un certain temps. Entre autres, l’apparition de l' »admin bar » : un « gadget » que nous allons aujourd’hui modifier.
Tout d’abord, si vous n’avez pas encore fait la mise à jour vers cette version 3.1, voici le lien vers la liste des changements.
Aujourd’hui nous allons donc parler de cette « fameuse Admin Bar », bien que ce ne soit pas la « killer feature » que nous attendions le plus (en fait, la nouveauté la plus attendue était de pouvoir faire des liens entre les articles sans se casser la tête… Nouveauté que je n’utiliserais donc pas à priori puisqu’elle n’apparait que dans l’éditeur tinymachin et que je n’utilise que l’éditeur html… Bref, je m’égare).
Hein?
Mais en fait, qu’est-ce que cette « Admin Bar »?
C’est une barre de menu qui va s’afficher lorsque nous sommes connecté. Son principal avantage (je trouve) c’est qu’elle s’affiche en front-end. C’est à dire que vous avez une barre de menu qui s’affiche en haut de votre fenêtre lorsque vous naviguez sur le site en étant connecté (oui, en front-end). Et si vraiment vous l’aimez, vous pouvez la garder dans l’administration. Pour cela, il suffit d’aller sur votre profil :
Une barre que je vais garder un certaine temps, avant que je me dise que, vraiment, ça me sert à rien.
Je dois dire que malgré tout cela, je n’ai pas encore envie de supprimer cette barre. Or, la quasi-totalité de mes recherches sur le net m’ont mené vers des « tutoriels » pour supprimer ce menu (sauf 1). DONC! Oui, donc vous en avez marre de lire du blabla donc je passe à l’essentiel, la modifier plutôt que la supprimer.
Comment faire
Après quelques recherches dans les fichiers de WP 3.1 et dans le codex, on s’aperçoit que les 2 seuls fichiers qui vont nous aider dans notre tâche sont wp-includes/admin-bar.php et wp-includes/class-wp-admin-bar.php. Maintenant que nous avons nos fonctions de base, nous pouvons les « modifier ».
La fonction principale qui va nous intéresser est add_menus()
, elle nous enseigne comment hooker le menu et on la trouve dans wp-includes/class-wp-admin-bar.php sous cette forme :
181182183184185186187188189190191192193194
function add_menus() {
add_action( 'admin_bar_menu', 'wp_admin_bar_my_account_menu', 10 );
add_action( 'admin_bar_menu', 'wp_admin_bar_my_sites_menu', 20 );
add_action( 'admin_bar_menu', 'wp_admin_bar_edit_menu', 30 );
add_action( 'admin_bar_menu', 'wp_admin_bar_shortlink_menu', 80 );
add_action( 'admin_bar_menu', 'wp_admin_bar_updates_menu', 70 );
if ( !is_network_admin() && !is_user_admin() ) {
add_action( 'admin_bar_menu', 'wp_admin_bar_new_content_menu', 40 );
add_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 50 );
add_action( 'admin_bar_menu', 'wp_admin_bar_appearance_menu', 60 );
}
do_action( 'add_admin_bar_menus' );
}
A noter que la priorité indiquée en paramètre de add_action()
(le nombre à la fin) va nous permettre de gérer l’ordre des boutons : plus le nombre sera grand, plus le bouton sera à droite.
Avec ça on retrouve presque tout ce qu’il nous faut. Il suffit ensuite de jeter un œil à ces fonctions pour s’apercevoir qu’elles utilisent add_menu()
(sans « s »).
D’après ce que j’ai pu voir, la fonction add_menu()
prend un array en argument : array('id', 'title', 'href')
.
Bien commencer
Commençons par créer la fonction de hook, que nous allons mettre dans le fichier functions.php de notre thème :
123456
function sf_admin_bar() {
// Code
}
add_action('add_admin_bar_menus', 'sf_admin_bar');
Ainsi, on pourrait par exemple supprimer le bouton vers les commentaires :
1234
function sf_admin_bar() {
remove_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 50 );
}
add_action('add_admin_bar_menus', 'sf_admin_bar');
Il m’arrive souvent de créer des sites WordPress avec uniquement des pages, sans posts. Donc autant supprimer le bouton « Nouvel article » et « Nouvelle page », et le remplacer un bouton avec uniquement « Nouvelle page » :
01020304050607080910
function wp_admin_bar_new_page() {
global $wp_admin_bar;
$wp_admin_bar->add_menu( array( 'id' => 'new-page', 'title' => __( 'Add New Page' ), 'href' => admin_url( 'post-new.php?post_type=page' ) ) );
}
function sf_admin_bar() {
remove_action( 'admin_bar_menu', 'wp_admin_bar_new_content_menu', 40 );
remove_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 50 );
add_action( 'admin_bar_menu', 'wp_admin_bar_new_page', 40 );
}
add_action('add_admin_bar_menus', 'sf_admin_bar');
On peut aussi rajouter des boutons vers certains plugins, comme par exemple wp Time Machine que j’aime assez :
0102030405060708091011121314151617
function wp_admin_bar_new_page() {
global $wp_admin_bar;
$wp_admin_bar->add_menu( array( 'id' => 'new-page', 'title' => __( 'Add New Page' ), 'href' => admin_url( 'post-new.php?post_type=page' ) ) );
}
function wp_admin_bar_time_machine() {
if ( function_exists( 'wpTimeMachine_init' ) && current_user_can('manage_options') ) {
global $wp_admin_bar;
$wp_admin_bar->add_menu( array( 'id' => 'wp-time-machine', 'title' => __( 'Backup' ), 'href' => admin_url( 'admin.php?page=wpTimeMachineCore.php' ) ) );
}
}
function sf_admin_bar() {
remove_action( 'admin_bar_menu', 'wp_admin_bar_new_content_menu', 40 );
remove_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 50 );
add_action( 'admin_bar_menu', 'wp_admin_bar_new_page', 40 );
add_action( 'admin_bar_menu', 'wp_admin_bar_time_machine', 65 );
}
add_action('add_admin_bar_menus', 'sf_admin_bar');
On peut également créer des boutons avec un sous-menu, comme le bouton « Apparence ». Pour cela il faut ajouter le paramètre « parent » à add_menu()
et lui indiquer l’id du bouton parent. Rajoutons par exemple un sous-menu « Nouveau média » à notre bouton « Nouvelle page » :
010203040506070809101112131415161718
function wp_admin_bar_new_page() {
global $wp_admin_bar;
$wp_admin_bar->add_menu( array( 'id' => 'new-page', 'title' => __( 'Add New Page' ), 'href' => admin_url( 'post-new.php?post_type=page' ) ) );
$wp_admin_bar->add_menu( array( 'parent' => 'new-page', 'id' => 'new-media', 'title' => __('New Media'), 'href' => admin_url('media-new.php') ) );
}
function wp_admin_bar_time_machine() {
if ( function_exists( 'wpTimeMachine_init' ) && current_user_can('manage_options') ) {
global $wp_admin_bar;
$wp_admin_bar->add_menu( array( 'id' => 'wp-time-machine', 'title' => __( 'Backup' ), 'href' => admin_url( 'admin.php?page=wpTimeMachineCore.php' ) ) );
}
}
function sf_admin_bar() {
remove_action( 'admin_bar_menu', 'wp_admin_bar_new_content_menu', 40 );
remove_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 50 );
add_action( 'admin_bar_menu', 'wp_admin_bar_new_page', 40 );
add_action( 'admin_bar_menu', 'wp_admin_bar_time_machine', 65 );
}
add_action('add_admin_bar_menus', 'sf_admin_bar');
[update]
Ajouter un bouton Akismet affichant le nombre de nouveaux spams.
Je viens de trouver le moyen de rajouter un bouton Akismet donc je vous en fait profiter.
Après un petit tour dans les entrailles du plugin, je découvre que la fonction qui permet d’afficher le nombre de nouveaux spams est akismet_spam_count()
. Seul problème, cette fonction n’est disponible que dans l’administration. Donc encore une fois je vais réinventer la roue en dupliquant la fonction si elle n’est pas définie.
Mais commençons par le commencement :
010203040506070809101112131415
function wp_admin_bar_akismet() {
if ( !current_user_can('moderate_comments') ) // Si la personne n'a pas la "capabilities" de gérer les commentaires, on zappe
return;
if ( !function_exists('akismet_spam_count') ) { // Si la fonction d'Akismet n'existe pas, on la défini ici
// La fonction d'Akismet ici
}
if ( $queue_count = akismet_spam_count() ) { // On enregistre le nombre le nouveaux spams : s'il n'y en a pas on aura 0, donc au sautera au "else"
// ...
} else
return;
}
function sf_admin_bar() {
// Les autres boutons et menus
add_action( 'admin_bar_menu', 'wp_admin_bar_akismet', 75 );
}
Maintenant rajoutons la fonction copiée dans Akismet :
0102030405060708091011121314151617181920212223242526272829303132333435
function wp_admin_bar_akismet() {
if ( !current_user_can('moderate_comments') ) // Si la personne n'a pas la "capabilities" de gérer les commentaires, on zappe
return;
if ( !function_exists('akismet_spam_count') ) { // Si la fonction d'Akismet n'existe pas, on la défini ici
function akismet_spam_count( $type = false ) {
global $wpdb;
if ( !$type ) { // total
$count = wp_cache_get( 'akismet_spam_count', 'widget' );
if ( false === $count ) {
if ( function_exists('wp_count_comments') ) {
$count = wp_count_comments();
$count = $count->spam;
} else {
$count = (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'");
}
wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 );
}
return $count;
} elseif ( 'comments' == $type || 'comment' == $type ) { // comments
$type = '';
} else { // pingback, trackback, ...
$type = $wpdb->escape( $type );
}
return (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type'");
}
}
if ( $queue_count = akismet_spam_count() ) { // On enregistre le nombre le nouveaux spams : s'il n'y en a pas on aura 0, donc au sautera au "else"
// ...
} else
return;
}
function sf_admin_bar() {
// Les autres boutons et menus
add_action( 'admin_bar_menu', 'wp_admin_bar_akismet', 75 );
}
Puis nous rajoutons notre bouton, de la même manière que pour les précédents, sauf qu’il faut tenir compte du singulier/pluriel dans « Spam »/ »Spams » :
01020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546
function wp_admin_bar_akismet() {
if ( !current_user_can('moderate_comments') ) // Si la personne n'a pas la "capabilities" de gérer les commentaires, on zappe
return;
if ( !function_exists('akismet_spam_count') ) { // Si la fonction d'Akismet n'existe pas, on la défini ici
function akismet_spam_count( $type = false ) {
global $wpdb;
if ( !$type ) { // total
$count = wp_cache_get( 'akismet_spam_count', 'widget' );
if ( false === $count ) {
if ( function_exists('wp_count_comments') ) {
$count = wp_count_comments();
$count = $count->spam;
} else {
$count = (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'");
}
wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 );
}
return $count;
} elseif ( 'comments' == $type || 'comment' == $type ) { // comments
$type = '';
} else { // pingback, trackback, ...
$type = $wpdb->escape( $type );
}
return (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type'");
}
}
if ( $queue_count = akismet_spam_count() ) { // Ajout du bouton si on a au moins 1 spam
$link = 'edit-comments.php?comment_status=spam';
$queue_text = sprintf(
_n(
'<span title="Il y a %1$s spam dans votre file d'attente">Spam %2$s</span>',
'<span title="Il y a %1$s spams dans votre file d'attente">Spams %2$s</span>',
$queue_count
),
number_format_i18n( $queue_count ),
'<span id="ab-akismet">'.number_format_i18n( $queue_count ).'</span>'
);
global $wp_admin_bar;
$wp_admin_bar->add_menu( array( 'id' => 'akismet', 'title' => $queue_text, 'href' => admin_url( $link ) ) );
} else
return;
}
function sf_admin_bar() {
// Les autres boutons et menus
add_action( 'admin_bar_menu', 'wp_admin_bar_akismet', 75 );
}
Dernier détail, WordPress n’a pas prévu que nous pourrions avoir besoin de rajouter un bouton ayant le même style que celui des mises à jour (avec le nombre dans un rond blanc). Il faut donc rajouter un peu de mise en forme dans le fichier css de votre thème :
123
/* ----------------------------------------------------------------------------- Admin Bar ------------------------------ */
#wpadminbar .quicklinks a span#ab-akismet{background:#eee;color:#333;text-shadow:none;display:inline;padding:2px 5px;font-size:10px;font-weight:bold;-moz-border-radius:10px;-khtml-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;}
#wpadminbar .quicklinks a:hover span#ab-akismet{background:#fff;color:#000;}
Résultat :
Touche finale
Il reste encore une chose que l’on peut modifier : la recherche à droite de la barre. En effet, elle a un truc qui me gène, elle n’est pas valide XHTML 1.0 Strict car les 2 inputs sont directement dans la balise form. Il faudrait englober ces 2 inputs dans une div pour avoir une page valide. Là, la méthode est différente car ce sont les fonctions render()
et wp_admin_bar_render()
qui gèrent l’affichage de ce formulaire. On va donc les copier, les modifier, et créer les hooks :
01020304050607080910111213141516171819202122232425262728293031323334353637
function sf_render() {
global $wp_admin_bar; ?>
<div id="wpadminbar">
<div class="quicklinks">
<ul>
<?php foreach ( (array) $wp_admin_bar->menu as $id => $menu_item ) : ?>
<?php $wp_admin_bar->recursive_render( $id, $menu_item ) ?>
<?php endforeach; ?>
</ul>
</div>
<div id="adminbarsearch-wrap">
<form action="<?php echo home_url(); ?>" method="get" id="adminbarsearch">
<div>
<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />
<input type="submit" class="adminbar-button" value="<?php _e('Search'); ?>"/>
</div>
</form>
</div>
</div>
<?php
$wp_admin_bar->menu = null;
}
function wp_admin_bar_sf_render() {
global $wp_admin_bar;
if ( ! is_admin_bar_showing() || ! is_object( $wp_admin_bar ) )
return false;
$wp_admin_bar->load_user_locale_translations();
do_action_ref_array( 'admin_bar_menu', array( &$wp_admin_bar ) );
do_action( 'wp_before_admin_bar_render' );
sf_render();
do_action( 'wp_after_admin_bar_render' );
$wp_admin_bar->unload_user_locale_translations();
}
remove_action( 'wp_footer', 'wp_admin_bar_render', 1000 );
remove_action( 'admin_footer', 'wp_admin_bar_render', 1000 );
add_action( 'wp_footer', 'wp_admin_bar_sf_render', 1000 );
add_action( 'admin_footer', 'wp_admin_bar_sf_render', 1000 );
Nous avons donc crée la fonction sf_render()
qui est identique à render()
, on y a juste rajouté la div nécessaire. Pour l’appeler, nous avons eu besoin de créer wp_admin_bar_sf_render()
. Dans les fonctions originales, on voit apparaitre des $this->
, ils font référence à la classe php de l’admin bar. Comme nous ne sommes pas dans cette classe, il est nécessaire de les remplacer par des $wp_admin_bar->
et de déclarer cette variable en global en début de fonction. Il n’y a que $this->render()
qui devient tout simplement sf_render()
car notre fonction ne fait pas partie de la classe de l’admin bar.
Il ne reste plus qu’à annuler les actions par défaut avec remove_action()
et ajouter les nôtres avec add_action()
.
Et voilà
Il ne vous reste plus qu’à trouver d’autres idées pour personnaliser votre Admin Bar.
Commentaires
Commentaire de Chris.
Bonsoir Greg,
Je suis novice avec wordpress car je publies des articles de mode depuis 2008 et en voulant changer d’apparence j’ai ce message qui apparaît :
Fatal error: Cannot instantiate non-existent class: twenty_eleven_ephemera_widget in /…blablabla…/widgets.php on line 320
En suite j’ai essayé de repartir de zero même en perdant mes article j’ai reçus un nouveau code d’accès mais voilà le nouveau message qui s’affiche :
Vous n’avez pas les droits suffisants pour accéder à cette page
Je ne sais plus trop quoi faire… Pourrais tu me conseiller à ce sujet ???
On te remerciant d’avance.
[edit Greg] Modification du chemin de l’erreur, info qui ne devrait pas trainer en clair sur le net pour des raisons sécurité.
Commentaire de Greg.
Bonsoir Chris.
Pour le premier message il semblerait que WP essaie d’initier un widget qui n’existe pas.
Pour le deuxième cela veut tout et rien dire à la fois (causes très diverses).
Peux-tu me donner plus d’infos sur ce que tu as fait? Sans ça je ne pourrais pas t’aider davantage.
Commentaire de Chris.
Bonsoir Greg,
Pour le deuxième j’ai voulu me reprendre mon blog à zero car il y a un message d’erreur fatal qui s’affiche et je crois avoir perdu le contenu de mon blog je sais vraiment pas quoi faire…
Pour le deuxième voilà les message et code d’accès que j’ai reçu de mon serveur ovh avec deus nouveau code d’accès mais qui ne marchent pas :
Bonjour,
L’installation du module WordPress3 pour le domaine thefashionworld.fr a eu lieu
avec succès.
Vous pouvez vous y connecter avec ces paramètres :
…
—————————————————————————————————————————-
Bonjour,
L’installation du module WordPress3 pour le domaine thefashionworld.fr a eu lieu
avec succès.
Vous pouvez vous y connecter avec ces paramètres :
…
[edit Greg] Sérieux? Login et mot de passe admin en clair sur le net?
Commentaire de Greg.
Bonjour, si le thème est vierge, on pourrait tenter de remettre à zéro les droits de tous les utilisateurs.
Créer un fichier « userrole.php » (ou autre chose) et y coller ceci :
123456
Enregistrer le fichier et l’uploader à la racine du site.
Appeler le fichier en allant à l’adresse http://www.monsite.com/userrole.php avec le navigateur. Résultat : une page blanche, normal.
Retenter de se connecter à l’administration et voir si cela a fonctionné.
Ce que fait le script : tous les rôles (administrateur, éditeur, etc.) sont stockés dans le champs de la base de données, le script va effacer ce champs avec delete_option( ), puis le recréer et le remplir correctement avec populate_roles( ) (comme le fait WordPress à l’installation).
Dernier point : supprimer le fichier « userrole.php ».
A part ça, je ne vois pas d’autre solution.
Commentaire de Fred Amorin.
Hello,
Ton site est vraiment trop cool et tu expliques trop bien ça change par rapport aux sites américains et autres…
J’ai créé un site sous wordpress. J’ai utilisé « User Role Editor » pour gérer les rôles car en tant qu’administrateur, je voudrais donner à « l’Editeur », la possibilité de créer des profils « abonnés » depuis le panneau de bord. Mais je n’arrive pas parce qu’il me semble que l’Editeur devrait avoir le statut d’amin, ce que je ne dois pas faire.
Après maintes recherches sans succès, auras-tu une idée de comment s’y prendre avec une fonction par hasard?
Et comment faire apparaitre la rubrique « Pages » sur son tableau de bord. Là non plus, aucun moyen.
Merci d’avance
Commentaire de Vince.
Bonsoir Greg,
Je tenais à te dire que ton site est tout simplement magnifique graphiquement. ;)
T’as jamais pensé à créer des thèmes sur Themeforest par exemple ?
Cordialement
Commentaire de Greg.
Salut Vince.
Faire des thèmes pour Themeforest… Non, je n’y ai jamais pensé et ça ne risque pas d’arriver.
1- Déjà je n’arrive pas à comprendre que l’on puisse avoir comme métier de faire des sites, et à côté, faire des thèmes sur Themeforest ou autres.
2- Quand je vois la qualité inacceptable de certains thèmes, je me dis que non, je n’ai pas du tout envie d’aller sur ce terrain.
Merci pour le compliment en tout cas :)
A bientôt.
Commentaire de Thierry4598.
Bonjour, j’ai quelques questions sur la suppression du bouton. Je ne suis pas profane en la matière mais je me débrouille un peu. Pouvez-vous me dire à quel ligne colle le code :
123456
et aussi quel est la ligne à supprimer :
1234
Je souhaite aussi garder uniquement le widget « moteur de recherche »
Merci de votre aide et bravo pour votre travail
Cordialement
Thierry
Commentaire de Greg.
Bonsoir Thierry.
Pour les widgets il y a justement une discussion récente dans les commentaires de cette article.
Pour le reste j’avoue ne pas comprendre votre question.
A+
Commentaire de Blaxxx.
Ce site est tout simplement une oeuvre d’art. Chapeau!
Commentaire de Greg.
Thx :)