Vous réalisez un blog avec WordPress et ce que l’auteur compte publier régulièrement ne sont pas des articles mais autre chose, comme des tableaux pour un blog d’artiste peintre par exemple. Vous avez le soucis du détail et vous voulez simplifier la vie de l’auteur en « transformant » les articles en tableaux? C’est possible, et sans avoir recours à un CPT.
Voilà une situation qui peut parfois arriver (quoi, qui a dit que c’est justement ce sur quoi je bosse en ce moment?!), l’idée principale du blog que vous êtes en train de réaliser n’est pas de publier des articles, mais tout autre chose. Vous me direz, ce n’est qu’un problème d’appellation, et c’est vrai, c’est d’ailleurs seulement à ce niveau que nous allons jouer : renommer les articles en autre chose. Pour cet exemple les articles vont devenir des tableaux.
Nota : par habitude je travaille toujours avec des textes traduisibles par WordPress, c’est à dire que j’utilise les fonctions __()
, _e()
, _n()
, etc. A vous de voir ensuite si vous ne voulez pas vous embêter et préférez travailler directement en français, sans avoir à jouer avec un fichier .po. Au passage, Canvas veut dire Toile et Canvases est sa forme plurielle (mais je vais prendre un raccourcis et appeler ça « Tableau » ^^).
Les labels
Les types de post d’origine sont construit de la même façon que lorsqu’on ajoute un type de post personnalisé, c’est à dire avec la fonction register_post_type()
(hookée sur « init »). Si vous avez déjà utilisé cette fonction, vous savez sûrement que les labels sont déclarés à ce moment là. Pour les articles, pages, etc, c’est un peu différent car les labels sont par défaut, mais ça ne va pas nous gêner (je voulais juste préciser, je sais, ça sert à rien xD).
Nous avons deux possibilités en fait : faire un hook sur « init » ou sur « registered_post_type » (il s’agit d’une action qui intervient à la fin de la fonction register_post_type()
). Nous allons utiliser « registered_post_type » mais apparemment il n’y a pas de problème à utiliser « init » (à condition de légèrement modifier ce qui va suivre).
Le code que je vais fournir est à rajouter dans le fichier functions.php de votre thème, de préférence dans une condition if ( is_admin() ) { ... }
:
01020304050607080910111213141516171819202122
add_action( 'registered_post_type', 'and_posts_become_canvases', 10, 2 );
function and_posts_become_canvases($post_type, $args) {
if ( $post_type != 'post' )
return;
global $wp_post_types;
$wp_post_types['post']->label = _x("Canvases", 'post type general name', 'mon-theme');
$wp_post_types['post']->labels->name = _x("Canvases", 'post type general name', 'mon-theme');
$wp_post_types['post']->labels->singular_name = _x("Canvas", 'post type singular name', 'mon-theme');
// $wp_post_types['post']->labels->add_new = __("Add");
$wp_post_types['post']->labels->add_new_item = __("Add a Canvas", 'mon-theme');
$wp_post_types['post']->labels->edit_item = __("Edit the Canvas", 'mon-theme');
$wp_post_types['post']->labels->new_item = __("New Canvas", 'mon-theme');
$wp_post_types['post']->labels->view_item = __("View Canvas", 'mon-theme');
$wp_post_types['post']->labels->search_items = __("Search in Canvases", 'mon-theme');
$wp_post_types['post']->labels->not_found = __("No Canvases", 'mon-theme');
$wp_post_types['post']->labels->not_found_in_trash = __("No Canvases found in trash", 'mon-theme');
// $wp_post_types['post']->labels->parent_item_colon = null;
$wp_post_types['post']->labels->all_items = __("All Canvases", 'mon-theme');
$wp_post_types['post']->labels->menu_name = _x("Canvases", 'post type general name', 'mon-theme');
$wp_post_types['post']->labels->name_admin_bar = _x("Canvas", 'post type singular name', 'mon-theme');
}
Ce hook « registered_post_type » nous fournit 2 paramètres : $post_type est (wait for it) le post type en train d’être enregistré, et $args contient des paramètres relatifs à l’enregistrement du type « post ». Nous pourrions avoir l’idée de modifier directement $args et le renvoyer ensuite, mais là nous somme dans un hook de type « action » (utilisation de add_action()
), pas dans un filtre. Donc nous ne pourrons pas modifier directement ce paramètre $args, qui pourtant contient nos labels (d’ailleurs, même avec un filtre on ne pourrait pas, étant donné que $args est placé en second et pas en premier, seul le premier serait alors modifiable).
Nous procédons donc ici autrement.
Mais avant tout, un détail qui a sa petite importance : au début nous vérifions que $post_type est bien égal à « post ». Pourquoi, alors que si on regarde le reste du code, on cible bien les « posts »?
Tout simplement pour éviter de faire cette action à chaque enregistrement d’un type de post. Les changements seront ainsi effectués une seule fois.
Dans la suite du code nous utilisons la variable globale $wp_post_types qui contient toutes les infos de tous les post types, et nous modifions les labels un à un. Vous noterez que j’ai commenté 2 lignes car elles ne nécessitent pas d’être modifiées, mais je les ai laissées pour information.
Voilà, avec ceci, une grande partie de l’administration est « encadrée » ;)
Maaaaiiiis, ce n’est pas tout!
Les messages d’alerte
Ha oui, voilà une chose que nous aurions pu oublier, qu’en est-il des messages « Article publié », ou « Article mis à jour »?
Et bien c’est assez simple quand on connait le bon hook (com’ d’hab’ quoi ^^) :
24252627282930313233343536373839404142434445464748
add_filter( 'post_updated_messages', 'canvas_updated_messages' );
function canvas_updated_messages($messages) {
global $post;
if ( $post->post_type != 'post' )
return $messages;
$post_url = get_permalink($post->ID);
$post_url_esc = esc_url( $post_url );
$post_url_pvw = esc_url( add_query_arg( 'preview', 'true', $post_url ) );
$messages['post'] = array(
0 => '', // Unused. Messages start at index 1.
1 => sprintf( __('Canvas updated. <a href="%s">View canvas</a>', 'mon-theme'), $post_url_esc ),
2 => __('Custom field updated.'),
3 => __('Custom field deleted.'),
4 => __('Canvas updated.', 'mon-theme'),
5 => isset($_GET['revision']) ? sprintf( __('Canvas restored to revision from %s', 'mon-theme'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
6 => sprintf( __('Canvas published. <a href="%s">View canvas</a>', 'mon-theme'), $post_url_esc ),
7 => __('Canvas saved.', 'mon-theme'),
8 => sprintf( __('Canvas submitted. <a target="_blank" href="%s">Preview canvas</a>', 'mon-theme'), $post_url_pvw ),
9 => sprintf( __('Canvas scheduled for: <strong>%s</strong>.', 'mon-theme'), date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ) ),
10 => sprintf( __('Canvas draft updated. <a target="_blank" href="%s">Preview canvas</a>', 'mon-theme'), $post_url_pvw ),
);
return $messages;
}
Là nous filtrons directement les messages s’affichant en haut de l’écran.
Là aussi un détail qui a son importance : Pourquoi vérifier que le type de post affiché est bien « post » alors que l’on modifie uniquement les messages de celui-ci, et pas des autres types?
Parce que lorsque l’on ajoute un type de post personnalisé à WordPress, si on omet la partie concernant les messages (ce qui est très courant), WordPress utilisera les messages par défaut, c’est à dire (roulement de tambours), ceux des articles. Il nous faut donc modifier les messages seulement si le post affiché est réellement de type « post », sinon on va se retrouver avec des tableaux partout x).
Hey, pars pas, on a des récalcitrants !
Et oui mon bon monsieur (ou madame), parfois WordPress n’utilise pas les labels que nous venons de modifier, mais tout simplement __("Post")
. Là on est bien embêtés. C’est le cas du menu latéral, il n’a pas changé. Heureusement nous savons déjà comment modifier ce menu (car bien sûr tu es un lecteur assidu de ce bloc, cher ami).
5051525354555657
add_action('admin_menu', 'sf_admin_menu', 11);
function sf_admin_menu() {
global $menu, $submenu;
if( $menu[5][0] == __('Posts') )
$menu[5][0] = _x('Canvases', 'post type general name', 'mon-theme');
if( $submenu['edit.php'][5][0] == __('All Posts') )
$submenu['edit.php'][5][0] = __('All canvases', 'mon-theme');
}
Bon, je ne pense pas qu’il y ait besoin de commenter cette partie, elle est facilement compréhensible si vous avez un peu l’habitude de mettre les doigts dans votre thème.
Oh, wait! On a encore des articles perdus au milieu du widget « Aujourd’hui » du Dashboard!
Gasp, celui-là va nous ennuyer. En plus d’être résistant à nos viles attaques pour le transformer en tableau, il ne va pas être facile à attraper. En effet, à moins de supprimer le widget et le réécrire derrière, il n’y a pas de solution directe car cette partie est codée « en dur » et ne propose pas de hook à ce niveau.
Nous allons utiliser un peu de maquillage pour camoufler tout ça avec jQuery (je te vois venir Julio avec ton no-js). Petite consolation, nous avons un hook à la fin de ce widget qui va nous permettre d’ajouter une balise <script>
à la fin du widget (et ça tombe bien, jQuery est présent dans le head de l’administration, et pas dans le footer) :
123456
add_action( 'rightnow_end', 'rightnow_end_posts_to_canvas' );
function rightnow_end_posts_to_canvas() {
$num_posts = wp_count_posts( 'post' );
$text = _n( "Canvas", "Canvases", intval($num_posts->publish), 'mon-theme' );
echo 'jQuery(document).ready(function($){$("#dashboard_right_now .posts a").text("'.$text.'");});';
}
Là nous utilisons la fonction _n()
pour offrir une traduction différente selon le nombre de posts (utilisation du singulier et du pluriel donc), et wp_count_posts( 'post' )
va nous servir à récupérer ce nombre de posts. Il ne nous reste plus qu’à insérer le texte au bon endroit avec jQuery.
One more thing, le poney sur le gâteau
Il parait que le diable se cache dans les détails, et je veux bien le croire. Que serait un type de post sans son icône? =D
Allez, nous allons ajouter un peu de css dans le head de l’administration. Je vous laisse construire votre sprite et le positionner correctement avec les valeurs de background et background-position. Avec ça nous changeons l’icône dans le menu (état normal et hover, et celle du titre sur les pages d’édition :
666768697071727374
add_action('admin_head', 'sf_admin_css');
function sf_admin_css() {
$templateurl = get_bloginfo( 'template_directory' );
echo ''
.'#adminmenu #menu-posts div.wp-menu-image{background:transparent url('.$templateurl.'/images/admin/admin-icons.png) 0 -18px no-repeat;}'
.'#adminmenu #menu-posts:hover div.wp-menu-image, #adminmenu #menu-posts.wp-has-current-submenu div.wp-menu-image{background-position:0 6px;}'
.'#icon-edit.icon32-posts-post{background:transparent url('.$templateurl.'/images/admin/admin-icons.png) -30px 0 no-repeat}'
.'';
}
Là je crois que nous avons fait le tour. N’hésitez pas à me signaler des « Articles » récalcitrants si vous en trouvez encore après tout ceci, je verrais si c’est rectifiable et mettrais à jour l’article en conséquence.
See ya!
Commentaires
Commentaire de Wilfrid.
Je me demandais dernièrement si cette modification était possible, c’est parfait,
merci pour le partage.
Commentaire de Roch Daniel.
Honnêtement, bravo. Tes articles sont souvent les plus complets et ciblés dans la communauté WordPress.
La méthode utilisée pour changer le labels a le mérite de ne pas toucher au coeur de WordPress, et va surtout permettre aux développeurs d’adapter l’interface pour que des néophytes d’Internet ou de WP ne soient pas perdu si leurs contenus ne sont pas de réels articles.
Encore bravo. ;)
Commentaire de Greg.
Merci à tous les 2 :]
@Daniel : oui il m’est aussi arrivé de toucher au core quand je débutais sur WordPress, mais on comprend vite que ce n’est pas une solution viable, que l’on doit la réitérer à chaque mise à jour, et qu’on oublie…
Commentaire de Geoffrey @ Geoffrey.Crofte.fr.
Hello,
Super article, comme toujours :)
J’ai une question pour toi, mais à défaut de réponse je testerai les deux solutions.
J’ai trouvé cette méthode qui semble similaire :
http://www.wprecipes.com/how-to-change-the-posts-label-to-articles
Mais peut-être correspond-elle à un « défaut de poney sur le gâteau » :D
As-tu déjà testé ?
Merci :)
Commentaire de Greg.
Hello. Merci :)
Nop, j’ai pas testé cette méthode. Ça a l’air simple et efficace. Le seul problème qui pourrait se poser c’est quand un nouveau CPT n’est pas fourni avec ses labels. Là les labels par défaut sont utilisés et donc…
A part cette petite ombre, la méthode m’a l’air très bien :)
Merci pour le partage :)
Commentaire de Mathias.
Bonjour,
superbe hack bien détaillé !
Question que je me pose après cette possibilité : pourrait-on imaginer dupliquer plusieurs fois la page d’édition d’articles, chacune dédiée à une seule catégorie ?
Et du coup un titre différent à chaque fois.
Commentaire de Greg.
Bonjour Mathias.
Tu parle bien du titre « Modifier l’article » sur la page edit.php avec le bouton ajouter à côté ? (celui ma capture d’écran quoi).
Tu voudrais donc faire quelque chose comme « Modifier le tableau tendance machin » où « tendance machin » serait la catégorie.
A priori oui, ça serait possible. Il faudrait récupérer l’id de l’article via
$_GET['post']
, chopper le nom de sa catégorie, et l’inclure dans$wp_post_types['post']->labels->add_new_item
en conséquence.Idée intéressante :)
Commentaire de Marc Ségur.
Super, merci, génial !
EJ suis régulièrement tes « trucs et astuces sur ton site et, à chaque fois, ca m’eneleve une épine du pied…
complet,clair, bien ecrit et à propos ! bref, merci !
Marc