grav plugins

Plugins - Parte 3

Tutorial práctico para crear un plugin

Los plugins generalmente se desarrollan porque hay una tarea que no se puede completar con la funcionalidad principal de Grav.

En este tutorial, crearemos un plugin que ayude a Grav a entregar una página aleatoria al usuario. Probablemente has visto una funcionalidad similar en sitios de blogs como una forma de proporcionar una entrada de blog aleatoria cuando haces clic en un botón.

Debido a que ya existe un plugin que realiza este trabajo llamado Random, llamaremos a este plugin de prueba Randomizer.

Esta característica no es posible de inmediato, pero se proporciona fácilmente a través de un plugin. Como ocurre con muchos aspectos de Grav, no hay una única forma de hacer esto. En cambio, tienes muchas opciones. Cubriremos solo un enfoque...

Resumen del Plugin Randomizer

Para nuestro plugin tomaremos el siguiente enfoque:

  1. Activar el plugin si un URI coincide con nuestra 'ruta de activación' configurada. (por ejemplo, /random)

  2. Crear un filtro para que solo las taxonomías configuradas estén en el grupo de páginas aleatorias. (por ejemplo, category: blog)

  3. Encontrar una página aleatoria de nuestro grupo filtrado y decirle a Grav que la use para el contenido de la página.

¡Bien! Suena bastante simple, ¿verdad? Así que, ¡manos a la obra!

Paso 1 - Instalar el plugin DevTools

Las versiones anteriores de este tutorial requerían crear un plugin manualmente. Este proceso completo se puede omitir gracias a nuestro nuevo plugin DevTools.

El primer paso para crear un nuevo plugin es instalar el plugin DevTools. Esto se puede hacer de dos maneras.

Instalar vía CLI GPM

  • Navega en la línea de comandos hasta la raíz de tu instalación de Grav
bin/gpm install devtools

Instalar vía plugin Admin

  • Después de iniciar sesión, simplemente navega a la sección Plugins desde la barra lateral.
  • Haz clic en el botón Añadir en la parte superior derecha.
  • Encuentra DevTools en la lista y haz clic en el botón Instalar.

Paso 2 - Crear el plugin Randomizer

Para este siguiente paso realmente necesitas estar en la línea de comandos ya que DevTools proporciona un par de comandos CLI para facilitar mucho el proceso de creación de un nuevo plugin.

Desde la raíz de tu instalación de Grav ingresa el siguiente comando:

bin/plugin devtools new-plugin

Este proceso te hará algunas preguntas que son necesarias para crear el nuevo plugin:

bin/plugin devtools new-plugin
Enter Plugin Name: Randomizer
Enter Plugin Description: Envía al usuario a una página aleatoria
Enter Developer Name: Acme Corp
Enter Developer Email: contact@acme.co

ÉXITO plugin Randomizer -> Creado exitosamente

Ruta: /www/user/plugins/randomizer

Asegúrate de ejecutar `composer update` para inicializar el autoloader

En este punto necesitas ejecutar composer update en la carpeta del nuevo plugin creado.

El comando DevTools te dice dónde se creó este nuevo plugin. Este plugin creado es completamente funcional pero no tendrá automáticamente la lógica para realizar la función que deseamos. Tendremos que modificarlo para adaptarlo a nuestras necesidades.

Paso 3 - Conceptos básicos del plugin

Ahora hemos creado un nuevo plugin que puede ser modificado y desarrollado. Vamos a desglosarlo y ver qué compone un plugin. Si miras en la carpeta user/plugins/randomizer verás:

.
├── CHANGELOG.md
├── LICENSE
├── README.md
├── blueprints.yaml
├── randomizer.php
└── randomizer.yaml

Esta es una estructura de ejemplo pero algunos elementos son requeridos:

Elementos necesarios para funcionar

Estos elementos son críticos y tu plugin no funcionará de manera confiable a menos que los incluyas en tu plugin.

  • blueprints.yaml - El archivo de configuración usado por Grav para obtener información sobre tu plugin. También puede definir un formulario que el admin puede mostrar al ver los detalles del plugin. Este formulario te permitirá guardar configuraciones para el plugin. Este archivo está documentado en el capítulo de Formularios.
  • randomizer.php - Este archivo se nombrará de acuerdo con tu plugin, pero puede usarse para albergar cualquier lógica que necesite tu plugin. Puedes usar cualquier gancho de evento de un plugin para realizar lógica en prácticamente cualquier punto del ciclo de vida de Grav.
  • randomizer.yaml - Esta es la configuración usada por el plugin para establecer opciones que el plugin podría usar. Debe nombrarse de la misma manera que el archivo .php.

Elementos necesarios para el lanzamiento

Estos elementos son necesarios si deseas lanzar tu plugin a través de GPM.

  • CHANGELOG.md - Un archivo que sigue el Formato de Changelog de Grav para mostrar los cambios en los lanzamientos.
  • LICENSE - Un archivo de licencia, probablemente debería ser MIT a menos que tengas una necesidad específica de otra cosa.
  • README.md - Un 'Readme' que debe contener cualquier documentación para el plugin. Cómo instalarlo, configurarlo y usarlo.

Paso 4 - Configuración del plugin

Como describimos en el Resumen del Plugin, necesitamos tener algunas opciones de configuración para nuestro plugin, así que el archivo randomizer.yaml debería verse algo así:

enabled: true
active: true
route: /random
filters:
    category: blog

Esto nos permite tener múltiples filtros si lo deseamos, pero por ahora, solo queremos que todo el contenido con la taxonomía category: blog sea elegible para la selección aleatoria.

