Mediaception

Médiaception

L'image à la une pour un média ? C'est possible.

1
2
3
4
5
add_action( 'init', 'sf_post_type_supports' );

function sf_post_type_supports() {
	add_post_type_support( 'attachment', 'thumbnail' );
}

Oui, tout simplement.
Utilité ? C'est vrai que c'est pas flagrant. On pourrait s'en servir comme jaquette pour un fichier audio, ou comme preview pour un fichier vidéo.
Du coup, on pourrait limiter le support de l'image à la une aux fichiers audio et vidéo.

1
2
3
4
5
6
add_action( 'init', 'sf_post_type_supports' );

function sf_post_type_supports() {
	add_post_type_support( 'attachment:audio', 'thumbnail' );
	add_post_type_support( 'attachment:video', 'thumbnail' );
}

Et... c'est presque ça. En théorie ça marche (la Théorie est un beau pays, j'aimerais y vivre un jour, car en Théorie tout se passe bien).
Le support est bien activé et la metabox dans la page d'édition d'un média audio ou vidéo (et pas les autres) est bien disponible. Seulement voilà, tout ne marche pas comme prévu, la fenêtre pour choisir son image ne s'affiche pas en "modale", on est redirigé vers la page d'upload.
Le problème est lié aux fonctions post_type_supports() et current_theme_supports() qui, dans le core de WordPress sont utilisées seulement avec 'attachment' et non avec 'attachment:audio' et 'attachment:video'.
Il faut donc ajouter quelques petites choses. D'abord je vais définir deux fonctions "outil" qui me seront utiles. La première est un raccourcis qui indiquera si le média est un fichier audio ou vidéo. La seconde est une sorte de post_type_supports() qui tient compte du mime en gros.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if ( !function_exists('post_mime_type_is_audio_or_video') ):
function post_mime_type_is_audio_or_video( $post ) {
	return $post->post_type == 'attachment' && !empty($post->post_mime_type) && ( 0 === strpos( $post->post_mime_type, 'audio/' ) || 0 === strpos( $post->post_mime_type, 'video/' ) );
}
endif;


if ( !function_exists('post_mime_type_supports_thumbnail') ):
function post_mime_type_supports_thumbnail( $post ) {
	if ( 'attachment' !== $post->post_type || empty( $post->post_mime_type ) )
		return false;

	$mime = reset((explode('/', $post->post_mime_type)));
	return (current_theme_supports( 'post-thumbnails', 'attachment' ) || current_theme_supports( 'post-thumbnails', 'attachment:'.$mime )) && post_type_supports( 'attachment:'.$mime, 'thumbnail' ) && !post_type_supports( 'attachment', 'thumbnail' );
}
endif;

Et maintenant il nous faut ajouter les scripts javascripts nécessaires pour la fenêtre modale.

1
2
3
4
5
6
7
8
add_action( 'admin_enqueue_scripts', 'sf_attachment_add_media_editor_js' );
function sf_attachment_add_media_editor_js( $hook_suffix ) {
	global $typenow, $post;
	if ( $hook_suffix == 'post.php' && $typenow == 'attachment' && post_mime_type_is_audio_or_video( $post ) && post_mime_type_supports_thumbnail( $post ) ) {
		add_thickbox();
		wp_enqueue_media( array( 'post' => $post ) );
	}
}

Attention, wp_enqueue_media() est disponible dans WordPress depuis la version 3.5 seulement.

Fini ? Non, pas tout à fait, il y a encore un bug.
À ce stade on arrive bien à ouvrir la fenêtre modale pour sélectionner l'image, mais au début de la liste il y a une image "vide", et si auparavant on a déjà choisi une image à la une, elle ne sera pas sélectionnée (c'était sensée être l'image vide justement).
Pour comprendre ce qui se passe il faut comprendre un peu le fonctionnement de la fenêtre, comment elle se rempli.
Lorsque l'on ouvre cette fenêtre modale pour la première fois, ce n'est pas un appel ajax qui est fait pour la remplir d'images, mais plusieurs.
Le premier appel va aller chercher l'image actuellement à la une. Les suivants iront chercher toutes les autres images par paquets de 50. Notre problème actuel est le premier appel qui ne se fait pas, car une variable javascript n'est pas imprimée dans la page.
La solution est donc toute simple (car il y a bien sûr le filtre kivabien) : ajouter un filtre depuis ma précédente fonction sf_attachment_add_media_editor_js() et ajouter cette variable dans la page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
add_action( 'admin_enqueue_scripts', 'sf_attachment_add_media_editor_js' );
function sf_attachment_add_media_editor_js( $hook_suffix ) {
	global $typenow, $post;
	if ( $hook_suffix == 'post.php' && $typenow == 'attachment' && post_mime_type_is_audio_or_video( $post ) && post_mime_type_supports_thumbnail( $post ) ) {
		add_filter( 'media_view_settings', 'sf_attachment_view_settings', 10, 2 );
		add_thickbox();
		wp_enqueue_media( array( 'post' => $post ) );
	}
}


