Saltar al contenido

Etiqueta: widget

Cómo migrar un widget de WordPress a un bloque de Gutenberg

Hace varios años desarrollé dos plugins para WordPress: JS Archive List y JS Categories List. Ambos nacieron cuando los widgets de WordPress se desarrollaban prácticamente por completo en PHP: creabas una clase, extendías WP_Widget, generabas el formulario de configuración y, finalmente, renderizabas el HTML. Funcionaba bastante bien, pero WordPress ha cambiado mucho desde la llegada de Gutenberg. Así que decidí migrar ambos plugins para que pudieran utilizarse como un bloque de Gutenberg. En el caso de JS Categories List, ocurrió desde la versión 4.0 y en JS Archive List desde la versión 5.0, manteniendo además el widget anterior en PHP por compatibilidad con instalaciones existentes.

Lo interesante de esta migración no fue solo aprender a crear un bloque. También me hizo ver, de una forma diferente, cómo ha evolucionado WordPress.

Se acabaron los tiempos de plugins 100% hechos en PHP, ahora es bloque de Gutenberg en JS (React) + PHP
Se acabaron los tiempos de plugins 100% hechos en PHP, ahora es bloque de Gutenberg en JS (React) + PHP

De widgets en PHP a una interfaz en React

Un widget clásico de WordPress normalmente hacía casi todo en PHP. Por ejemplo, teníamos algo parecido a esto:

class My_Widget extends WP_Widget {

    public function widget( $args, $instance ) {
        // Obtener datos.
        // Generar HTML.
        // Mostrar el widget.
    }

    public function form( $instance ) {
        // Formulario de configuración.
    }
}

El formulario que veía el administrador, la configuración y el HTML final estaban muy ligados entre sí. Con Gutenberg la separación es diferente. Ahora puedes tener PHP encargándose de los datos y del renderizado mientras que el editor utiliza JavaScript y React para construir la interfaz de configuración.

Por esta razón, siento que WordPress cada vez se siente más como un CMS que ofrece servicios y APIs en PHP, mientras que diferentes interfaces consumen esos servicios.

Gutenberg es probablemente el mejor ejemplo, porque el editor trabaja con entidades como posts, páginas, usuarios o términos mediante @wordpress/core-dataQue internamente puede procesar los datos mediante las APIs de WordPress.

PHP no desapareció. Simplemente ya no tiene que encargarse de toda la interfaz.

¿Cómo comenzar un bloque de Gutenberg?

WordPress posee una herramienta oficial llamada @wordpress/create-block que genera la estructura inicial de un plugin con un bloque, incluyendo JavaScript, PHP, CSS y la configuración necesaria para compilar todo. Puedes crear uno ejecutando:

npx @wordpress/create-block@latest my-block --namespace=my-plugin

Luego:

cd my-block
npm start

Aunque estés migrando un plugin existente, te recomiendo ejecutar este comando al menos una vez. Es una forma sencilla de entender cuál es la estructura recomendada actualmente por WordPress.

Entre los archivos encontrarás uno particularmente importante:

block.json

Este archivo contiene la definición del bloque: nombre, atributos, scripts, estilos y demás metadatos. Por ejemplo:

{
    "apiVersion": 3,
    "name": "my-plugin/archive-list",
    "title": "Archive List",
    "category": "widgets",
    "attributes": {
        "showCount": {
            "type": "boolean",
            "default": false
        }
    }
}

WordPress actualmente recomienda registrar los bloques utilizando esta metadata y register_block_type() Desde PHP se hace asi:

add_action( 'init', function() {
    register_block_type( __DIR__ . '/build' );
} );

Con eso PHP conoce nuestro bloque y WordPress puede cargar los scripts y estilos necesarios.

La configuración del bloque de Gutenberg ahora vive en React

En un widget clásico, las opciones se construían con inputs HTML generados en PHP. En un bloque de Gutenberg puedes crear esa interfaz con los componentes que ya ofrece WordPress. Por ejemplo:

import { InspectorControls } from '@wordpress/block-editor';
import {
    PanelBody,
    ToggleControl
} from '@wordpress/components';

export default function Edit({ attributes, setAttributes }) {
    return (
        <InspectorControls>
            <PanelBody title="Options">
                <ToggleControl
                    label="Show post count"
                    checked={ attributes.showCount }
                    onChange={ ( value ) =>
                        setAttributes({ showCount: value })
                    }
                />
            </PanelBody>
        </InspectorControls>
    );
}

De esta forma, Gutenberg se encarga de gran parte de la experiencia del editor y nosotros solo debemos definir qué opciones necesita nuestro bloque.

En mis plugins esto reemplazó buena parte de los formularios que antes tenía que generar manualmente desde PHP.

Consumir los datos de WordPress desde el bloque de Gutenberg