Todos los plugins deben tener la opción enabled. Si esto es false en la configuración global del sitio, tu plugin nunca será inicializado por Grav. Todos los plugins también tienen la opción active. Si esto es false en la configuración global del sitio, cada página deberá activar tu plugin. Ten en cuenta que múltiples plugins también soportan enabled/active en el frontmatter de la página usando mergeConfig, detallado a continuación.

La instalación predeterminada de Grav tiene taxonomía definida para category y tag por defecto. Esta configuración puede ser modificada en tu archivo user/config/site.yaml.

Por supuesto, como con todas las demás configuraciones en Grav, se aconseja no tocar esta configuración predeterminada para el control diario. En lugar de eso, deberías crear una anulación en un archivo llamado /user/config/plugins/randomizer.yaml para alojar cualquier configuración personalizada. Este randomizer.yaml proporcionado por el plugin está realmente destinado a establecer algunos valores predeterminados sensatos para tu plugin.

Paso 5 - Estructura básica del plugin

La estructura de la clase base del plugin ya se verá algo así:

<?php
namespace Grav\Plugin;

use Composer\Autoload\ClassLoader;
use Grav\Common\Plugin;
use RocketTheme\Toolbox\Event\Event;

/**
 * Class RandomizerPlugin
 * @package Grav\Plugin
 */
class RandomizerPlugin extends Plugin
{
    /**
     * Composer autoload.
     *
     * @return ClassLoader
     */
    public function autoload(): ClassLoader
    {
        return require __DIR__ . '/vendor/autoload.php';
    }
}

Necesitamos agregar algunas declaraciones use porque vamos a usar estas clases en nuestro plugin, y ahorra espacio y hace que el código sea más legible si no tenemos que poner el espacio de nombres completo para cada clase en línea.

Modifica las declaraciones use para que se vean así:

use Composer\Autoload\ClassLoader;
use Grav\Common\Plugin;
use Grav\Common\Page\Collection;
use Grav\Common\Uri;
use Grav\Common\Taxonomy;

Las dos partes clave de esta estructura de clase son:

  1. Los plugins deben tener namespace Grav\Plugin en la parte superior del archivo PHP.
  2. Los plugins deben ser nombrados en titlecase basado en el nombre del plugin con la cadena Plugin añadida al final, y deben extender Plugin, por lo tanto el nombre de la clase RandomizerPlugin.

Paso 6 - Eventos suscritos

Grav utiliza un sistema de eventos sofisticado, y para asegurar un rendimiento óptimo, todos los plugins son inspeccionados por Grav para determinar a qué eventos está suscrito el plugin.

public static function getSubscribedEvents(): array
{
    return [
        'onPluginsInitialized' => [
            ['autoload', 100000], // TODO: Eliminar cuando el plugin requiera Grav >=1.7
            ['onPluginsInitialized', 0]
        ]
    ];
}

En este plugin vamos a decirle a Grav que nos suscribimos al evento onPluginsInitialized. De esta manera nuestro plugin puede ser llamado durante la inicialización de todos los plugins, incluso antes de que Grav determine qué página entregar.

Los eventos de plugin están ampliamente documentados en la documentación de eventos de plugin.

En resumen, vamos a filtrar cualquier solicitud a nuestra ruta de activación configurada. Para ello, añadimos el siguiente método:

public function onPluginsInitialized(): void
{
    if (!$this->isAdmin() && $this->config->get('plugins.randomizer.active') && $this->config->get('plugins.randomizer.route') === $this->grav['uri']->path()) {
        $this->enable([
            'onPageInitialized' => ['onPageInitialized', 0]
        ]);
    }
}

Necesitamos comprobar si estamos en el Admin o no, de lo contrario nuestro plugin podría interferir con las páginas del Admin.

Además, añadimos la verificación para ver si nuestro plugin está configurado para active y si la ruta coincide con la ruta configurada. Si estas verificaciones fallan, nuestro plugin no hará nada.

Paso 7 - Obtener la página aleatoria

En el método onPluginsInitialized() le hemos dicho a Grav que se suscriba al evento onPageInitialized(). Vamos a añadir este método para realizar la lógica necesaria para encontrar y usar la página aleatoria.

public function onPageInitialized(): void
{
    /** @var Taxonomy $taxonomy */
    $taxonomy = $this->grav['taxonomy'];
    /** @var Uri $uri */
    $uri = $this->grav['uri'];
    $filters = (array)$this->config->get('plugins.randomizer.filters');
    $collection = new Collection();

    foreach ($filters as $taxonomy => $items) {
        $collection->append($taxonomy->findTaxonomy([$taxonomy => $items]));
    }

    if (count($collection) > 0) {
        $random = $collection->random();
        $uri->redirect($random->url(), 302);
    }
}

La mayor parte de la lógica se encuentra en este método. Aquí obtenemos el taxonomy y uri de Grav, que son necesarias para obtener las taxonomías configuradas y para redirigir a la página aleatoria, respectivamente.

Primero, obtenemos el grupo de páginas relevantes basadas en la configuración de filters.

Luego, generamos una Collection vacía y recorremos cada filtro que hemos configurado.

Cada filtro es buscado en la taxonomía para obtener una Collection de páginas coincidentes.

Luego, si tenemos alguna página en nuestra Collection, usamos el método random() para obtener una página aleatoria de la Collection.

Finalmente, redirigimos al usuario a la página aleatoria.

Conclusión

¡Y ahí lo tienes! Ahora tienes un plugin completamente funcional que puede entregar una página aleatoria a un usuario cuando visita una URL específica. Recuerda siempre mantener la documentación y actualizar los README.md y CHANGELOG.md con cada cambio significativo en tu plugin.