array( 'name' => 'Animales', 'singular_name' => 'Animal', 'add_new' => 'Añadir animal', 'add_new_item' => 'Añadir nuevo animal', 'edit_item' => 'Editar animal', 'new_item' => 'Nuevo animal', 'view_item' => 'Ver ficha', 'search_items' => 'Buscar animales', 'not_found' => 'No hay animales', 'not_found_in_trash' => 'No hay animales en la papelera', 'all_items' => 'Todos los animales', 'featured_image' => 'Foto principal', 'set_featured_image' => 'Elegir foto principal', 'remove_featured_image' => 'Quitar foto principal', 'use_featured_image' => 'Usar como foto principal', 'excerpt' => 'Frase corta', 'menu_name' => 'Animales', ), 'public' => true, 'has_archive' => 'adopta', 'rewrite' => array( 'slug' => 'adopta', 'with_front' => false ), 'menu_icon' => 'dashicons-pets', 'menu_position' => 5, 'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ), 'show_in_rest' => true, 'rest_base' => 'animals', 'show_in_graphql' => true, 'graphql_single_name' => 'animal', 'graphql_plural_name' => 'animals', ) ); register_taxonomy( 'especie', 'animal', array( 'labels' => array( 'name' => 'Especies', 'singular_name' => 'Especie', 'add_new_item' => 'Añadir especie', ), 'hierarchical' => true, 'show_admin_column' => true, 'show_in_rest' => true, 'rest_base' => 'species', 'show_in_graphql' => true, 'graphql_single_name' => 'species', 'graphql_plural_name' => 'speciesList', 'rewrite' => array( 'slug' => 'especie', 'with_front' => false ), ) ); register_post_type( 'ga_mensaje', array( 'labels' => array( 'name' => 'Mensajes', 'singular_name' => 'Mensaje', 'edit_item' => 'Mensaje', 'all_items' => 'Mensajes recibidos', 'not_found' => 'Aún no hay mensajes', ), 'public' => false, 'show_ui' => true, 'menu_icon' => 'dashicons-email-alt', 'menu_position' => 6, 'supports' => array( 'title', 'editor' ), 'capability_type' => 'post', 'capabilities' => array( 'create_posts' => 'do_not_allow' ), 'map_meta_cap' => true, ) ); foreach ( array_keys( ga_fields() ) as $key ) { // Los metadatos internos no se exponen tal cual: la API usa el campo «profile» (en inglés, ver api.php). register_post_meta( 'animal', "_ga_$key", array( 'type' => 'string', 'single' => true, 'show_in_rest' => false, 'auth_callback' => fn() => current_user_can( 'edit_posts' ), ) ); } } ); /* ------------------------------------------------------------------------- * Campos de la ficha * * 'shared' => true: el dato es común a la versión en castellano y en euskera. * Los textos (carácter, necesidades…) se escriben en cada idioma. * ---------------------------------------------------------------------- */ function ga_fields() { return array( 'estado' => array( 'shared' => true, 'label' => ga__( 'Estado', 'Egoera' ), 'type' => 'select', 'options' => array( 'disponible' => ga__( 'Disponible', 'Eskuragarri' ), 'proceso' => ga__( 'En proceso', 'Prozesuan' ), 'adoptado' => ga__( 'Adoptado', 'Adoptatuta' ), ), 'help' => 'Los adoptados salen solos del listado.' ), 'destacado' => array( 'shared' => true, 'label' => ga__( 'Destacado', 'Nabarmendua' ), 'type' => 'checkbox', 'help' => 'Aparece en la portada. Útil para quien lleva más tiempo esperando o necesita un hogar especial.' ), 'apadrinable' => array( 'shared' => true, 'label' => ga__( 'Busca padrino o madrina', 'Aitabitxi edo amabitxi bila' ), 'type' => 'checkbox', 'help' => 'Aparece en la sección «Apadrina» (si está activada en Personalizar).' ), 'sexo' => array( 'shared' => true, 'label' => ga__( 'Sexo', 'Sexua' ), 'type' => 'select', 'options' => array( 'macho' => ga__( 'Macho', 'Arra' ), 'hembra' => ga__( 'Hembra', 'Emea' ), ) ), 'nacimiento' => array( 'shared' => true, 'label' => ga__( 'Fecha de nacimiento', 'Jaiotze-data' ), 'type' => 'date', 'help' => 'Si no se conoce, deja la fecha vacía y rellena la edad aproximada.' ), 'edad' => array( 'shared' => true, 'label' => ga__( 'Edad aproximada', 'Gutxi gorabeherako adina' ), 'type' => 'number' ), 'edad_unidad' => array( 'shared' => true, 'label' => ga__( 'Edad en', 'Adina' ), 'type' => 'select', 'options' => array( 'anos' => ga__( 'Años', 'Urteak' ), 'meses' => ga__( 'Meses', 'Hilabeteak' ), ) ), 'tamano' => array( 'shared' => true, 'label' => ga__( 'Tamaño', 'Tamaina' ), 'type' => 'select', 'options' => array( 'pequeno' => ga__( 'Pequeño', 'Txikia' ), 'mediano' => ga__( 'Mediano', 'Ertaina' ), 'grande' => ga__( 'Grande', 'Handia' ), ), 'help' => 'Solo en perros.' ), 'llegada' => array( 'shared' => true, 'label' => ga__( 'En Bilagun desde', 'Bilagunen noiztik' ), 'type' => 'date', 'help' => 'Fecha de entrada, solo si está confirmada.' ), 'galeria' => array( 'shared' => true, 'label' => ga__( 'Más fotos', 'Argazki gehiago' ), 'type' => 'gallery' ), 'video' => array( 'shared' => true, 'label' => ga__( 'Vídeo', 'Bideoa' ), 'type' => 'url', 'help' => 'Enlace de YouTube, Vimeo o Instagram, o un vídeo subido a la biblioteca.' ), 'caracter' => array( 'label' => ga__( 'Cómo es', 'Nolakoa den' ), 'type' => 'textarea', 'help' => 'Su carácter, contado como en redes.' ), 'necesidades' => array( 'label' => ga__( 'Qué necesita', 'Zer behar duen' ), 'type' => 'textarea' ), 'convivencia' => array( 'label' => ga__( 'Convivencia con niños y otros animales', 'Haurrekin eta beste animaliekin bizikidetza' ), 'type' => 'textarea', 'help' => 'Solo lo observado, con contexto. Déjalo vacío si no lo sabemos.' ), 'hogar' => array( 'label' => ga__( 'El hogar que buscamos', 'Bilatzen dugun etxea' ), 'type' => 'textarea' ), ); } function ga_get( $post_id, $key ) { return (string) get_post_meta( $post_id, "_ga_$key", true ); } /** Estado normalizado (acepta valores antiguos). */ function ga_status( $post_id ) { $estado = ga_get( $post_id, 'estado' ); return match ( $estado ) { 'adoptado' => 'adoptado', 'proceso', 'reservado' => 'proceso', default => 'disponible', }; } /** Etiqueta legible de un campo de opciones. */ function ga_label( $post_id, $key ) { $fields = ga_fields(); $value = 'estado' === $key ? ga_status( $post_id ) : ga_get( $post_id, $key ); if ( '' === $value || ! isset( $fields[ $key ] ) ) { return ''; } $field = $fields[ $key ]; if ( 'select' === $field['type'] ) { return $field['options'][ $value ] ?? ''; } if ( 'date' === $field['type'] ) { return date_i18n( get_option( 'date_format' ), strtotime( $value ) ); } return $value; } /** Edad legible: calculada desde la fecha de nacimiento o la aproximada. */ function ga_age( $post_id ) { $birth = ga_get( $post_id, 'nacimiento' ); if ( $birth && strtotime( $birth ) ) { $diff = date_diff( date_create( $birth ), date_create( 'today' ) ); $n = $diff->y ?: $diff->m; $months = ! $diff->y; if ( ! $n ) { return ga__( 'Menos de un mes', 'Hilabete bat baino gutxiago' ); } } else { $n = ga_get( $post_id, 'edad' ); if ( '' === $n || ! is_numeric( $n ) ) { return ''; } $n = (float) $n + 0; $months = 'meses' === ga_get( $post_id, 'edad_unidad' ); } if ( 'eu' === ga_lang() ) { return $n . ( $months ? ' hilabete' : ' urte' ); } if ( $months ) { return $n . ( 1 == $n ? ' mes' : ' meses' ); } return $n . ( 1 == $n ? ' año' : ' años' ); } /** ¿Es un perro? (el tamaño solo se muestra en perros) */ function ga_is_dog( $post_id ) { $terms = get_the_terms( $post_id, 'especie' ) ?: array(); foreach ( $terms as $term ) { if ( in_array( $term->slug, array( 'perro', 'txakurra' ), true ) ) { return true; } } return false; } /** IDs de las fotos: la principal primero y después la galería. */ function ga_gallery_ids( $post_id ) { $ids = array_filter( array_map( 'absint', explode( ',', ga_get( $post_id, 'galeria' ) ) ) ); if ( has_post_thumbnail( $post_id ) ) { array_unshift( $ids, (int) get_post_thumbnail_id( $post_id ) ); } return array_values( array_unique( $ids ) ); } /* ------------------------------------------------------------------------- * Ficha en el panel * ---------------------------------------------------------------------- */ /* Editor clásico para los animales: la historia arriba y la ficha justo debajo, siempre a la vista. */ add_filter( 'use_block_editor_for_post_type', fn( $use, $type ) => 'animal' === $type ? false : $use, 10, 2 ); /* El cuadro de Yoast SEO va al final, debajo de la ficha. */ add_filter( 'wpseo_metabox_prio', fn() => 'low' ); add_action( 'add_meta_boxes_animal', function () { add_meta_box( 'ga_ficha', 'Ficha del animal', 'ga_render_metabox', 'animal', 'normal', 'high' ); } ); function ga_render_metabox( $post ) { wp_nonce_field( 'ga_ficha', 'ga_ficha_nonce' ); $fields = ga_fields(); $groups = array( 'Datos (comunes a castellano y euskera)' => array_filter( $fields, fn( $f ) => ! empty( $f['shared'] ) ), 'Textos de la ficha (en el idioma de esta página)' => array_filter( $fields, fn( $f ) => empty( $f['shared'] ) ), ); echo '
La historia se escribe en el editor principal. La «frase corta» (extracto) es opcional.
'; foreach ( $groups as $title => $group ) { echo '| ';
switch ( $f['type'] ) {
case 'select':
echo '';
break;
case 'checkbox':
printf( '', esc_attr( $name ), checked( $value, '1', false ) );
break;
case 'textarea':
printf( '', esc_attr( $name ), esc_textarea( $value ) );
break;
case 'gallery':
printf( '', esc_attr( $name ), esc_attr( $value ) );
echo ' ';
foreach ( array_filter( explode( ',', $value ) ) as $id ) {
$thumb = wp_get_attachment_image( (int) $id, array( 80, 80 ) );
if ( $thumb ) {
printf( '%s', (int) $id, $thumb );
}
}
echo ' ';
break;
case 'number':
printf( '', esc_attr( $name ), esc_attr( $value ) );
break;
default:
printf( '', esc_attr( $f['type'] ), esc_attr( $name ), esc_attr( $value ) );
}
if ( ! empty( $f['help'] ) ) {
echo '' . esc_html( $f['help'] ) . ' '; } echo ' |
' . esc_html( ga__( 'Ahora mismo no hay animales en esta sección. ¡Vuelve pronto!', 'Une honetan ez dago animaliarik atal honetan. Itzuli laster!' ) ) . '
'; } wp_reset_postdata(); return ob_get_clean(); } ); /** Apertura y cierre de un carrusel accesible (el tema aporta el CSS y el JS). */ function ga_carousel_open( $label = '' ) { printf( '