Otra parte interesante es que no necesariamente tienes que crear tus propios endpoints para obtener información que WordPress ya conoce. Desde el editor puedes consultar entidades utilizando core-data. Por ejemplo, para obtener páginas puedes utilizar:

import { useEntityRecords } from '@wordpress/core-data';

const { records, isResolving } = useEntityRecords(
    'postType',
    'page'
);

WordPress se encarga de resolver la petición, de mantener los datos en su store y de entregarlos al componente. En un plugin como JS Categories List, el mismo concepto permite trabajar con taxonomías y categorías desde la interfaz del bloque, sin tener que imprimir previamente toda esa información en el HTML generado por PHP.

Eso también tiene otra ventaja, la nueva versión de mis plugins puede leer la información dinámicamente y cargar JavaScript y CSS solamente cuando realmente existe un bloque o widget en la página, en lugar de cargar recursos innecesariamente en todo el sitio.

No tienes que reescribir todo tu PHP

Esta fue una de las cosas que pensé inicialmente que serían más complicadas.

Migrar a un bloque de Gutenberg no significa necesariamente convertir todo el plugin a JavaScript. Puedes crear un bloque dinámico y continuar renderizando su contenido desde PHP, por ejemplo, block.json puede indicar:

{
    "render": "file:./render.php"
}

Y dentro de render.php Puedes reutilizar buena parte de la lógica que ya tenía tu antiguo widget, permitiendo tener una migración más progresiva:

<?php

$show_count = $attributes['showCount'] ?? false;

echo my_old_archive_render_function(
    $show_count
);

La interfaz del editor puede estar hecha con React, mientras que el frontend todavía utiliza funciones PHP que llevan años funcionando. Los bloques dinámicos están diseñados precisamente para casos donde el contenido debe calcularse al momento de renderizar la página, y WordPress permite hacerlo mediante un archivo render.php o un render_callback.

En mi caso, esto fue bastante útil porque no tenía sentido reescribir código estable solamente por utilizar Gutenberg.

Mantener el antiguo widget por retrocompatibilidad

También decidí no eliminar de inmediato los widgets anteriores. Tanto JS Archive List como JS Categories List mantienen una versión legacy en PHP para instalaciones que todavía la utilizan, mientras que el desarrollo nuevo está enfocado en el bloque Gutenberg.

Creo que esta es una buena estrategia para plugins que llevan muchos años publicados. Puedes modernizar el código sin afectar las instalaciones de los usuarios que configuraron el widget hace más de cinco años. Ya con el tiempo puedes dejar la implementación antigua únicamente en modo de mantenimiento.

WordPress es bastante diferente ahora

Después de hacer esta migración, creo que desarrollar para WordPress actualmente se parece bastante menos al WordPress con el que comencé hace años.

PHP continúa siendo una parte fundamental, pero ahora tenemos una capa de APIs, bases de datos, componentes y una interfaz escrita en React.

En lugar de pensar:

“Tengo que crear una página PHP para configurar esto.”

Cada vez pienso más:

“¿Qué datos o servicios debe proporcionar WordPress y cómo los va a consumir la interfaz?”

Ese cambio de mentalidad hace que Gutenberg tenga mucho más sentido. Así que si tienes un plugin antiguo basado en WP_Widget, no necesitas reescribirlo por completo de una vez. Puedes comenzar creando un bloque, mover las opciones del formulario a React y reutilizar tu código PHP para el renderizado. Luego moderniza el resto poco a poco.

Para empezar y entender cómo funciona todo, crea primero un bloque vacío con @wordpress/create-block, ejecuta npm start Y comienza a modificarlo. Es probablemente la forma más rápida de dejar de ver Gutenberg como algo extraño y comenzar a verlo simplemente como la nueva interfaz de desarrollo de WordPress.

Happy coding!

Deja un comentario

JS Categories List 4.0

Luego de 7 años tuve la oportunidad de dedicarle tiempo a mi plugin JS Categories List y poder actualizarlo para que esté al día respecto a los estándares de WordPress y de la web en general.

Listado de categorías de forma dinámica
El plugin muestra un listado de categorías expandibles

Durante este tiempo WordPress añadió Gutenberg, un editor visual que ahora se incorpora en cada instalación y poco a poco va tomando el liderazgo de como crear el contenido. Por este motivo los widget/bloques han migrado a ser hechos con una aplicación en React y que llame a entradas del API del sitio.

Eliminación de jQuery de JS Categories List

En estos 7 años el principal cambio fue lo innecesario de depender de jQuery. Su popularidad se debía porque está incluida en cada instalación y anteriormente ayudaba a manipular el DOM fácilmente debido a las limitaciones de los navegadores.

Pero actualmente no es necesario usarla: los navegadores ya permiten hacer nativamente mucha de sus funcionalidad, la librería requiere cargar contenido JS innecesario y los bloques de Gutenberg se realizan con React quien ofrece mucho mas.

