El bootstrap process de WordPress explicado para desarrolladores

Cuando hablamos del bootstrap process de WordPress hablamos de todo lo que ocurre desde que llega una petición HTTP hasta que WordPress decide qué plantilla cargar y empieza a pintar HTML. No es una parte especialmente visible del CMS, pero entenderla cambia mucho cómo programas plugins, temas y optimizaciones.

La idea importante es esta: WordPress no “salta” directamente a tu tema. Antes construye un entorno entero: constantes, rutas, base de datos, caché, plugins, traducciones, tema activo, usuario actual, query principal y jerarquía de plantillas.

El recorrido corto

En una instalación estándar, la petición entra por el index.php de la raíz. Ese archivo define WP_USE_THEMES y carga wp-blog-header.php. A partir de ahí empieza la cadena real.

index.php
-> wp-blog-header.php
   -> wp-load.php
      -> wp-config.php
         -> wp-settings.php
   -> wp()
   -> wp-includes/template-loader.php

Visto así parece poca cosa, pero wp-settings.php es donde WordPress arma casi todo lo que luego damos por sentado: incluye librerías core, inicializa la base de datos, carga drop-ins, mu-plugins, plugins activos, traducciones, funciones pluggable y el tema.

1. index.php: la puerta de entrada

El archivo raíz no resuelve rutas, no consulta posts y no sabe qué plantilla se va a renderizar. Su trabajo es mínimo: decirle a WordPress que debe cargar el tema y requerir wp-blog-header.php.

define( 'WP_USE_THEMES', true );
require __DIR__ . '/wp-blog-header.php';

Ese WP_USE_THEMES importa más de lo que parece. Hay contextos donde quieres cargar WordPress sin renderizar el tema, por ejemplo scripts internos, cron, peticiones AJAX o WP-CLI. En una visita normal de frontend, lo habitual es que esté a true.

2. wp-load.php: localizar la configuración

wp-blog-header.php llama primero a wp-load.php. Este archivo define ABSPATH y busca wp-config.php, normalmente en la raíz de WordPress o un nivel por encima.

En wp-config.php viven las constantes que condicionan el arranque: credenciales de base de datos, prefijo de tablas, modo debug, claves de seguridad, entorno, caché, rutas personalizadas y cualquier constante definida antes de que WordPress termine de cargar.

La consecuencia práctica: si una constante debe influir en cómo arranca WordPress, tiene que existir antes de wp-settings.php. Definirla tarde en un plugin puede ser inútil si el core ya tomó una decisión.

3. wp-settings.php: construir WordPress

Este archivo es el corazón del bootstrap. Carga piezas del core en un orden muy concreto y va abriendo puntos de extensión para que plugins y temas entren en juego.

Un resumen razonable del orden sería:

  1. Definir constantes y cargar funciones base.
  2. Inicializar base de datos y object cache.
  3. Cargar drop-ins como advanced-cache.php u object-cache.php si existen.
  4. Cargar mu-plugins.
  5. Disparar muplugins_loaded.
  6. Cargar plugins activos.
  7. Disparar plugins_loaded.
  8. Cargar funciones pluggable.
  9. Cargar el tema activo y su functions.php.
  10. Disparar setup_theme y after_setup_theme.
  11. Disparar init: aquí se registran la mayoría de tipos de contenido, taxonomías y piezas del core que dependen de que todo esté cargado.
  12. Disparar wp_loaded: WordPress ya está montado por completo, pero la query principal todavía no se ha resuelto.

wp_loaded es un punto intermedio que a menudo se pasa por alto. En ese momento ya existen plugins, tema, usuario actual y casi todo el core, pero wp() aún no ha convertido la URL en consulta. Es útil para inicializar lógica que necesita WordPress entero —por ejemplo cuando dependes de rewrite rules ya registradas— sin asumir todavía qué pantalla se está sirviendo. Si necesitas modificar la query o usar condicionales como is_page(), todavía es demasiado pronto; para eso vienen pre_get_posts o template_redirect.

