<?xml version="1.0" encoding="UTF-8" standalone="no"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0">

<channel>
	<title>Ayuda WordPress</title>
	<atom:link href="https://ayudawp.com/feed/" rel="self" type="application/rss+xml"/>
	<link>https://ayudawp.com</link>
	<description>Recursos, temas, plugins, tutoriales en español</description>
	<lastBuildDate>Thu, 03 Sep 2026 15:24:25 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://ayudawp.com/wp-content/uploads/2026/05/cropped-ayuda-wordpress-32x32.png</url>
	<title>Ayuda WordPress</title>
	<link>https://ayudawp.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<xhtml:meta content="noindex" name="robots" xmlns:xhtml="http://www.w3.org/1999/xhtml"/><item>
		<title>Error 404 en el sitemap XML nativo de WordPress</title>
		<link>https://ayudawp.com/404-wp-sitemap-xml/</link>
					<comments>https://ayudawp.com/404-wp-sitemap-xml/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Thu, 03 Sep 2026 06:28:04 +0000</pubDate>
				<category><![CDATA[SEO / AEO / GEO / AIO]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Experto]]></category>
		<category><![CDATA[Sitemap]]></category>
		<category><![CDATA[Visibility]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160177</guid>

					<description><![CDATA[Si tu web no tiene ninguna entrada publicada y usas el mapa nativo de WordPress le está contestando a Google y cualquier bot con un error 404.]]></description>
										<content:encoded><![CDATA[<p>Si tu web no tiene ninguna una entrada publicada y <strong>usas el mapa nativo de WordPress</strong> (<code>wp-sitemap.xml</code>), deberías saber que le <strong>está contestando a Google y cualquier bot con un error 404</strong> aunque veas el XML y, aparentemente, salga entero y perfecto.</p>
<pre>curl -I https://ejemplo.com/wp-sitemap.xml<code></code></pre>
<p>Si en la primera línea sale un <code>404</code> y el <code>content-type</code> dice <code>application/xml</code>, bienvenido al club, y si te sale un 403 no cantes victoria, que te ha contestado tu cortafuegos y no WordPress, un par de secciones más abajo te cuento cómo salir de esa.</p>
<p><strong>Le pasa a tiendas, campus, webs de servicios, porfolios y a cualquier web sin blog</strong>, que son muchísimas y son justo las que menos lo van a notar, porque no hay ni un síntoma a la vista.</p>
<p>La web funciona igual de bien, el mapa del sitio se ve de maravilla en el navegador y <strong>los únicos avisos los tienes si añades el mapa del sitio a la Google Search Console o lo revisas</strong> un día por yo que sé, que te mostrará el error, y también <strong>lo verías si te da por mirar en la consola del navegador para buscar errores</strong>, eso que nunca haces salvo que aparezca rota la web.</p>
<p>Y esto no venía de serie, <strong>es nuevo desde WordPress 7.1, publicada el 19 de agosto de 2026</strong>, o sea que si actualizaste esta semana y tu web no tiene blog te lo has llevado puesto sin enterarte. En las versiones anteriores el mismo mapa del sitio se entregaba con código de estado normal, o sea, 200.</p>
<p>Además, <strong>el problema es más gordo</strong>, porque wwwwwwno se queda solo en el índice de mapas, <strong>los submapas de páginas, de productos, de categorías y de usuarios salen con código de estado de error 404 también</strong>, cada uno con todas sus URLs dentro, así que a esa web no le queda ni un mapa del sitio aprovechable.</p>
<p>Vamos a verlo deeespacito, primero si te toca y cómo salir del paso, y luego, para el que quiera, analizaremos la chicha, veremos qué se rompió en las tripas de WordPress.</p>
<h2>Si usas plugins SEO que generan sus propios mapas del sitio XML no hace falta que sigas leyendo (salvo para aprender)</h2>
<p><strong>Los plugins de SEO grandes sirven un mapa del sitio propio, con su propia ruta distinta de la del mapa nativo, y mandan su cabecera 200 forzada </strong>, así que este asunto no les afecta.</p>
<p>Yoast y Rank Math (casualidad) usan <code>sitemap_index.xml</code>, AIOSEO crea un <code>sitemap.xml</code> y SEOPress <code>sitemaps.xml</code>, <strong>ninguno de estos aprovecha el mapa del sitio nativo que ya existe, y en este caso juega a su favor</strong>.</p>
<p>De hecho, si tienes uno de esos activo y visitas <code>wp-sitemap.xml</code> te vas a encontrar <strong>un 404 de verdad, de página no encontrada</strong>, al filtrar <code>wp_sitemaps_enabled</code> a <code>false</code> su código desactiva el sitemap nativo pero deja las reglas puestas precisamente para poder contestar ese 404. Ahí no hay nada roto, aunque tampoco es buena práctica, pero <a href="https://ayudawp.com/mapas-del-sitio-xml-wordpress/" target="_blank" rel="noopener">eso ya lo hemos comentado</a>.</p>
<p>Ahora, <strong>si lo que usas es algo que utiliza el mapa del sitio nativo</strong> en lugar de montar el suyo, <strong>heredas el fallo entero</strong>, porque el sitemap que se sirve es el del core de WordPress con sus filtros y todo lo que lleva por defecto.</p>
<p>Es el caso de mi plugin de SEO, <a href="https://es.wordpress.org/plugins/native-aeo-pack/" target="_blank" rel="nofollow noopener">Visibility</a>, que trabaja así a propósito, y por eso <strong>desde la versión 2.4.0 trae entre sus novedades el blindaje del estado del sitemap, y así mapa del sitio se entrega con código de estado 200 aunque la web no tenga ni una entrada publicada</strong>, y tú no tienes que tocar nada. Por ahi sin problema, sin 404 de ningún tipo, todo perfecto, ¿o lo dudabas?</p>
<p>Cualquier otro plugin que personalice el nativo en vez de sustituirlo te vale el arreglo que te cuento más abajo.</p>
<h2>Cómo saber si mi sitemap XML da error 404</h2>
<p>Lo primero que tienes que asumir es que <strong>el navegador te miente en esto</strong>. Abres la URL, ves el XML con su hoja de estilos y sus enlaces, todo precioso, y del código de estado no te dice ni mu, salvo que investigues, claro.</p>
<p><a href="https://ayudawp.com/?attachment_id=160180" rel="nofollow"><img fetchpriority="high" decoding="async" class="sombra alignnone wp-image-160180 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/09/wp-sitemap-xml-no-posts-404-1200x633.jpg" alt="" width="1200" height="633" srcset="https://ayudawp.com/wp-content/uploads/2026/09/wp-sitemap-xml-no-posts-404-1200x633.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/09/wp-sitemap-xml-no-posts-404-768x405.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/09/wp-sitemap-xml-no-posts-404-1536x810.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/09/wp-sitemap-xml-no-posts-404.jpg 1920w" sizes="(max-width: 1200px) 100vw, 1200px"></a></p>
<p>El que sí te lo muestra enseguida es Google, que cuando se <strong>encuentra un error 4xx al procesar el mapa del sitio</strong> <a href="https://support.google.com/webmasters/answer/7451001?hl=es" target="_blank" rel="nofollow noopener">te muestra el código recibido</a> y no hay dudas.</p>
<p>Hay que mirar la cabecera de la respuesta, y de las tres formas de hacerlo la que nunca falla es la del navegador:</p>
<ul>
<li>Abre las <strong>herramientas de desarrollo</strong> con F12 y mira la pestaña <strong>Red</strong>, o directamente la <strong>consola</strong>, que te canta el 404 del documento en cuanto cargas la URL. El navegador supera cualquier protección antibots que tengas delante, así que lo que ves ahí es lo que hay.</li>
<li>En <strong>Google Search Console</strong>, añadiendo o viendo el informe de <strong>Sitemaps</strong>, que es donde lo vas a ver sin duda posible porque te lo cuenta el propio Google.</li>
<li>Con <code>curl -I https://ejemplo.com/wp-sitemap.xml</code>, que es lo más rápido si la web no tiene cortafuegos delante. Ojo con esto, que lo explico ahora mismo.</li>
</ul>
<p>En Search Console el aviso es <strong>«No se ha podido leer el sitemap»</strong>, con un <strong>«Error general de HTTP»</strong> y, desplegando, el <strong>«Error HTTP: 404»</strong>.</p>
<p><a href="https://ayudawp.com/?attachment_id=160181" rel="nofollow"><img decoding="async" class="sombra alignnone wp-image-160181 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/09/error-404-sitemap-google-search-console-1200x678.jpg" alt="" width="1200" height="678" srcset="https://ayudawp.com/wp-content/uploads/2026/09/error-404-sitemap-google-search-console-1200x678.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/09/error-404-sitemap-google-search-console-768x434.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/09/error-404-sitemap-google-search-console-1536x867.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/09/error-404-sitemap-google-search-console.jpg 1920w" sizes="(max-width: 1200px) 100vw, 1200px"></a></p>
<p>Fíjate en el resto de la ficha, que es lo que le da la puntilla, <strong>las páginas descubiertas son cero</strong>.</p>
<p>Y ahí viene lo cruel del asunto, que <strong>el consejo que te da Google te manda a buscar justo donde no está el problema</strong>. Te dice que compruebes que el sitemap se encuentra en la dirección especificada y que no le tengas bloqueado el acceso.</p>
<p>Pues está en su dirección, se ve perfectamente y no está bloqueado. Con esas dos pistas te puedes tirar la tarde revisando el <code>robots.txt</code>, las reglas del cortafuegos y los permisos, sin encontrar nada, porque <strong>lo que falla es el código de estado</strong> y de eso no hay pistas visibles.</p>
<p><strong>El <code>curl</code> desde tu ordenador se lo va a tragar el cortafuegos en la mitad de las webs decentes.</strong> Si tienes Cloudflare, el WAF del hosting o un plugin de seguridad con protección antibots, la petición ni llega a WordPress y te contesta la capa de delante con un 403, un 202 o un 503, siempre en <code>text/html</code>.</p>
<p>Yo mismo me he llevado un 403 en la primera prueba y he tardado un minuto en caer en la cuenta.</p>
<p>Si tienes acceso a la terminal del servidor puedes saltarte a Cloudflare pidiéndoselo al origen directamente, con la cabecera <code>Host</code> puesta a mano:</p>
<pre><code>curl -skI https://127.0.0.1/wp-sitemap.xml -H "Host: midominio.com"</code></pre>
<p>Y ahora el detalle que separa tres problemas que se confunden todo el rato. <strong>Mira el <code>content-type</code> que viene al lado del código de estado</strong>:</p>
<ul>
<li><code>404</code> con <code>content-type: application/xml</code>, es este fallo. El sitemap se ha generado y se está sirviendo, solo que con el cartel de cerrado.</li>
<li><code>404</code> con <code>content-type: text/html</code>, no es esto. Ahí lo que pasa es que las reglas de reescritura no están puestas, la petición ni siquiera llega al sistema de sitemaps y lo que te devuelve es la página de error de tu tema. Se arregla yendo a «<strong>Ajustes &gt; Enlaces permanentes</strong>» y dando a guardar sin tocar nada.</li>
<li><code>403</code>, <code>202</code> o <code>503</code>, no has llegado a WordPress. Te ha contestado la protección antibots y no has comprobado nada, así que repite por el navegador.</li>
</ul>
<p>Una sola cabecera te dice cuál de los tres tienes, y te ahorras el rato (largo).</p>
<p>Si quieres profundizar en los sitemaps que no se ven, salen en blanco o dan errores raros, tengo <a href="https://ayudawp.com/errores-sitemap/" target="_blank" rel="ugc noopener">una guía entera sobre eso</a> que cubre los tres tipos de problema. Pero no vayas ahora, que queda mucho por ver, aprender y sobre todo hay que arreglar este problema.</p>
<h2>Cómo hacer la prueba con una instalación limpia y cero plugins</h2>
<p>Esto no es una sospecha ni una teoría, lo he medido en una instalación recién hecha, sin un solo plugin activo:</p>
<table>
<tbody>
<tr>
<th>Portada</th>
<th>Entradas publicadas</th>
<th>Páginas publicadas</th>
<th>/wp-sitemap.xml</th>
</tr>
<tr>
<td>Blog</td>
<td>1</td>
<td>1</td>
<td>200</td>
</tr>
<tr>
<td>Blog</td>
<td>0</td>
<td>1</td>
<td><strong>404</strong></td>
</tr>
<tr>
<td>Estática</td>
<td>1</td>
<td>1</td>
<td>200</td>
</tr>
<tr>
<td>Estática</td>
<td>0</td>
<td>1</td>
<td><strong>404</strong></td>
</tr>
</tbody>
</table>
<p>Borras la única entrada de una instalación nueva y el sitemap el código de estado es 404 (arriba te cuento como verlo). Publicas una y vuelve a 200.</p>
<p><strong>Da igual el tipo de portada y da igual que tengas cien páginas, mil productos o los cursos del campus publicados</strong>: lo único que cuenta es que exista al menos un <code>post</code>, que no pinta absolutamente nada en el mapa del sitio que se va a servir.</p>
<p>Y hay un dato que parece un detalle y en realidad es la pista que lo explica todo: <code>/wp-sitemap-index.xsl</code>, la hoja de estilos que le da el aspecto bonito al XML, sí devuelve 200 en los dos casos. Guarda el dato que lo vemos enseguida. Apasionante ¿verdad? ¿o triste? Venga, que ya llegamos…</p>
<h3>El error 404 en el sitemap es peor aún de lo que imaginas</h3>
<p>Esto es lo que convierte el asunto en <strong>un problema serio y no en una cosa curiosa del <em>güorpré</em></strong>, lo he probado en una tienda WooCommerce de pruebas sin una sola entrada de blog, con sus productos, sus páginas y sus categorías publicados, y el índice lista sus cuatro sitemaps ahí <em>to guapos</em>: páginas, productos, categorías de producto y usuarios.</p>
<p><strong>Los cuatro muestran todas sus URLs.</strong> El de productos enseña sus veintitrés fichas con sus fechas de modificación, perfectamente formado, y <strong>¡todos con código de estado 404!</strong>.</p>
<p><a href="https://ayudawp.com/?attachment_id=160182" rel="nofollow"><img decoding="async" class="sombra alignnone wp-image-160182 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/09/wp-sitemap-xml-products-404-1200x634.jpg" alt="" width="1200" height="634" srcset="https://ayudawp.com/wp-content/uploads/2026/09/wp-sitemap-xml-products-404-1200x634.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/09/wp-sitemap-xml-products-404-768x406.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/09/wp-sitemap-xml-products-404-1536x811.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/09/wp-sitemap-xml-products-404.jpg 1920w" sizes="(max-width: 1200px) 100vw, 1200px"></a></p>
<p>O sea, que a una tienda sin blog, que son legión, no tiene <strong>ni una sola URL que Google pueda extraer de sus mapas del sitio</strong>.</p>
<p>Ni las fichas de producto, ni las categorías, ni las páginas. Y todo esto con la tienda funcionando de maravilla, a priori, sin un error en el escritorio de WordPress ni nada que te avise.</p>
<h2>¿Pero qué han roto en WordPress 7.1? Análisis forense…</h2>
<p>El 8 de julio de 2026 entró en el core el <a href="https://core.trac.wordpress.org/changeset/62664" target="_blank" rel="nofollow noopener">changeset 62664</a>, que añade la etiqueta condicional <code>is_sitemap()</code>, un añadido de lo más razonable y que mucha gente llevaba años pidiendo, para poder saber desde un plugin si la petición que estás atendiendo es la de un sitemap.</p>
<p>El propio mensaje del commit lo cuenta, y ahí está la frase del delito, que la marca se activa cuando existe la variable de consulta <code>sitemap</code> y <strong>una petición de mapa del sitio deja de tratarse como la portada</strong>.</p>
<p>Suena inofensivo y no lo es ni de lejos, porque de eso dependía el estado HTTP.</p>
<p>Para empezar, <code>WP::handle_404()</code> se ejecuta antes que <code>template_redirect</code>, o sea antes de que el sistema de sitemaps pinte nada. En una petición de sitemap la consulta principal es la consulta por defecto, la de la portada, que en una web sin entradas no devuelve ni un solo resultado.</p>
<p>Y <code>handle_404()</code> funciona de manera muy simple, si la consulta trae contenido entrega con código 200, si no trae nada mira una lista corta de excepciones, y si no está en ninguna tienes un código 404.</p>
<p>Esa lista de excepciones es <code>is_author()</code>, <code>is_tag()</code>, <code>is_category()</code>, <code>is_tax()</code>, <code>is_post_type_archive()</code>, <code>is_home()</code>, <code>is_search()</code> e <code>is_feed()</code>.</p>
<p><strong>Lo único que salvaba al sitemap era <code>is_home()</code></strong>, por pura chiripa, porque una petición de sitemap se consideraba portada. Al dejar de considerarse portada se quitó el salvavidas, y en <code>handle_404()</code> no hay excepción para <code>is_sitemap()</code>, ni en la 7.1 ni inicialmente en el trunk (desarrollo) de la 7.2.</p>
<p>Medido por dentro, con el filtro <code>pre_handle_404</code>:</p>
<pre>sin entradas:  is_404=false is_home=false is_singular=false is_archive=false is_feed=false is_paged=false posts=0  -&gt; 404
con 1 entrada: is_404=false is_home=false is_singular=false is_archive=false is_feed=false is_paged=false posts=1  -&gt; 200</pre>
<p>Todas las excepciones en <code>false</code>, <code>is_home()</code> la primera. Lo único que cambia entre las dos líneas es que <code>$wp_query-&gt;posts</code> traiga algo, y esas entradas no tienen nada que ver con el sitemap.</p>
<p>Después, ya en <code>template_redirect</code>, <code>WP_Sitemaps::render_sitemaps()</code> pinta el XML y hace <code>exit</code> sin llamar nunca a <code>status_header( 200 )</code>, así que sale con el estado que se puso antes.</p>
<p>Y aquí encaja la pieza que te dije que ponía esto aún más apasionante, porque aa hoja de estilos se salva porque su variable de consulta es <code>sitemap-stylesheet</code>, no <code>sitemap</code>, así que <code>is_sitemap</code> no se activa, la petición sigue considerándose portada y contesta 200.</p>
<p>El fallo y la excepción salen del mismo sitio, que es lo que confirma que el diagnóstico es ese y no otro. Quedarse sin contenido no es lo mismo que no existir, y un mapa del sitio con páginas dentro existe aunque no haya un solo artículo en la web.</p>
<h2>Cómo arreglar el problema con solo nueve líneas</h2>
<p>Mientras esto se corrige en el core, se soluciona forzando el 200 solo en las peticiones de sitemap. Crea un archivo, llámalo <code>ayudawp-sitemap-200.php</code>, y súbelo por FTP o por el gestor de archivos de tu hosting a la carpeta <code>wp-content/mu-plugins/</code>. Si esa carpeta no existe la creas tú, WordPress la carga sola.</p>
<p>Lo pongo ahí y no en el <code>functions.php</code> del tema a propósito, porque así sobrevive a un cambio de tema y no se te queda un sitemap roto el día que decidas rediseñar:</p>
<pre>&lt;?php
/**
 * Plugin Name: Corregir el mapa del sitio nativo: de 404 a 200.
 * Plugin URI: https://plugins.ayudawp.com
 * Description: Fuerza código de estado 200 en peticiones del mapa del sitio nativo, en vez de 404. Borra este plugin cuando salga el arreglo nativo en WordPress.
 * Version: 1.0.0
 * Author: Fernando Tellado
 * Author URI: https://tellado.es
 * License: GPL2
 */

// Forzamos estado 200 dejando el resto como 404
function ayudawp_sitemap_force_200_status( $preempt, $wp_query ) {

$is_sitemap_request = get_query_var( 'sitemap' ) || get_query_var( 'sitemap-stylesheet' );

// Si no es petición al sitemap dejar que WordPress decida el estado
if ( ! $is_sitemap_request ) {
return $preempt;
}

$wp_query-&gt;is_404 = false;
status_header( 200 );

// Devuelve true para parar WP::handle_404() y guarda el estado de arriba
return true;
}
add_filter( 'pre_handle_404', 'ayudawp_sitemap_force_200_status', 10, 2 );</pre>
<p>Súbelo, vuelve a pasarle el <code>curl -I</code> que vimos antes y deberías ver ya el código de estado 200. Sin caché que purgar ni enlaces permanentes que guardar, porque esto no toca las reglas de <code>rewrite</code>.</p>
<h3>¡Que nooo, que este código no rompe nada!</h3>
<p><strong>Los 404 legítimos siguen intactos</strong>, que es lo que te tiene que importar antes de meter esto en una web de cliente. En una web sin entradas, <code>/wp-sitemap-posts-post-1.xml</code> sigue devolviendo 404, y es lo correcto, porque ese sitemap está vacío de verdad.</p>
<p>Lo fuerza el propio core, en <code>render_sitemaps()</code>, después de que nuestro filtro haya pasado. Lo mismo pasa con el 404 de cuando tienes los mapas del sitio desactivados por otro plugin de SEO.</p>
<p>El filtro <strong>solo actúa donde hay una variable de consulta del sitemap</strong>, y devuelve el control a WordPress en cualquier otra petición.</p>
<p><strong>De regalo arregla de paso los sitemaps paginados que se iban a 404 cuando el número de página superaba al de páginas del blog</strong>, que es otro caso viejo del mismo mecanismo.</p>
<blockquote><p>Nota: como ya habrás imaginado, una versión refinada y más sólida de este ajuste (opcional, porque no le pasa a todas las webs) está implementado en el plugin <a href="https://visibility.quest/" target="_blank" rel="noopener">Visibility</a></p></blockquote>
<h2>Con los feeds pasó exactamente lo mismo en 2017</h2>
<p>Esto, como casi todo, ya lo hemos vivido, y con el mismo desenlace, pues en WordPress 4.7 entró un cambio para que las URLs no válidas de feeds dejaran de generar RSS, y de rebote los feeds válidos pero vacíos empezaron a devolver 404.</p>
<p>Se avisó en el <a href="https://core.trac.wordpress.org/ticket/39157" target="_blank" rel="nofollow noopener">ticket 39157</a>, se aceptó como fallo y se corrigió en la 4.7.3 revirtiendo el trozo de código que lo causaba. Lo he comprobado versión a versión, el bloque está en la 4.7.2 y ya no está en la 4.7.3.</p>
<p>O sea que el criterio ya está ahí desde hace nueve años. Lo que hay que decidir ahora es dónde se pone el parche esta vez, si en <code>handle_404()</code> con una excepción para <code>is_sitemap()</code>, que es el equivalente exacto de lo que hay para los feeds, o en <code>render_sitemaps()</code> mandando el 200 antes de pintar el XML, pero eso ya no es decision mía, yo he avisado (mira más abajo), y te ofrezco soluciones.</p>
<h2>El estado en Trac ahora mismo</h2>
<p>Hay dos tickets abiertos en el componente de sitemaps que te interesan:</p>
<ul>
<li>El <a href="https://core.trac.wordpress.org/ticket/65936" target="_blank" rel="nofollow noopener">65936</a>, anterior al mío, sobre sitemaps del core servidos con estado 404. Va con parche y está marcado para la 7.1.1, así que la corrección tiene pinta de estar en camino.</li>
<li>El <a href="https://core.trac.wordpress.org/ticket/65945" target="_blank" rel="nofollow noopener">65945</a>, que he abierto yo mismo con este caso concreto, el de las webs sin entradas publicadas, los datos de la tabla de arriba y la medición del párrafo anterior. Ya se ha contemplado incluir este arreglo en WordPress 7.2.</li>
</ul>
<p>Por debajo de los dos está el <a href="https://core.trac.wordpress.org/ticket/51117" target="_blank" rel="nofollow noopener">51117</a>, abierto desde 2020, que es la raíz de todo el asunto: las peticiones de sitemap ejecutan la consulta principal de la portada, que es una consulta que no se va a usar para nada y que además decide el estado HTTP de una página que no tiene nada que ver con ella.</p>
<p>El changeset de la 7.1 lo cita como referencia, pero mientras eso siga así vamos a seguir teniendo sorpresas de este tipo cada vez que alguien toque una condición.</p>
<p>Un apunte que debes saber es que <code>is_sitemap()</code> es una etiqueta condicional nueva que cambia el comportamiento de <code>is_home()</code> en una petición del core, y <strong>no tiene nota de desarrollo</strong>, no aparece por ninguna parte en la guía de campo de la 7.1.</p>
<p>Un cambio que altera un condicional que usan miles de plugins merecía su párrafo, o en mi cabeza es lo que me parece lógico, pero vaya, será que soy raro o algo.</p>
<h2>¿Me afecta?</h2>
<p>Si mantienes webs de clientes, y sobre todo si mantienes tiendas o webs corporativas sin blog, pásale el <code>curl -I</code> que vimos antes a las que ya tengan la versión 7.1 o superior antes de que Googlebot pase otra vez.</p>
<p>Si tienes muchas y quieres salir del paso rápido, mete el mu-plugin en las que te den 404 con XML dentro y reenvía el sitemap desde Search Console para que Google lo vuelva a leer sin esperar a su ritmo.</p>
<p>Si andas con ganas de cacharrear, en el <a href="https://ayudawp.com/mapas-del-sitio-xml-wordpress/" target="_blank" rel="ugc noopener">artículo sobre cómo personalizar el mapa del sitio XML nativo</a> tienes los filtros para quitar tipos de contenido, taxonomías y usuarios del sitemap, que combinan perfectamente con el arreglo de arriba, y por supuesto, no me cansaré de animarte a darle una oportunidad al mejor plugin de SEO del mundo mundial, nacido de mi (extraña) necesidad de tener un buen plugin de SEO, todo gratuito, y adaptado a las nuevas funcionalidades y cambios de rastreo por bots e IAs. Se llama <a href="https://es.wordpress.org/plugins/native-aeo-pack/" target="_blank" rel="noopener">Visibility</a>, facilito.</p>
<p>Y si lo compruebas y te sale 404 con el XML dentro, cuéntamelo abajo en los comentarios con la versión de WordPress y si tu web tiene blog o no, que cuantos más casos reunamos más fácil es que esto se arregle cuanto antes.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/404-wp-sitemap-xml/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Editor clásico en Multisitio</title>
		<link>https://ayudawp.com/editor-clasico-en-multisitio/</link>
					<comments>https://ayudawp.com/editor-clasico-en-multisitio/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Wed, 02 Sep 2026 06:28:20 +0000</pubDate>
				<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Experto]]></category>
		<category><![CDATA[Multisitio]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160087</guid>

					<description><![CDATA[Hay tres formas en el editor clásico que funciona de verdad en una red multisitio, los plugins Classic Editor y No Gutenberg?, o un par de líneas de código sin depender de ningún plugin…]]></description>
										<content:encoded><![CDATA[<p>Si administras una red de WordPress y quieres desactivar el editor de bloques, la mayoría de información que vas a encontrar están pensados para un solo sitio, y en multisitio eso se queda corto, porque esto tiene sus cosas.</p>
<p>Hay tres formas en el editor clásico que funciona de verdad en una red multisitio, los plugins Classic Editor y <a href="https://wordpress.org/plugins/no-gutenberg/" target="_blank" rel="nofollow noopener">No Gutenberg?</a> o un par de líneas de código sin depender de ningún plugin. Vamos a verlas, con lo que hace cada una en una red.</p>
<h2>¿Qué cambia que sea una red multisitio para usar el editor clásico?</h2>
<p>Desactivar el editor de bloques en un sitio único es instalar un plugin, activarlo y punto. En una red hay una capa más, porque un plugin se puede activar sitio a sitio o en red completa con activación para la red, y esas dos vías no siempre se comportan igual.</p>
<p>Y luego está la tercera vía, los mu-plugins, que ni siquiera pasan por la pantalla de plugins, que se cargan solos, en todos los sitios, sin que nadie los active. Esa diferencia es la que decide qué opción te conviene, así que vamos con las tres.</p>
<h2>Opción 1: Plugin oficial Classic Editor</h2>
<p>Es el plugin que mantiene el propio equipo de WordPress. En un sitio normal añade dos ajustes en «<strong>Ajustes &gt; Escritura &gt; Editor por defecto para todos los usuarios</strong>» (clásico o de bloques) y «<strong>Permitir a los usuarios cambiar de editor</strong>» (sí o no) ,para que cada usuario, puede además elegir su propio editor por defecto desde su perfil.</p>
<p><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160125 size-full" src="https://ayudawp.com/wp-content/uploads/2026/09/editor-clasico-ajustes-sitio.jpg" alt="" width="830" height="320" srcset="https://ayudawp.com/wp-content/uploads/2026/09/editor-clasico-ajustes-sitio.jpg 830w, https://ayudawp.com/wp-content/uploads/2026/09/editor-clasico-ajustes-sitio-768x296.jpg 768w" sizes="auto, (max-width: 830px) 100vw, 830px"></p>
<p>En una red la cosa cambia si lo activas en red. Al <strong>activarlo para la red</strong> aparece una sección nueva en «<strong>Administrador de la red &gt; Ajustes</strong>», con «<strong>Editor por defecto para todos los sitios</strong>» y la casilla «<strong>Permitir a los administradores de sitios cambiar los ajustes</strong>».</p>
<p><a href="https://ayudawp.com/?attachment_id=160126" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160126 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/09/ajustes-red-editor-clasico-1200x678.jpg" alt="" width="1200" height="678" srcset="https://ayudawp.com/wp-content/uploads/2026/09/ajustes-red-editor-clasico-1200x678.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/09/ajustes-red-editor-clasico-768x434.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/09/ajustes-red-editor-clasico-1536x867.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/09/ajustes-red-editor-clasico.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>O sea, que si lo activas para l a red, mandas tú y nadie más puede tocar el editor por sitio, salvo que lo permitas explícitamente desde esa pantalla de red. Si no lo activas en red entonces cada administrador de sitio decide por su cuenta.</p>
<blockquote><p><strong>Advertencia:</strong> esa casilla de red viene desmarcada por defecto la primera vez que el plugin toca la instalación, esté activado en red completa o solo en un sitio suelto de esa red. Así que si cada sitio activa Classic Editor por su cuenta, es fácil acabar con un ajuste de red heredado que nadie recuerda haber marcado. Revísalo en Administrador de la red antes de dar nada por hecho.</p></blockquote>
<p>Y esta opción tiene una limitación que la descarta en bastantes casos: <strong>no funciona con temas de bloques</strong>. Lo dice la propia FAQ del plugin, «<em>No, ya que los temas de bloques no funcionan con bloques</em>». Si tu red usa temas FSE de edición completa del sitio, esta vía no es para ti.</p>
<h2>Opción 2: No Gutenberg?</h2>
<p>Aquí ya hablo de mi propio plugin, así que toca ser especialmente exigente con lo que cuento. Desde las versiones 2.2.0 y siguientes, publicadas en agosto de 2026, <strong>No Gutenberg? dejó de ser el interruptor de todo o nada</strong> que fue durante años.</p>
<p>Ahora tiene una pantalla de ajustes en «<strong>Ajustes &gt; No Gutenberg?</strong>» con reglas por tipo de contenido, por perfil de usuario, por plantilla de página y por entradas concretas, además de un interruptor maestro y protección automática para que ninguna entrada ya construida con bloques pierda su editor por las reglas que pongas.</p>
<p><a href="https://ayudawp.com/?attachment_id=160129" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160129 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/09/No-Gutenberg-ajustes-por-contenido-y-usuario-1200x1122.jpg" alt="" width="1200" height="1122" srcset="https://ayudawp.com/wp-content/uploads/2026/09/No-Gutenberg-ajustes-por-contenido-y-usuario-1200x1122.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/09/No-Gutenberg-ajustes-por-contenido-y-usuario-768x718.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/09/No-Gutenberg-ajustes-por-contenido-y-usuario-1536x1436.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/09/No-Gutenberg-ajustes-por-contenido-y-usuario.jpg 1684w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>Te cuento el porqué de este cambio de rumbo con calma en otro artículo, que es de hecho la razón por la que estoy escribiendo esta guía ahora, pues fue uno de los retos con los que me encontré.<em style="font-size: 16px;">.</em></p>
<p>Sobre el tema de multisitio, no, <strong>no hay una pantalla de red dedicada, y no la hay porque no hace falta</strong>.</p>
<p>Cada sitio guarda sus ajustes como cualquier plugin normal, y para forzar el mismo criterio en toda la red de un plumazo, presente y futura, sitios que aún no existen incluidos, usas <code>wp-config.php</code>, que por diseño de WordPress es un único archivo compartido por toda la instalación.</p>
<p>Las constantes son estas tres, y son las únicas que reconoce el plugin:</p>
<ul>
<li><code>NO_GUTENBERG_OPTIONS</code>: un array con cualquier ajuste de la pantalla. Fija esa configuración y bloquea automáticamente la pantalla de ajustes en todos los sitios.</li>
<li><code>NO_GUTENBERG_LOCK_SETTINGS</code>: deja la pantalla visible pero de solo lectura, para que cada administrador de sitio vea qué está pasando sin poder tocarlo.</li>
<li><code>NO_GUTENBERG_HIDE_SETTINGS</code>: oculta directamente la pantalla del menú.</li>
</ul>
<p>Ejemplo real, sacado de mi propia documentación:</p>
<pre>define( 'NO_GUTENBERG_OPTIONS', array( 'complete' =&gt; true ) );
define( 'NO_GUTENBERG_HIDE_SETTINGS', true );</pre>
<p>Con esas dos líneas en <code>wp-config.php</code>, todos los sitios de la red quedan con el editor de bloques desactivado por completo y sin pantalla de ajustes que nadie pueda tocar.</p>
<p>Si lo que quieres son reglas más finas, solo ciertos tipos de contenido, ciertos roles, ciertas plantillas, el array admite las mismas claves que ves en el formulario de ajustes, configúralo primero en un sitio de pruebas desde la pantalla, y si quieres el nombre exacto de cada clave para replicarla en wp-config, está en <code>includes/class-no-gutenberg-options.php</code>, dentro del propio plugin.</p>
<p>Un detalle que merece mención si administras una red grande es que el interruptor «Bloquear el editor del sitio», dentro de la sección de ajustes de todo el sitio, es el único de los tres métodos de este artículo que llega a tocar la edición de plantillas de un tema de bloques. Ni el plugin Classic editor ni el código nativo de la siguiente sección llegan a tanto, como veremos.</p>
<h2>Opción 3: Sin plugins, solo código</h2>
<p>Si prefieres no depender de ningún plugin, ni siquiera del mío, WordPress trae de serie los filtros que necesitas. Los dos que te interesan en multisitio son <code>use_block_editor_for_post_type</code>, desde WordPress 5.0, que decide el editor por tipo de contenido, y <code>use_widgets_block_editor</code>, desde WordPress 5.8, que hace lo mismo con la pantalla de widgets.</p>
<p>La forma más robusta de aplicarlos en toda una red es un mu-plugin. Como <a href="https://ayudawp.com/que-son-los-mu-plugins-de-wordpress/" target="_blank" rel="noopener">ya sabrás</a>, de guardan en <code>wp-content/mu-plugins</code>, una carpeta compartida por toda la instalación, así que WordPress los carga automáticamente en todos los sitios de la red sin que nadie los active ni pueda desactivarlos por error desde el escritorio.</p>
<p>El código sería este:</p>
<pre>&lt;?php
/**
 * Desactiva el editor de bloques en toda la red: entradas, páginas y widgets.
 */
add_filter( 'use_block_editor_for_post_type', '__return_false' );
add_filter( 'use_widgets_block_editor', '__return_false' );</pre>
<p>Guarda eso como, por ejemplo, <code>wp-content/mu-plugins/desactivar-editor-bloques.php</code> y ya está, sin pantalla de ajustes, sin activación, sin nada que un administrador de sitio pueda cambiar sin querer.</p>
<blockquote><p><strong>Advertencia:</strong> WordPress solo carga los archivos que están directamente dentro de <code>mu-plugins</code>, no los que metas en subcarpetas. Si organizas el código en varios archivos, necesitas uno en la raíz que haga los <code>require</code> del resto.</p></blockquote>
<p>Si lo que quieres es más quirúrgico, por ejemplo <strong>desactivarlo solo en entradas y dejarlo activo en páginas</strong>, el mismo filtro te sirve con un poco más de código:</p>
<pre>add_filter( 'use_block_editor_for_post_type', function( $use_block_editor, $post_type ) {
    if ( 'post' === $post_type ) {
        return false;
    }
    return $use_block_editor;
}, 10, 2 );</pre>
<p>Esta distinción exacta, bloques sí en páginas, bloques no en entradas, es justo el argumento de fondo por el qué he cambiado de postura con mi propio plugin. Si te ha convencido el porqué, aquí tienes el cómo hacerlo sin depender de nada.</p>
<h2>La constante mágica en wp-config (spoiler: no existe)</h2>
<p>Como vas a encontrarte información por ahí que habla de una supuesta constante nativa de WordPress para desactivar el editor de bloques te lo confirmo ya: <strong>no existe, nunca ha existido, y se rechazó expresamente</strong>.</p>
<p>En 2018 alguien pidió justo eso en el <a href="https://core.trac.wordpress.org/ticket/43068" target="_blank" rel="nofollow noopener">ticket 43068 de Trac</a>, algo del estilo <code>define('ENABLE_GUTENBERG', false)</code>. Se cerró como «wontfix», y la respuesta de un responsable de sistemas de WordPress.org lo explica mejor que yo:</p>
<blockquote><p><em>«No creo que vayamos a admitir una constante para esto […] WordPress ha estado intentando dejar de usar constantes, ya que son muy difíciles de cambiar más adelante […] «Oh, quiero Gutenberg, ¿por qué está desactivado? Oh, mi plugin de SEO cualquiera (o mi ex-desarrollador) pensó que no lo querría y lo desactivó a la fuerza, genial… ahora, ¿a quién puedo pedirle que me lo arregle?.</em></p></blockquote>
<p>O sea, que la rechazaron para evitarte justo el lío que estás intentando resolver con este artículo: una constante mágica en wp-config que nadie recuerda por qué está ahí.</p>
<p>Las únicas constantes reales para esto son las de plugins concretos, como las tres de no gutenberg que has visto arriba. Si un tutorial te dice que existe una constante nativa de WordPress para esto, está equivocado o está desactualizado.</p>
<h2>Lo que ninguna de las tres vías modifica: el editor del sitio</h2>
<p>Un tema de bloques de edición completa del sitio no edita sus plantillas por la pantalla clásica de entradas, sino por el Site Editor, una aplicación aparte.</p>
<p>Los filtros <code>use_block_editor_for_post_type</code> y <code>use_block_editor_for_post</code> solo deciden qué pasa en la pantalla de editar entradas y páginas, así que ni ellos ni el plugin Classic Editor llegan a tocar la edición de plantillas. Lo confirma la propia documentación de WordPress para temas clásicos, que «no funciona con el editor del sitio».</p>
<p>No Gutenberg? es la excepción parcial, con el interruptor específico para bloquear el acceso al editor del sitio que ya te he contado arriba, aunque ahí seguimos hablando de bloquear el acceso, no de convertir esas plantillas en algo editable de otra forma.</p>
<h2>¿Qué opción elijo, cuál es mejor?</h2>
<p>Pues, como con casi todo, dependerá de tus necesidades, te lo resumo fácil:</p>
<table>
<thead>
<tr>
<th>Necesitas</th>
<th>Classic Editor</th>
<th>No Gutenberg?</th>
<th>Archivo mu-plugin</th>
</tr>
</thead>
<tbody>
<tr>
<td>Elegir por tipo de contenido, perfil o plantilla</td>
<td>No</td>
<td>Sí</td>
<td>Sí, a base de código</td>
</tr>
<tr>
<td>Forzar toda la red desde wp-config, sin pantalla</td>
<td>No</td>
<td>Sí</td>
<td>Sí, por naturaleza</td>
</tr>
<tr>
<td>Proteger entradas ya construidas con bloques</td>
<td>No</td>
<td>Sí</td>
<td>No</td>
</tr>
<tr>
<td>Bloquear también el editor del sitio</td>
<td>No</td>
<td>Sí</td>
<td>No, sin código extra</td>
</tr>
<tr>
<td>Cero plugins</td>
<td>No</td>
<td>No</td>
<td>Sí</td>
</tr>
</tbody>
</table>
<h2>¿Cuál usar en una red multisitio?</h2>
<p>Dicho todo lo anterior, mi recomendación práctica:</p>
<ul>
<li><strong>Red de sitios parecidos entre sí</strong>, un único superadministrador y quieres algo simple de gestionar: plugin Classic Editor activado en red.</li>
<li><strong>Necesitas reglas distintas</strong> según el sitio, el tipo de contenido o el perfil, o te preocupa que alguna entrada ya maquetada con bloques se rompa: No Gutenberg?, configurado por sitio o forzado entero desde wp-config si quieres uniformidad total.</li>
<li><strong>Red grande y cero dependencias</strong>, control absoluto por código y ni un ajuste que nadie pueda tocar por error: mu-plugin con los filtros nativos.</li>
</ul>
<p>Si te decides por No Gutenberg? tienes la <a href="https://wordpress.org/plugins/no-gutenberg/" target="_blank" rel="nofollow noopener">página del plugin en wordpress.org</a> con el resto de ajustes que no caben en este artículo centrado en multisitio.</p>
<p>Si tienes una red con una configuración rara que no encaja en ninguna de las tres opciones, cuéntamelo en los comentarios, que seguro que no eres el único.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/editor-clasico-en-multisitio/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Si usas Markdown para agentes y llms-full.txt en WordPress podrían estar «regalando» tu contenido de pago</title>
		<link>https://ayudawp.com/markdown-llms-full-vulnerabilidad/</link>
					<comments>https://ayudawp.com/markdown-llms-full-vulnerabilidad/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Tue, 01 Sep 2026 06:28:00 +0000</pubDate>
				<category><![CDATA[Plugins WordPress]]></category>
		<category><![CDATA[Programación + WordPress]]></category>
		<category><![CDATA[Seguridad WordPress]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Experto]]></category>
		<category><![CDATA[llms-full.txt]]></category>
		<category><![CDATA[Markdown]]></category>
		<category><![CDATA[Sensei]]></category>
		<category><![CDATA[VigIA]]></category>
		<category><![CDATA[Visibility]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=160028</guid>

					<description><![CDATA[Si tienes contenido privado y/o de pago en tu WordPress y sirves Markdown para agentes de IA o generas un fichero llms-full.txt podrías estar regalando ese contenido, gratis.]]></description>
										<content:encoded><![CDATA[<p>Si tienes <strong>contenido privado o de pago en tu WordPress</strong> (un curso, una zona de socios, cualquier cosa que hayas restringido) y además tienes instalado un plugin de los que sirven <strong>Markdown para agentes de IA</strong> o te generan el <code>llms.txt</code>, compruébalo tú mismo ahora mismo, es fácil, añade <code>.md</code> al final de la URL de ese contenido y mira qué te devuelve.</p>
<p><strong>Puede que lleves meses regalando tu contenido y tus datos a cualquiera</strong> que sepa hacer eso, que tampoco hace falta ser muy espabilado.</p>
<p>Lo probé en siete plugins, dos de ellos míos, y el resultado no me hizo ninguna gracia, solo uno pasaba limpios los tres casos que le puse por delante.</p>
<p>Y no, esto no va de «estos plugins están mal hechos», que sería quedarme corto y además aburrido. Va de algo más interesante, de que existe una forma correcta de hacerlo, la usaba uno solo de los siete, y resulta que <strong>WordPress ya había resuelto exactamente este mismo problema hace años en su API REST</strong>.</p>
<p>La solución estaba escrita, publicada y a la vista de cualquiera, y todos habíamos pasado por delante de ella sin darnos ni puta cuenta, de puro bobo que era el fallo, pero sobre todo porque no habíamos caído nadie en ello.</p>
<p>La buena noticia es que esto acaba bien, avisé al equipo de plugins de WordPress.org el 27 de julio, los autores reaccionaron rápido, y a día de hoy de los siete solo queda uno sin corregir, precisamente el único que lleva más de un año abandonado. Y por el camino ha salido una propuesta para mejorar las comprobaciones de Plugin Check, que es lo mejor que le podía pasar a todo esto.</p>
<p>Te cuento cómo lo probé, qué me encontré, lo que me pasó arreglando mis propios plugins (que no me lo esperaba, oye), qué puedes hacer tú para saber si te afecta y cómo se hace bien si desarrollas plugins.</p>
<h2>Análisis forense</h2>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-160044" src="https://ayudawp.com/wp-content/uploads/2026/07/filtracion-datos-markdown-WordPress.jpg" alt="" width="1200" height="800" srcset="https://ayudawp.com/wp-content/uploads/2026/07/filtracion-datos-markdown-WordPress.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/07/filtracion-datos-markdown-WordPress-768x512.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/07/filtracion-datos-markdown-WordPress-240x160.jpg 240w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></p>
<p>Empezamos por <strong>el diagnóstico técnico</strong>, por todo lo que puede fallar y, para variar, fallará, como reza la famosa Ley de Murphy.</p>
<h3>En qué hemos fallado todos los que hacemos plugins de Markdown para agentes y archivos llms.txt</h3>
<p>Un plugin que quiere servir tu contenido en Markdown para agentes de IA tiene <strong>dos maneras</strong> de construir ese <code>.md</code>, una mala y otra buena:</p>
<ul>
<li>Tomar el <code>post_content</code> tal cual está en la base de datos, pasarlo por los filtros de turno y convertirlo. Es la rápida, la que usa casi todo el mundo, y también la que abre el problema, pues <strong>genera una ruta paralela que se salta por completo la capa de protección de tu contenido</strong>.</li>
<li>Dejar que WordPress procese la página como lo hace siempre, con toda su lógica de permisos incluida, y convertir a Markdown el HTML que ya ha salido. Es la lenta, porque generas la página entera para quedarte solo con el texto, y era la que usaba exactamente uno de los siete plugins que probé.</li>
</ul>
<p><strong>La clave de todo el asunto es que WordPress no tiene una API de autorización de contenido separada de la visualización</strong>, tiene <code>post_password_required()</code> (la función que decide si hay que pedir la contraseña antes de enseñar una entrada) para las contraseñas del propio núcleo, y las capacidades de usuario para lo demás.</p>
<p>Todo lo demás, LMS y plugins de membresías incluidos, se protege enganchándose al filtro <code>the_content</code> (el que procesa el cuerpo de una entrada justo antes de pintarlo en pantalla) o sustituyendo directamente la plantilla que se muestra.</p>
<p>Son capas de presentación, no de datos, por lo que <strong>si un plugin no pasa por ahí, no se entera de que existen, y las salta todas</strong>.</p>
<p>Dentro de la opción rápida hay además una parte que <strong>depende de una sola línea de código, y que explica por qué unos plugins protegían la mitad de los casos y otros ninguno</strong>.</p>
<p>Los filtros de restricción, para saber qué entrada están mirando, preguntan con <code>get_the_ID()</code>, y esa función lee la variable global <code>$GLOBALS['post']</code>.</p>
<p>Si el plugin que genera el Markdown no ha rellenado antes esa variable, el filtro pregunta por un post que no existe, no encuentra nada que proteger y deja pasar el contenido entero, con contraseña, con restricción de perfil de usuario o sin ninguna de las dos.</p>
<p>Aquí viene el matiz que genera el problema, <code>setup_postdata()</code>, la función que prepara las variables del loop de WordPress (título, extracto, autor…) para pintar una entrada, <strong>no rellena por sí sola <code>$GLOBALS['post']</code></strong>. Hacen falta las dos cosas, asignar la variable global y llamar a la función, y quedarte solo con una de ellas es dejar la tarea a medias sin saberlo.</p>
<p>Y aun haciéndolo perfecto se te <strong>queda fuera cualquier plugin que proteja por plantilla</strong> en lugar de por <code>the_content</code>. <strong>Sensei LMS</strong> es el caso típico, porque no filtra el contenido, sustituye directamente lo que se muestra en pantalla, así que ninguna comprobación sobre <code>the_content</code> le va a hacer siquiera cosquillas.</p>
<p>Un detalle técnico que conviene tener claro es que la contraseña de WordPress y la restricción por perfil no son el mismo tipo de comprobación, aunque lo parezcan desde fuera.</p>
<p>La segunda suele resolverse casi sola si tu plugin usa bien <code>current_user_can()</code> (la función que comprueba los permisos del usuario), porque va de capacidades. La primera va por libre, con su propio mecanismo, que no tiene nada que ver con perfiles ni capacidades, así que hay que tratarla aparte, a propósito. Por eso te vas a encontrar plugins que aciertan con una cosa y fallan con la otra.</p>
<h3>Cómo hice las pruebas de esta cagada</h3>
<p>Instalación limpia de WordPress 7.0.2 en Local, con tres contenidos restringidos de tres formas distintas:</p>
<ul>
<li>Una entrada con <strong>contraseña de WordPress</strong>, el mecanismo del propio núcleo.</li>
<li>Una página con <strong>restricción por perfil de usuario</strong>, usando el plugin Members 3.2.26.</li>
<li>Una <strong>lección de pago de un curso de Sensei LMS 4.26.1</strong>, con inicio de sesión obligatorio.</li>
</ul>
<p>De cada uno comprobé lo mismo, que la versión HTML normal oculta el contenido tal y como toca, y después pedí la versión Markdown de esa misma URL sin haber iniciado sesión, a ver qué me devolvía. Sin cookies, sin usuario, tal y como lo pediría cualquier agente de IA que pase por tu web.</p>
<h3>Lo que me encontré (¡ay madre!)</h3>
<p>Probé cinco plugins de terceros más los dos míos, <a href="https://ayudawp.com/tag/vigia/" target="_blank" rel="ugc noopener">VigIA</a> y <a href="https://ayudawp.com/tag/visibility/" target="_blank" rel="ugc noopener">Visibility</a>. De los siete <strong>solo uno pasaba limpios los tres casos</strong>, <a href="https://wordpress.org/plugins/markdown-for-ai-agents/" target="_blank" rel="nofollow noopener">Markdown for AI Agents</a>.</p>
<p>Esta es la foto del 27 de julio de 2026, con las versiones que había ese día, y la última columna te dice cómo está la cosa ahora:</p>
<table>
<thead>
<tr>
<th>Plugin y versión probada</th>
<th>Contraseña</th>
<th>Perfil</th>
<th>Lección LMS</th>
<th>Corregido en</th>
</tr>
</thead>
<tbody>
<tr>
<td>Markdown for AI Agents 1.0.0</td>
<td>Protege</td>
<td>Protege</td>
<td>Protege</td>
<td>No le hacía falta</td>
</tr>
<tr>
<td>JumpsuitAI llms.txt + Markdown Endpoints 1.1.6</td>
<td>Protege</td>
<td>Protege</td>
<td><em>Filtraba</em></td>
<td>1.1.7</td>
</tr>
<tr>
<td>Website LLMs.txt 8.5.3</td>
<td>Sin confirmar</td>
<td><em>Filtraba</em></td>
<td>Sin confirmar</td>
<td>8.5.6</td>
</tr>
<tr>
<td>LLMs.txt and LLMs-Full.txt Generator 2.0.9</td>
<td><em>Filtraba</em></td>
<td><em>Filtraba</em></td>
<td><em>Filtraba</em></td>
<td>2.1.1</td>
</tr>
<tr>
<td><span style="color: #ff0000;">Markdown Mirror 1.0.0</span></td>
<td><span style="color: #ff0000;">Filtra</span></td>
<td><span style="color: #ff0000;">Filtra</span></td>
<td>No aplica</td>
<td><span style="color: #ff0000;">Sin corregir</span></td>
</tr>
<tr>
<td>VigIA 2.4.3</td>
<td>Protege</td>
<td>Protege</td>
<td><em>Filtraba</em></td>
<td>2.4.4</td>
</tr>
<tr>
<td>Visibility 2.0.0</td>
<td>Protege</td>
<td><em>Filtraba</em></td>
<td><em>Filtraba</em></td>
<td>2.1.0</td>
</tr>
</tbody>
</table>
<p>Las dos filas de abajo son mías, y las corregí y publiqué antes de escribir a nadie, que era lo mínimo. Los «sin confirmar» de Website LLMs.txt son literales, esos dos casos no llegué a medirlos y no voy a decir que fallaban sin haberlo comprobado.</p>
<p>Notas por plugin, todas verificadas contra el código:</p>
<ul>
<li><strong>Markdown for AI Agents</strong> es el único que no estaba afectado, y lo consigue haciendo algo distinto a todos los demás, engancha un buffer de salida sobre <code>template_include</code> y convierte a Markdown el HTML que WordPress ya ha renderizado. Hereda la protección entera, incluida la de Sensei, sin saber que Sensei existe. Paga más rendimiento y el Markdown le sale con restos del decorado de la página, pero en seguridad es correcto por construcción, que es lo que cuenta.</li>
<li><strong>JumpsuitAI</strong> establecía <code>$GLOBALS['post']</code> y llamaba a <code>setup_postdata()</code> antes de aplicar los filtros, y llevaba un comentario en el código explicando que si no lo hace, los endpoints <code>.md</code> devuelven el cuerpo equivocado. Alguien ya se había topado con esto antes. Protegía los dos primeros casos y caía con Sensei.</li>
<li><strong>Website LLMs.txt</strong> volcaba el contenido de la página restringida por perfil en <code>/llms.txt</code> al activar la opción de contenido detallado. Además listaba los títulos y las URLs del contenido restringido aunque no volcara el cuerpo, lo que ya revela su existencia.</li>
<li><strong>LLMs.txt and LLMs-Full.txt Generator</strong> era el de mayor impacto. Tomaba <code>post_content</code> directo de la base de datos, sin pasar por <code>the_content</code> siquiera, y lo escribía en un <strong>fichero físico en la raíz del sitio</strong>, con los tres casos dentro. Y como es un <code>.txt</code> estático que sirve el servidor web sin pasar por WordPress, desactivar el plugin no impide que se siga sirviendo, y ningún otro plugin puede taparlo. En mi instalación de pruebas ese fichero ocupaba 59 KB con el contenido privado dentro.</li>
<li><strong>Markdown Mirror</strong> es el ejemplo del matiz técnico de antes, llama a <code>setup_postdata()</code> pero no asigna <code>$GLOBALS['post']</code>, y con eso ya filtra. Incluso el caso de la contraseña de WordPress, que es el más básico de todos y no necesita ningún plugin de terceros para reproducirse. La salida arrastra además el prefijo que WordPress pone a los títulos protegidos, justo encima del contenido que acaba de destapar:</li>
</ul>
<pre># Protected: Post con contrasena
CONTENIDO BAJO CONTRASEÑA</pre>
<h3>Lo que aprendí arreglando mis propios plugins</h3>
<p>Esta es la parte del artículo que más vale la pena (creo), y no salió de auditar nada, salió de arreglarlo.</p>
<p>Un plugin puede aprobar los tres casos de la tabla de arriba y aun así tener dos agujeros más, porque las tres pruebas se hacen <strong>sin haber iniciado sesión</strong>, y hay cosas que solo se ven con una sesión de administrador abierta.</p>
<h4>La primera capa: preguntarle al usuario equivocado</h4>
<p>El arreglo obvio, el que se te ocurre a la primera, es comprobar si el visitante que pide el Markdown puede leer esa entrada, usando la propia API del plugin de turno que la protege.</p>
<p>Suena razonable, ¿verdad?, pues el problema es que Sensei tiene una función, <code>sensei_all_access()</code>, que <strong>da acceso total a los administradores</strong> por defecto, y tiene todo el sentido del mundo para la interfaz de administración, dicho sea de paso.</p>
<p>Así que si le preguntas a esa función «¿puede este usuario ver la lección?» con un administrador identificado, te dice que sí, aunque la lección sea de pago y ese administrador no esté matriculado en el curso, y ese «sí» se cuela en el Markdown que generas.</p>
<p>Esto me pasó primero en Visibility, mientras lo probaba con sesión iniciada para otra cosa, la lección de pago salía entera por el <code>.md</code> mientras que la página HTML de esa misma lección me enseñaba, correctamente, el aviso de que no estaba matriculado.</p>
<p>Lo reproduje después en VigIA, con un administrador devolvía un <code>200</code> con el contenido dentro, y como visitante anónimo un <code>404</code>. Mismo agujero en dos plugins.</p>
<p>Pero no tuvo la misma gravedad en los dos casos, y esto es importante:</p>
<ul>
<li>En VigIA se quedó en una incoherencia sin consecuencias para nadie más, porque su función que decide qué se puede guardar en caché no dejaba cachear nada generado con una sesión abierta, así que ese documento con fugas no llegó a servirse jamás a otra persona.</li>
<li>En Visibility sí había fuga de verdad, porque esa misma salvaguarda existía en el Markdown por entrada, pero no en el generador de <code>llms.txt</code>, que cachea el archivo entero sin ningún componente de usuario. Un archivo generado una vez con mis ojos de administrador delante se podía quedar ahí, servido después a cualquiera que lo pidiera.</li>
</ul>
<p><strong>La pregunta correcta en estas superficies no es «¿puede leerlo quien lo pide?», es «¿puede leerlo cualquiera?»</strong>, porque lo que se genera aquí se entrega igual a todo el que lo pida después, esté cacheado o no.</p>
<p>La solución de verdad es <strong>evaluar siempre como si fueras un visitante anónimo</strong>, con un contexto que se abre antes de decidir y se cierra después, venga quien venga a pedirlo.</p>
<h4>La segunda capa, la peor: quién genera el fichero</h4>
<p>Los plugins que escriben un <code>llms.txt</code> físico en la raíz de tu web lo generan casi siempre desde una petición de administración o desde una tarea programada, un cron.</p>
<p>Si la comprobación de acceso se hace con el usuario de esa petición concreta, el fichero se escribe con todo lo que ve un administrador dentro, y luego es tu propio servidor web el que sirve ese fichero a cualquiera, sin que WordPress vuelva a intervenir para nada.</p>
<p>Es <strong>el mismo agujero</strong> de antes, pero por <strong>una puerta que ninguna prueba en anónimo detecta jamás</strong>, porque el fichero ya está escrito de antemano.</p>
<p>Esta capa fue solo de Visibility, y el orden en que llegué a ella tiene su miga. VigIA no la traía resuelta de serie, su versión anterior, la 2.4.3, ni siquiera tenía una clase de control de acceso en su generador de <code>llms.txt</code>.</p>
<p>Preparé el arreglo de VigIA después de haber arreglado ya Visibility, y ese arreglo volvió con una parte que yo no había pedido para esa tarea concreta, el contexto anónimo ya integrado en el generador de LLMS de VigIA.</p>
<p>Al leer esa parte de más para entender qué hacía fue cuando vi que Visibility escribía su <code>llms-full.txt</code> desde <code>admin_init</code> (el momento en que WordPress arranca cualquier pantalla del escritorio), es decir, con el administrador identificado, en <strong>un fichero que después entrega el servidor web a cualquiera sin preguntar</strong> nada.</p>
<p>El nivel de certeza no es el mismo en las dos capas, y te lo digo tal cual para que lo sepas. La primera la medí en los dos estados, antes y después del arreglo, en los dos plugins.</p>
<p>La segunda la establecí leyendo el código antes de tocarlo, y la comprobé después generando el fichero como administrador con las lecciones incluidas en los tipos de contenido, cero fugas y 36 entradas legítimas dentro.</p>
<p>Si te sirve la moraleja, la secuencia fue arreglar Visibility, preparar el arreglo de VigIA, y recibir de vuelta una parte que no había siquiera adivinado, y descubrir con ella un agujero propio que se me había pasado.</p>
<p>Tener dos implementaciones distintas del mismo problema y poder compararlas es un lujo que no siempre te puedes permitir, y esta vez me vino de maravilla.</p>
<p><strong>Para quien quiera auditar lo suyo:</strong> todas las comprobaciones con <code>curl</code> sin cookie te van a salir en verde aunque tu web esté filtrando. Hace falta repetirlas también con una sesión de administrador abierta, y comprobar después qué se ha quedado escrito en las cachés y en los ficheros.</p>
<h3>Dos matices técnicos más</h3>
<p>Van verificados contra el código, son de la parte densa del artículo, pero merece la pena que los conozcas si programas o mantienes plugins.</p>
<p><strong>La función <code>is_post_type_viewable()</code> no responde lo que parece que responde.</strong> Es la función a la que uno recurre para preguntar «¿este tipo de contenido tiene una URL pública de verdad?», y la respuesta puede ser que sí cuando la realidad es que no.</p>
<p>Termina pasando por un filtro, <code>is_post_type_viewable</code>, que muchos plugins usan con toda lógica, para que el editor de bloques trate como visible un tipo de contenido interno suyo, y Sensei lo hace con sus plantillas de correo, en <code>includes/internal/emails/class-email-post-type.php</code>.</p>
<p>El resultado es que en una petición hecha desde el área de administración <strong>la función te contesta que sí, que es público, para un tipo de contenido que no tiene ninguna página pública</strong>.</p>
<p>Si tu plugin se apoya en esa función para decidir qué publicar en el Markdown o en el <code>llms.txt</code>, vas a publicar de más. Lo único que no falla es calcular la regla del núcleo a mano, <code>publicly_queryable || ( _builtin &amp;&amp; public )</code>.</p>
<p>Y ojo, que este fallo es traicionero, porque no aparece en las comprobaciones automatizadas, solo asoma cuando se renderiza una pantalla de administración de verdad.</p>
<p><strong>Los mensajes privados de un LMS son, oficialmente, un tipo de contenido público.</strong> Sensei registra su tipo de contenido <code>sensei_message</code>, que es la correspondencia entre alumno y profesor, con <code>public =&gt; true</code> y <code>publicly_queryable =&gt; true</code>.</p>
<p>Cualquier plugin que te ofrezca un selector de «elige qué tipos de contenido publicar» lo va a listar ahí, tan tranquilo, justo al lado de entradas y páginas, y como no le pongas cuidado y lo marques, <strong>acabas de publicar conversaciones privadas entre tus alumnos y tus profesores</strong>. No hace falta que nadie tenga mala intención, basta con no saber esto.</p>
<h3>La API REST ya tenía resuelto este tipo de problema</h3>
<p>Y este es el remate de todo el análisis, porque resulta que la API REST del propio núcleo de WordPress es exactamente el mismo tipo de superficie paralela que un endpoint de Markdown o un <code>llms.txt</code>, y ahí las tres pruebas salen perfectas:</p>
<pre>GET /wp-json/wp/v2/pages/&lt;id&gt;   (restringida por perfil)  → content.rendered vacío
GET /wp-json/wp/v2/posts/&lt;id&gt;   (con contraseña)          → content.rendered vacío, protected: true
GET /wp-json/wp/v2/lesson/&lt;id&gt;  (lección de Sensei)       → 404, la ruta ni siquiera existe</pre>
<p>Hay tres decisiones de diseño detrás de esto, y las tres sirven para cualquier sitio donde las apliques:</p>
<ol>
<li><strong>El controlador establece el contexto de la publicación antes de aplicar <code>the_content</code></strong>, así que los plugins de restricción funcionan sin tener ni idea de que existe una API REST. No hace falta que nadie lo sepa para que funcione.</li>
<li><strong>El caso de la contraseña está tratado de forma explícita, y se señaliza</strong> con un campo <code>protected</code> en la respuesta. No se limita a vaciar el contenido y ya está, te avisa de por qué está vacío.</li>
<li><strong>Sensei directamente no expone su tipo de contenido <code>lesson</code> en la API REST.</strong> Cuando no puedes garantizar el control de acceso en una superficie nueva, no abres esa superficie, y punto.</li>
</ol>
<p>Esa tercera es la lección de fondo, y va mucho más allá del Markdown para IA, que cada vez que abres una salida nueva del mismo contenido, un feed, un endpoint, un fichero estático, un <code>.md</code>, heredas la obligación de reimplementar los controles de acceso desde cero, y WordPress no te avisa de eso en ningún sitio.</p>
<p>Precedentes hay de sobra, los feeds RSS, oEmbed, AMP en su día, y el propio Sensei tuvo que parchear su feed RSS por este motivo exacto en la versión 4.24.5.</p>
<h2>Qué hacer si usas plugins de Markdown para agentes o llms.txt</h2>
<p>La comprobación te lleva diez segundos, y hazla <strong>con la sesión cerrada, o en una ventana de incógnito</strong>:</p>
<ol>
<li>Copia la URL de cualquier contenido restringido de tu web.</li>
<li>Añádele <code>.md</code> al final y ábrela.</li>
<li>Mira si sale el contenido privado que no debería verse sin restricción.</li>
</ol>
<p>De paso, abre <code>tudominio.com/llms.txt</code> y <code>tudominio.com/llms-full.txt</code> y busca ahí dentro cosas que no deberían estar.</p>
<p><strong>Y ahora repite las dos comprobaciones con tu sesión de administrador abierta</strong>, que es donde aparecen los dos agujeros que te contaba antes.</p>
<p>Si con la sesión abierta ves contenido que en anónimo no aparecía, ese documento puede estar quedándose guardado en una caché o en un fichero, a disposición de cualquiera que pase después que tú.</p>
<p>Si te sale <strong>contenido que no debería verse</strong>:</p>
<ul>
<li>Actualiza el plugin, que si es de los de la tabla ya está corregido, salvo Markdown Mirror.</li>
<li>Si no hay versión nueva, <strong>desactiva el módulo de Markdown o el plugin entero</strong> hasta que la haya.</li>
<li>Comprueba si te ha quedado un fichero físico en la raíz de tu instalación, porque desactivar el plugin no lo borra, y bórralo tú a mano.</li>
<li>Y si has tenido el <code>llms-full.txt</code> publicado un tiempo, da por hecho que alguien lo ha leído y actúa en consecuencia con lo que hubiera dentro.</li>
</ul>
<p>Avisar al autor del plugin, mejor en privado, nunca está de más, y si no contesta ni saca parche en un tiempo razonable, cambia de plugin y listo, no merece la pena jugársela por algo que ni siquiera está tremendamente extendido.</p>
<h2>Qué pasó cuando lo reporté</h2>
<p>Esta parte me parece la más interesante de contar, además porque es la que no suele contarse nunca.</p>
<p>Lo primero fue arreglar lo mío y publicarlo, Visibility 2.1.0 y VigIA 2.4.4 salieron el 27 de julio, antes de escribir a nadie. No puedes ir señalando fallos ajenos con los tuyos sin parchear, así que eso ni se discute.</p>
<p>Con eso hecho escribí a plugins@wordpress.org, el equipo de plugins de WordPress.org, con el detalle técnico, los pasos de reproducción y las ubicaciones exactas en el código de cada hallazgo.</p>
<p>Les ofrecí ajustarme a la ventana de divulgación que ellos prefirieran, y a falta de indicación distinta me quedé con los 30 días de siempre.</p>
<p>Su respuesta fue breve y al grano, que gracias por el reporte, que es importante para la comunidad señalar este tipo de cosas y que ellos avisarían a los autores.</p>
<p>Y los autores respondieron, que es lo que quería contarte:</p>
<ul>
<li><strong>JumpsuitAI</strong> corrigió el caso de Sensei en la 1.1.7.</li>
<li><strong>LLMs.txt and LLMs-Full.txt Generator</strong>, que era el de mayor impacto de todos, corrigió en la 2.1.1.</li>
<li><strong>Website LLMs.txt</strong> merece un párrafo aparte y va justo debajo.</li>
<li><span style="color: #ff0000;"><strong>Markdown Mirror</strong></span> sigue sin corregir, y es el único. Su última actualización es de julio de 2025, no tiene soporte activo y ronda las 200 instalaciones. Si lo tienes puesto, quítalo, ni lo dudes.</li>
</ul>
<p>Lo de Website LLMs.txt es muy buen ejemplo de reacción bien hecha, y hablamos de un plugin con unas 40.000 instalaciones activas, o sea que la decisión no era ninguna tontería para ellos.</p>
<p>No taparon el síntoma, fueron a la raíz. En su registro de cambios explican que el contenido que no es públicamente visible ya no entra en el fichero generado, y que si usas un plugin de membresía o de control de acceso tus entradas y páginas se quedan fuera por defecto, porque no hay forma fiable de saber desde la base de datos cuáles puede leer un visitante.</p>
<p>Esa última frase es exactamente el problema de fondo que yo les había descrito, asumido y convertido en decisión de producto. Prefirieron publicar de menos antes que arriesgarse a publicar de más, y añadieron un resumen en pantalla de lo que se ha quedado fuera para que el usuario pueda incluir a mano lo que quiera. Eso es hacerlo bien.</p>
<p>Y tiene un epílogo que me hizo mucha gracia, porque les hicieron falta tres versiones. La 8.5.4 arregló el fondo, la 8.5.5 arregló que en algunos sitios el <code>llms.txt</code> viejo no se llegaba a borrar durante la actualización y se seguía sirviendo, y la 8.5.6 remató lo mismo por otra vía. Justo mi segunda capa, la del fichero físico que sobrevive a todo, pasándole a otro en tiempo real.</p>
<p>Lo importante es que lo arreglaron.</p>
<h3>Cómo se hace bien, si desarrollas plugins</h3>
<p>Esto es lo que le mandé al equipo de plugins como resumen de implementación correcta, por si le sirve a alguien que esté montando algo parecido:</p>
<ol>
<li>Establece <code>$GLOBALS['post']</code> y llama a <code>setup_postdata()</code> antes de aplicar <code>the_content</code>, y restaura después.</li>
<li>Evalúa el acceso como visitante no identificado, nunca como el usuario actual, porque la salida es pública y se cachea sin componente de usuario.</li>
<li>Comprueba explícitamente contra los plugins de LMS y membresías que publiquen una API de acceso, y deja fuera los tipos de contenido de los que no la publiquen.</li>
<li>No publiques nunca nada de un tipo de contenido que no tenga portada propia en <code>frontend</code>.</li>
<li>Ofrece un filtro para que cada sitio pueda vetar una entrada por su cuenta, pensando en el plugin que nadie ha previsto.</li>
</ol>
<h3>Lo que WordPress podría hacer, y lo que ya se está moviendo</h3>
<p>En el reporte incluí también unas observaciones sobre la plataforma, porque el núcleo no está exponiendo nada y la API REST lo hace bien, pero hay tres cosas que ponen muy fácil cometer este error.</p>
<p><strong>No existe una API de autorización de contenido separada de la presentación.</strong> El núcleo ofrece <code>post_password_required()</code> y el modelo de capacidades, y nada más, así que todos los LMS y plugins de membresías acaban aplicando sus reglas filtrando <code>the_content</code> o sustituyendo la plantilla. Algo como una función <code>is_post_content_readable( $post, $user )</code>, filtrable, que implementaran los plugins que restringen y consultaran los que publican, convertiría este tipo de fallo en algo difícil de escribir en lugar de fácil.</p>
<p><strong><code>is_post_type_viewable()</code> merece al menos una nota en la documentación</strong>, y mejor todavía una función hermana no filtrable que responda de verdad a «¿este tipo tiene URL pública?».</p>
<p><strong>Y el patrón de la API REST no está escrito en ninguna parte como patrón.</strong> Un apartado en el manual del desarrollador de plugins que dijera algo tan simple como «si expones contenido fuera de la plantilla, heredas estas responsabilidades» probablemente habría evitado casi todo lo que te he contado aquí.</p>
<p>Lo mejor de todo esto es que no se ha quedado en un correo. David Pérez, del equipo de plugins, abrió a partir del reporte <a href="https://github.com/WordPress/plugin-check/issues/1427" target="_blank" rel="nofollow noopener">una propuesta para mejorar las comprobaciones de Plugin Check</a>, la herramienta por la que pasan todos los plugins que se suben al repositorio. Si eso sale adelante, el fallo se detecta antes de publicarse, en todos los plugins que vengan a partir de ahora, no solo en estos siete.</p>
<p>Que un rato de trastear con tus propios plugins <strong>acabe mejorando la seguridad de los plugins que todavía no existen</strong> es, con diferencia, la mejor parte de esta historia.</p>
<h2>Resumiendo, revisa lo que tengas</h2>
<p>Si tienes <a href="https://wordpress.org/plugins/vigia/" target="_blank" rel="nofollow noopener">VigIA</a>, asegúrate de estar en la 2.4.4 o posterior, y si tienes <a href="https://wordpress.org/plugins/native-aeo-pack/" target="_blank" rel="nofollow noopener">Visibility</a>, en la 2.1.0 o posterior. Si usas cualquier otro plugin de los que sirven Markdown o generan tu <code>llms.txt</code>, actualízalo y haz la prueba de los diez segundos (arriba lo he dejado), primero sin sesión y después con ella.</p>
<p>Si te sale algo raro cuéntamelo en los comentarios, que entre todos se audita mejor que cada uno solo en su cueva. Y si quieres seguir aprendiendo de estas cosas tienes <a href="https://ayudawp.com/markdown-agentes-ia/" target="_blank" rel="ugc noopener">la guía completa de Markdown para agentes de IA</a> y <a href="https://ayudawp.com/llms-txt-llms-full-txt/" target="_blank" rel="ugc noopener">el pilar de llms.txt y llms-full.txt</a>.</p>
<hr>
<p>Para terminar, una reflexión que me ha surgido de todo esto, y es que las dos capas, el administrador que ve de más y el fichero que se escribe solo, han pasado sobre algo que en apariencia no podía ser más inofensivo.</p>
<p>Un <code>llms.txt</code> no es más que un listado de tus contenidos en texto plano, una especie de mapa del sitio pensado para agentes en vez de para buscadores.</p>
<p>Igualmente, servir tus entradas en Markdown es literalmente lo mismo que hacía AMP hace una década, ofrecer una versión ligera de tu contenido para un consumidor concreto, entonces Google, ahora un agente de IA.</p>
<p>Nada de esto tenía pinta de superficie de riesgo, en principio, pero resulta que <strong>la prisa por adaptarse a las nuevas exigencias de visibilidad en IA, sin pararse a comprobar que lo básico seguía funcionando, es la que acaba exponiendo datos sensibles o simplemente privados</strong>, y fíjate tú que sí, que hay que mirarlo todo, darse un momento de reflexión.</p>
<p>Yo he aprendido la lección, he reaccionado a tiempo, y mira que soy meticuloso probándolo todo, pero <strong>seguramente hay por ahí ahora mismo vulnerabilidades de todo tipo corriendo en tu web</strong> si alguien no ha tenido el mismo cuidado.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/markdown-llms-full-vulnerabilidad/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Seguridad WordPress en piloto automático: protege tu web cuando no estás</title>
		<link>https://ayudawp.com/seguridad-wordpress-piloto-automatico/</link>
					<comments>https://ayudawp.com/seguridad-wordpress-piloto-automatico/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Thu, 30 Jul 2026 06:28:14 +0000</pubDate>
				<category><![CDATA[Seguridad WordPress]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Principiante]]></category>
		<category><![CDATA[Vigilante]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159988</guid>

					<description><![CDATA[No siempre estás para vigilar tu web, así que aquí tienes una guía con la que poner en autopilot la seguridad de WordPress.]]></description>
										<content:encoded><![CDATA[<p>Tu web trabaja sola cuando tú no estás, el problema es que los que intentan reventarla también.</p>
<p>En agosto en la playa, en Navidad entre turrones, en ese puente que llevas esperando desde marzo, o un martes cualquiera si eres freelance y lo llevas todo tú solo, tu WordPress sigue ahí, abierto al mundo, recibiendo <strong>visitas de personas y de bots a partes iguales</strong> (y estoy siendo generoso con las personas).</p>
<p><strong>Los ataques a WordPress son automáticos en su inmensa mayoría</strong>, scripts que escanean millones de webs buscando la misma vulnerabilidad conocida, sin descanso, sin vacaciones y sin cogerse el puente de diciembre, así que <strong>la defensa también puede, y debe, ser automática</strong>.</p>
<p>Y esa es la buena noticia que vengo a contarte, que <strong>la seguridad de un WordPress no necesita que estés delante, necesita que la dejes bien montada</strong>.</p>
<p>Copias que se hacen y se comprueban solas, actualizaciones con red de seguridad, vigilancia que escanea sin que se lo pidas y alertas que solo te escriben cuando pasa algo de verdad, a eso es a lo que le llamo yo <strong>poner la seguridad en piloto automático</strong>.</p>
<p>Y ojo, que esto no va solo de vacaciones, va de cualquier web desatendida, y <strong>desatendida es toda web cuyo dueño tiene una vida, un trabajo, clientes o las tres cosas a la vez</strong>.</p>
<p>Si eres autónomo y no tienes a nadie detrás revisando registros de actividad (nadie revisa registros a diario, tranquilo, ni yo), este artículo es para ti los 365 días del año, no solo cuando haces la maleta.</p>
<p>Vamos a verlo de a poquito, en modo fácil, que ya sabes que soy cortito y explico las cosas como si fuesen para mi. Al final, por si no te apetece leer (ni aprender, tú verás) te dejo la lista de comprobación completa, la de cerrar la casa antes de irte de viaje.</p>
<h2>Qué puedes automatizar, qué puedes delegar y qué te toca a ti</h2>
<p>Cada tarea de seguridad de esta guía acaba en uno de tres sitios. O la haces tú una sola vez y se queda hecha, o la hace una máquina por ti cada día, o la hace otra persona por ti. <strong>Lo que no puede ser es que la seguridad de tu web dependa de que tú te acuerdes</strong>, porque no te vas a acordar, yo tampoco, y me dedico a esto.</p>
<p>¿Y quién es esa otra persona en la que delegar?</p>
<p>Pues según el caso, <strong>tu hosting, que si lo eliges bien hace bastante</strong> más de lo que crees, <strong>un buen plugin de seguridad</strong> bien configurado, o directamente <strong>un servicio de mantenimiento profesional</strong> como el que ofrecemos en <a href="https://mantenimiento.ayudawp.com/" target="_blank" rel="noopener">mantenimiento.ayudawp.com</a>, que viene a ser el vecino de confianza al que le dejas una copia de las llaves, solo que este sabe de WordPress y no tienes que traerle imanes de nevera a la vuelta.</p>
<p>Para que no te pierdas, cada sección termina con dos líneas, lo que se automatiza y lo que se puede delegar, y en quién. Empezamos por donde hay que empezar siempre.</p>
<h2>Lo primero, siempre: copias de seguridad automáticas</h2>
<p>Antes de tocar un solo ajuste, antes de actualizar nada, antes incluso de seguir leyendo, asegúrate de esto, porque <strong>la copia de seguridad es el paso previo de cualquier cambio y la última red cuando todo lo demás falla</strong>.</p>
<p>Si el cortafuegos no para el ataque, si una actualización rompe la web, si borras lo que no debías, <strong>un backup es lo que te devuelve el negocio a su sitio</strong>.</p>
<p>La regla de oro se llama 3-2-1, tres copias de tus datos, en dos soportes distintos y al menos una fuera del servidor de tu web, porque si tu única copia vive en el mismo servidor que la web y el servidor revienta, te quedas sin web y sin copia a la vez, bonito plan.</p>
<p>Sobre todo es importante <strong>que la copia sea completa, con todos los archivos imprescindibles y la base de datos</strong>, que he visto más de una «copia» que solo guardaba los archivos y dejaba fuera la base de datos, donde viven tus entradas, tus pedidos y tus usuarios, o sea, todo lo que importa, todo eso que no puedes descargar ni encargárselo a una IA.</p>
<p><strong>Cómo se automatizan las copias de seguridad</strong> fácil y (casi) gratis:</p>
<ol>
<li><strong>Las copias diarias de tu hosting</strong>, que los buenos las hacen sin que se lo pidas y te dejan además lanzar copias adicionales a mano antes de un cambio gordo.</li>
<li><strong>Al menos otra copia externa</strong> programada con un plugin de backups hacia otro sitio, tu Google Drive, un Dropbox, un almacenamiento S3, donde quieras, pero fuera del servidor.</li>
</ol>
<p>Con esas dos patas la ejecución queda resuelta sin que muevas un dedo, y la frecuencia la marca tu web, semanal para una web que apenas cambia, diaria como mínimo para un blog activo. En una tienda con pedidos entrando piénsate incluso algo más frecuente para la base de datos, que <strong>cada hora de diferencia son pedidos que podrías perder en una restauración</strong>.</p>
<p>Lo único que no se automatiza del todo es comprobar que la copia sirve de algo si la necesitases. <strong>Un backup que nunca has probado si se restaura bien es una promesa, pero aún no sabes si es una copia de seguridad.</strong></p>
<p>Antes de relajarte restaura una en un entorno de pruebas o en local, cronométralo y apunta los pasos, porque cuando la necesites de verdad no querrás estar aprendiendo a restaurar con la web caída y el móvil al 12% de batería.</p>
<p>Tengo publicada una <a href="https://ayudawp.com/copias-seguridad-wordpress/">guía completa de copias de seguridad en WordPress</a> con métodos y herramientas para cada caso, así que aquí no me extiendo más.</p>
<ul>
<li><strong>En piloto automático:</strong> las copias diarias del hosting y una copia externa programada fuera del servidor.</li>
<li><strong>Delegable:</strong> en tu hosting la ejecución diaria, y en un servicio de mantenimiento que además verifique las copias y haga restauraciones de prueba de vez en cuando.</li>
</ul>
<h2>Accesos: menos llaves repartidas y mejores cerraduras</h2>
<p>Piensa en cuánta gente tiene llaves de tu casa y desde cuándo, pues con tu WordPress pasa igual, pero peor, porque <strong>las llaves digitales no caducan solas</strong>. Ahí siguen el usuario del diseñador que pasó por la web en 2019, el de aquella agencia que probaste tres meses y el <code>admin2</code> que ya ni recuerdas quién creó.</p>
<p><strong>Cada usuario es una puerta abierta</strong>, y cada puerta con privilegios de administrador es una puerta blindada con la llave puesta por dentro si la contraseña es mala. La limpieza es manual pero de una sola vez.</p>
<p>Entra en la pantalla de gestión de usuarios de tu WordPress, <strong>borra los que no reconozcas o no se usen</strong> (WordPress te preguntará a quién reasignar sus contenidos, así que no pierdes nada) y <strong>baja privilegios a todo el que no necesite ser administrador</strong>, que un editor publica y edita perfectamente sin poder instalar plugins ni tocar ajustes.</p>
<p>El resto sí se queda funcionando en automático, a saber:</p>
<ul>
<li><strong>Contraseñas únicas</strong> y largas guardadas en un gestor de contraseñas</li>
<li><strong>Identificación en dos pasos</strong> activada y a poder ser forzada para todos los que acceden (el famoso 2FA, ese código del móvil que hace que <strong>aunque te roben la contraseña no puedan entrar sin tu teléfono</strong>)</li>
<li><strong>Protección contra fuerza bruta</strong> que bloquee sola las IPs que prueban contraseñas en cadena.</li>
</ul>
<p>Todo eso lo hace gratis cualquier plugin de seguridad serio, y una vez configurado no vuelve a pedirte nada.</p>
<p>Y <strong>ya que estás con la limpieza, aplícala también al código</strong>. Los plugins desactivados y los temas antiguos que guardas «por si acaso» siguen siendo archivos presentes en tu servidor, y algunos agujeros se explotan aunque el plugin esté desactivado.</p>
<p><strong>Menos código instalado es menos superficie de ataque</strong>, así que borra lo que no uses y deja un solo tema de reserva de los oficiales, por si toca descartar problemas algún día.</p>
<ul>
<li><strong>En piloto automático:</strong> el bloqueo de fuerza bruta, el 2FA forzado y las políticas de contraseñas.</li>
<li><strong>Delegable:</strong> la auditoría de usuarios, permisos y plugins sobrantes, que es de lo primero que se revisa en cualquier puesta a punto profesional.</li>
</ul>
<h2>Ajustes de una sola vez que trabajan para siempre</h2>
<p>Hay una parte de la seguridad WordPress que es puro «<strong>configurar y olvidarte</strong>», el famoso <strong><em>hardening</em></strong> (refuerzo, vaya), y es la más agradecida para una web desatendida porque <strong>no genera avisos, ni mantenimiento, ni nada</strong>, lo activas y ya está.</p>
<p>Lo esencial cabe en <strong>cuatro acciones</strong>:</p>
<ol>
<li><strong>Desactivar la edición de archivos</strong> desde el escritorio de WordPress, para que si alguien entra con una cuenta robada no pueda reescribirte el tema desde dentro, que es una línea en <code>wp-config.php</code> y listo.</li>
<li><strong>Cerrar <code>xmlrpc.php</code> si no lo usas</strong>, un protocolo de acceso remoto de otra época que hoy casi nadie necesita y que los bots adoran.</li>
<li><strong>Añadir cabeceras de seguridad</strong>, unas instrucciones que tu servidor manda al navegador para evitar cosas feas, como que otra web meta la tuya en un marco invisible para robarle los clics a tus visitantes.</li>
<li><strong>Proteger de miradas ajenas los archivos sensibles</strong> de la instalación.</li>
</ol>
<p>¿Quieres hacerlo a mano y gratis? En las <a href="https://herramientas.ayudawp.com/">herramientas gratuitas para WordPress</a> tienes generadores de <a href="https://herramientas.ayudawp.com/wpconfig/">wp-config.php</a>, de <a href="https://herramientas.ayudawp.com/htaccess/">.htaccess</a> y de <a href="https://herramientas.ayudawp.com/security-headers/">cabeceras de seguridad</a> que te montan el código marcando opciones, copiar, pegar y hasta luego <em>maricarmen</em>.</p>
<p><strong>¿Prefieres que lo haga un plugin?</strong> Pues aquí presento al que va a salir varias veces en lo que queda de artículo, <a href="https://vigilante.works/es/">Vigilante</a>, ese pedazo de plugin de seguridad, gratuito del todo y sin versión de pago, que <strong>aplica todo este refuerzo de manera sencilla y casi por defecto</strong>.</p>
<p>Y con un detalle especialmente importante para el que va a dejar la web sola, y es que antes de tocar <code>wp-config.php</code>, <code>.htaccess</code> o <code>robots.txt</code> el plugin hace <strong>copia de los archivos originales con verificación de integridad</strong>, y si un día lo desactivas lo restaura todo como estaba.</p>
<p>Más majo él, hasta cuando tú decides no darle el cariño que merece te cuida, y luego tú criticando.</p>
<p>Cualquier <strong>plugin de seguridad serio bien configurado</strong> te cubre buena parte de esta guía, y tienes una <a href="https://vigilante.works/es/comparativa.html">comparativa función a función de los plugins de seguridad</a> más conocidos por si quieres elegir con datos, casi sin opiniones.</p>
<ul>
<li><strong>En piloto automático:</strong> todo, esa es la gracia. Se configura una vez y las reglas se mantienen solas.</li>
<li><strong>Delegable:</strong> en un profesional para una puesta a punto única, un par de horas de trabajo que se quedan hechas para siempre.</li>
</ul>
<h2>Actualizaciones automáticas, sí, no te quejes, que es gratis</h2>
<p>Aquí llega <strong>el debate más bobo del mundo WordPress</strong>, entre el «actualiza siempre al momento» y el «si no está roto no lo toques». Ambps dos bandos tienen (algo de) razón, pero ninguno la tiene del todo.</p>
<h3>Lo que WordPress trae de serie</h3>
<p>Desde la versión 3.7, allá por 2013, seguro que ni te acuerdas, <strong>WordPress se actualiza solo en las versiones menores, las de seguridad y mantenimiento</strong>, y eso déjalo como está, que ha salvado muchas más webs de las que ha roto.</p>
<p>Y desde la versiób 5.5 puedes activar además actualizaciones automáticas por cada plugin y cada tema desde el propio escritorio, con su enlace al lado de cada uno en el listado.</p>
<p>El problema de la vía nativa es que <strong>actualiza a pelo, sin copia previa, sin comprobar después si la web sigue viva, sin marcha atrás si algo peta</strong>. De este modo, si un plugin rompe tu web un sábado a las tres de la madrugada, <strong>te enteras el lunes por un cliente, o no te enteras, que es peor</strong>.</p>
<h3>Los pros y los contras</h3>
<p>A favor de automatizar hay un dato que lo aplasta casi todo, y es que <strong>la inmensa mayoría de los hackeos de WordPress explotan vulnerabilidades conocidas que ya tenían arreglo publicado</strong>.</p>
<p>Nada de hazañas de película ni ataques dirigidos a tu web en concreto, sino <strong>puertas que llevaban semanas con el parche disponible sin que nadie lo aplicara</strong>. Una web sin actualizar durante un mes de vacaciones es exactamente eso, un escaparate de puertas conocidas con el cartel de «pasen y vean».</p>
<p>En contra, lo que ya sabes si llevas tiempo en esto. <strong>Una actualización puede romper la web</strong>, por incompatibilidades entre plugins, por un tema que no sigue el ritmo, por lo que sea, y romperla sin nadie delante para enterarse. Además <strong>los plugins premium comprados fuera del directorio oficial van por libre</strong>, cada uno con su sistema de licencias, así que la automatización nativa ni los ve.</p>
<p>Si eres del bando manual tienes más razón que un santo en una cosa, actualizar a ciegas y sin red es jugar a la ruleta. Pero la conclusión correcta es otra: <strong>automatizar sí, pero con red</strong>.</p>
<h3>Automatizar con red, lo que hace un buen hosting</h3>
<p>La red existe y la ponen algunos hosting, yo te cuento cómo lo hace <a href="https://www.siteground.es/go/ayudawp">SiteGround</a>, que es el que uso y recomiendo desde hace años, con su herramienta de <a href="https://es.siteground.com/tutoriales/primeros-pasos/actualizaciones-automaticas-wordpress/">actualización automática</a> de las Site Tools, pero seguramente habrá más que también lo hacen bien.</p>
<p>Antes de cada actualización hace una copia de seguridad, después comprueba automáticamente que la web funciona y, si detecta un problema, revierte los cambios y te avisa. Puedes decidir <strong>con qué margen se aplican las versiones mayores y las menores</strong>, y además también actualizar los plugins del directorio oficial que tengas desactualizados.</p>
<p>O sea, que el escenario de pesadilla del bando manual, la web rota un mes entero sin que nadie se entere, con este sistema se convierte en un email que viene a decir «lo intenté, algo no cuadraba y lo he dejado como estaba». Así la cosa cambia del todo, ahora sí hay red de seguridad.</p>
<p>Y si quieres el control fino, el entorno de pruebas (el <em>staging</em> de toda la vida) te deja ensayar las actualizaciones gordas en una copia de la web antes de aplicarlas en la real. Es la opción de matrícula de honor para antes de un parón largo, <strong>actualizas todo en el entorno de pruebas, compruebas que nada se rompe y lo pasas a producción</strong>.</p>
<h3>Qué y cómo actualizar según el tipo de web</h3>
<p>Esto, como todo, es mi opinión, pero también como todo, basado en mi experiencia, yo te lo cuento y tú decides.</p>
<p>En un blog o web corporativa no veo problema alguno para tener actualizaciones automáticas con red para todo y a disfrutar de la vida.</p>
<p>En una tienda online, con WooCommerce, las menores y las de seguridad automáticas siempre, pero las versiones mayores de WooCommerce, de la pasarela de pago y del tema, mejor con entorno de pruebas o a mano en horario controlado.</p>
<p>Y es que una tienda caída o rota no son visitas perdidas, son pedidos que vuelan, dinero que no entra, y el proceso de compra tiene demasiadas piezas delicadas como para actualizarlo a ciegas en mitad de una campaña.</p>
<p>Por resumir:</p>
<ul>
<li><strong>En piloto automático:</strong> las actualizaciones menores de WordPress (seguridad y manteniento) siempre, y todo lo demás con un sistema que haga copia previa, verificación y marcha atrás.</li>
<li><strong>Delegable:</strong> en tu hosting si tiene actualización inteligente, o en un servicio de mantenimiento, que además se ocupa de lo que la automatización no cubre, como los plugins premium y las versiones mayores con su entorno de pruebas.</li>
</ul>
<h2>Un vigilante no se coge vacaciones</h2>
<p>Con la casa cerrada y las actualizaciones con red, falta el sistema de alarma, la parte que mira cuando tú no miras. Y aquí es donde el piloto automático se luce de verdad, porque <strong>casi todo lo importante de la vigilancia moderna funciona solo</strong>.</p>
<blockquote><p>La seguridad que funciona es la que se revisa sola, sin esperar a que tú te acuerdes.</p></blockquote>
<p>El cortafuegos y el bloqueo de fuerza bruta deben funcionar sin ti por defecto, filtrando peticiones maliciosas y bloqueando IPs a cualquier hora, da igual el sistema que apliques (CDN, plugin, hosting, todos a. la vez).</p>
<p>Ahora bien, la vigilancia que a mí me deja dormir tranquilo es otra, la de integridad, porque <strong>el malware moderno no se ve desde fuera</strong>.</p>
<p>Me refiero a la situación en que la web carga normal, el escritorio parece normal, y mientras tanto hay un archivo PHP colado en tu carpeta de subidas haciendo cosas raras, o una puerta trasera escondida en un plugin.</p>
<p>La única forma fiable de pillarlo es comparar, y comparar es justo lo que las máquinas hacen mejor que nosotros, <strong>comprobar el núcleo de WordPress contra las sumas de verificación oficiales, revisar los archivos de plugins y temas</strong>, y escanear la carpeta <code>uploads</code> buscando <strong>PHP donde solo debería haber imágenes</strong>.</p>
<p>Otra bomba de relojería silenciosa de la web desatendida son los <strong>plugins cerrados o abandonados</strong>, esos que WordPress.org retira del directorio por <strong>una vulnerabilidad sin arreglar o por abandono del autor</strong>, y que en tu web siguen instalados y activos tan campantes, porque nadie te avisa. Salvo que algo te avise, claro.</p>
<p>Esto último <a href="https://ayudawp.com/ataques-cadena-suministro-plugins/" target="_blank" rel="noopener">lo añadí a Vigilante justo después de que nos enterásemos de que alguien había colado puertas falsas en decenas de plugins</a> en el directorio oficial. Gracias, o por culpa de eso, <strong>detecta los plugins cerrados y te dice además el motivo</strong> del cierre, que no es lo mismo «el autor lo dejó» que «tiene un agujero de seguridad sin parche».</p>
<p>Y el ejemplo que mejor resume la filosofía de todo este artículo es el <strong>analizador de seguridad</strong> de <a href="https://es.wordpress.org/plugins/vigilante/">Vigilante</a>, más de 40 comprobaciones con una puntuación de 0 a 100 que <strong>se ejecuta sola cada semana y únicamente te manda un email si la puntuación baja de verdad</strong>.</p>
<p>Ni resúmenes diarios que acabas ignorando, ni silencio absoluto, un vigilante que solo te llama si hay algo que contar, así se hace el <strong>piloto automático bien hecho</strong>.</p>
<p>El <strong>registro de actividad</strong> completa el arsenal, y no para que lo leas cada día (no lo vas a leer, y no pasa nada), sino para que a la vuelta puedas <strong>reconstruir qué ha pasado, quién entró, qué se instaló, qué cambió y cuándo</strong>.</p>
<p>Antes de que te relajes, por si no te has dado cuenta, los escáneres de seguridad están incorporando inteligencia artificial para detectar comportamientos anómalos en lugar de limitarse a firmas conocidas, un salto interesante que ya conté a fondo en mi artículo sobre <a href="https://ayudawp.com/seguridad-wordpress-ia/">seguridad WordPress con inteligencia artificial</a>.</p>
<p>Otra amenaza que conviene vigilar también desde fuera, y para eso tienes dos opciones gratuitas, el <a href="https://herramientas.ayudawp.com/security-check/">análisis de seguridad WordPress</a> online, que pasa más de 30 comprobaciones externas a tu web sin instalar nada (hazlo antes de irte, guarda la puntuación y repítelo a la vuelta), y un servicio de monitorización de disponibilidad tipo <a href="https://uptimerobot.com/">UptimeRobot</a>, que te avisa al momento si la web se cae, que es lo primero que notarías si estuvieras delante y lo último que descubres si no lo estás.</p>
<ul>
<li><strong>En piloto automático:</strong> cortafuegos, escaneos de integridad y malware, detección de plugins cerrados, análisis semanal con aviso solo si empeora, y monitorización de disponibilidad.</li>
<li><strong>Delegable:</strong> la interpretación y la reacción. Que las alertas las reciba y las resuelva un servicio de mantenimiento, y a ti te llegue solo el resumen.</li>
</ul>
<h2>Alertas: pocas y claras</h2>
<p>La trampa clásica del que monta todo esto con ganas es activar todas las notificaciones de todos los sistemas. El resultado son veinte emails a la semana de cosas irrelevantes, tu cerebro los archiva como ruido y el día que llega el importante ni lo abres.</p>
<p><strong>Si todo avisa, nada avisa</strong>, es el cuento de Pedro y el lobo, versión bandeja de entrada.</p>
<p>Mi recomendación es quedarte con cuatro alertas de verdad y mandar a resumen semanal, o directamente silenciar, todo lo demás. La caída de la web, una actualización automática que ha fallado y se ha revertido, la bajada de la puntuación del análisis semanal de seguridad, y cualquier detección de malware o cambio de integridad en archivos.</p>
<p>Y <strong>haz pruebas de todo</strong> antes de relajarte. Provoca un aviso de prueba o comprueba en el histórico que los emails llegan y no acaban en la carpeta de spam, que sería el colmo, el vigilante gritando y tú con los cascos puestos.</p>
<ul>
<li><strong>En piloto automático:</strong> el filtrado. Se configura una vez qué avisa y qué calla.</li>
<li><strong>Delegable:</strong> el buzón entero. En un servicio de mantenimiento las alertas las recibe quien las va a resolver, y a ti solo te llega lo que necesita tu decisión.</li>
</ul>
<h2>Recomendaciones de seguridad que valen poquito</h2>
<p>Hay medidas que se venden mucho y protegen poco, y en una web desatendida cada pieza de más es una pieza que puede fallar sola.</p>
<p>La primera, <strong>no apiles plugins de seguridad</strong> «por si acaso». Duplican reglas de cortafuegos, bloqueos de acceso y cabeceras, y el resultado suelen ser falsos positivos, avisos por duplicado y webs rotas, justo lo contrario de lo que buscas cuando no vas a estar delante. <strong>Elige uno que tenga de todo y bueno, configúralo bien y a otra cosa</strong>.</p>
<p>La segunda, ocultar la versión de WordPress es más cosmética que otra cosa. Los bots no leen tu número de versión y deciden educadamente si atacar, prueban el exploit directamente contra millones de webs y a ver cuál cae. <strong>Lo que te protege es actualizar y no tener la vulnerabilidad</strong>, por mucho cartel que escondas.</p>
<p>Y la tercera, la más importante, <strong>no tomes decisiones de seguridad por miedo</strong>, ni por el email alarmista de turno ni por el vendedor que te asegura que sin su suscripción premium tu web está condenada.</p>
<p><strong>Lo que de verdad para los ataques es aburridísimo</strong> (copias, actualizaciones, accesos limpios y vigilancia automática, todo lo que llevamos visto) pero lo mejor es que es casi todo gratis o viene incluido en un buen hosting.</p>
<h2>Plan B, por si aun así pasa algo</h2>
<p>Todo lo anterior reduce muchísimo la probabilidad de sustos, pero <strong>el riesgo cero no existe</strong>, así que deja preparado el plan B, que consiste en <strong>poder reaccionar desde donde sea y cuándo haga falta</strong>, sin tener que acordarte de nada de memoria.</p>
<p>Tres escenarios más que probables:</p>
<ul>
<li><strong>Si la web se cae</strong> entra en el panel de tu hosting, desde el navegador del móvil si no tienes otra cosa, y restaura la última copia buena, que para eso practicaste la restauración y apuntaste los pasos.</li>
<li><strong>Si ves un ataque en curso</strong>, con intentos de acceso masivos o tráfico raro, activa el modo «bajo ataque» de tu plugin de seguridad o de Cloudflare, que refuerza temporalmente los accesos mientras dura la tormenta.</li>
<li><strong>Si confirmas un hackeo</strong>, restaura la copia anterior al desastre, cambia todas las contraseñas y abre ticket con el soporte de tu hosting, que para eso pagas y además saben seguro más que tú y yo juntos, porque ellos ven estas cosas a diario.</li>
</ul>
<p>Para que todo eso sea posible desde cualquier parte, <strong>deja apuntado antes de confiarte</strong>, en tu gestor de contraseñas, el acceso al panel del hosting, dónde están las copias y cómo se restauran, el canal de soporte y el teléfono de la persona a la que llamarás si prefieres no tocar nada.</p>
<p>Volvemos al vecino con la copia de las llaves, y si ese vecino no existe, para eso están los <a href="https://mantenimiento.ayudawp.com/">servicios de mantenimiento</a>, que en el fondo son eso, el teléfono <strong>al que llamas para no tener que ser tú quien apague el fuego</strong> o al menos no hacerlo a solas. No es su función principal, que es más la prevención, pero también cuando hay problemas deben demostrar que elegiste bien.</p>
<ul>
<li><strong>En piloto automático:</strong> nada, esta parte es tuya, pero se deja preparada en diez minutos.</li>
<li><strong>Delegable:</strong> entera. Tener mantenimiento contratado es exactamente esto, que el plan B sea el teléfono de otro.</li>
</ul>
<h2>Lista de comprobación de seguridad en piloto automático</h2>
<p>Cuando sales de viaje cierras la llave del gas, bajas las persianas, pones alguna luz con temporizador, conectas la alarma y le dejas las llaves a alguien de confianza. Pues con tu web, exactamente igual.</p>
<p>Aquí tienes la lista completa, pensada para hacerla en una tarde. Imprímela, guárdala o pásala a tu gestor de tareas, pero repásala entera antes de cada parón, y una vez al trimestre aunque no te vayas a ningún sitio, que como decíamos al principio, la web desatendida no entiende de calendarios.</p>
<p><strong>Previsión obligatoria antes del piloto automático de seguridad:</strong></p>
<ul>
<li>Restaura una copia de seguridad de prueba y apunta los pasos y el tiempo que te llevó.</li>
<li>Comprueba que la copia externa programada existe, es completa (archivos y base de datos) y se guarda fuera del servidor.</li>
<li>Borra los usuarios que no se usen y baja privilegios a quien no necesite ser administrador.</li>
<li>Activa la identificación en dos pasos para todos los que acceden a la web.</li>
<li>Borra los plugins desactivados y los temas que no uses, dejando solo uno oficial de reserva.</li>
<li>Aplica el refuerzo: edición de archivos desactivada, XML-RPC cerrado si no lo usas y cabeceras de seguridad puestas.</li>
<li>Actualiza todo a mano una última vez, núcleo, plugins, temas y traducciones.</li>
<li>Configura las actualizaciones automáticas con red, copia previa, comprobación posterior y marcha atrás.</li>
<li>Pasa el análisis de seguridad externo, corrige lo que salga en rojo y guarda la puntuación para comparar a la vuelta.</li>
<li>Revisa las notificaciones, deja sonando solo las cuatro importantes y mándate un aviso de prueba.</li>
</ul>
<p><strong>Las medidas de seguridad imprescindibles en piloto automático:</strong></p>
<ul>
<li>Copias diarias del hosting más la copia externa programada.</li>
<li>Actualizaciones automáticas con copia previa y reversión si algo falla.</li>
<li>Cortafuegos y bloqueo de fuerza bruta.</li>
<li>Escaneo de integridad de archivos y detección de malware.</li>
<li>Detección de plugins cerrados o abandonados.</li>
<li>Análisis semanal de seguridad con aviso solo si la puntuación baja.</li>
<li>Monitorización de disponibilidad con aviso al móvil.</li>
</ul>
<p><strong>Notas de rescate:</strong></p>
<ul>
<li>Acceso al panel del hosting.</li>
<li>Donde están las copias y los pasos para restaurarlas.</li>
<li>Canal de soporte del hosting.</li>
<li>A quién llamar si necesitas ayuda.</li>
</ul>
<h2>Y ahora sí, cierra la puerta con dos vueltas</h2>
<p>Si me preguntas como profesional que mantiene decenas de webs de clientes, mi posición es clara, mía, pero te la cuento. <strong>El piloto automático no es un apaño para vacaciones, es como debería estar montada la seguridad de cualquier web todo el año</strong>, porque eso de «yo lo reviso a mano cada día» dura dos semanas, como los propósitos de enero, y lo que queda después es una web que no revisa nadie.</p>
<p>¿Que ni siquiera quieres montarlo? Vale, es una decisión respetable, que para eso está la opción de delegarlo todo, y ahí te espero en mi <a href="https://mantenimiento.ayudawp.com/">servicio de mantenimiento WordPress</a>.</p>
<p>¿Que gestionas webs de clientes y esta guía se te queda corta? Tengo publicada una <a href="https://ayudawp.com/seguridad-wordpress-empresas-agencias/">guía de seguridad WordPress para empresas y agencias</a> que sigue justo donde esta lo deja, y sino <a href="https://ayudawp.com/categoria/seguridad/"><strong>tienes toda una lista enorme de tutoriales de seguridad para WordPress</strong></a>.</p>
<p>Para dudas, matices o contarme tu propia lista de cerrar la casa, me tienes ahí abajo (que mis vacaciones son siempre teóricas), en la sección de comentarios.</p>
<p>Buen viaje, que la web queda en buenas manos. Las <del>tuyas</del> suyas.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/seguridad-wordpress-piloto-automatico/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Directiva Ómnibus en tiendas WordPress con WooCommerce</title>
		<link>https://ayudawp.com/directiva-omnibus-woocommerce/</link>
					<comments>https://ayudawp.com/directiva-omnibus-woocommerce/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Wed, 29 Jul 2026 06:28:56 +0000</pubDate>
				<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Ómnibus]]></category>
		<category><![CDATA[Principiante]]></category>
		<category><![CDATA[WooCommerce]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159921</guid>

					<description><![CDATA[Si tu tienda creada con WordPress y WooCommerce se limita a tachar el precio normal y mostrar el de oferta al lado, es muy probable que no estés cumpliendo la directiva Ómnibus de precios.]]></description>
										<content:encoded><![CDATA[<p>Si tu tienda creada con WordPress y WooCommerce se limita a tachar el precio normal y mostrar el de oferta al lado, <strong>es muy probable que no estés cumpliendo la directiva Ómnibus de precios</strong>.</p>
<p>Esta ley no pide enseñar el precio habitual, pide enseñar <strong>el precio más bajo que ese producto haya tenido en los últimos 30 días</strong>, y esa diferencia lleva aplicándose desde hace tiempo sin que casi nadie repare en ella.</p>
<p>No es una norma nueva ni un borrador pendiente, está muy vigente, así que vamos a ver exactamente qué exige, qué te juegas si no la cumples y cómo resolverlo sin volverte loco con el catálogo.</p>
<h2>Lo que exige la directiva Ómnibus en cada rebaja de precios</h2>
<p>La norma viene de la Directiva (UE) 2019/2161, conocida como <strong>directiva Ómnibus</strong>, que añadió el artículo 6 bis a la <a href="https://www.boe.es/buscar/act.php?id=BOE-A-1996-1072" target="_blank" rel="nofollow noopener">Directiva 98/6/CE de indicación de precios</a>.</p>
<p>España la transpuso a través del artículo 20.1 de la Ley de Ordenación del Comercio Minorista, redactado por el Real Decreto-ley 24/2021, <strong>en vigor desde el 28 de mayo de 2022</strong>.</p>
<p>La regla en sí se explica en una frase y se cumple mal en la mayoría de tiendas:</p>
<blockquote><p>Toda reducción de precio debe mostrar, junto al precio rebajado, el precio anterior.</p></blockquote>
<p>Y ojo, porque «precio anterior» no es lo que la mayoría cree. <strong>No es el precio habitual del producto, es el precio más bajo que haya tenido en los 30 días previos a la rebaja</strong>, sea cual sea el motivo por el que estuvo a ese precio.</p>
<p>Aquí tienes los requisitos por la vía rápida, para que no digas que me hago esperar:</p>
<table>
<thead>
<tr>
<th>Requisito</th>
<th>Qué exige la norma</th>
</tr>
</thead>
<tbody>
<tr>
<td>Precio anterior visible</td>
<td>Mostrar el precio más bajo de los 30 días previos junto al precio rebajado</td>
</tr>
<tr>
<td>Cálculo del precio anterior</td>
<td>El más bajo aplicado en los 30 días precedentes, sea cual sea el motivo de ese precio</td>
</tr>
<tr>
<td>Productos nuevos</td>
<td>Exentos solo si es la primera vez que se ponen a la venta, no por llevar menos de 30 días</td>
</tr>
<tr>
<td>Perecederos próximos a caducar</td>
<td>Los precios de liquidación por desperdicio alimentario no cuentan en el cálculo de los 30 días</td>
</tr>
<tr>
<td>Descuento mínimo o máximo</td>
<td>No se puede condicionar una promoción a un porcentaje de reducción fijo</td>
</tr>
</tbody>
</table>
<h3>A qué te arriesgas si no cumples la directiva Ómnibus</h3>
<p>Esto no es una recomendación de buenas prácticas, es una infracción tipificada, un delito, <strong>no es broma y las multas son tremendas</strong>.</p>
<p>El artículo 49 del texto refundido de la Ley General para la Defensa de los Consumidores y Usuarios clasifica las <strong>sanciones en tres niveles</strong>.</p>
<ul>
<li>Leves, que van de 150 a 10.000 €.</li>
<li>Graves de 10.001 a 100.000 € (con posibilidad de superar esa cifra hasta 4 o 6 veces el beneficio ilícito obtenido).</li>
<li>Muy graves llegan de 100.001 € hasta 1.000.000 €.</li>
</ul>
<p>Y no es solo sobre el papel, ni de lejos, ya se han estrenado y con honores, el Ministerio de Derechos Sociales, Consumo y Agenda 2030 <a href="https://www.dsca.gob.es/es/comunicacion/notas-prensa/justicia-respalda-sanciones-consumo-falsas-rebajas-durante-black-friday" target="_blank" rel="nofollow noopener">sancionó a siete empresas</a> por <strong>subir el precio de varios productos justo antes del Black Friday para bajarlo después a su valor original y presentarlo como oferta</strong>.</p>
<p>El conjunto de las multas rondó los 350.000 € y una de las empresas recurrentes tuvo que depositar un aval de 110.000 € mientras se resuelve su recurso. Imagino que no te sobra el dinero ¿verdad?</p>
<p>Para detectarlo, la Dirección General de Consumo usó la <strong>Price Reduction Tool</strong>, una herramienta de la propia Comisión Europea que <strong>monitoriza precios en tiempo real durante campañas</strong> como esta.</p>
<p>Por si te lo estás planteando, la propia Comisión Europea ya avisó de que <strong>subir el precio antes de bajarlo no cuela</strong>, ni presentándolo como «precio futuro».</p>
<blockquote><p>El precio anterior sigue siendo el más bajo real de los últimos 30 días, ponga lo que ponga en el cartel de la oferta.</p></blockquote>
<p>Y ya que estamos una aclaración rápida, porque el nombre podría llevar a confusión, y es que <strong>esto no tiene nada que ver con el Digital Omnibus</strong> del que tanto se oye hablar últimamente, ese paquete que tiene que ver con el RGPD y las cookies. Ese <em>otro Omnibus</em> sigue paseándose por Bruselas, aún sin texto definitivo. La directiva Ómnibus de precios de la que te hablo aquí lleva aplicándose desde hace tiempo y no tiene nada pendiente de aprobar, está de un vigente que asusta.</p>
<h2>Por qué el precio tachado de WooCommerce no te libra de nada</h2>
<p>Siento decirlo, pero no, <strong>eso de los precios tachados no sirve de nada</strong>, ni de lejos, te lo explico.</p>
<p>Como sabes, <strong>WooCommerce tacha el precio habitual del producto y muestra al lado el precio de oferta</strong>, así que parece que ya cumples, per va a ser que no.</p>
<p>La realidad es que el precio habitual solo coincide con el precio anterior legal si no has tocado ese precio ni hecho ninguna promoción en los últimos 30 días. <strong>Si encadenas rebajas, el tachado de WooCommerce deja de servir como prueba de nada</strong>.</p>
<p>Es exactamente el truco que le costó el expediente a esas siete empresas del punto anterior, subir el precio unos días antes para que el descuento posterior parezca mayor de lo que es en realidad.</p>
<p>WooCommerce te deja hacerlo sin ningún aviso, porque el plugin no sabe nada de la directiva Ómnibus, solo compara el precio habitual con el de oferta rebajado que tú le pongas.</p>
<h2>Plugins que ayudan con a cumplir la directiva Ómnibus de precios</h2>
<p>Aquí no hace falta reinventar nada, hay opciones ya disponibles, solo te queda elegir con cabeza:</p>
<ul>
<li><a href="https://wordpress.org/plugins/omnibus/" target="_blank" rel="nofollow noopener"><strong>Omnibus — show the lowest price</strong></a>, de iWorks (gratuito): Con más de 10.000 instalaciones activas, aunque sin cambios funcionales desde marzo de 2024 (la actualización de 2025 solo tocó el módulo de valoraciones), probado hasta WordPress 6.8.5 y sin traducción al español. Ojo con esto, pues varias reseñas señalan que en el primer descuento de un producto sin histórico previo, el plugin muestra el propio precio rebajado como si fuera el anterior, justo el fallo que no te puedes permitir, pruébalo antes de dejarlo activo pensando que cumple.</li>
<li><a href="https://wpdesk.net/products/wp-desk-omnibus/" target="_blank" rel="nofollow noopener"><strong>WP Desk Omnibus for WooCommerce</strong></a> (de pago): Actualizado el 28 de mayo de 2026, con interpretación configurable según el país y soporte activo, buena opción si prefieres pagar por tranquilidad.</li>
<li><a href="https://wordpress.org/plugins/fleekcode-omnibus/" target="_blank" rel="nofollow noopener"><strong>FleekCode Omnibus Price Tracker</strong></a> (gratuito): Con tabla propia en base de datos en lugar de <code>postmeta</code> y base de instalación todavía pequeña. Pruébalo antes de pagar por el anterior, igual sin necesidad.</li>
</ul>
<p>Con cualquiera de los tres cumples suficientemente, salvo que se confirme lo de WP Desk, en cuyo caso habría que descartar ese. Revísalos en una tienda de pruebas que tenga de todo antes de instalar nada definitivamente, porque el panorama de plugins cambia con el tiempo y lo que te cuento aquí tiene fecha de caducidad.</p>
<h2>Un apaño con código si tu caso es de los sencillos</h2>
<p>Si vendes <strong>solamente productos simples</strong>, nada de variables, y no te apetece meter un plugin enorme más para esto, aquí tienes un código que hace lo imprescindible.</p>
<p>Además, para que no creas que es una birria, tiene una salvaguarda que muchos plugins comerciales no tienen, y es que nunca inventa un precio anterior, si no hay 30 días reales de histórico no muestra nada:</p>
<pre>&lt;?php

/***
 * Plugin Name: Registro de precios mínimos según la Directiva Ómnibus de la UE
 * Plugin URI: https://servicios.ayudawp.com/
 * Description: Muestra un precio anterior solo si hay un historial real de al menos 30 días. Nunca inventa ni calcula un precio anterior. Solo para productos simples.
 * Version: 1.0
 * Author: Fernando Tellado
 * Author URI: https://ayudawp.com/
 * License: GPL2
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: registro-precios-omnibus
 * Domain Path: /languages
*/

/**
 * Registro de precios mínimos previsto en la Directiva Ómnibus de la UE (Directiva (UE) 2019/2161)
 * Solo muestra un precio anterior cuando hay un historial real registrado de al menos 30 días
 * Nunca inventa ni calcula un precio anterior. Solo para productos simples
 */

// Registra el precio cada vez que se guarde un producto, solo si ha cambiado
add_action( 'woocommerce_update_product', 'ayudawp_omnibus_log_price', 20, 2 );
function ayudawp_omnibus_log_price( $product_id, $product ) {

if ( ! $product || ! $product-&gt;is_type( 'simple' ) ) {
return; // Variable products need a dedicated plugin, not this snippet.
}

$current_price = $product-&gt;get_regular_price();

if ( '' === $current_price ) {
return;
}

$log        = get_post_meta( $product_id, '_ayudawp_omnibus_price_log', true );
$log        = is_array( $log ) ? $log : array();
$last_entry = end( $log );

if ( ! $last_entry || (float) $last_entry['price'] !== (float) $current_price ) {
$log[] = array(
'price' =&gt; (float) $current_price,
'date'  =&gt; current_time( 'timestamp' ),
);
}

// Eliminar las entradas con más de 45 días de antigüedad (el plazo legal de 30 días más un margen de seguridad)
$cutoff = current_time( 'timestamp' ) - ( 45 * DAY_IN_SECONDS );
$log    = array_values( array_filter( $log, function( $entry ) use ( $cutoff ) {
return $entry['date'] &gt;= $cutoff;
} ) );

update_post_meta( $product_id, '_ayudawp_omnibus_price_log', $log );
}

// Mostrar únicamente el precio anterior con un historial acumulado de al menos 30 días reales
add_action( 'woocommerce_single_product_summary', 'ayudawp_omnibus_display_prior_price', 11 );
function ayudawp_omnibus_display_prior_price() {

global $product;

if ( ! $product || ! $product-&gt;is_type( 'simple' ) || ! $product-&gt;is_on_sale() ) {
return;
}

$log = get_post_meta( $product-&gt;get_id(), '_ayudawp_omnibus_price_log', true );
$log = is_array( $log ) ? $log : array();

if ( empty( $log ) ) {
return; // No history yet: show nothing rather than guessing.
}

$days_of_history = ( current_time( 'timestamp' ) - $log[0]['date'] ) / DAY_IN_SECONDS;

if ( $days_of_history &lt; 30 ) {
return; // Core safeguard: never show a prior price without a real 30-day track record.
}

$window_start = current_time( 'timestamp' ) - ( 30 * DAY_IN_SECONDS );
$in_window    = array_filter( $log, function( $entry ) use ( $window_start ) {
return $entry['date'] &gt;= $window_start;
} );

if ( empty( $in_window ) ) {
return;
}

$lowest_price = min( wp_list_pluck( $in_window, 'price' ) );

if ( $lowest_price &lt;= (float) $product-&gt;get_sale_price() ) {
return; // Nunca muestra un precio anterior que no sea realmente inferior al precio rebajado
}

echo '&lt;p class="ayudawp-omnibus-prior-price"&gt;' .
esc_html__( 'Precio anterior: ', 'ayudawp' ) .
wp_kses_post( wc_price( $lowest_price ) ) .
'&lt;/p&gt;';
}</pre>
<p>Este código registra el precio cada vez que guardas el producto, solo si ha cambiado, y purga las entradas de más de 45 días (30 de la ley más un margen de seguridad). En la parte visible de la web solo pinta el precio anterior cuando ya hay al menos 30 días reales de histórico acumulado, nunca antes.</p>
<p>Y para que no te lleves un susto, solo funciona con productos simples, no cuenta los cambios hechos por edición rápida, importación masiva o la API REST, y no sustituye a un plugin dedicado si tu catálogo es grande o vendes productos variables.</p>
<blockquote><p>El código te lo dejo preparado como plugin, por si quieres subirlo como plugin o a <code>mu-plugins</code>, lo que prefieras. Si eres más de añadirlo como código quítale toda la cabecera que lo identifica como plugin, eso te sobra, y el <code>&lt;?php</code> inicial, o no funcionará.</p></blockquote>
<p>Si quieres más para eso están las opciones del punto anterior de los plugins.</p>
<h2>Rebajas encadenadas, el caso donde más se la juegan las tiendas</h2>
<p>Este es el escenario que más dudas genera, y por suerte la propia Comisión Europea lo aclaró bastante detallado en una <a href="https://eur-lex.europa.eu/legal-content/ES/TXT/HTML/?uri=CELEX:52021XC1229(06)" target="_blank" rel="nofollow noopener">comunicación</a> publicada en el Diario Oficial de la UE en diciembre de 2021.</p>
<p>Hay dos situaciones muy distintas, y conviene no confundirlas:</p>
<ul>
<li><strong>Campañas separadas con el precio subiendo entre medias</strong> (Black Friday, luego Navidad, luego rebajas de enero): Se aplica la norma general sin excepciones. El precio anterior de cada nueva rebaja tiene que ser el más bajo de, como mínimo, los últimos 30 días, y eso incluye el precio de la promoción anterior. Si bajaste un producto a 80 € en el Black Friday, dos semanas después no puedes anunciarlo «rebajado» tomando como referencia los 100 € de precio normal: tu referencia sigue siendo 80 €.</li>
<li><strong style="font-size: 16px;">Reducción progresiva dentro de una misma campaña, sin interrupción y sin que el precio suba en ningún momento</strong><span style="font-size: 16px;">: Aquí sí se puede mantener el precio previo a toda la campaña como referencia constante en cada escalón. Es la excepción que prevé el propio artículo 6 bis, aunque no he encontrado que España la haya transpuesto de forma explícita, así que el mensaje práctico y seguro es aplicar siempre la regla general de los 30 días, sin dar el atajo por hecho.</span></li>
</ul>
<p>Si programas varias campañas con esa joya de plugin llamado <a href="https://es.wordpress.org/plugins/multiple-sale-prices-scheduler/" target="_blank" rel="nofollow noopener">Multiple Sale Prices Scheduler</a>, ten en cuenta que <strong>el plugin programa los cambios de precio, no calcula el precio anterior legal por ti</strong>. Combínalo con alguna de las opciones de este artículo si vas a encadenar promociones.</p>
<h2>Lo demás que trae la directiva Ómnibus y no tiene que ver con precios</h2>
<p>El artículo 6 bis es la pieza que más te afecta si vendes con descuentos, pero <strong>la directiva Ómnibus trae más obligaciones que quizá también te toca cumplir</strong>.</p>
<p>Me refiero a cosas como <strong>verificar que las reseñas de tus productos vienen de compradores reales</strong>, dar una <strong>información mínima al consumidor antes de la compra</strong>, identificar con claridad la <strong>publicidad de influencers</strong>, y reconocer que <strong>los servicios «gratuitos» pagados con datos personales también generan derechos</strong> para el consumidor.</p>
<p>Cada una de estas otras cuestiones a tener en cuenta da para su propio artículo, así que aquí me quedo solo con el aviso, para que tengas en cuenta que esto es mucho más que solo precios.</p>
<h2>Listado rápido para cumplir la directiva Ómnibus de precios</h2>
<p>Si vendes con descuentos en WooCommerce, sí, y aquí te dejo el resumen para revisar tu tienda de un vistazo:</p>
<table>
<thead>
<tr>
<th>Requisito</th>
<th>Qué exige la norma</th>
<th>Cómo lo cubres</th>
</tr>
</thead>
<tbody>
<tr>
<td>Precio anterior visible</td>
<td>Precio más bajo de los 30 días previos junto al rebajado</td>
<td>Plugin específico, o el código de este artículo en productos simples</td>
</tr>
<tr>
<td>Cálculo en campañas sucesivas</td>
<td>Incluye siempre la rebaja anterior si cayó en los últimos 30 días</td>
<td>Plugin específico con histórico real, el snippet de este artículo no cubre esto</td>
</tr>
<tr>
<td>Productos nuevos</td>
<td>Exentos solo por ser primera venta, nunca por antigüedad</td>
<td>Revisa que el plugin que elijas distinga bien este caso</td>
</tr>
<tr>
<td>Perecederos con desperdicio alimentario</td>
<td>Esos precios no cuentan en el cálculo de los 30 días</td>
<td>Revisa la configuración si vendes este tipo de producto</td>
</tr>
<tr>
<td>Descuento mínimo o máximo</td>
<td>No se puede condicionar una promoción a un porcentaje fijo</td>
<td>Revisión manual de tus propias campañas</td>
</tr>
<tr>
<td>Reseñas, información previa, publicidad de influencers</td>
<td>Resto de obligaciones de la directiva Ómnibus</td>
<td><em>Pendiente de artículo específico</em></td>
</tr>
</tbody>
</table>
<p>Nada más por ahora, dale una vuelta a tu catálogo antes de la próxima campaña que actives, sea cual sea. Si te ha quedado alguna duda sobre tu caso concreto, ya sabes dónde encontrarme, en los comentarios aquí abajo.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/directiva-omnibus-woocommerce/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Tu currículum de WordPress ya está escrito</title>
		<link>https://ayudawp.com/curriculum-wordpress/</link>
					<comments>https://ayudawp.com/curriculum-wordpress/#comments</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Tue, 28 Jul 2026 06:28:36 +0000</pubDate>
				<category><![CDATA[Plugins WordPress]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Comunidad]]></category>
		<category><![CDATA[EEAT]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159996</guid>

					<description><![CDATA[A todos los que contribuís de alguna forma a WordPress os hago un regalo. Se llama Contributor Résumé, un plugin gratuito que muestra todas tus colaboraciones en un currículum, siempre actualizado, que puedes publicar en tu propia web]]></description>
										<content:encoded><![CDATA[<p>Escribo en Ayuda WordPress desde diciembre de 2007, tengo <a href="https://profiles.wordpress.org/fernandot/" target="_blank" rel="noopener">perfil de colaborador en WordPress.org</a> desde noviembre de 2008 y desde entonces he sido GTE de la traducción al español, parte del equipo de soporte en los foros, administrador de la web en español de WordPress.org y ponente en más WordCamps de las que me caben en la cabeza.</p>
<p>Todo eso se puede comprobar, sí, pero queda repartido en media docena de sitios que casi nadie visita (tu perfil de wordpress.org, translate.wordpress.org, los foros de soporte, la API de reconocimientos del núcleo, el directorio de fotos), y cada uno cuenta solo un trocito de tu historia, nunca la historia entera.</p>
<p>Así que <strong>me he hecho un regalo, y de paso os lo hago a todos los que contribuís de alguna forma a este proyecto</strong> llamado WordPress. Se llama <strong><a href="https://es.wordpress.org/plugins/contributor-resume/">Contributor Résumé</a></strong>, un plugin gratuito que coge todo ese trabajo disperso y lo convierte en un currículum bonito, siempre actualizado, que puedes publicar en tu propia web con un solo bloque.</p>
<p>Vamos a ver qué tiene dentro, cómo lo pones en marcha y por qué para mí <strong>esto no es un plugin más</strong>.</p>
<h2>Un currículum de verdad para quien nos regala su tiempo y conocimiento</h2>
<p>La idea es tan sencilla que casi da vergüenza no haberla hecho antes, pues escribes tu nombre de usuario de WordPress.org, compruebas lo que ha encontrado el plugin y publicas tu página. <strong>Nada de IDs numéricos, nada de tokens, nada de código.</strong> Esto vale igual si traduces, si respondes en el foro, si organizas meetups o si simplemente haces fotos para el directorio, no solo si publicas plugins.</p>
<p>Un único bloque, o el shortcode <code>[contributor_resume]</code> si trabajas con un tema clásico, agrupa decenas de secciones distintas, todas opcionales. Estas son algunas de las que más se van a usar:</p>
<ul>
<li><strong>Perfil destacado:</strong> tu avatar, tus distinciones reales de wordpress.org y los enlaces a tu web, GitHub y Slack.</li>
<li><strong>Impacto reciente:</strong> tus contribuciones de los últimos 30, 90 y 365 días, con puntuación incluida.</li>
<li><strong>Eventos:</strong> las WordCamps y meetups en las que hablas, organizas o asistes.</li>
<li><strong>Traducciones:</strong> tus idiomas, tus permisos y el número de proyectos en cada uno.</li>
<li><strong>Soporte:</strong> los hilos que has abierto y las respuestas que has dado en los foros.</li>
<li><strong>Reconocimientos del núcleo:</strong> las versiones de WordPress en cuyos créditos aparece tu nombre.</li>
<li><strong>Plugins y temas:</strong> los que has publicado, con sus estadísticas, y los que tienes marcados como favoritos.</li>
<li><strong>GitHub:</strong> tu perfil y tus repositorios con más estrellas, sin necesitar ningún token para verlo.</li>
</ul>
<p>Y quedan más, porque también incluye <strong>fotos del directorio</strong> de WordPress con su propia caja de luz, tu <strong>compromiso de horas</strong> semanales, la <strong>biografía</strong> con tu historia de origen, los <strong>equipos</strong> e <strong>idiomas</strong> de tu comunidad de contribución, y alguna sección más. Decenas de proyectos, cada uno reordenable arrastrando y soltando, y activable o no según lo que quieras enseñar. No está mal ¿no?</p>
<p>Además, que es <a href="https://ayudawp.com/por-que-no-hay-certificaciones-oficiales-de-wordpress/" target="_blank" rel="noopener">el único currículum de WordPress real que hay</a>.</p>
<h2>¡Es taaan mooonoooo!</h2>
<p><a href="https://ayudawp.com/?attachment_id=160032" rel="nofollow"><img loading="lazy" decoding="async" class="sombra alignnone wp-image-160032 size-medium" src="https://ayudawp.com/wp-content/uploads/2026/07/contributor-resume-ajustes-1200x730.jpg" alt="" width="1200" height="730" srcset="https://ayudawp.com/wp-content/uploads/2026/07/contributor-resume-ajustes-1200x730.jpg 1200w, https://ayudawp.com/wp-content/uploads/2026/07/contributor-resume-ajustes-768x467.jpg 768w, https://ayudawp.com/wp-content/uploads/2026/07/contributor-resume-ajustes-1536x934.jpg 1536w, https://ayudawp.com/wp-content/uploads/2026/07/contributor-resume-ajustes.jpg 1920w" sizes="auto, (max-width: 1200px) 100vw, 1200px"></a></p>
<p>Si es que encima es bonito y para (casi) todos los gustos. Tienes <strong>tres estilos</strong>, uno moderno, uno clásico con aspecto de currículum impreso de toda la vida y uno monoespaciado que parece sacado de una terminal, para quien quiera presumir de friki con estilo.</p>
<p>A eso le sumas <strong>claro, oscuro o automático</strong> según lo que prefiera quien visita tu web, color de realce propio o heredado del tema, radio de esquinas, sombra, columnas de la cuadrícula y un diseño compacto si prefieres ir al grano. Las estadísticas se animan con un contador que sube según entran en pantalla, y se paran en seco si el visitante tiene activada la reducción de movimiento.</p>
<p>Puedes arrastrar las secciones para reordenarlas, elegir cuántos elementos muestra cada cuadrícula, y probarlo todo con una vista previa en directo, en escritorio y en móvil, sin salir de los ajustes. Y si con eso no tienes bastante, cada plantilla se puede copiar a tu tema y editarla a mano, con variables CSS documentadas bajo el prefijo <code>--cvr-</code>.</p>
<h2>Solo tus datos, y ni uno de quien te visita</h2>
<p>El plugin lee <strong>tus datos públicos de contribución en las URLs oficiales de WordPress.org</strong> (y, si añades tu usuario, también en la API pública de GitHub), y nunca recoge ni envía nada de quien entra en tu página. Las páginas públicas no hacen ninguna petición externa, y los avatares y las fotos los carga el navegador de tu visitante directamente desde WordPress.org, Gravatar o GitHub, igual que hace WordPress toda la vida con los avatares de los comentarios.</p>
<p>El único dato que sale de tu servidor es tu nombre de usuario, y solo cuando generas o actualizas el currículum en segundo plano. Si añades un token de acceso de GitHub (opcional, solo para subir el límite de peticiones a su API), se queda guardado en tu web y no se muestra jamás en la parte pública.</p>
<h2>Cómo lo pones en marcha en un par de minutos</h2>
<ol>
<li>Instala y activa el plugin.</li>
<li>Abre «Contributor Résumé» desde el menú de tu cuenta en la barra de admin superior, o desde el enlace de ajustes que aparece junto al plugin en la pantalla de plugins.</li>
<li>Escribe tu nombre de usuario de WordPress.org (y, si quieres, el de GitHub) y pulsa «Comprobar y crear mi currículum».</li>
<li>Pulsa «Crea mi página de currículum», o añade el bloque (o el shortcode <code>[contributor_resume]</code>) a cualquier página que ya tengas.</li>
</ol>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-160011" src="https://ayudawp.com/wp-content/uploads/2026/07/Activar-Contributor-Resume.jpg" alt="" width="1200" height="1184"></p>
<p>Funciona igual de bien con el editor de bloques que con un tema clásico, y si administras varias instalaciones o trabajas con entornos de prueba, <code>wp cresume refresh</code>, <code>wp cresume status</code> y <code>wp cresume clear-cache</code> te dejan gestionar la caché entera desde WP-CLI.</p>
<h2>¿Quieres verlo ya?</h2>
<p>Tengo mi propio currículum publicado en <a href="https://ayudawp.com/fernando-tellado-wordpress-org/">esta misma web</a>, con casi todas las secciones activadas, así que puedes verlo en marcha antes de instalar nada. Ahí aparecen mis 24 plugins publicados, mis traducciones a 23 idiomas repartidas en 3.416 proyectos, mis 134 hilos abiertos y 856 respuestas en los foros de soporte, y las WordCamps en las que he hablado solo en lo que llevamos de 2026.</p>
<p>Lo mejor es ver cómo suben solos los contadores de «Impacto reciente» mientras cargas la página, en vez de una foto de perfil de 2015 congelada para siempre. Los datos se actualizan sin que yo tenga que tocar nada.</p>
<p>Si lo prefieres, en la página del plugin <a href="https://es.wordpress.org/plugins/contributor-resume/?preview=1" target="_blank" rel="nofollow noopener">puedes lanzar una vista previa en directo</a> y WordPress.org te monta una web con el plugin activo para que pruebes con tu propio perfil.</p>
<h2>Por qué esto no es un plugin más, es un regalo</h2>
<p>Todos mis plugins resuelven un problema técnico, ya sea de seguridad, de rendimiento, de SEO o de cumplimiento normativo. Este no, este es diferente, este está dedicado a ti, que contribuyes a que todos podamos disfrutar de WordPress.</p>
<p>Es un plugin para quien traduce cadenas a las tres de la mañana, para quien modera un hilo de soporte enrevesado, quien organiza una WordCamp sin cobrar un euro, o quien hace fotos para el directorio de WordPress, porque todas esas personas, casi siempre anónimas, se merecen algo más que una insignia enterrada en un perfil que casi nadie mira. E</p>
<p>s gratis, sin letra pequeña ni versión de pago escondida detrás de las funciones buenas, porque la comunidad que me ha dado casi 20 años de carrera no me debe nada a mí, se lo debo yo a ella. Ya escribí en su día sobre <a href="https://ayudawp.com/tag/gpl/" target="_blank" rel="noopener">por qué es importante tanto el software libre</a>, así que no me voy a repetir aquí.</p>
<p>Si contribuyes de cualquier forma (código, traducciones, soporte, fotos, eventos, lo que sea), instálalo en tu web, crea tu página, y enséñale al mundo lo que llevas currado todo este tiempo. Y si todavía no contribuyes a nada, esto también vale como <strong>excusa estupenda para empezar a contribuir a WordPress</strong>, porque ya sabes dónde vas a poder enseñarlo después.</p>
<p>Puedes incluso <a href="https://translate.wordpress.org/projects/wp-plugins/contributor-resume">traducirlo tú mismo</a> a tu idioma, porque de momento solo está en español e inglés (dentro de nada en italiano), y a un plugin que celebra a quien traduce le vendría de perlas que también lo traduzcan.</p>
<p>Como dice el pie de página de wordpress.org, «<code><strong>el código es poesía</strong></code>». Pues ahora, además, tienes dónde publicar el tuyo. Si te lo instalas, cuéntame en los comentarios cómo te ha quedado o qué sección echas en falta.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/curriculum-wordpress/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>¿Qué tipos de Schema elijo entre todo esto?: Article, BlogPosting, NewsArticle, TechArticle, FAQ, WebPage…</title>
		<link>https://ayudawp.com/schemas-article-webpage/</link>
					<comments>https://ayudawp.com/schemas-article-webpage/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Mon, 27 Jul 2026 06:28:09 +0000</pubDate>
				<category><![CDATA[SEO / AEO / GEO / AIO]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[JSON-LD]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[Visibility]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159980</guid>

					<description><![CDATA[¿Te lías con los distintos tipos de Schema que puedes elegir para tus publicaciones? Te lo explico facilito…]]></description>
										<content:encoded><![CDATA[<p>Desde que <a href="https://es.wordpress.org/plugins/native-aeo-pack/" target="_blank" rel="noopener">Visibility</a> estrenó el <strong>selector de tipo de schema</strong> me llega la misma pregunta por todas partes, en los comentarios, en el foro de soporte y hasta por correo. <strong>¿Qué elijo aquí?</strong></p>
<p>Te lo adelanto ya, pero en plan básico: para una entrada normal de blog, <code>BlogPosting</code> o el valor por defecto, para una página corriente, <code>WebPage</code>, y entre los subtipos de la familia <code>Article</code> la elección apenas cambia nada en los resultados de Google, aunque sí en cómo te leen los asistentes de IA.</p>
<p>Sí, para empezar vale, como resumen cojonudo, pero si quieres hacerlo bien no te puedes quedar ahí, que la cosa tiene su miga, y lo mejor de todo es que de paso te va a servir aunque uses Yoast, Rank Math, el mismo Visibilty o cualquier otro plugin SEO, porque la etiqueta final es la misma.</p>
<p>Vamos a verlo de a pasito que dirían en mi pueblo.</p>
<h2>Qué es eso del «tipo de schema»</h2>
<p>Cualquier plugin de SEO, Visibility, Yoast, Rank Math el que sea, añade al código de cada página que publicas un bloque de <strong>JSON-LD, que son datos estructurados</strong> en formato JSON, invisibles para el visitante pero que las máquinas leen sin problema.</p>
<p>Dentro de ese bloque JSON-LD hay <strong>una propiedad llamada <code>@type</code> que dice qué es esa página</strong>, si un artículo, una noticia, una página de contacto o un perfil.</p>
<p><strong>El tipo de schema es la etiqueta</strong> de una caja de mudanza, donde todas las cajas son iguales por fuera, y lo que cambia cómo las tratan los transportistas es que ponga libros o vajilla. Si marcas como vajilla una caja llena de libros no pasa nada grave, pero el que la abra esperando platos dejará de fiarse de tus etiquetas.</p>
<p>Con Google pasa lo mismo,<strong> una etiqueta que no se corresponde con el contenido no te penaliza de entrada, pero deja de servir para algo</strong>, y si encima es engañosa a propósito hay una <a href="https://support.google.com/webmasters/answer/9044175" target="_blank" rel="noopener nofollow">acción manual</a> esperándote en Search Console con el nombre de «marcado estructurado con spam».</p>
<h2>Dónde se elige el tipo de Schema en tu plugin SEO</h2>
<p>Cada plugin tiene sus manías, por ejemplo, en Visibility te deja <strong>fijarlo en dos niveles</strong>, por un lado, en los ajustes del módulo de descubrimiento <strong>eliges el tipo por defecto para cada tipo de contenido, uno para las entradas, otro para las páginas y así con cada tipo personalizado</strong> que tengas.</p>
<p>Luego, en la barra lateral del editor, entrada por entrada, puedes <strong>sustituir ese valor cuando una publicación concreta consideres que requiera otro Schema</strong>. Esto también lo tienen otros plugins, como Rank Math o Yoast.</p>
<p>La opción «Por defecto (<code>Article</code>)» del desplegable de Visibility y otros plugins significa justo eso, que se aplique lo que hayas configurado para ese tipo de contenido, así que <strong>si no tienes un motivo concreto para cambiarlo, déjalo en «Por defecto» y a otra cosa</strong>.</p>
<p><!-- CAPTURA: selector de tipo de schema en la barra lateral del editor, con el desplegable abierto --></p>
<p>Si vienes de otro plugin SEO la lógica es muy parecida, Yoast lo llama «Page type» y «Article type» en su pestaña de schema, Rank Math lo llama «Schema Type» y SEOPress tiene su equivalente en los datos estructurados.</p>
<p>Todo lo que cuento en este artículo te <strong>sirve igual con cualquier plugin de SEO</strong>. Si te pasas a Visibility el importador de un clic se trae también estos valores desde Yoast, Rank Math y All in One SEO, junto con el resto de tus metadatos, al contrario no te prometo lo mismo.</p>
<h2>La familia <code>Article</code>: seis etiquetas para casi lo mismo</h2>
<p>El primer grupo del selector lo forman los <strong>subtipos de artículo, pensados para contenido editorial con autor y fecha</strong>:</p>
<ul>
<li><code>Article</code>: el genérico, válido para cualquier contenido editorial y la elección segura cuando dudas.</li>
<li><code>BlogPosting</code>: la entrada de blog clásica, con voz y firma. Si tu web es un blog es tu etiqueta natural.</li>
<li><code>NewsArticle</code>: noticias y actualidad, contenido pegado a un hecho con fecha. Si cubres la actualidad de tu sector, este.</li>
<li><code>TechArticle</code>: tutoriales, guías paso a paso y documentación técnica. En un blog de tutoriales como este es el que más sentido tiene.</li>
<li><code>ScholarlyArticle</code>: estudios y trabajos con metodología, más propio de webs académicas o de investigación.</li>
<li><code>Report</code>: informes y análisis con datos, tipo estudio anual o comparativa documentada.</li>
</ul>
<p>Pues bien, <strong><a href="https://developers.google.com/search/docs/appearance/structured-data/article" target="_blank" rel="noopener nofollow">la documentación de Google</a> solo contempla tres de ellos</strong> para su función de artículo, <code>Article</code>, <code>NewsArticle</code> y <code>BlogPosting</code>, y los trata como intercambiables. Los otros tres son subtipos válidos de schema.org que Google ni siquiera menciona.</p>
<p>O sea, que <strong>elegir entre <code>BlogPosting</code> y <code>NewsArticle</code> no va a cambiar cómo te muestra Google, y elegir <code>TechArticle</code> no te da nada extra en sus resultados</strong>.</p>
<p>¿Entonces para qué molestarse?, pues porque <strong>Google no es el único que lee esa etiqueta, los asistentes de IA y los motores de respuesta leen el <code>@type</code></strong> tal cual, sin interpretarlo, igual que cualquier agente que rastree tu web.</p>
<p>Para un asistente de IA <strong>un <code>TechArticle</code> le dice que lo que tiene delante es un tutorial técnico</strong>, y que lo entregue cuando alguien pregunte cómo hacer algo, y <strong>de un <code>NewsArticle</code>  le dice que es una noticia, y que tenga muy en cuenta la fecha</strong>.</p>
<p>Ser preciso te cuesta un clic y aporta contexto a todo lo que no es Google.</p>
<blockquote><p>Para Google, BlogPosting y NewsArticle son la misma etiqueta con distinto nombre, pero para un asistente de IA son dos cosas distintas.</p></blockquote>
<p>Eso sí, sin venirte arriba, que <a href="https://developers.google.com/search/docs/appearance/ai-features" target="_blank" rel="noopener nofollow">Google ha dicho por escrito</a> que sus funciones de IA no requieren ningún schema especial. La etiqueta correcta evita que las máquinas tengan que adivinar qué es tu contenido, y ahí se acaba su potencial.</p>
<h2>La familia <code>WebPage</code>: sus apellidos</h2>
<p>El segundo grupo es para páginas, <strong>contenido sin la lógica de autor y fecha de un artículo</strong>. La estructura se repite, con un tipo genérico y varios subtipos que lo afinan:</p>
<ul>
<li><code>WebPage</code>: la página genérica, tu elección por defecto para páginas y la correcta en el 90% de los casos.</li>
<li><code>AboutPage</code>: la página «sobre mí» o «sobre nosotros». Refuerza la identidad del sitio, que es de lo que hablamos un poco más abajo.</li>
<li><code>ContactPage</code>: la página de contacto, una señal de transparencia que a las máquinas les viene de perlas para saber cómo localizarte.</li>
<li><code>ProfilePage</code>: el perfil de una persona o entidad. Es el único de este grupo con función propia <a href="https://developers.google.com/search/docs/appearance/structured-data/profile-page" target="_blank" rel="noopener">documentada por Google</a> desde noviembre de 2023, y el propio Google recomienda usarlo en las páginas de autor que enlaza el schema A<code>Tu código aquí</code>rticle, pura señal <a href="https://ayudawp.com/eeat-wordpress/" target="_blank" rel="noopener">E-E-A-T</a> (experiencia, conocimiento, autoridad y confianza, su mantra de calidad).</li>
<li><code>CollectionPage</code>: páginas que recopilan otras cosas, como un directorio de recursos o un listado de herramientas.</li>
<li><code>ItemPage</code>: una página dedicada a un único elemento concreto, la ficha de algo que no está a la venta.</li>
</ul>
<p>Ninguno de estos tipos te va a pintar estrellitas en Google, y no pasa nada. <strong>Su trabajo es de identidad, decirle a quien rastrea tu web qué es cada página dentro del conjunto</strong>, que es lo que un asistente necesita para citarte bien.</p>
<h2>Los que no suelen estar en el selector de Schema, y casi mejor</h2>
<p>Faltan los famosos <code>Product</code>, <code>Recipe</code>, <code>Event</code>, <code>VideoObject</code> y <code>LocalBusiness</code> y si no los he incluido en Visibility no ha sido por despiste, es una decisión que tiene sus motivos.</p>
<p>El motivo principal para no incluir en un plugin de SEO por defecto este montón de tipos de Schema es que todos esos tipos tienen <strong>propiedades obligatorias que tu contenido no lleva (normalmente) de serie</strong>.</p>
<p>Un <code>Product</code> exige precio, moneda y disponibilidad, un <code>Recipe</code> quiere ingredientes y tiempos, un <code>Event</code> pide fechas y lugar, para que nos entendamos rápido.</p>
<p>Generar esas etiquetas sin sus propiedades te genera errores en Search Console, y <strong>un schema con errores es peor que no tener schema</strong>, porque le estás enseñando a Google cajas que prometen un contenido pero que al abrirlas están vacías.</p>
<p>Hay una segunda razón de peso, y es que <strong>quien de verdad posee ese dato ya genera ese schema</strong>. Un ejemplo que conocerás de sobras es WooCommerce, que ya genera el <code>Product</code> con el precio y el inventario reales.</p>
<p>Plugins muy conocidos, como por ejemplo The Events Calendar, genera el <code>Event</code> con sus fechas, y los plugins de recetas tipo WP Recipe Maker hacen lo propio con el <code>Recipe</code>.</p>
<p>Si Visibility, u otro plugin de SEO, te dejase elegir <code>Product</code> en el desplegable de una entrada, estaría duplicando o, peor todavía, contradiciendo al plugin que tiene los datos buenos, y de serie.</p>
<p>También hay que decirlo, los plugins de SEO que ofrecen estos tipos mediante un <strong>constructor de campos manuales de datos estructurados</strong> lo hacen bien si te molestas en rellenarlos, y si es así al menos tienes la oportunidad de hacerlo bien.</p>
<p>El problema es el desplegable alegre que te deja marcar cualquier cosa sin pedirte los datos, que de esos también hay. Si algún día estos tipos decido meterlos en Visibility será con un constructor de campos en condiciones, que <strong>lo último que te hace falta es una casilla que te anime a mentirle a Google</strong>.</p>
<h2>El cementerio de los resultados enriquecidos</h2>
<p>Google lleva años haciendo poda de resultados enriquecidos, y ese recorte explica por qué tampoco verás <code>FAQ</code> ni <code>HowTo</code> en el selector de tipos de Schema.</p>
<p>La lista de bajas impresiona (que en paz descansen):</p>
<ul>
<li><code>HowTo</code>: limitado primero en móvil y <a href="https://developers.google.com/search/blog/2023/08/howto-faq-changes" target="_blank" rel="noopener">eliminado del todo en septiembre de 2023</a>. Los pasos con fotos en los resultados son historia.</li>
<li><code>FAQ</code>: restringido en agosto de 2023 a webs gubernamentales y de salud, y <a href="https://developers.google.com/search/docs/appearance/structured-data/faqpage" target="_blank" rel="noopener">rematado para todo el mundo el 7 de mayo de 2026</a>. Los desplegables de preguntas bajo tu resultado ya no existen para nadie, y en junio de 2026 desaparecieron también del informe de Search Console y de la prueba de resultados enriquecidos.</li>
<li>La masacre de junio de 2025: <code>Course Info</code>, <code>Claim Review</code>, <code>Estimated Salary</code>, <code>Learning Video</code>, <code>Special Announcement</code> y <code>Vehicle Listing</code>, <a href="https://developers.google.com/search/blog/2025/06/simplifying-search-results" target="_blank" rel="noopener nofollow">todos fuera por poco uso</a>.</li>
<li>La segunda tanda de noviembre de 2025: <a href="https://developers.google.com/search/blog/2025/11/update-on-our-efforts" target="_blank" rel="noopener nofollow">más funciones retiradas</a>, entre ellas los problemas de práctica (<em>practice problems</em>) desde enero de 2026.</li>
</ul>
<p>La razón, en el caso del <code>FAQ</code> es, para variar, el abuso por parte de los SEO y usuarios <em>demasiado comprometidos</em>, que se marcaron preguntas de relleno a mansalva para ocupar más sitio en los resultados hasta convertirlo en <strong>spam con acordeón</strong>. En el resto de casos Google simplifica su página de resultados para dejar hueco a sus propia funciones de IA.</p>
<p>Así que <strong>el marcado <code>FAQPage</code> sigue siendo schema.org válido y otros sistemas pueden leerlo, pero como truco para ganar espacio en Google está muerto</strong>, y si un tutorial de 2022 te anima a marcar <code>FAQ</code> para conseguir los desplegables, ya sabes de qué año es esa información.</p>
<h2>La identidad del sitio: <code>Organization</code>, <code>Person</code> y el baile de los <code>@id</code></h2>
<p>Queda un tipo de schema que no aparece en los desplegables, y es debido a que no es de página, es de sitio. Tu web entera tiene una identidad, una <strong><code>Organization</code> si eres una empresa o un proyecto, una <code>Person</code> si eres tú a título personal</strong>, y esa identidad debe declararse una sola vez, en la portada, con todos sus datos.</p>
<p>Aquí entra el baile de los <code>@id</code>, porque cada nodo de schema puede llevar un <code>@id</code>, que viene a ser su DNI, <strong>una URL única que permite que otros schemas lo referencien en vez de repetirlo</strong>.</p>
<p>Si usas <a href="https://es.wordpress.org/plugins/vigia/" target="_blank" rel="noopener">VigIA</a>, que emite el JSON-LD de identidad del sitio en la portada, Visibility detecta ese nodo y hace que el <code>publisher</code> de cada artículo apunte al mismo <code>@id</code> en lugar de crear una Organization duplicada.</p>
<p>Dos fichas de la misma entidad con datos distintos confunden a cualquier máquina, y <strong>la gracia de coordinar los <code>@id</code> es que todo tu sitio dice lo mismo sobre quién eres, lo mire quien lo mire</strong>.</p>
<p>Lo bueno de usar este conjunto es que <strong>se complementan sin pisarse</strong>, la ventaja de coordinar plugins, en principio para usos diferentes, pero al final todo tiene algo de relación, como es el caso.</p>
<h2>Cómo comprobar si lo has hecho bien</h2>
<p>Tres pruebas rápidas y gratis:</p>
<ol>
<li>Abre el código fuente de una entrada (clic derecho en la página) y busca <code>application/ld+json</code>. Ahí verás el bloque con el <code>@type</code> que has elegido, junto al <code>BreadcrumbList</code> (las migas de pan) que Visibility añade por su cuenta.</li>
<li>Pasa la URL por la <a href="https://search.google.com/test/rich-results" target="_blank" rel="noopener nofollow">prueba de resultados enriquecidos de Google</a> para ver qué funciones detecta. Ojo, solo te enseñará las que Google mantiene vivas.</li>
<li>Pasa la misma URL por el <a href="https://validator.schema.org/" target="_blank" rel="noopener nofollow">validador de schema.org</a>, que comprueba si el marcado es válido aunque Google no pinte nada con él. Para los tipos que Google ignora, este es tu árbitro.</li>
</ol>
<h2>Chuleta rápida para casi ni pensar</h2>
<table>
<thead>
<tr>
<th>Contenido</th>
<th>Tipo recomendado</th>
</tr>
</thead>
<tbody>
<tr>
<td>Entrada de blog</td>
<td><code>BlogPosting</code> (o «Por defecto»)</td>
</tr>
<tr>
<td>Noticia o actualidad del sector</td>
<td><code>NewsArticle</code></td>
</tr>
<tr>
<td>Tutorial, guía o documentación</td>
<td><code>TechArticle</code></td>
</tr>
<tr>
<td>Estudio con metodología</td>
<td><code>ScholarlyArticle</code></td>
</tr>
<tr>
<td>Informe o análisis con datos</td>
<td><code>Report</code></td>
</tr>
<tr>
<td>Página corriente</td>
<td><code>WebPage</code></td>
</tr>
<tr>
<td>Página «sobre mí» o «sobre nosotros»</td>
<td><code>AboutPage</code></td>
</tr>
<tr>
<td>Página de contacto</td>
<td><code>ContactPage</code></td>
</tr>
<tr>
<td>Recopilación, directorio o listado</td>
<td><code>CollectionPage</code></td>
</tr>
<tr>
<td>Página de autor o perfil</td>
<td><code>ProfilePage</code></td>
</tr>
<tr>
<td>Ficha de un elemento único (sin venta)</td>
<td><code>ItemPage</code></td>
</tr>
</tbody>
</table>
<p>Si después de la tabla sigues con dudas, déjalo en «Por defecto», que para eso está y no te vas a equivocar. <strong>Lo importante es no mentir con la etiqueta, el subtipo perfecto es secundario</strong>.</p>
<p>Si quieres seguir tirando del hilo de cómo leen tu web los asistentes de IA, tengo <a href="https://ayudawp.com/categoria/seo/" target="_blank" rel="noopener">unas cuantas guías publicadas sobre el tema de visibilidad en IAs</a>.</p>
<p>Para dudas concretas sobre tu caso, que seguro que las hay porque este tema las genera solas, me tienes ahí abajo, en la sección de comentarios.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/schemas-article-webpage/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Por qué el robots.txt es un problema gordo en WordPress multisitio … pero afortunadamente tiene solución</title>
		<link>https://ayudawp.com/robots-txt-wordpress-multisitio/</link>
					<comments>https://ayudawp.com/robots-txt-wordpress-multisitio/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 06:28:23 +0000</pubDate>
				<category><![CDATA[SEO / AEO / GEO / AIO]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Content Signals]]></category>
		<category><![CDATA[Experto]]></category>
		<category><![CDATA[llms.txt]]></category>
		<category><![CDATA[robots.txt]]></category>
		<category><![CDATA[Visibility]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159867</guid>

					<description><![CDATA[Quieres que un sitio tenga unas reglas en el robots.txt y otro las suyas, porque no todos necesitan lo mismo, y resulta que WordPress te sirve el mismo robots.txt para todos]]></description>
										<content:encoded><![CDATA[<p>Si gestionas una <strong>red de WordPress con varios sitios</strong> esto te va a sonar…</p>
<p><strong>Quieres que un sitio tenga unas reglas en el <code>robots.txt</code> y otro las suyas</strong>, normal ¿no?, porque no todos necesitan lo mismo, y resulta que <strong>WordPress te sirve el mismo <code>robots.txt</code> para todos</strong>. Y encima, si abres el de cualquiera de los dominios, ves uno que no has puesto tú.</p>
<p>Me lo trajo hace poco un cliente <a href="https://mantenimiento.ayudawp.com/" target="_blank" rel="noopener">del servicio de mantenimiento</a>, con un multisitio de varios dominios, que me pidió <strong>tocarle los <code>robots.txt</code> de cada web</strong>.</p>
<p>Cuando me puse a mirarlo <strong>resulta que el problema no era suyo ni de su configuración, era de cómo funciona WordPress por dentro con los ficheros en una red multisitio</strong>.</p>
<p>Así que aprovecho para contártelo con calma, porque tiene más miga de la que parece. Y sí, ya te lo adelanto, <strong>se puede tener un robots.txt distinto por sitio en una red multisitio de WordPress</strong>, pero antes hay que darle una pensada, porque todo tiene sus matices.</p>
<h2>¿Por qué en cada dominio de WordPress multisitio hay dos archivos para robots?</h2>
<p>Primero, un apunte rápido para quien llegue nuevo. WordPress no crea un fichero <code>robots.txt</code> de verdad en el disco, lo genera dinámicamente cada vez que alguien lo pide, lo que se llama un <code>robots.txt</code> virtual. Puedes verlo y modificarlo, pero eso ya te lo conté al detalle en <a href="https://ayudawp.com/robots-txt-virtual-wordpress/" target="_blank" rel="ugc noopener">el post sobre el robots.txt virtual de WordPress</a>, con el truco de verlo tecleando <code>?robots=1</code> y el filtro para cambiarlo.</p>
<p>El caso de mi cliente era que en su multisitio hay un <code>robots.txt</code> físico, un fichero de verdad, en la raíz del dominio principal, el que aloja la red y desde el que se instalan los plugins y el tema.</p>
<p>Y <strong>como toda la red comparte esa misma carpeta raíz, ese fichero se sirve igual para todos los dominios</strong>, así que tecleas <code>otro-dominio.com/robots.txt</code> y <strong>sale el del principal, no el del subsitio, porque no tiene un <code>robots.txt</code> físico</strong>, no es posible.</p>
<p><strong>¿Y el virtual de cada sitio, el que tú crees que estás editando con tu plugin de SEO?</strong> Ahí sigue, pero solo aparece si lo fuerzas a mano con <code>otro-dominio.com/?robots=1</code>.</p>
<p><strong>Los rastreadores piden siempre <code>/robots.txt</code>, así que se meriendan el físico compartido y nunca ven las reglas propias de cada web</strong>. De ahí la sensación de tener dos, el que sirven los bots y el que gestiona el plugin, cada uno con sus reglas y sin enterarse el uno del otro.</p>
<p><strong>¿Y por qué gana el físico?</strong> Pues porque cuando existe uno en la raíz, <strong>lo entrega el servidor web antes de que WordPress ni siquiera arranque</strong>, así que el virtual y el filtro se quedan sin pintar nada para esa dirección.</p>
<h2>Subdominios, dominios mapeados y subcarpetas</h2>
<p>El estándar del <code>robots.txt</code>, recogido en el RFC 9309 que es la norma oficial, dice que <strong>el archivo vive en la raíz de cada host, o sea de cada dominio o subdominio</strong>, y de ahí salen tres escenarios muy distintos según cómo tengas montada la red.</p>
<ul>
<li><strong>Red por subdominios</strong> (<code>es.tudominio.com</code>, <code>en.tudominio.com</code>): cada sitio es un host distinto, así que cada uno puede y debe tener su propio <code>robots.txt</code>. Aquí lo de «uno por sitio» tiene todo el sentido.</li>
<li><strong>Red por dominios mapeados</strong> (<code>dominio.com</code>, <code>domain.com</code>): igual que el anterior, cada dominio es un host, así que cada uno lleva el suyo.</li>
<li><strong>Red por subcarpetas</strong> (<code>dominio.com/es</code>, <code>dominio.com/en</code>): todos comparten el mismo host, así que solo hay un <code>robots.txt</code> que cuente, el de la raíz del dominio, y manda el sitio principal. Un subsitio en subcarpeta no puede servir el suyo a los rastreadores por mucho plugin que le pongas.</li>
</ul>
<p><strong>Y ojo, que lo de las subcarpetas no es una carencia de WordPress, es el propio estándar.</strong></p>
<p>El <code>robots.txt</code> va en la raíz del host y punto, así que si tu red es por subcarpetas, lo máximo que puedes hacer es meter todas las reglas que necesites, conjuntas, en el <code>robots.txt</code> del dominio principal, teniendo cuidado de no meter reglas que solo sirvan para el dominio o una carpeta concreta, todas generales.</p>
<h2>¿Qué hago con el robots.txt del sitio principal?</h2>
<p>Da igual la vía que elijas luego, con código o con plugin, s<strong>i hay un <code>robots.txt</code> físico en la raíz y quieres reglas por subsitio quítalo, porque carga antes que WordPress y ningún plugin o PHP se lo puede saltar.</strong></p>
<p>Mientras ese fichero siga ahí los bots seguirán leyéndolo a él y las reglas por sitio no llegarán a ninguna parte.</p>
<p>Pero, si es el caso, <strong>con quitarlo no basta, además tienes que asegurarte de que ningún plugin te lo vuelve a crear</strong>. El editor de ficheros de Yoast, por ejemplo, escribe un <code>robots.txt</code> físico si le das al botón, y en una red ese fichero se te cuela para todos. Así que bórralo, comprueba por FTP que no reaparece, <a href="https://ayudawp.com/desactivar-el-editor-de-plugins-y-temas-en-wordpress-3-0/" target="_blank" rel="noopener">desactiva la edición de archivos dentro de WordPress</a>, y solo entonces pasamos al siguiente paso.</p>
<p>Una vez fuera  el archivo físico <strong>WordPress ya sirve el virtual de cada sitio</strong> por su cuenta, y <strong>ahí sí puedes empezar a configurar en cada web el suyo</strong>. En subdominios y dominios mapeados esto funciona tal cual, cada host sirve el suyo. En subcarpetas no hay manera, se siente, solo cuenta el del dominio principal.</p>
<h2>Cómo darle reglas propias de robots a cada subsitio de una red multisitio (con código)</h2>
<p>Si no quieres depender de ningún plugin de SEO para esto, WordPress trae un filtro, <code>robots_txt</code>, que te deja modificar el robots.txt virtual, y combinándolo con <code>get_current_blog_id()</code> (la función que te dice en qué sitio de la red estás) puedes dar reglas distintas según la web. La idea, que he ido ampliando y actualizando, me la dio <a href="https://florianbrinkmann.com/en/modifying-robots-txt-for-individual-sites-of-a-multisite-install-3364/" target="_blank" rel="nofollow noopener">Florian Brinkmann</a>, en un post de hace ya unos pocos años.</p>
<p>Lo que hay que hacer es meter el siguiente código en un <code>mu-plugin</code> que se activa en toda la red. Lo subes por FTP a la carpeta <code>wp-content/mu-plugins</code> y listo:</p>
<pre>/**
 * Plugin Name: Archivo robots.txt por sitio en WordPress Multisitio
 * Plugin URI: https://ayudawp.com/
 * Description: Permite definir reglas de robots.txt diferentes para cada sitio en una red multisitio de WordPress.
 * Version: 1.0
 * Author: Fernando Tellado
 * Author URI: https://tellado.es
 */

// Añade reglas por sitio al archivo robots.txt virtual de cada sitio a través de la red
add_filter( 'robots_txt', 'ayudawp_multisite_robots_txt', 20, 2 );

function ayudawp_multisite_robots_txt( $output, $public ) {

// Solo funciona si es multisitio
if ( ! is_multisite() ) {
return $output;
}

// Reglas por sitio asignadas por ID de blog (tienes el ID en Administrador de la red &amp;gt; Sitios)
switch ( get_current_blog_id() ) {

// Sitio con ID 2: tienda online
case 2:
$output .= "Disallow: /carrito/\n";
$output .= "Disallow: /finalizar-compra/\n";
$output .= "Disallow: /mi-cuenta/\n";
break;

// Sitio con ID 3: blog
case 3:
$output .= "Disallow: /?s=\n";
$output .= "Disallow: /descargas/\n";
$output .= "Disallow: /gracias/\n";
break;
}

return $output;
}</pre>
<p>Cambias los ID (<code>case x</code>)  y las reglas por las tuyas, y cada web servirá las suyas.</p>
<p>El código tiene sus límites, como que es obvio que lo mantienes tú a mano cada vez que cambien las necesidades, y luego claro está, no se puede aplicar a otros archivos, como el <code>llms.txt</code>, que arrastra el mismo problema. Y por supuesto, te recuerdo de nuevo que en una red en subcarpetas no hay milagro que valga.</p>
<h2>¿Afecta esto también al llms.txt?</h2>
<p>Ya que estás con el <code>robots.txt</code>, los archivos <code>llms.txt</code> sufren del mismo problema.</p>
<p>Es un fichero que <strong>sirve de índice en Markdown</strong> de tu web para los agentes de IA, y <strong>en una red cada sitio querría el suyo</strong>. Mismo patrón que el <code>robots.txt</code>, por sitio si lo sirves dinámico, y compartido y roto si escribes un físico en la raíz. La diferencia con el <code>robots.txt</code> es que aquí ni el filtro tienes.</p>
<p>WordPress no genera archivos <code>llms.txt</code> ni trae ninguna función para tocarlo, así que el <code>mu-plugin</code> de arriba no sirve y por código te quedas sin un atajo como el del <code>robots.txt</code>. Para tenerlo por sitio en una red la vía práctica es un plugin que lo genere dinámico por sitio, y de eso va lo que viene ahora.</p>
<h2>Cómo darle reglas propias de robots a cada sitio (con plugins)</h2>
<p>Si lo de mantener un mu-plugin no te apetece, o también quieres que el <code>llms.txt</code> sea configurable en cada sitio, esto <strong>lo resuelven algunos plugins</strong>.</p>
<p>De pago te lo ofrece AIOSEO, que tiene un editor de <code>robots.txt</code> de red que te deja tocar el de cada subsitio, pero solo en redes por subdominios, no por subcarpetas (lo dicen ellos en su documentación), y en su versión Pro. SEOPress anuncia edición de <code>robots.txt</code> para multisitio y multidominio, y luego hay plugins dedicados solo a esto, como Multisite Robots.txt Manager. De las subcarpetas nos seguimos olvidando, porque ya sabes que ahí manda el estándar.</p>
<p>Y luego está <strong><a href="https://wordpress.org/plugins/native-aeo-pack/" target="_blank" rel="nofollow noopener">Visibility</a></strong>, <strong>plugin gratuito de SEO que sirve el <code>robots.txt</code> y también el <code>llms.txt</code> de cada sitio de la red</strong> por su cuenta, sin que tengas que tocar nada.</p>
<p><strong>Entrega por una única URL, la de siempre</strong>, <code>/robots.txt</code>, y de paso arregla ese lío del <code>?robots=1</code> y los 404 en instalaciones en subcarpeta. Además, está pensado para no repetir el problema, porque en una red no escribe un físico compartido, solo lo escribe donde de verdad es del sitio, en una instalación normal o en el sitio principal de una red por subcarpetas.</p>
<p>Visibility <strong>sustituye a tu plugin de SEO, no convive con él</strong>, así que si vienes de Yoast u otro plugin, esto supone cambiar el que tuvieses por Visibility, no añadir uno más, que siempre es mala idea. Pero no es algo preocupante, no pierdes nada importante, tiene lo que los demás, y algunas cosas (casi todas) las hace mejor.</p>
<p>Ah, y da igual la elección, aunque uses Visibility <strong>el <code>robots.txt</code> físico de la raíz hay que quitarlo igual</strong>, porque un fichero que sirve el servidor no lo salta nadie. Eso sí, si Visibility detecta un físico compartido tapando el virtual, te avisa en su pestaña de descubrimiento para que sepas que está ahí y lo quites.</p>
<p>Y, por si no lo sabías Visibility, además de hacer lo que todos los demás plugins de SEO, redirecciones incluidas, también emite las señales por sitio (<code>robots.txt</code>, <code>llms.txt</code> y el schema), y si además quieres medir, tienes <a href="https://wordpress.org/plugins/vigia/" target="_blank" rel="nofollow noopener">VigIA</a>, que ofrece analítica de qué rastreadores de IA entran de verdad en cada web y puede bloquearlos, y puedes complementar el pack IA con <a href="https://es.wordpress.org/plugins/ai-content-signals/" target="_blank" rel="noopener">AI Content Signals</a>, que añade las directivas de IA de Cloudflare.</p>
<h2>Resumiendo: Qué hacer con los ficheros robots.txt en multisitio según el tipo de red</h2>
<p>En un par de líneas, por si ya estás con algo de lío:</p>
<ul>
<li><strong>Si tu red es por subdominios o por dominios mapeados</strong>: quita el físico de la raíz y luego das las reglas por sitio con el mu-plugin del filtro <code>robots_txt</code>, o dejas que lo haga tu plugin de SEO (o Visibility) por ti. Cada dominio servirá el suyo.</li>
<li><strong>Si tu red es por subcarpetas</strong>: solo hay un <code>robots.txt</code>, el del dominio principal, así que mete ahí todas las reglas que necesites para los distintos subsitios. Es el único sitio donde los bots las van a leer.</li>
</ul>
<h2>¡Te toca decidir!</h2>
<p>Antes de tocar nada, échale un vistazo a tu red y mira si tienes el problema. Pide el <code>robots.txt</code> de cada dominio y compáralos, y si todos te devuelven exactamente el mismo, tienes un físico compartido mandando sobre todos.</p>
<p>Desde el terminal es tan fácil como teclear la URL tipo <code>https://dominio.com/robots.txt</code> cambiando el dominio o subdominio, y comparar lo que sale. Y si quieres ver el virtual la URL es añadir <code>?robots=1</code> al dominio o subdominio.</p>
<p>Con eso claro <strong>decides si quitar el físico y tirar de código, o quitar el físico y dejar que un plugin te sirva el de cada sitio</strong>. Lo que no funciona es dejar el <code>robots.txt</code> físico compartido ahí, porque se antepone en toda la red y, salvo que uses las mismas reglas para todos los subsitios, puedes estar creándote un problema de rastreo.</p>
<p>Si tienes una red montada de una forma rara, o te topas con algún caso que no encaja con esto, me tienes en los comentarios aquí abajo, que estos temas de multisitio siempre traen su cosilla, y no lo usa muchísima gente.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/robots-txt-wordpress-multisitio/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AI Act: ¿en qué te afecta el reglamento europeo sobre inteligencia artificial si tienes una web WordPress?</title>
		<link>https://ayudawp.com/ai-act/</link>
					<comments>https://ayudawp.com/ai-act/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Wed, 22 Jul 2026 06:28:59 +0000</pubDate>
				<category><![CDATA[IA + WordPress]]></category>
		<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[AESIA]]></category>
		<category><![CDATA[AI Act]]></category>
		<category><![CDATA[Avanzado]]></category>
		<category><![CDATA[Principiante]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159915</guid>

					<description><![CDATA[El reglamento europeo de inteligencia artificial obliga a avisar cuando cierto contenido está hecho o tocado por IA, pero no todo, ni mucho menos, así que la primera buena noticia es que la mayoría de lo que publicas en tu WordPress no va a necesitar ningún cartel.]]></description>
										<content:encoded><![CDATA[<p>Desde el 2 de agosto de 2026 <strong>el reglamento europeo de inteligencia artificial obliga a avisar cuando cierto contenido está hecho o tocado por IA</strong>, pero no todo, ni mucho menos, así que la primera buena noticia es que la mayoría de lo que publicas en tu WordPress no va a necesitar ningún cartel de aviso. La obligación legal se centra en tres casos concretos, un chatbot que no se identifica como tal, un <em>deepfake</em> (vídeo, imagen o voz que ha sido manipulado utilizando IA) y un texto sobre un asunto serio sin revisión humana.</p>
<p>Y el problema es que la mayoría de la información disponible sobre el tema está mezclada, sin querer, entre el aplazamiento de las obligaciones de alto riesgo y lo que de verdad te toca a ti con un sitio WordPress. Vamos a separarlo con calma, caso por caso, sin dar nada por hecho, a ver si soy capaz de explicártelo como yo lo he entendido, y como lo aplico.</p>
<h2>Quién es quién ante la norma: proveedor y responsable del despliegue</h2>
<p>El reglamento reparte las obligaciones entre dos papeles distintos, y confundirlos es la fuente de la mitad de los problemas que te puedes buscar sin ayuda de nadie.</p>
<ul>
<li>El <strong>proveedor</strong> es quien construye y comercializa el sistema de IA, Anthropic con Claude, OpenAI con ChatGPT, Google con Gemini.</li>
<li>El <strong>responsable del despliegue</strong> es quien usa esa herramienta ya hecha para su propio contenido, o sea, tú con tu WordPress.</li>
</ul>
<p>Piénsalo como la diferencia entre quien fabrica un coche y quien lo conduce. Al fabricante le tocan las revisiones técnicas del motor, la homologación, que las piezas cumplan norma, al conductor le toca circular con las luces encendidas de noche y llevar el cinturón puesto. Son obligaciones distintas sobre el mismo vehículo, y confundir una con otra no libra a nadie de la suya.</p>
<p>En la práctica <strong>casi todo lo que te afecta a ti como propietario de un WordPress cae del lado del responsable del despliegue</strong>. El marcado técnico invisible del contenido, ese que debe ser legible por una máquina, corresponde al proveedor del modelo, no a ti. Lo que sí te toca es el aviso visible al usuario, y ahí es donde vamos a entrar ahora.</p>
<h2>¿Y si no estás en España, o ni siquiera en la Unión Europea?</h2>
<p>Aquí conviene hacerse una pregunta que va más allá de dónde vive tu empresa o dónde tienes contratado el hosting. El reglamento europeo tiene alcance extraterritorial, igual que el RGPD con el que ya convives si tienes un formulario de contacto en tu web. Se aplica también a proveedores y responsables del despliegue establecidos en un tercer país cuando el resultado que produce el sistema de IA se usa dentro de la Unión Europea.</p>
<p>Vamos, en lo que nos afecta, <strong>si tu web la lee gente en algún país de la Unión Europea, algo que le pasa a prácticamente cualquier blog público con un mínimo de tráfico, el reglamento entra en juego</strong> aunque tú estés en México, Argentina o al otro lado del mundo. No hace falta que factures en euros ni que tengas oficina en Europa.</p>
<p>Dicho esto, y como pasa siempre que se habla de normativa, esto es información general para que entiendas el criterio, no una sentencia sobre tu caso concreto. Si tienes dudas serias porque tu negocio tiene peso real en la Unión Europea, consulta con un abogado especializado, que para eso están.</p>
<h2>Los tres casos que de verdad te afectan en un WordPress</h2>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-159977" src="https://ayudawp.com/wp-content/uploads/2026/07/AI-Act.jpg" alt="" width="1200" height="800"></p>
<p>El artículo 50 del reglamento, que es el que regula la transparencia, cubre varios supuestos, pero solo tres tienen encaje real en un sitio WordPress «normal».</p>
<h3>Un chatbot o asistente que habla con tus visitantes</h3>
<p>Si tienes un <a href="https://ayudawp.com/crear-chatbot-ia/" target="_blank" rel="ugc noopener">chatbot de atención al cliente</a>, la norma exige que quien interactúa con él sepa que está hablando con una máquina, salvo que sea tan obvio que no haga falta decirlo, un bot con nombre «Asistente IA» y avatar de robot no necesita cartel adicional. La excepción de la obviedad no es una puerta trasera para no avisar, es sentido común aplicado a los casos donde nadie en su sano juicio pensaría que habla con una persona.</p>
<h3>Una imagen, audio o vídeo que sea un deepfake</h3>
<p>Aquí está el mito más extendido de todos, la idea de que toda imagen generada con IA necesita aviso, y no es así. La obligación solo se activa con deepfakes, y la propia norma define el término con precisión, pues <strong>se refiere únicamente a contenido de imagen, audio o vídeo creado o modificado por IA que imita</strong> a personas, objetos, lugares, entidades o hechos reales de forma que pudiera hacer creer a alguien que es genuino.</p>
<p>Una ilustración abstracta para acompañar un artículo de seguridad, un fondo decorativo, una infografía inventada, nada de eso es deepfake, porque no simula que algo real haya ocurrido. <strong>Donde sí entras en el supuesto es si generas una imagen que aparenta ser una captura real de un evento que nunca pasó</strong>, o que hace pasar por auténtica la imagen de una persona real en una situación inventada.</p>
<h3>Un texto sobre un asunto de interés público</h3>
<p>Este es el que caso que tiene más matices de los tres. De lo que se trata es que <strong>si usas IA para generar o manipular texto que se publica con el fin de informar sobre asuntos de interés público</strong>, tienes que avisar de que es artificial, salvo que ese texto haya pasado por una revisión editorial sustantiva y haya una persona, física o jurídica, que asuma la responsabilidad editorial de lo publicado.</p>
<p>El matiz más relevante es que las directrices de la Comisión Europea interpretan esa excepción de forma estricta. <strong>No vale una revisión superficial ni un visto bueno de trámite</strong>, tiene que haber un examen deliberado del fondo del contenido por alguien con criterio suficiente para hacerlo. Corregir la ortografía o dar el visto bueno sin leerte el texto entero no cuenta.</p>
<p>Para la inmensa mayoría de tutoriales técnicos, el supuesto ni siquiera se activa, porque explicar cómo desactivar un widget no es informar de un asunto de interés público en el sentido que persigue la norma. Pero un artículo sobre una vulnerabilidad que afecta a un millón de webs, o sobre este mismo reglamento, empieza a acercarse a esa categoría, así que conviene tenerlo presente cuando el tema es importante.</p>
<table>
<thead>
<tr>
<th>Caso</th>
<th>¿Hay que avisar?</th>
<th>Por qué</th>
</tr>
</thead>
<tbody>
<tr>
<td>Chatbot que interactúa con visitantes</td>
<td>Sí, salvo que sea obvio</td>
<td>Artículo 50.1: evita que alguien crea hablar con una persona</td>
</tr>
<tr>
<td>Imagen, audio o vídeo que es deepfake</td>
<td>Sí</td>
<td>Artículo 50.4: simula algo real que no ha ocurrido</td>
</tr>
<tr>
<td>Ilustración o imagen decorativa sin pretensión de realismo</td>
<td>No</td>
<td>No cumple la definición de deepfake</td>
</tr>
<tr>
<td>Texto sobre un asunto de interés público, sin revisión editorial sustantiva</td>
<td>Sí</td>
<td>Artículo 50.4, párrafo dedicado al texto</td>
</tr>
<tr>
<td>Texto sobre un asunto de interés público, con revisión tuya a fondo</td>
<td>No</td>
<td>Aplica la excepción de responsabilidad editorial</td>
</tr>
<tr>
<td>Tutorial técnico habitual, sin relación con asuntos de interés público</td>
<td>No</td>
<td>Queda fuera del supuesto por la propia naturaleza del contenido</td>
</tr>
</tbody>
</table>
<p>Cuando lo ves así, en una tabla, el titular de «hay que etiquetar todo lo que hagas con IA» se cae solo.</p>
<h2>Mitos sobre AI Act</h2>
<p>Antes de seguir, cinco ideas que circulan por ahí y que no ayudan nada.</p>
<ul>
<li><strong>«Se ha retrasado el AI Act»:</strong> Cierto a medias, y la parte cierta es justo la que no te afecta. La Unión Europea sí ha aplazado las obligaciones de los sistemas de alto riesgo, empleo, biometría, infraestructuras críticas, hasta diciembre de 2027 y agosto de 2028. Pero las obligaciones de transparencia del artículo 50, las que trata este artículo, no se han tocado y se aplican desde el 2 de agosto de 2026. Quien lea «se retrasa el AI Act» y deje de prepararse por completo se va a llevar un disgusto.</li>
<li><strong>«Tengo que etiquetar cada imagen que hago con IA»:</strong> Ya lo hemos visto arriba, y solo los deepfakes necesitan aviso, y la mayoría de las imágenes ilustrativas de un blog no lo son ni de lejos.</li>
<li><strong>«Como la ley española no está en el BOE, tengo tiempo»:</strong> El proyecto de ley española, que ya está en el Congreso, no inaugura estas obligaciones, las adapta con maquinaria propia de sanción en España. El reglamento europeo es de aplicación directa, con ley española o sin ella, así que el reloj corre igual.</li>
<li><strong>«Me pueden caer 35 millones de euros por no avisar»:</strong> Esa cifra corresponde a las prácticas prohibidas del artículo 5, cosas como la manipulación subliminal o la valoración social, no al incumplimiento del artículo 50. Lo que arriesgas aquí son multas de hasta 15 millones de euros o el 3 % de la facturación mundial, según lo que sea mayor, que tampoco es una broma, pero conviene tener la cifra correcta.</li>
<li><strong>«Tengo que revisar y etiquetar todo lo que ya he publicado»:</strong> No. La obligación se aplica a partir del 2 de agosto de 2026, el contenido que ya llevaba tiempo circulando antes de esa fecha no necesita marcado retroactivo. Lo que sí entra en juego es todo lo que generes o publiques a partir de ese día.</li>
</ul>
<h2>El caso de los resúmenes generados con IA</h2>
<p>Vamos a bajarlo a un ejemplo real, que es más útil que quedarse en la teoría. Cada vez hay más plugins, el mío incluido con <a href="https://wordpress.org/plugins/ai-share-summarize/" target="_blank" rel="ugc noopener">Share Buttons &amp; AI-powered Summaries</a>, que generan un <a href="https://ayudawp.com/resumenes-ia-integrados/" target="_blank" rel="ugc noopener">resumen automático de la entrada</a> con un proveedor de IA externo. ¿Ese resumen necesita aviso?</p>
<p>Pues bien, las directrices de la Comisión, al desarrollar el artículo 50.2, ponen a los resúmenes generados por IA en la lista de <strong>cambios sustantivos, junto a las traducciones o la eliminación de objetos</strong> de una imagen, frente a la edición estándar que sí queda exenta, como corregir ortografía o ajustar el color.</p>
<p>Y hay algo más directo todavía, porque la propia Comisión, en la página donde publica los iconos oficiales de etiquetado, incluye <strong>los resúmenes de noticias generados por IA entre los ejemplos de uso del icono de contenido totalmente generado</strong>. Ojo al matiz, que habla de resúmenes de noticias y el resumen de un tutorial de WordPress no lo es, pero deja claro por dónde va el criterio del regulador.</p>
<p>Esa parte concreta de la norma habla del marcado técnico que corresponde al proveedor del modelo, no directamente de tu aviso al lector, pero deja clara una cosa, que <strong>un resumen no es una tontería formal, es contenido nuevo con entidad propia</strong>.</p>
<p>La pregunta que de verdad te afecta como responsable del despliegue es si ese resumen entra en el supuesto de texto sobre un asunto de interés público y si ha pasado por esa revisión editorial de la que hablábamos antes. Y ojo, <strong>revisar el artículo del que sale el resumen no es lo mismo que revisar el resumen</strong> en sí, que suele generarse solo, en cada visita o en cada publicación, sin que nadie le eche un vistazo concreto a esa pieza de texto en particular.</p>
<p>Por suerte la salida práctica no depende de resolver ese debate. <strong>Share Buttons &amp; AI-powered Summaries ya muestra por defecto la etiqueta «Resumen generado con IA» encima de cada resumen</strong>, así que si usas el plugin sin tocar ese ajuste, este supuesto no te da ningún quebradero de cabeza.</p>
<p>El matiz es que el texto de la etiqueta es configurable, y si lo cambias por algo que no mencione la IA, o lo quitas directamente, la responsabilidad de que el aviso siga ahí es tuya, no del plugin. La herramienta te pone el camino fácil, no te lo puede recorrer por ti.</p>
<p>Esto vale igual si generas el resumen con cualquier otro plugin o a mano con tu proveedor de IA favorito. La etiqueta de una línea, «resumen generado con inteligencia artificial» o similar, resuelve el debate entero sin necesidad de elucubrar si tu web informa o no de un asunto de interés público.</p>
<h2>Textos alternativos e imágenes generadas con IA</h2>
<p>WordPress 7 trae de serie una <a href="https://ayudawp.com/seguridad-conectores-ia-wordpress/" target="_blank" rel="ugc noopener">pantalla de conectores de IA</a> donde guardas tu clave de Anthropic, OpenAI o Gemini para que cualquier plugin compatible la use. Si la usas para generar texto alternativo de tus imágenes o para crear una ilustración con la que acompañar un artículo, ¿entras en el supuesto de aviso?</p>
<p>Con el <strong>texto alternativo la respuesta corta es que no</strong>, y aquí no hay una directriz de la Comisión que lo diga con esas palabras exactas, así que es mi lectura razonada del propósito de la norma, no una cita textual de nadie. El <code>alt</code> describe una imagen para quien usa lector de pantalla, no informa al público de ningún asunto, ni siquiera lo ve quien navega con la vista, así que se queda fuera del espíritu del artículo 50.4 igual que se quedaría fuera un pie de foto meramente descriptivo.</p>
<p>Y hay un argumento técnico que va en la misma dirección, porque el propio Anthropic reconoce que un pasaje muy corto deja demasiado poco texto para una señal fiable, así que un <code>alt</code> de diez palabras se queda fuera del marcado por pura física, no solo por interpretación legal.</p>
<p>Con las <strong>imágenes ilustrativas</strong> aplica exactamente lo que vimos antes, pues si no simula un hecho, una persona o un lugar real de forma creíble, no es deepfake y no necesita aviso.</p>
<p>Y para quien se pregunte quién marca técnicamente qué cuando usa el conector, el proveedor del modelo que hayas conectado, Anthropic, OpenAI o Google, es quien responde del marcado legible por máquina del artículo 50.2. Tú, como responsable del despliegue, respondes de lo que ya hemos visto, el aviso visible cuando el contenido lo requiere. Usar el conector nativo no te añade ninguna obligación nueva que no tuvieras ya generando el mismo contenido por otra vía.</p>
<h2>Marcas de agua de los proveedores de IA</h2>
<p>Aquí llega la parte más reciente, y que te afecta aunque no tengas ninguna obligación nueva por ella. Los proveedores de IA han empezado a marcar técnicamente lo que generan, y esas marcas pasan por tu WordPress.</p>
<p>Anthropic, por ejemplo, ha firmado el código de buenas prácticas del artículo 50.2 y ha publicado <a href="https://support.claude.com/en/articles/16266773-how-claude-marks-ai-generated-content" target="_blank" rel="nofollow noopener">cómo va a marcar el contenido que genera Claude</a>, con dos técnicas que conviene entender.</p>
<p>Por un lado, los modelos lanzados a partir del 2 de agosto de 2026 <strong>tejen una marca de agua imperceptible dentro del propio texto</strong>, que no se ve, no cambia el significado ni la legibilidad, y lo interesante, viaja con el texto cuando lo copias y lo pegas en otro sitio.</p>
<p>Por otra parte, los archivos que genera llevan metadatos de procedencia firmados con el estándar C2PA, el mismo que ya usan DALL·E, Firefly o Imagen.</p>
<p>Esto implica que si redactas con IA y pegas el resultado en el editor de WordPress, la marca se viene con el texto, así que la suposición de «esto no lo detecta nadie» ha dejado de ser cierta. No te crea ninguna obligación que no tuvieras ya, pero conviene saberlo.</p>
<p>Con las imágenes pasa lo contrario, y es donde está el detalle jugoso para cualquiera que tenga un WordPress.</p>
<p>Los metadatos C2PA se pierden en cuanto el archivo se reguarda, se convierte de formato o se le hace una captura de pantalla, y resulta que <strong>eso es exactamente lo que hace tu web todos los días</strong>.</p>
<p>Subes la imagen a la biblioteca de medios, WordPress genera sus miniaturas, y tu plugin de optimización, sea Smush, ShortPixel, Imagify o EWWW, borra los metadatos por defecto para ahorrar bytes. La marca del proveedor se evapora en tu propio flujo de trabajo sin que tú hayas tocado nada.</p>
<p>Que no cunda el pánico, porque lo que la norma persigue es la eliminación deliberada de esas marcas, no que tu optimizador de imágenes haga su trabajo de siempre.</p>
<p>Lo que sí saco de aquí es una conclusión práctica, y es que <strong>no puedes apoyarte en la marca técnica del proveedor como red de seguridad</strong>, porque tu propia web la borra sin querer. Tu obligación siempre fue el aviso visible, y ahí no hay atajo técnico que valga.</p>
<p>Por completar el panorama, ya circulan por ahí herramientas y repositorios que dicen eliminar la marca de agua del texto, y el propio Anthropic reconoce en sus limitaciones que la marca puede no detectarse si el texto se ha editado a fondo, parafraseado, traducido o mezclado con otra escritura, y que la ausencia de marca no demuestra que algo no venga de una IA.</p>
<p>No voy a enlazarlas, entre otras cosas porque quitar la marca a propósito es justo lo que la norma trata como incumplimiento. Y aprovecho para avisarte de lo que viene, porque en cuanto esto se sepa aparecerán plugins vendiéndote que «cumplen el AI Act preservando el C2PA», que es el marketing del miedo de toda la vida con etiqueta nueva.</p>
<h2>Qué deberías tener listo desde ya</h2>
<p>Con todo lo anterior ya tienes el criterio. Esto es lo concreto que conviene dejar hecho:</p>
<ul>
<li>Revisa si tienes chatbot o asistente de IA en la web, y confirma que el visitante sabe que habla con una máquina.</li>
<li>Si generas imágenes con IA plantéate en cada caso si podría confundirse con algo real, no solo si «se ve muy realista».</li>
<li>Si te importa conservar la procedencia de las imágenes generadas con IA, revisa los ajustes de tu optimizador, porque casi todos borran los metadatos por defecto.</li>
<li>Si usas resúmenes generados con IA mejor con la etiqueta visible que sin ella, cuesta una línea de HTML y te ahorra la inquietud y un posible susto.</li>
<li>No toques lo ya publicado antes del 2 de agosto de 2026 solo por esto, la obligación mira hacia delante.</li>
<li>Si tu contenido tiene peso en asuntos de interés público, documenta que lo revisas tú antes de publicar, no hace falta un proceso complicado, basta con que sea real y puedas explicarlo si alguien pregunta.</li>
</ul>
<p>Con la tabla de más arriba ya tienes el criterio completo caso por caso. Y si quieres el aviso de una línea listo para pegar en cualquier resumen o texto generado con IA, aquí lo tienes:</p>
<pre>&lt;div style="border-left: 4px solid #8a8a8a; background: #f5f5f5; padding: 10px 16px; margin: 16px 0; font-size: 0.9em; line-height: 1.5;"&gt;
  &lt;strong&gt;Aviso:&lt;/strong&gt; este resumen ha sido generado con inteligencia artificial.
&lt;/div&gt;</pre>
<p>La Unión Europea también ha publicado un <a href="https://digital-strategy.ec.europa.eu/es/policies/eu-icons-labelling-ai-generated-content" target="_blank" rel="nofollow noopener">conjunto de iconos oficiales</a> pensado para este etiquetado, gratuitos y sin necesidad de atribución, con tres variantes según si el contenido es totalmente generado, parcialmente modificado o solo lleva IA por medio.</p>
<p>Tres cosas que conviene tener claras antes de usarlos:</p>
<ul>
<li>El icono es opcional pero el etiquetado no, y ponerlo no acredita por sí solo que cumples nada.</li>
<li>La propia Comisión hizo pruebas con usuarios y el reconocimiento mejoró en todas las medidas cuando el icono iba acompañado de una etiqueta de texto, así que mejor los dos juntos que el icono a secas.</li>
<li>Recomiendan que el icono sea legible por tecnologías de apoyo mediante <code>alt</code> o etiquetas ARIA que indiquen que el contenido es generado o manipulado por IA, algo que en WordPress te sale casi solo si rellenas el texto alternativo al subirlo.</li>
</ul>
<h2>España y la capa nacional: AESIA</h2>
<p>Todo lo anterior aplica ya, por el reglamento europeo, tengas o no ley española, pero si estás en España tenemos espía nuevo, gracias a esos políticos que siempre están pensando en nosotros.</p>
<p>El <a href="https://digital.gob.es/comunicacion/notas-prensa/mtdfp/2026/05/el-gobierno-aprueba-el-proyecto-de-ley-que-garantizara-una-super" target="_blank" rel="nofollow noopener">Gobierno español aprobó el proyecto de ley orgánica</a> para el buen uso y la gobernanza de la inteligencia artificial el 26 de mayo de 2026 y lo envió al Congreso, donde sigue su trámite parlamentario con paso por el Senado antes de publicarse en el BOE.</p>
<p>Esa ley no inventa las obligaciones que has leído en este artículo, las aplica con maquinaria sancionadora propia y designa a la Agencia Española de Supervisión de la Inteligencia Artificial, la AESIA, como autoridad principal para vigilar y sancionar. <strong>Mientras el texto sigue su trámite, este artículo se actualiza en cuanto haya novedad publicada en el BOE</strong>, así que no hace falta que vayas comprobándolo tú.</p>
<h2>Resumen rápido</h2>
<p>Si te quedas con una sola idea de todo esto, que sea esta: <strong>la norma no castiga usar IA, castiga hacerlo pasar por algo que no es</strong>.</p>
<p>Un chatbot que se presenta como humano, una imagen que finge ser una foto real, un texto que informa de algo serio sin que nadie se haya hecho responsable de su contenido, eso es lo que persigue el reglamento. Un resumen con su etiqueta, una ilustración decorativa, un texto alternativo bien escrito, ninguno de esos tres necesita que te compliques la vida.</p>
<p>Este artículo es información general para que entiendas el criterio y actúes con cabeza, no asesoría legal sobre tu caso concreto, así que si tu situación tiene matices importantes, consulta con un profesional. Y si detectas algo que ha cambiado, ley española publicada, directrices finales de la Comisión distintas de lo que cuento aquí, dímelo en los comentarios y actualizo el artículo.</p>
<p>Si quieres profundizar en la parte legal más amplia, tengo también la guía de <a href="https://ayudawp.com/registro-consentimiento-cookies-formularios-pedidos/" target="_blank" rel="ugc noopener">registro de consentimientos</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/ai-act/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>¿Por qué WordPress no acierta a optimizar el LCP … aún?</title>
		<link>https://ayudawp.com/image-prioritizer/</link>
					<comments>https://ayudawp.com/image-prioritizer/#respond</comments>
		
		<dc:creator><![CDATA[Fernando Tellado]]></dc:creator>
		<pubDate>Tue, 21 Jul 2026 06:28:32 +0000</pubDate>
				<category><![CDATA[Tutoriales - Trucos]]></category>
		<category><![CDATA[WordPress.com]]></category>
		<category><![CDATA[WordPress.org]]></category>
		<category><![CDATA[WPO - Optimizar WordPress]]></category>
		<category><![CDATA[DietPress]]></category>
		<category><![CDATA[fetchpriority]]></category>
		<category><![CDATA[LCP]]></category>
		<guid isPermaLink="false">https://ayudawp.com/?p=159925</guid>

					<description><![CDATA[Existe una forma de que WordPress deje de adivinar el elemento inicial más pesado de tu página y lo sepa de verdad, a partir de datos reales de tus propios visitantes.]]></description>
										<content:encoded><![CDATA[<p>Hay un elemento en cada página, casi siempre una imagen, que <strong>pesa más que ningún otro en si tu web se siente rápida o lenta nada más entrar</strong>.</p>
<p>Me refiero a lo que Google mide como <a href="https://ayudawp.com/google-core-web-vitals-wordpress/" target="_blank" rel="noopener"><strong>LCP</strong></a> (el <strong>tiempo que tarda en aparecer el bloque más grande de tu pantalla</strong>), y cuanto antes aparezca, mejor.</p>
<p>El problema es que <strong>WordPress tiene que adivinar cuál es esa imagen</strong> sin haberte visto navegar, y esa adivinanza falla más de lo que te gustaría.</p>
<p>La buena noticia es que <strong>ya existe una forma de que WordPress deje de adivinar el elemento inicial más pesado de tu página y lo sepa de verdad</strong>, a partir de datos reales de tus propios visitantes.</p>
<p>En este artículo te cuento <strong>qué es, qué gana tu web con ello, qué pegas tiene todavía, y qué hacer</strong> si prefieres quedarte con algo más probado mientras tanto.</p>
<h2>Optimization Detective e Image Prioritizer</h2>
<p>El núcleo de WordPress lleva desde la versión 6.3 <a href="https://ayudawp.com/fetchpriority-wordpress/" target="_blank" rel="noopener">detectando de forma automática cuál es probablemente la imagen del LCP</a>, casi siempre la destacada, y le añade el atributo <code>fetchpriority="high"</code> sin que hagas nada.</p>
<p>El límite de esa detección automática es que <strong>se basa en heurísticas desde el servidor, reglas fijas que no saben cómo se ve realmente tu web</strong> en un móvil, en una tablet o con una ventana pequeña de escritorio.</p>
<p>Esas heurísticas aciertan la imagen correcta en torno a la mitad de las veces, mientras que la otra mitad, el navegador, recibe la orden de prioridad equivocada. <strong>Optimization Detective</strong> nace para resolver justo eso.</p>
<p>Es un plugin del equipo de rendimiento de WordPress que <strong>no optimiza nada por sí solo, es un framework que recoge datos reales de tus visitantes</strong> (o RUM, siglas de Real User Monitoring, monitorización de usuarios reales) sobre qué elemento se pinta primero en cada tipo de dispositivo.</p>
<p>No tiene pantalla de ajustes ni la va a tener, funciona solo, en segundo plano. El que hace algo con esos datos es <strong>Image Prioritizer</strong>, el plugin que depende de Optimization Detective para funcionar.</p>
<p>Con la información real de tus visitas, añade <code>fetchpriority="high"</code> a la imagen que de verdad es el LCP en cada punto de ruptura, ajusta la carga diferida para que no se quede vacío justo lo que sí se ve al entrar, y <strong>reduce el peso del fotograma inicial de los vídeos que hacen de LCP</strong>.</p>
<p>Anteriormente, Image Prioritizer también calculaba el atributo <code>sizes</code> de las imágenes responsive, pero ya no, esa función se quitó por un problema, y hoy ese trabajo lo hace otro plugin del mismo equipo, <a href="https://wordpress.org/plugins/auto-sizes/" target="_blank" rel="nofollow noopener">Enhanced Responsive Images</a>.</p>
<h2>¿Para cuándo estará esto en WordPress?</h2>
<p>El equipo de rendimiento suele probar la funcionalidad completa en un plugin independiente, la validan con tráfico real de decenas de miles de webs, y cuando por fin entra en el núcleo, suele hacerlo con ajustes más prudentes que los que tenía el plugin original.</p>
<p>Ya te conté ese proceso con la <a href="https://ayudawp.com/carga-especulativa-nativa/" target="_blank" rel="ugc noopener">carga especulativa nativa</a>, que también nació como plugin, se probó en más de 50.000 sitios, con una mejora media del 1,9% en LCP en los que lo llevaban activado, y aterrizó en WordPress 6.8 con el modo prefetch y la anticipación más conservadora en vez del <code>prerender</code> y la anticipación moderada que traía el plugin.</p>
<p>El cálculo del atributo <code>sizes</code> para imágenes con carga diferida siguió un camino parecido hasta la versión 6.7.</p>
<p>Dicho esto, <strong>no hay fecha para Optimization Detective ni para Image Prioritizer</strong>. Ninguno de los dos aparece nombrado de momento en planes de futuras versiones, solo Enhanced Responsive Images y View Transitions figuran como trabajo del equipo de rendimiento en marcha hacia alguna versión de WordPress de las próximas.</p>
<h2>Esa cosa es cojonuda ¿no? … pues no del todo</h2>
<p>Antes de que instales los dos plugins unos cuantos peros que conviene que conozcas:</p>
<ul>
<li><strong>Los dos siguen en beta:</strong> Optimization Detective en la 1.0.0-beta5 e Image Prioritizer en la 1.0.0-beta3, y ninguno tiene pantalla de ajustes.</li>
<li><strong>No deberías usar plugins canonical en webs en producción:</strong> Como cualquier plugin de este tipo su misión es terminar en el núcleo de WordPress y, aunque te corroa la impaciencia, no deberías usarlos como si fuesen plugins normales, nunca, ni estos ni ningún otro.</li>
<li><strong>Necesitas la API REST abierta a visitantes anónimos:</strong> Así es como se recogen los datos de cada visita. El propio plugin trae un aviso en Salud del sitio que te avisa si la tiene bloqueada, así que no te vas a quedar a ciegas. Si usas Vigilante con el modo de protección de la API REST más restrictivo, revisa que no le esté cerrando el paso a este plugin en concreto, o nunca vas a ver ninguna optimización aplicada sin saber por qué.</li>
<li><strong>No optimiza nada para ti como administrador:</strong> Hace falta que sean visitantes normales, así que no esperes ver cambios nada más activarlo, necesitas que pase tráfico real primero, para móvil y para escritorio.</li>
</ul>
<h2>¿Hago algo ya?</h2>
<p>No hay una respuesta única, depende de cuánto te guste ir por delante y de cuánto tiempo le quieras dedicar, pero sobre todo teniendo en cuenta que <strong>si pruebas este tipo de plugins debe ser únicamente como experimentació</strong>n.</p>
<p>Si no te importa que algo esté en beta y tienes tráfico suficiente para que se llenen de datos las visitas en pocos días, con todas las precauciones, instala <a href="https://wordpress.org/plugins/optimization-detective/" target="_blank" rel="nofollow noopener">Optimization Detective</a> y <a href="https://wordpress.org/plugins/image-prioritizer/" target="_blank" rel="nofollow noopener">Image Prioritizer</a>, revisa el código fuente de tu web a los pocos días y compara.</p>
<p>Si prefieres no depender de tráfico acumulado ni de tener la API REST abierta a cualquiera, y quieres algo que ya lleva tiempo funcionando sin sorpresas <strong>hay plugins que sí puedes usar ya para optimizar WordPress</strong>.</p>
<h3>¿De qué plugin estás hablando?</h3>
<p>Sabes que hay muchos plugins de optimización, pero <strong>yo solo uso uno gratuito, <a href="https://dietpress.dev/es/" target="_blank" rel="ugc noopener">DietPress</a></strong>, y este ya pone <code>fetchpriority="low"</code> a todas las imágenes menos la primera, sin mirar visitas ni dispositivos, <strong>una regla fija que sigue siendo mejor que lo que hace el núcleo por su cuenta con el resto de imágenes de la página, que es no hacer nada</strong>.</p>
<p>Pero esa regla fija y la lógica de Image Prioritizer, que decide con visitas reales por punto de ruptura, no siempre van a estar de acuerdo. Si en el móvil la imagen importante no es la primera del HTML, más habitual de lo que parece con maquetadores y avisos que se cuelan antes del contenido, tu plugin le estaría bajando la prioridad justo a la imagen a la que el otro se la quiere subir.</p>
<p>Lo tengo controlado, <strong>en cuanto Image Prioritizer deje la beta adaptaré DietPress para que no se pisen cuando se incorpore en WordPress</strong>, todavía no sé si apartándose cuando lo detecte o afinando la regla, pero se adapta, eso seguro.</p>
<p>Y si prefieres no tocar nada de esto todavía, tampoco pasa nada. Por el patrón que te contaba antes, es candidato real a acabar en el núcleo tarde o temprano, y cuando lo haga no vas a tener que instalar ni configurar nada, como pasó con la carga especulativa.</p>
<p>Elijas lo que elijas, <strong>tu web no tiene por qué seguir dependiendo de una adivinanza para saber cuál es su imagen más importante</strong>, y eso tarde o temprano juega a tu favor.</p>
<p>Si acabas probando alguno de los dos plugins, cuéntame qué tal te ha ido, aquí abajo en los comentarios tienes hueco.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ayudawp.com/image-prioritizer/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>