Creación del bloque de Gutenberg

Primero fue mejorar el código fuente, cuya tarea mas que todo fue aplicar estandarización de código PHP, organizar mejor el código, rescribir partes mal hechas

Luego fue la creación del bloque de Gutenberg, tomé como base el código fuente de mi otro plugin recientemente actualizado y lo modifiqué para funcionar con categorías en vez de archivos.

Los bloques de Gutenberg usan React, así que me tocó rescribir el plugin desde el PHP que genera HTML a componentes JSX. La lógica es similar pero en esta migración pude hacer mejoras que luego apliqué a la versión de PHP.

Para facilitar futuras mejoras y ver que el código funciona, agregué pruebas jest a los componentes y así asegurarme que todo funciona bien. En futuros cambios, ahora tendré como probar los cambios y garantizar el correcto funcionamiento,

Animaciones en JavaScript

Una de las principales funcionalidades que ofrecía jQuery es de animaciones sencillas con simplemente llamar una función. Esta funcionalidad no está disponible en el JavaScript puro porque esas características se fueron agregando a CSS.

En mi plugin de JS Archive List, logré implementar las animaciones usando clases CSS pero no funcionan bien en algunos casos reportados por usuarios, sobre todo, cuando hay altura dinámica.

Por ello, para este JS Categories List decidí crearlas desde 0 en vanilla JS para que funcionen bien en cualquier escenario. Descarté el uso de clases CSS por el problema mencionado, ademas que es mas fácil de probar de forma automatizada.

Experiencia al actualizar JS Categories List

Aprendí mucho al rescribir mi código antiguo. Noté como ha evolucionado mi forma de programar a lo largo de estos años, cómo la tecnología cambia pero las bases de WordPress se mantienen y la retrocompatibilidad se respeta. Con razón este CMS es el mas usado en el mundo.

Pude pulir mis conocimientos de React, de pruebas automatizadas con Jest y aplicar mejores patrones en el código de PHP. También el resultado me permitirá actualizar con mayor frecuencia este plugin y ofrecer mejoras.

Si usas WordPress te recomiendo descargar e instalar mi plugin.

Espero que te guste y lo uses en tu sitio.

Deja un comentario

Liberado jQuery Categories List 1.1

Hace unas semanas hice un plugin para wordpress, donde se imprime una lista de las categorías de forma compacta y expandible mediante animaciones  jQuery, pues hoy he liberado la versión 1.1 del mismo, con la novedad que ahora pueden excluir del listado las categorías que deseen. Esta característica fue agregada debido a la solicitud de varios usuarios del plugin y expandir las posibilidades de uso de este plugin.

Para instalarlo pueden ir a su página oficial o actualizar desde el mismo gestor de actualizaciones de WordPress. Si no lo han probado, se los recomiendo y recuerden votar por él.

1 comentario

jQuery Archive List Widget

Para los lectores / amigos que me leen, saben que siempre en las vacaciones suelo programar algo por diversión como: el resolvedor de sudokus, el cheater para Word Challenge, el Skate or Dice para el PSP. Pues esta vez realicé un widget para WordPress utilizando la librerí­a jQuery, el cual consiste en mostrar los archivos de los artí­culos en una lista contraida, al hacer clic en cada uno de los items se despliega el contenido con un efecto de acordeón o de desvanecimiento tal como se puede observar en la sección de Archivos en la parte izquierda de esta página.

Entre las principales caracterí­sticas que posee son:

  • Utiliza el script de jQuery de WordPress por lo que no sobrecarga las páginas.
  • Sencillo y fácil de configurar.
  • Permite mostrar o no la cantidad de artí­culos por año o mes.
  • Permite mostrar o no los artí­culos que hay en cada mes.
  • Permite seleccionar el formato del mes a mostrar.
  • Se puede utilizar dentro de páginas o artículos.
  • Seleccionar efectos de jQuery.
  • Carga el script en un archivo separado para mejor ejecución y permitir guardarlo en caché.
  • Permite seleccionar el sí­mbolo de la viñeta.

Sé que es sencillo y no ofrece mucho, pero dependiendo del uso y si pueden colaborar con donaciones podré dedicarle mas tiempo con el fin de agregar mas caracterí­sticas configurables. Por ahora, pues descárguenlo e instálenlo, cualquier sugerencia o corrección pueden hacerlo por mensaje privado y/o un comentario en esta entrada.

La licencia del mismo es GPL2 y pueden descargarlo desde el siguiente enlace:

https://wordpress.org/extend/plugins/jquery-archive-list-widget/

Si les gustó mucho el widget y desean colaborar con el desarrollo de futuras versiones pueden ayudar con una donación libre usando el siguiente botón.

Cambios en las versiones: Leer los cambios de esta versión

Contribuye con la creación de este plugin

5 comentarios