Contenu principal
Et les articles deviennent des tableaux

Administration WordPress : changer les labels des articles

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 » ;)

Et les articles deviennent des tableaux

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!