Symfony: Crear una extensión de Twig llamando a un método de un servicio

Explicación del problema

La semana pasado tuve un problema con la aplicación web que estoy manteniendo y yo no hice. Han pasado varios programadores hasta que yo he llegado a esta empresa.

Os pongo en contexto para que veáis el motivo de crear una extensión de Twig.

El otro día la API que utilizamos para realizar unas tareas en la aplicación no funcionaba pero ese aunque es un problema que puede pasar, el verdadero problema fue otro. La gran sorpresa fue que al intentar entrar en la aplicación web, no me dejaba entrar y bloqueaba el sistema por culpa de que una API de terceros hubiera caído.

¿QUÉ??? Eso mismo pensé yo. No me lo podía creer.

Empecé a buscar el problema y por suerte lo encontré después de varias horas. Si!!! varias horas, el código, como he dicho antes, no lo he hecho yo. Además, no está muy bien organizado y en Symfony soy un poco novato. Así que todo influye.

El «Listo» que lo había programado (aunque se le podría llamar otra cosa) había puesto que si fallaba la llamada se salia de la aplicación utilizando el método die() [PHP].

Por lo que empecé a arreglarlo, pero al poco pensé: «Si no hay conexión y entra en la aplicación, tendré que visualizarlo de alguna forma». Así que me propuse crear un icono en el menú superior, donde tengo otros iconos, que si no había conexión me saliera un icono y si hubiera conexión cambiaba el icono.

Contento por la solución encontrada, me puse a trabajar y cuando ya tenia una parte hecha, me encontré con otro problema. Tenía que cambiar casi todas las páginas hechas en Twig.

¿Porqué? os preguntareis.

Pues el asunto es que la página/template Twig donde está el navbar que iba a modificar, se asociaba a otra página/template Twig. Está última actuaba como template de las página de contenido.

Al estar todo asociado, tenia que crear bloques en cada página para que pudiera ir pasando de hijos a padres teniendo que cambiarlo en todas la páginas de contenido ya que sino, el icono solo aparecería en la página donde hubiera puesto la modificación del bloque.

Volví a pensar: «Esto se puede tener que hacer de otra forma. ¿Es necesario modificar todas la páginas para esto? Debe de haber alguna forma de crear alguna variable o función global que se pueda llamar desde Twig y no tener que cambiar todas las plantillas de contenido que tengo». Me puse a investigar y no encontraba gran cosa. Si encontré la opción de variables globales, pero solo me servia para la página en cuestión, así que no me servia.

Al final, pregunté a los cracks de la comunidad WebReactiva a la que estoy apuntado y me dijeron que podría hacer una extensión de Twig.

Me puse a investigar que era y encontré que las extensiones de Twis es una forma de crear comandos personalizados y que se pueden utilizar en cualquier página de Twig sin necesidad de ir heredando de padres a hijos o viceversa.

Así que me puse a ello y como yo ya había creado una función en un servicio que me indicaba si había problema de conexión o no, os quiero describir como se realiza paso a paso la creación de la extensión de Twig y la llamada a la función al servicio que ya tenía creado.

Descripción de la solución

Paso 1: Crea el Servicio Symfony

Primero, asegúrate de tener un servicio en tu aplicación Symfony.

// src/Service/MiServicio.php

namespace App\Service;

class MiServicio
{
    public function obtenerSaludo()
    {
        return 'Hola desde MiServicio';
    }
}

Paso 2: Crea la Extensión Twig

Ahora, crea la extensión Twig que utilizará el servicio:

// src/Twig/Extension/MiExtension.php

namespace App\Twig\Extension;

use App\Service\MiServicio;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class MiExtension extends AbstractExtension
{
    private $miServicio;

    public function __construct(MiServicio $miServicio)
    {
        $this->miServicio = $miServicio;
    }

    public function getFunctions()
    {
        return [
            new TwigFunction('saludar', [$this, 'saludar']),
        ];
    }

    public function saludar()
    {
        return $this->miServicio->obtenerSaludo();
    }
}

Paso 3: Registra la Extensión y el Servicio en Symfony

Registra la extensión Twig y el servicio en el archivo services.yaml:

# config/services.yaml

services:
    App\Service\MiServicio:
        # Configura tu servicio según tus necesidades

    App\Twig\Extension\MiExtension:
        arguments:
            $miServicio: '@App\Service\MiServicio'
        tags:
            - { name: 'twig.extension' }

Paso 4: Usa la Función en una Plantilla Twig

Ahora puedes utilizar la función saludar en tus plantillas Twig:

{# Ejemplo en una plantilla Twig #}
{{ saludar() }}

Esta plantilla llamará al método obtenerSaludo() de MiServicio a través de la extensión Twig MiExtension.

Asegúrate de ajustar los nombres de espacio y las rutas de los archivos según la estructura de tu proyecto Symfony. Este ejemplo proporciona una base simple que puedes adaptar según tus necesidades específicas.


Espero que os pueda servir.

Saludos.

Deja un comentario