Cómo usar taxonomías en adjuntos con la nueva Biblioteca Multimedia
WordPress 3.5 cambió la gestión de medios y ahora la pantalla de edición de la Biblioteca Multimedia utiliza la interfaz de tipo de publicación predeterminada. Las taxonomías son muy útiles para instalaciones de WP con diferentes usuarios y archivos adjuntos, ofreciendo más posibilidades para encontrar el archivo y/o añadir clasificación.
He visto ¿Puedo añadir un Metabox de Categoría a los adjuntos? en WPSE, pero no es perfecto para usar con WP 3.5 y tampoco tiene información sobre el uso de categorías personalizadas en adjuntos, no solo las categorías de las publicaciones.
En resumen: ¿es posible añadir categorías/etiquetas personalizadas a adjuntos para usar en la Biblioteca Multimedia con WP 3.5?

Para añadir las taxonomías del tipo de entrada 'post' (el predeterminado), entonces es fácil añadir las taxonomías 'category' y 'tags' con un pequeño plugin como el código fuente a continuación.
<?php
/**
* Plugin Name: Attachment Taxonomies
* Plugin URI:
* Text Domain: attachment_taxonomies
* Domain Path: /languages
* Description:
* Version: 1.0.0
* Author: Frank Bültge
* Author URI: http://bueltge.de
* License: GPLv3
*/
add_action( 'init', 'fb_attachment_taxonomies' );
function fb_attachment_taxonomies() {
$taxonomies = array( 'category', 'post_tag' ); // añadir las 2 taxonomías a ...
foreach ( $taxonomies as $tax ) {
register_taxonomy_for_object_type( $tax, 'attachment' ); // añadir al tipo de entrada 'attachment'
}
}
Para usar taxonomías personalizadas en adjuntos es importante que crees una taxonomía personalizada y la asignes al tipo de entrada attachment
, como en el siguiente plugin.
<?php
/**
* Plugin Name: Attachment Taxonomies
* Plugin URI:
* Text Domain: attachment_taxonomies
* Domain Path: /languages
* Description:
* Version: 1.0.0
* Author: Frank Bültge
* Author URI: http://bueltge.de
* License: GPLv3
*/
if ( function_exists( 'add_filter' ) )
add_action( 'plugins_loaded', array( 'Fb_Attachment_Taxonomies', 'get_object' ) );
/**
* Añadir taxonomías de Tags y Categories a Attachment con WP 3.5
*/
class Fb_Attachment_Taxonomies {
static private $classobj;
/**
* Constructor, inicializa las funciones dentro de WP
*
* @since 1.0.0
* @return void
*/
public function __construct() {
// cargar archivos de traducción
add_action( 'admin_init', array( $this, 'localize_plugin' ) );
// añadir taxonomías
add_action( 'init', array( $this, 'setup_taxonomies' ) );
}
/**
* Manejador para la acción 'init'. Instancia esta clase.
*
* @since 1.0.0
* @access public
* @return $classobj
*/
public function get_object() {
if ( NULL === self::$classobj ) {
self::$classobj = new self;
}
return self::$classobj;
}
/**
* Función para localizar el plugin.
*
* @uses load_plugin_textdomain, plugin_basename
* @since 2.0.0
* @return void
*/
public function localize_plugin() {
load_plugin_textdomain(
'attachment_taxonomies',
FALSE,
dirname( plugin_basename( __FILE__ ) ) . '/languages/'
);
}
/**
* Configurar Taxonomías
* Crea las taxonomías 'attachment_tag' y 'attachment_category'.
* Mejorable mediante el filtro `fb_attachment_taxonomies`
*
* @uses register_taxonomy, apply_filters
* @since 1.0.0
* @return void
*/
public function setup_taxonomies() {
$attachment_taxonomies = array();
// Tags
$labels = array(
'name' => _x( 'Etiquetas de Medios', 'taxonomy general name', 'attachment_taxonomies' ),
'singular_name' => _x( 'Etiqueta de Medio', 'taxonomy singular name', 'attachment_taxonomies' ),
'search_items' => __( 'Buscar Etiquetas de Medios', 'attachment_taxonomies' ),
'all_items' => __( 'Todas las Etiquetas de Medios', 'attachment_taxonomies' ),
'parent_item' => __( 'Etiqueta de Medio Padre', 'attachment_taxonomies' ),
'parent_item_colon' => __( 'Etiqueta de Medio Padre:', 'attachment_taxonomies' ),
'edit_item' => __( 'Editar Etiqueta de Medio', 'attachment_taxonomies' ),
'update_item' => __( 'Actualizar Etiqueta de Medio', 'attachment_taxonomies' ),
'add_new_item' => __( 'Añadir Nueva Etiqueta de Medio', 'attachment_taxonomies' ),
'new_item_name' => __( 'Nombre de Nueva Etiqueta de Medio', 'attachment_taxonomies' ),
'menu_name' => __( 'Etiquetas de Medios', 'attachment_taxonomies' ),
);
$args = array(
'hierarchical' => FALSE,
'labels' => $labels,
'show_ui' => TRUE,
'show_admin_column' => TRUE,
'query_var' => TRUE,
'rewrite' => TRUE,
);
$attachment_taxonomies[] = array(
'taxonomy' => 'attachment_tag',
'post_type' => 'attachment',
'args' => $args
);
// Categories
$labels = array(
'name' => _x( 'Categorías de Medios', 'taxonomy general name', 'attachment_taxonomies' ),
'singular_name' => _x( 'Categoría de Medio', 'taxonomy singular name', 'attachment_taxonomies' ),
'search_items' => __( 'Buscar Categorías de Medios', 'attachment_taxonomies' ),
'all_items' => __( 'Todas las Categorías de Medios', 'attachment_taxonomies' ),
'parent_item' => __( 'Categoría de Medio Padre', 'attachment_taxonomies' ),
'parent_item_colon' => __( 'Categoría de Medio Padre:', 'attachment_taxonomies' ),
'edit_item' => __( 'Editar Categoría de Medio', 'attachment_taxonomies' ),
'update_item' => __( 'Actualizar Categoría de Medio', 'attachment_taxonomies' ),
'add_new_item' => __( 'Añadir Nueva Categoría de Medio', 'attachment_taxonomies' ),
'new_item_name' => __( 'Nombre de Nueva Categoría de Medio', 'attachment_taxonomies' ),
'menu_name' => __( 'Categorías de Medios', 'attachment_taxonomies' ),
);
$args = array(
'hierarchical' => TRUE,
'labels' => $labels,
'show_ui' => TRUE,
'query_var' => TRUE,
'rewrite' => TRUE,
);
$attachment_taxonomies[] = array(
'taxonomy' => 'attachment_category',
'post_type' => 'attachment',
'args' => $args
);
$attachment_taxonomies = apply_filters( 'fb_attachment_taxonomies', $attachment_taxonomies );
foreach ( $attachment_taxonomies as $attachment_taxonomy ) {
register_taxonomy(
$attachment_taxonomy['taxonomy'],
$attachment_taxonomy['post_type'],
$attachment_taxonomy['args']
);
}
}
} // fin de la clase
Mira el resultado en la siguiente captura de pantalla, también la diferencia - más fácil que mis pequeñas palabras sobre el código. Pero la imagen de mi persona en el ejemplo de la captura no es relevante para el código ;)
Pequeñas pistas: la interfaz de usuario del cuadro modal para añadir medios en el tipo de entrada es un poco diferente a la pantalla de edición del tipo de entrada 'attachment'. Las taxonomías jerárquicas solo tienen un árbol en la pantalla de edición. En el cuadro modal es un campo de entrada y la taxonomía funciona con coma como separador. Ver también este post de Helen en el blog de WP Core. Pero mira las taxonomías personalizadas para 'tags' y 'categories' también en una captura de pantalla.