Este orden explica muchas decisiones de arquitectura. Un plugin no debería registrar un custom post type en cuanto se carga el archivo principal, sino engancharlo a init. Un tema no debería declarar soporte de thumbnails en cualquier sitio, sino en after_setup_theme. Y si necesitas reaccionar cuando todos los plugins están disponibles, plugins_loaded suele ser mejor sitio que el cuerpo global de tu plugin.

4. Mu-plugins, plugins y funciones pluggable

Los must-use plugins se cargan antes que los plugins normales. Son útiles para comportamiento que quieres garantizar en una instalación: bootstrap de contenido, configuración de entorno, reglas de seguridad o integraciones que no deben depender de que alguien active un plugin desde el panel.

Después llegan los plugins activos. Más tarde WordPress carga las funciones pluggable, como parte de autenticación, cookies o funciones de usuario. Se llaman “pluggable” porque un plugin puede definir algunas de ellas antes de que el core las declare. Es una puerta histórica de extensibilidad, pero hay que usarla con muchísimo cuidado: normalmente un hook o filtro es más mantenible.

5. wp(): resolver la petición

Cuando el entorno ya existe, wp-blog-header.php llama a wp(). Aquí WordPress empieza a convertir la URL actual en una consulta.

En términos prácticos, esta fase:

  • Parsea la URL y las reglas de rewrite.
  • Rellena query vars.
  • Construye la query principal.
  • Determina condicionales como is_home(), is_page() o is_single().
  • Prepara cabeceras HTTP.

Por eso muchos bugs aparecen cuando se usan condicionales demasiado pronto. Antes de la query principal, WordPress todavía no sabe del todo qué tipo de pantalla está resolviendo. Para modificar la query principal, pre_get_posts es el lugar habitual; para redirecciones de frontend, suele tener sentido template_redirect; para cambiar la plantilla final, template_include.

6. template-loader.php: elegir plantilla

Después de wp(), WordPress carga template-loader.php. Este archivo dispara template_redirect y luego busca la plantilla adecuada usando la jerarquía de plantillas del tema.

Si estás en un post, WordPress puede acabar en single.php, single-post.php o una plantilla más específica. Si estás en una página, puede cargar page.php, una plantilla asignada o una variante por slug/ID. Si no encuentra algo específico, baja por la jerarquía hasta index.php.

Hooks útiles según intención

Una forma sana de trabajar con el bootstrap es elegir el hook por intención, no por costumbre.

  • plugins_loaded: inicializar un plugin cuando ya están cargados los demás plugins.
  • after_setup_theme: declarar soportes del tema, menús, tamaños de imagen o configuración propia del theme.
  • init: registrar custom post types, taxonomías, shortcodes o rewrite rules.
  • wp_loaded: ejecutar lógica cuando WordPress ya está completamente cargado, pero antes de resolver la query principal.
  • wp_enqueue_scripts: cargar CSS y JavaScript de frontend.
  • pre_get_posts: modificar la query principal sin romper plantillas.
  • template_redirect: redirigir antes de renderizar.
  • template_include: sustituir la plantilla final de forma controlada.

La lectura de rendimiento

Cada visita de frontend arranca WordPress. Eso significa que el código global de plugins y tema se ejecuta en cada request. Si metes consultas, llamadas HTTP, lecturas de archivos pesadas o lógica condicional compleja en el nivel global, estás cobrando ese coste siempre, incluso cuando no hace falta.

Una regla simple: carga definiciones pronto, ejecuta trabajo tarde y solo cuando el contexto lo justifique. El bootstrap de WordPress es flexible, pero esa flexibilidad se paga si todo el mundo decide hacer cosas caras antes de saber qué pantalla se está sirviendo.

Cierre

Entender el bootstrap no es memorizar todos los includes del core. Es saber en qué momento WordPress ya conoce la configuración, cuándo están disponibles los plugins, cuándo existe el tema, cuándo se ha resuelto la query y cuándo empieza el render.

Cuando colocas cada pieza en el hook correcto, el código se vuelve más predecible, más fácil de depurar y bastante más amable con producción. Y en WordPress, eso suele ser media batalla ganada.

Contrátame