Aunque WordPress ya cuenta con un REST API, y aunque ya contase con el XML-RPC API, todavía hay muchos casos en los que cargar directamente WordPress desde PHP pueda estar más que justificado.

Sin entrar en el debate de lo conveniente que pueda ser, vamos a ver los diferentes métodos para hacerlo y las diferencias más importantes de cada uno. Al final del post deberíamos ser capaces de elegir un método en concreto sabiendo exactamente que es lo que estamos haciendo.

Vamos a imaginar que tenemos esta estructura de archivos:

  • /home/usuario/public_html/wp/: directorio dónde tienes instalado WordPress. En este directorio puedes encontrar wp-load.php y wp-blog-header.php.
  • /home/usuario/public_html/miapp.php: script PHP en el que quieres cargar WordPress.
home/usuario/public_html
├───wp
│ ├───wp-admin
│ ├───wp-content
│ ├───wp-includes
│ ├───wp-blog-header.php
│ ├───wp-load.php
│ ├───index.php
│ ├───......
├───miapp.php

Cargar WordPress en miapp.php sería tan sencillo como:

1.- Cargar wp-blog-header.php

require('/home/usuario/public_html/wp/wp-blog-header.php');

Como se va a utilizar WordPress fuera de WordPress, la presentación de la información no estará a cargo de WordPress. Es habitual que se recomiende decirle a WordPress que no utilice un theme:

define( WP_USE_THEMES, false );
require('/home/usuario/public_html/wp/wp-blog-header.php');

2.- Cargar wp-load.php

A través de este método, los themes no son utilizados y la constante WP_USE_THEMES no tiene ningún efecto.

require('/home/usuario/public_html/wp/wp-load.php');

Ahora ya podrías utilizar cualquier función de WordPress en el script miapp.php, así como acceder a todos los datos gestionados por WordPress. Por ejemplo. miapp.php podría ser:

<?php

require('/home/usuario/public_html/wp/wp-load.php');

?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Mi super aplicación</title>
    </head>
    <body>
        <?php
        // Podemos utilizar las funciones de WordPress
        $recent_posts = wp_get_recent_posts();
 
        if( $recent_posts ) {
 
            echo '<ul>';
 
            foreach( $recent_posts as $post ){
 
                echo '<li><a href="' . get_permalink( $post["ID"] ) . '">' . $post["post_title"] . '</a></li>';
 
            } 
 
            echo '</ul>';
 
        } else {
 
            echo "No se han encontrado posts";
 
        }
        ?>
    </body>
</html>

¿Qué hace exactamente cada método?

Si abrimos el archivo index.php, que se puede encontrar en el directorio de instalación de WordPress, veremos que contiene esto:

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

Lo que hace, básicamente, es cargar wp-blog-header.php y decirle a WordPress que utilice un theme. Este es el método que utiliza WordPress para cargarse a sí mismo. Al igual que en uno de los métodos descritos antes, lo mismo se puede hacer desde otro script PHP para cargar WordPress, eligiendo si es necesario utilizar un theme o no.

Si seguimos el hilo y vamos al archivo wp-blog-header.php, vemos esto:

if ( !isset($wp_did_header) ) {

    $wp_did_header = true;

    // Load the WordPress library.
    require_once( dirname(__FILE__) . '/wp-load.php' );

    // Set up the WordPress query.
    wp();

    // Load the theme template.
    require_once( ABSPATH . WPINC . '/template-loader.php' );

}

Lo que hace wp-blog-header.php es:

  1. cargar wp-load.php: cargar el motor de WordPress
  2. ejecutar la función wp(): crea el query en WordPress
  3. cargar template-loader.php: carga el sistema de theming si WP_USE_THEMES es true.

El método para cargar WordPress utilizando wp-load.php es tan sólo un paso más abajo que wp-blog-header.php, y se salta la creación del query y el sistema de theming. Ni el query ni los themes suelen ser necesarios cuándo se carga WordPress desde fuera, por ello creo que es el método recomendable en la mayoría de las situaciones.

SHORTINIT

No podía hacer un post sobre cargar WordPress desde PHP y no hablar de SHORTINIT. Si definimos esta constante como true, el core de WordPress se cargará con funciones mínimas y podemos elegir sólo los módulos que necesitemos.

Por ejemplo:

define('SHORTINIT', true);

require( '/path/to/wordpress/wp-load.php' );
// Tras cargar WordPress, ABSPATH y WPINC están definidos
require( ABSPATH . WPINC . '/class-wp-post.php' );
require( ABSPATH . WPINC . '/formatting.php' );
require( ABSPATH . WPINC . '/meta.php' );
require( ABSPATH . WPINC . '/post.php' );
require( ABSPATH . WPINC . '/revision.php' );

if( isset( $_GET['post_ID'] ) ) {
    $post_ID = filter_input( INPUT_GET, 'post_ID', FILTER_VALIDATE_INT );
    update_post_meta( $post_ID, 'field_key', 'field_value' );
}

Si vamos al archivo wp-settings.php, cargado en wp-config.php, podemos ver como WordPress se va preparando hasta llegar a estas líneas:

// Stop most of WordPress from being loaded if we just want the basics.
if ( SHORTINIT )
    return false;

Después de estas líneas hay una extensa lista de scripts PHP con funcionalidades y módulos de WordPress que no se cargarán si SHORTINIT es true y que puedes cargar manualmente según necesites.

Así, la carga de WordPress desde otra aplicación puede ser mucho más ligera. Tenlo en cuenta.