Contenu principal
Icônes de post formats

Pré-cocher un format d’article selon le type de contenu

Salut. Une petite astuce rapide pour pouvoir en quelques sortes changer le format d’article par défaut selon le type de contenu.
En clair, lorsque l’on est sur la page de création d’un article (ou de tout autre type de contenu supportant les formats), wp-admin/post-new.php, on va filtrer la fonction get_post_format() (enfin, presque).

Edith
Le sujet initial de l’article était de simplement assigner une valeur par défaut au format d’article, mais comme le fait remarquer Jeremy dans les commentaires, il existe déjà une option dans les réglages de WordPress pour désigner un format par défaut. Réglage que j’ai joyeusement oublié, n’utilisant pas les formats moi-même. Le seul intérêt restant à mon code est donc limité : pouvoir choisir une valeur différente selon le type de contenu. L’article est donc modifié en conséquence.

Article original
Pour cet exemple, on va considérer qu’on a un type de contenu « Évènements » (« event ») et nous voulons le format vidéo par défaut, alors que nous avons indiqué autre-chose dans les réglages de WordPress (Réglages >> Écriture).
Comme d’habitude, le code est à mettre dans le fichier functions.php de votre thème :

010203040506070809101112131415161718192021222324252627282930
add_action( 'admin_head-post-new.php', 'sf_default_post_format' );
function sf_default_post_format() {
	global $typenow, $post_ID;
	if ( $typenow != 'event' || !post_type_supports( $typenow, 'post-formats' ) )
		return;
	if ( $post_ID ) {
		sf_cache_data( 'def_format_post_ID', $post_ID );
		add_filter( 'get_the_terms', 'sf_default_post_format_filter', 10, 3 );
	}
}


function sf_default_post_format_filter( $terms, $post_ID, $taxonomy ) {
	if ( $taxonomy == 'post_format' && $post_ID && $post_ID == sf_cache_data( 'def_format_post_ID' ) ) {
		return array(
			(object) array( 'slug' => 'post-format-video' )
		);
	}
	return $terms;
}


if ( !function_exists('sf_cache_data') ):
function sf_cache_data( $key, $data = null ) {
	static $datas = array();
	if ( !is_null($data) )
		$datas[$key] = $data;
	return isset($datas[$key]) ? $datas[$key] : null;
}
endif;

En fait on ne va pas filtrer get_post_format() directement, car cette fonction ne dispose pas de hook, on filtre get_the_terms() à la place (car oui, les formats sont une taxonomie, et pas une meta comme on pourrait le penser au premier abord).

Pour cela on lance d’abord une action sur 'admin_head-post-new.php' afin de se placer dans le header de wp-admin/post-new.php (si on utilise un hook qui arrive trop tôt, les variables globales $typenow ou $post_ID pourront être vides). Là on vérifie d’abord que le type de post est bien « event » et qu’il supporte les formats.
Ensuite on utilise un de mes petits utilitaires : sf_cache_data(), c’est une fonction qui me permet de mettre temporairement des données en cache sans passer par une variable globale (qui pourrait être interceptée par un plugin -ou la NSA- et modifiée). Lorsque je fournis une clé et une valeur, cette dernière est mise en cache. Si je ne fournis que la clé, la valeur n’est pas changée mais simplement retournée. Pratique pour véhiculer une valeur entre deux fonctions.
Ici, on met donc l’ID du post en cache, il nous sera utile dans la fonction qui va filtrer get_the_terms(). Filtre que nous lançons d’ailleurs à la ligne suivante.

Dans la fonction sf_default_post_format_filter() on vérifie d’abord que la taxonomie en question est bien 'post_format' (il faudrait pas filtrer les tags ou les catégories hein), et on vérifie l’ID du post, que l’on compare à celui que l’on a mis en cache. Si ça colle, on retourne donc un tableau contenant un faux terme de taxonomie. Le terme ne contiendra qu’une seule information, celle utilisée par get_post_format().

Avantage de la méthode : on ne fait pas que cocher la case, on « change » la valeur du format, donc si le thème ou un plugin prévoit une interface spéciale pour les formats d’articles c’est tout bon, elle se « déclenchera » aussi.
Inconvénient de la méthode : comme on filtre get_the_terms(), si le thème ou un plugin utilise directement get_the_terms($post->ID, 'post_format') pour une raison quelconque, on va casser un truc quelque part et déclencher certainement des notices php, puisqu’on ne retourne pas un vrai terme de taxonomie. Si le problème se présente il faudrait peut-être fournir plus d’informations dans notre objet (le term_id, le label, la taxonomie, etc) et voir si ça passe.

See ya! :)

Edith
Allez, la même avec une classe php pour faire plaisir à l’ami Ricoré Julio dans les coms (et aussi parce que c’est plus simple, mais il ne faut pas lui dire) :)

01020304050607080910111213141516171819202122232425
add_action( 'admin_head-post-new.php', array( 'SF_Def_PF', 'init' ) );

class SF_Def_PF {
	static $post_ID;

	static public function init() {
		global $typenow, $post_ID;
		if ( $typenow != 'event' || !post_type_supports( $typenow, 'post-formats' ) )
			return;
		if ( $post_ID ) {
			self::$post_ID = $post_ID;
			add_filter( 'get_the_terms', array( __CLASS__, 'filter' ), 10, 3 );
		}
	}


	static public function filter( $terms, $post_ID, $taxonomy ) {
		if ( $taxonomy == 'post_format' && $post_ID && $post_ID == self::$post_ID ) {
			return array(
				(object) array( 'slug' => 'post-format-image' )
			);
		}
		return $terms;
	}
}