function sf_attachment_view_settings( $settings, $post ) {
	if ( post_mime_type_is_audio_or_video( $post ) && post_mime_type_supports_thumbnail( $post ) ) {
		$featured_image_id = get_post_meta( $post->ID, '_thumbnail_id', true );
		$settings['post']['featuredImageId'] = $featured_image_id ? $featured_image_id : -1;
	}
	return $settings;
}

Le code complet pour cette seconde partie :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
add_action( 'init', 'sf_post_type_supports' );

function sf_post_type_supports() {
	add_post_type_support( 'attachment:audio', 'thumbnail' );
	add_post_type_support( 'attachment:video', 'thumbnail' );
}


add_action( 'admin_enqueue_scripts', 'sf_attachment_add_media_editor_js' );
function sf_attachment_add_media_editor_js( $hook_suffix ) {
	global $typenow, $post;
	if ( $hook_suffix == 'post.php' && $typenow == 'attachment' && post_mime_type_is_audio_or_video( $post ) && post_mime_type_supports_thumbnail( $post ) ) {
		add_filter( 'media_view_settings', 'sf_attachment_view_settings', 10, 2 );
		add_thickbox();
		wp_enqueue_media( array( 'post' => $post ) );
	}
}


function sf_attachment_view_settings( $settings, $post ) {
	if ( post_mime_type_is_audio_or_video( $post ) && post_mime_type_supports_thumbnail( $post ) ) {
		$featured_image_id = get_post_meta( $post->ID, '_thumbnail_id', true );
		$settings['post']['featuredImageId'] = $featured_image_id ? $featured_image_id : -1;
	}
	return $settings;
}


if ( !function_exists('post_mime_type_is_audio_or_video') ):
function post_mime_type_is_audio_or_video( $post ) {
	return $post->post_type == 'attachment' && !empty($post->post_mime_type) && ( 0 === strpos( $post->post_mime_type, 'audio/' ) || 0 === strpos( $post->post_mime_type, 'video/' ) );
}
endif;


if ( !function_exists('post_mime_type_supports_thumbnail') ):
function post_mime_type_supports_thumbnail( $post ) {
	if ( 'attachment' !== $post->post_type || empty( $post->post_mime_type ) )
		return false;

	$mime = reset((explode('/', $post->post_mime_type)));
	return (current_theme_supports( 'post-thumbnails', 'attachment' ) || current_theme_supports( 'post-thumbnails', 'attachment:'.$mime )) && post_type_supports( 'attachment:'.$mime, 'thumbnail' ) && !post_type_supports( 'attachment', 'thumbnail' );
}
endif;

See ya!

Geoffrey
13
déc
2013
@15:12

Hello,

Pratique, ça peut même permettre de sortir une thumbnail pour une vidéo dans le cadre d'une microdata exploitable pour les résultats de recherche dans Google.

Merci pour ce partage Greg :)

#
Greg
13
déc
2013
@19:06

Anéfé :)

"En réponse à Geoffrey"Répondre
#

Salutations, étranger.

Envie d'un avatar?
Gravatar
Do not fill the next field
:D :lol: :) ;) :P 8) :roll: :( :cry: :oops: :? :| :o 8O :x :twisted: :evil: :mrgreen:

.

Afficher le panneau des Smilies:D   Afficher le panneau des balises html utilisables Balises
Vous pouvez utiliser ces balises:
<b></b> <i></i> <del></del> <a href=""></a> <abbr title=""></abbr> <cite></cite> <code></code> <pre lang="" line=""></pre>
Exemples pour "pre": lang="css", "html", "javascript", "jquery", "php", "sql"... (ou laisser vide)