Este hook para WordPress soluciona el problema de accesibilidad de los enlaces de varias maneras:
Características principales:
- Detección automática: Identifica enlaces que solo contienen imágenes o íconos sin texto descriptivo
- Generación de descripciones: Crea automáticamente descripciones basadas en:
- Patrones de URL (servicios, contacto, redes sociales, etc.)
- Contenido interno del enlace (alt text de imágenes)
- Clases CSS del elemento
- Atributo aria-label: Agrega automáticamente el atributo
aria-labelcon texto descriptivo - Estilos de accesibilidad: Incluye CSS para mejorar el foco visual y marcar enlaces externos

Cómo usar:
- Instalación: Copia el código al
functions.phpde tu child theme - Personalización: Modifica el array
$url_patternspara agregar más patrones específicos de tu sitio - Shortcode: Usa
[accessible_link]para crear enlaces accesibles manualmente:-
[accessible_link url="/servicios" description="Ver todos nuestros servicios"] <img src="arrow.png" alt="flecha"> [/accessible_link]
-
- Función PHP: Usa
accessible_link()en templates:-
echo accessible_link('/contacto', '<i class="icon-arrow"></i>', 'Ir a página de contacto');El hook procesará automáticamente el contenido y mejorará la accesibilidad de enlaces existentes sin modificar tu HTML actual, solucionando el problema que muestras en la imagen de la auditoría de accesibilidad.
-
Orden de prioridad para generar nombres:
- Texto visible del enlace – Si hay texto real en el enlace, lo usa directamente
- Alt text de imágenes – Si contiene una imagen con alt descriptivo
- Atributo title – De cualquier elemento interno
- Atributos data-* – Como data-title, data-label, data-text
- Patrones de URL – Solo como respaldo para URLs conocidas
- Slug de la URL – Convierte el slug en texto legible (ej: «peritaje-informatico» → «Peritaje Informático»)
La función extract_link_text() es especialmente inteligente porque:
- Extrae texto real de spans, divs, párrafos dentro del enlace
- Ignora elementos vacíos o que solo contienen símbolos
- Busca texto en atributos como placeholder y value
- Como último recurso, extrae cualquier texto visible
Y extract_text_from_url() convierte URLs como /analisis-forense/ en «Análisis Forense» de forma automática.
/**
* Hook para mejorar la accesibilidad de los enlaces agregando nombres descriptivos
* Agregar al functions.php del child theme
*/
// Hook para procesar el contenido y mejorar los enlaces
add_filter('the_content', 'improve_link_accessibility');
add_filter('widget_text', 'improve_link_accessibility');
function improve_link_accessibility($content) {
// Procesar enlaces que solo contienen imágenes o íconos
$content = preg_replace_callback(
'/<a([^>]*href="([^"]*)"[^>]*)>(\s*<[^>]*>\s*)*<\/a>/i',
'add_accessible_link_text',
$content
);
return $content;
}
function add_accessible_link_text($matches) {
$full_link = $matches[0];
$link_attributes = $matches[1];
$url = $matches[2];
$inner_content = $matches[3];
// Si el enlace ya tiene texto descriptivo, no modificarlo
if (preg_match('/[a-zA-Z]{3,}/', strip_tags($inner_content))) {
return $full_link;
}
// Si ya tiene aria-label o title descriptivo, no modificarlo
if (preg_match('/aria-label\s*=\s*["\'][^"\']{10,}["\']/', $link_attributes) ||
preg_match('/title\s*=\s*["\'][^"\']{10,}["\']/', $link_attributes)) {
return $full_link;
}
// Generar texto descriptivo basado en la URL o contexto
$descriptive_text = generate_link_description($url, $inner_content);
if ($descriptive_text) {
// Agregar aria-label con el texto descriptivo
$new_attributes = $link_attributes . ' aria-label="' . esc_attr($descriptive_text) . '"';
return '<a' . $new_attributes . '>' . $inner_content . '</a>';
}
return $full_link;
}
function generate_link_description($url, $inner_content = '') {
if (!empty($inner_content)) {
// 1. Primero intentar extraer texto visible del enlace
$text_content = extract_link_text($inner_content);
if (!empty($text_content)) {
return trim($text_content);
}
// 2. Si contiene una imagen, usar el alt text
if (preg_match('/<img[^>]*alt\s*=\s*["\']([^"\']+)["\'][^>]*>/i', $inner_content, $alt_match)) {
$alt_text = trim($alt_match[1]);
if (!empty($alt_text) && $alt_text !== 'image' && strlen($alt_text) > 2) {
return $alt_text;
}
}
// 3. Buscar title en elementos internos
if (preg_match('/title\s*=\s*["\']([^"\']{3,})["\']/', $inner_content, $title_match)) {
return trim($title_match[1]);
}
// 4. Buscar data-* attributes que puedan tener descripción
if (preg_match('/data-(?:title|label|text)\s*=\s*["\']([^"\']{3,})["\']/', $inner_content, $data_match)) {
return trim($data_match[1]);
}
}
// 5. Como último recurso, usar patrones de URL
$url_patterns = array(
'/peritaje-informatico/i' => 'Peritaje Informático',
'/analisis-forense/i' => 'Análisis Forense',
'/contacto/i' => 'Contacto',
'/servicios/i' => 'Servicios',
'/blog/i' => 'Blog',
'/portfolio/i' => 'Portfolio',
'/sobre-nosotros|about/i' => 'Sobre Nosotros',
'/telefono|phone|tel:/i' => 'Teléfono',
'/email|mailto:/i' => 'Email',
'/facebook\.com/i' => 'Facebook',
'/twitter\.com|x\.com/i' => 'Twitter',
'/linkedin\.com/i' => 'LinkedIn',
'/instagram\.com/i' => 'Instagram',
'/youtube\.com/i' => 'YouTube',
'/whatsapp/i' => 'WhatsApp',
);
foreach ($url_patterns as $pattern => $description) {
if (preg_match($pattern, $url)) {
return $description;
}
}
// 6. Extraer texto del slug de la URL
$url_text = extract_text_from_url($url);
if (!empty($url_text)) {
return $url_text;
}
return 'Enlace';
}
// Función auxiliar para extraer texto visible del contenido del enlace
function extract_link_text($content) {
// Remover scripts y estilos
$content = preg_replace('/<(script|style)[^>]*>.*?<\/\1>/si', '', $content);
// Extraer texto de elementos con contenido textual
$text_elements = array();
// Buscar spans, divs, p, etc. con texto
if (preg_match_all('/>([^<]{3,})</i', $content, $matches)) {
foreach ($matches[1] as $text) {
$cleaned_text = trim(strip_tags($text));
if (strlen($cleaned_text) > 2 && !preg_match('/^[\s\W]*$/', $cleaned_text)) {
$text_elements[] = $cleaned_text;
}
}
}
// Buscar texto en atributos placeholder, value, etc.
if (preg_match('/(?:placeholder|value)\s*=\s*["\']([^"\']{3,})["\']/', $content, $attr_match)) {
$text_elements[] = trim($attr_match[1]);
}
// Devolver el primer texto válido encontrado
if (!empty($text_elements)) {
return $text_elements[0];
}
// Como último recurso, extraer cualquier texto visible
$plain_text = trim(strip_tags($content));
if (strlen($plain_text) > 2 && !preg_match('/^[\s\W]*$/', $plain_text)) {
return $plain_text;
}
return '';
}
// Función auxiliar para extraer texto legible de una URL
function extract_text_from_url($url) {
$parsed_url = parse_url($url);
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
// Extraer la última parte del path (slug)
$path_parts = array_filter(explode('/', $path));
if (!empty($path_parts)) {
$slug = end($path_parts);
// Limpiar el slug y convertirlo en texto legible
$slug = preg_replace('/\.[^.]+$/', '', $slug); // remover extensión
$slug = str_replace(array('-', '_'), ' ', $slug);
$slug = ucwords(trim($slug));
if (strlen($slug) > 2) {
return $slug;
}
}
return '';
}
// Hook adicional para enlaces específicos en el tema
add_action('wp_head', 'add_custom_link_styles');
function add_custom_link_styles() {
?>
<style>
/* Mejorar visualmente los enlaces para accesibilidad */
a:focus {
outline: 2px solid #005fcc;
outline-offset: 2px;
}
/* Indicador visual para enlaces externos */
a[href^="http"]:not([href*="<?php echo home_url(); ?>"])::after {
content: " ↗";
font-size: 0.8em;
opacity: 0.7;
}
</style>
<?php
}
// Función para agregar manualmente aria-label a enlaces específicos
function accessible_link($url, $content, $description = '', $class = '') {
$aria_label = $description ? 'aria-label="' . esc_attr($description) . '"' : '';
$class_attr = $class ? 'class="' . esc_attr($class) . '"' : '';
return '<a href="' . esc_url($url) . '" ' . $aria_label . ' ' . $class_attr . '>' . $content . '</a>';
}
// Shortcode para crear enlaces accesibles
add_shortcode('accessible_link', 'accessible_link_shortcode');
function accessible_link_shortcode($atts, $content = null) {
$atts = shortcode_atts(array(
'url' => '#',
'description' => '',
'class' => '',
'target' => ''
), $atts);
$target_attr = $atts['target'] ? 'target="' . esc_attr($atts['target']) . '"' : '';
$aria_label = $atts['description'] ? 'aria-label="' . esc_attr($atts['description']) . '"' : '';
$class_attr = $atts['class'] ? 'class="' . esc_attr($atts['class']) . '"' : '';
return '<a href="' . esc_url($atts['url']) . '" ' . $aria_label . ' ' . $class_attr . ' ' . $target_attr . '>' . do_shortcode($content) . '</a>';
}
/**
* Uso del shortcode:
* [accessible_link url="https://ejemplo.com" description="Visitar página de servicios"]Contenido del enlace[/accessible_link]
*/