+1+ Un paso más en el descubrimiento de Media Library 3.5, ¡el gran desconocido de 2012!

Sí, tienes razón. Me gusta este parámetro en WP 3.6; lo uso frecuentemente con una pequeña clase auxiliar, cuando uso muchas taxonomías: https://github.com/bueltge/WP-Control-Taxonomy

Frank, no olvides que para las taxonomías de adjuntos, probablemente deberías establecer update_count_callback
como _update_generic_term_count
. Consulta la entrada actualizada del Codex para saber por qué: http://codex.wordpress.org/Function_Reference/register_taxonomy#Arguments

Extenderé la respuesta de Frank con Agregar un Filtro de Taxonomía a la Lista de Administración para un Tipo de Entrada Personalizado
Buscando ambas cosas, Categorías de Medios y Filtro de Taxonomía, combiné el código de Frank con la respuesta de Kaiser en esa publicación. También agregué un toque adicional mío para agregar el tipo de publicación, donde se subió el adjunto, como una Categoría.
Produce esto:
add_action(
'plugins_loaded',
array ( WPSE76720_Attachment_Taxonomies::get_object(), 'plugin_setup' )
);
// BUELTGE/KAISER/RUDOLF
class WPSE76720_Attachment_Taxonomies
{
protected static $instance = NULL;
public $post_type;
public $taxonomies;
/**
* Usado para el trabajo regular del plugin.
*
* @wp-hook plugins_loaded
* @return void
*/
public function plugin_setup()
{
// Filtro de taxonomías
add_action( 'load-upload.php', array( $this, 'setup' ) );
// agregar taxonomías
add_action( 'init', array( $this, 'setup_taxonomies' ) );
add_action( 'add_attachment', array( $this, 'auto_tax' ), 10, 2 );
}
/**
* Constructor, inicializa las funciones dentro de WP
*
* @since 1.0.0
* @return void
*/
public function __construct() {}
/**
* Manejador para la acción 'init'. Instancia esta clase.
*
* @since 1.0.0
* @access public
* @return $instance
*/
public function get_object()
{
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
/**
* Configurar Taxonomías
* Crea las taxonomías 'attachment_tag' y 'attachment_category'.
* Mejora mediante el filtro `fb_attachment_taxonomies`
*
* @uses register_taxonomy, apply_filters
* @since 1.0.0
* @return void
*/
public function setup_taxonomies()
{
$attachment_taxonomies = array();
// Categorías
$labels = array(
'name' => __( 'Categorías de Medios', 'b5f-mc' ),
'singular_name' => __( 'Categoría de Medio', 'b5f-mc' ),
'search_items' => __( 'Buscar Categorías de Medios', 'b5f-mc' ),
'all_items' => __( 'Todas las Categorías de Medios', 'b5f-mc' ),
'parent_item' => __( 'Categoría de Medio Padre', 'b5f-mc' ),
'parent_item_colon' => __( 'Categoría de Medio Padre:', 'b5f-mc' ),
'edit_item' => __( 'Editar Categoría de Medio', 'b5f-mc' ),
'update_item' => __( 'Actualizar Categoría de Medio', 'b5f-mc' ),
'add_new_item' => __( 'Agregar Nueva Categoría de Medio', 'b5f-mc' ),
'new_item_name' => __( 'Nombre de Nueva Categoría de Medio', 'b5f-mc' ),
'menu_name' => __( 'Categorías de Medios', 'b5f-mc' ),
);
$args = array(
'hierarchical' => TRUE,
'labels' => $labels,
'show_admin_column' => TRUE,
'show_ui' => TRUE,
'query_var' => TRUE,
'rewrite' => TRUE,
);
$attachment_taxonomies[] = array(
'taxonomy' => 'attachment_category',
'post_type' => 'attachment',
'args' => $args
);
$attachment_taxonomies = apply_filters( 'fb_attachment_taxonomies', $attachment_taxonomies );
foreach ( $attachment_taxonomies as $attachment_taxonomy ) {
register_taxonomy(
$attachment_taxonomy['taxonomy'],
$attachment_taxonomy['post_type'],
$attachment_taxonomy['args']
);
}
}
public function setup()
{
add_action( current_filter(), array( $this, 'setup_vars' ), 20 );
add_action( 'restrict_manage_posts', array( $this, 'get_select' ) );
add_filter( "manage_taxonomies_for_attachment_columns", array( $this, 'add_columns' ) );
}
public function setup_vars()
{
$this->post_type = 'attachment';
$this->taxonomies = get_object_taxonomies( $this->post_type );
}
public function add_columns( $taxonomies )
{
return array_merge(
$taxonomies
,$this->taxonomies
);
}
public function get_select()
{
$walker = new WCMF_walker;
foreach ( $this->taxonomies as $tax )
{
wp_dropdown_categories( array(
'taxonomy' => $tax
,'hide_if_empty' => false
,'show_option_all' => sprintf(
get_taxonomy( $tax )->labels->all_items
)
,'hide_empty' => false
,'hierarchical' => is_taxonomy_hierarchical( $tax )
,'show_count' => false
,'orderby' => 'name'
,'selected' => '0' !== get_query_var( $tax )
? get_query_var( $tax )
: false
,'name' => $tax
,'id' => $tax
,'walker' => $walker
) );
}
}
/**
* Agrega el tipo de publicación padre como una categoría de adjunto
*
* @author Rodolfo Buaiz
*/
public function auto_tax( $post_id )
{
$the_p = get_post( $post_id );
if( $the_p->post_parent > 0 )
{
$cpt = get_post_type( $the_p->post_parent );
$term = term_exists( $cpt, 'attachment_category' );
if( !$term )
$term = wp_insert_term( $cpt, 'attachment_category' );
wp_set_post_terms( $post_id, $term['term_id'], 'attachment_category', true );
}
}
} // fin BUELTGE/KAISER/RUDOLF
// KAISER
class WCMF_walker extends Walker_CategoryDropdown
{
var $tree_type = 'category';
var $db_fields = array(
'parent' => 'parent'
,'id' => 'term_id'
);
public $tax_name;
/**
* @see Walker::start_el()
* @param string $output Pasado por referencia. Usado para agregar contenido adicional.
* @param object $term Objeto de datos de término de taxonomía.
* @param int $depth Profundidad de la categoría. Usado para relleno.
* @param array $args Usa las claves 'selected' y 'show_count', si existen.
* @param int $id
* @return void
*/
function start_el( &$output, $term, $depth, $args, $id = 0 )
{
$pad = str_repeat( ' ', $depth * 3 );
$cat_name = apply_filters( 'list_cats', $term->name, $term );
$output .= sprintf(
'<option class="level-%s" value="%s" %s>%s%s</option>'
,$depth
,$term->slug
,selected(
$args['selected']
,$term->slug
,false
)
,"{$pad}{$cat_name}"
,$args['show_count']
? " ({$term->count})"
: ''
);
}
}
// fin KAISER

Mi plugin Media Categories puede hacer esto por ti - incluso limpia la interfaz en el Modal de Medios para que sigas obteniendo la lista de casillas de verificación, ya que por defecto solo obtendrás campos de texto.
