
La función de hoy crea un acceso desde /Herramientas para exportar una lista de etiquetas (tags) en formato .txt con esta cuatro opciones:
Exportar tags en Español. Genera una lista de etiquetas en español con la cifra de post en los que se añadieron y la cantidad total.
Exportar tags sin Posts. Devuelve la lista de las etiquetas no asignadas a ningún post con información de idioma. /ES/ /EN/ /DE/ etc.
Exportar tags con un solo post. Crea la lista de etiquetas asignadas a un solo post con información de idioma.
Exportar Todas las Tags. Aquí se puede descargar la lista completa con todos los idiomas asociados, el número de post donde se añadieron y la cantidad total.

Quizá te estés preguntando qué utilidad tiene esto si desde el área de administración de WordPress se puede ver la lista de etiquetas filtrando por distintos parámetros.
Pues bien, te resultará muy útil en un escenario en el que descubres que tienes cientos o miles de etiquetas huérfanas o con un solo post asociado acumuladas por dejadez y decides reorganizarlas para borrar etiquetas vacías, fusionarlas o moverlas a entradas que solo tienen una etiqueta y redireccionar aquellas que estén recibiendo tráfico.
Sí, aunque gran parte del personal recomienda no indexar categorías y etiquetas, si las optimizas bien pueden ser una fuente de tráfico orgánico estable nada despreciable. Si tienes interés real por este asunto, deja un comentario por aquí e intentaré añadir una nota con los detalles en algún momento.
Llegados a ese punto en el que tenemos un amontonamiento excesivo de etiquetas, provocando un engorde innecesario de tablas en tu base de datos y ralentizando las consultas, el área de administración se volverá cada vez más lenta. Esto puede provocar desde errores 503 a sobrecargas CPU que impidan navegar por la lista.
Trabajando en local con las listas descargadas en .txt evitarás esto y además podrás tener siempre listas actualizadas del estado de tus etiquetas para consulta rápida y retomar el tedioso trabajo de reorganización en cualquier momento. Si tienes muchas, tómatelo con calma. Como un proyecto a largo plazo.
En septiembre de 2024 empecé con la tarea de reorganización de categorías y etiquetas y aún no he terminado. El objetivo es reducir, como mínimo, a la mitad las etiquetas acumuladas y las que se asocian a un solo post o dos para reagrupar, borrar y fusionar con una estructura más lógica.
Código (compatible con los plugins WPML y Polylang)
El uso es el de siempre. Se añade el código en el functions.php de tu plantilla y encontrarás el acceso a los botones para descargar las listas desde el admin en Herramientas/ Exportar Tags Avanzado.
// Exportar lista de tags en .txt compatible VPML y Polylang
add_action('admin_menu', 'agregar_menu_exportar_tags_avanzado');
function agregar_menu_exportar_tags_avanzado() {
add_submenu_page(
'tools.php',
'Exportar Tags Avanzado',
'Exportar Tags Avanzado',
'manage_options',
'exportar-tags-avanzado',
'pagina_exportar_tags_avanzado'
);
}
function generar_archivo_tags($tipo) {
if (!current_user_can('manage_options')) {
wp_die(__('No tienes permisos suficientes para acceder a esta página.'));
}
if (ob_get_level()) {
ob_end_clean();
}
$all_tags = get_tags(array(
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false
));
$tags_filtradas = array();
$nombre_archivo = '';
$titulo = '';
switch ($tipo) {
case 'espanol':
if (function_exists('pll_get_term_language')) {
foreach ($all_tags as $tag) {
if (pll_get_term_language($tag->term_id) == 'es') {
$tags_filtradas[] = $tag;
}
}
}
$nombre_archivo = 'lista-tags-espanol';
$titulo = 'Etiquetas en Español';
break;
case 'sin_posts':
foreach ($all_tags as $tag) {
if ($tag->count == 0) {
$tags_filtradas[] = $tag;
}
}
$nombre_archivo = 'lista-tags-sin-posts';
$titulo = 'Etiquetas sin Posts';
break;
case 'un_post':
foreach ($all_tags as $tag) {
if ($tag->count == 1) {
$tags_filtradas[] = $tag;
}
}
$nombre_archivo = 'lista-tags-un-post';
$titulo = 'Etiquetas con un solo Post';
break;
default:
$tags_filtradas = $all_tags;
$nombre_archivo = 'lista-tags-completa';
$titulo = 'Todas las Etiquetas';
}
if (empty($tags_filtradas)) {
wp_die(__('No se encontraron etiquetas que coincidan con el criterio seleccionado.'));
}
$contenido = "Lista de {$titulo}\n";
$contenido .= str_repeat("=", strlen($titulo) + 6) . "\n\n";
$contenido .= "Total de etiquetas: " . count($tags_filtradas) . "\n\n";
foreach ($tags_filtradas as $tag) {
$idioma = '';
if (function_exists('pll_get_term_language')) {
$idioma = pll_get_term_language($tag->term_id);
$idioma = $idioma ? strtoupper($idioma) : 'ND';
}
$contenido .= sprintf("%-50s %-8s %s\n",
$tag->name,
"(Usos: {$tag->count})",
$idioma ? "IDIOMA: /{$idioma}/" : "");
}
header('Content-Description: File Transfer');
header('Content-Type: text/plain; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $nombre_archivo . '-' . date('Y-m-d') . '.txt"');
header('Content-Length: ' . strlen($contenido));
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
echo $contenido;
exit;
}
function pagina_exportar_tags_avanzado() {
if (!current_user_can('manage_options')) {
wp_die(__('No tienes permisos suficientes para acceder a esta página.'));
}
if (isset($_GET['tipo_exportacion'])) {
generar_archivo_tags(sanitize_text_field($_GET['tipo_exportacion']));
return;
}
?>
<div class="wrap">
<h1>Exportar Etiquetas Avanzado</h1>
<p>Selecciona el tipo de etiquetas que deseas exportar:</p>
<div style="margin: 20px 0;">
<a href="<?php echo esc_url(add_query_arg('tipo_exportacion', 'espanol')); ?>" class="button button-primary">
Exportar Tags en Español
</a>
<span class="description">Lista de etiquetas en español con información de idioma</span>
</div>
<div style="margin: 20px 0;">
<a href="<?php echo esc_url(add_query_arg('tipo_exportacion', 'sin_posts')); ?>" class="button button-primary">
Exportar Tags sin Posts
</a>
<span class="description">Etiquetas no asignadas a ningún post con información de idioma</span>
</div>
<div style="margin: 20px 0;">
<a href="<?php echo esc_url(add_query_arg('tipo_exportacion', 'un_post')); ?>" class="button button-primary">
Exportar Tags con un solo Post
</a>
<span class="description">Etiquetas asignadas a un solo post con información de idioma</span>
</div>
<div style="margin: 20px 0;">
<a href="<?php echo esc_url(add_query_arg('tipo_exportacion', 'todas')); ?>" class="button button-primary">
Exportar Todas las Tags
</a>
<span class="description">Lista completa con todos los idiomas asociados</span>
</div>
</div>
<style>
.description {
margin-left: 10px;
color: #666;
font-style: italic;
}
.wrap > div {
padding: 10px;
border-bottom: 1px solid #eee;
}
.button-primary {
min-width: 220px;
text-align: left;
}
</style>
<?php
}