El propósito de este artículo es orientar sobre la posibilidades que tenemos de pasar variables globales al render de symfony (twig). En mi caso, trabajando en desarrolo de web corporativa es habitual tener que pasar variables globales o variables que el usuario edita en el backend. También enfocado a tener un codigo recicable para futuros proyectos.
Entrando ya en el ejemplo, tengo una entidad (Entity) Project.php
tabla project
con el que guardamos variables del proyecto, por ejemplo, las url de las redes sociales, o el e-mail de contacto. Aquí también podemos guardar keys de api's o otras variables de configuración.
La tabla practicamente es una relación key => valor
guardada en base de datos:
// src/Entity/Project.php
class Project
{
token: string, // por ejemplo: social_twitter
name: string, // por ejemplo: "URL Twitter"
value: string, // por ejemplo: "http://twitter.com/albertserra"
}
La finalidad es que después en twig, hacer:
<a href="{{ project.get('social_twitter') }}" target="_blank">Twitter</a>
y que imprima la url de twitter.
Así, que vamos allà.
1. Service
Vamos a crear un servicio de Symfony4 para que connecte a la base de datos, y a traves del método get
le podamos pedir al ORM el valor de la key/token pedido.
// src/Service/ProjectService.php
namespace App\Service;
use Doctrine\ORM\EntityManager;
use App\Entity\Project;
class ProjectService
{
protected $em;
public function __construct( EntityManager $em )
{
$this->em = $em;
}
public function get( $token )
{
$item = $this->em->getRepository(Project::class)->findOneBy(array('token' => $token));
return $item ? $item->getValue() : null;
}
}
Ya hemos creado la clase y el método que devuelve el valor en función del token pasado.
2. Registro del Service
Falta registrar el servicio en la configuración de Symfony config/services.yaml
dentro de la clave de services:
le añadimos nuestro servicio llamado project
y le pasamos como argumento el entity manager
.
# config/services.yaml
services:
[ ... ]
project:
class: App\Service\ProjectService
arguments:
- '@doctrine.orm.entity_manager'
3. Registro a twig
Le tenemos que especificar a twig que le vamos a pasar la clase de manera global, dentro de clave de twig:
# config/packages/twig.yaml
twig:
[ ... ]
globals:
project: '@project'
4. Render
Ya podemos utilizar nuestra clase global en cualquier template de Twig con la sintaxis habitual {{ project.get('key') }}
.
En mi caso, la utilizo habitualmente para los datos del Footer: Redes sociales, Horario, E-mail de contacto, ...
Un ejemplo:
# templates/components/_PageFooter.html.twig
<footer class="PageFooter">
<div class="PageFooter-container">
<p>© {{ project.get('project_name') }} {{ "now"|date('Y') }}</p>
<div class="social-links">
<a href="{{ project.get('social_facebook') }}" class="social-links__item" target="_blank">
<i class="fa fa-fw fa-facebook" aria-hidden="true"></i>
</a>
<a href="{{ project.get('social_twitter') }}" class="social-links__item" target="_blank">
<i class="fa fa-fw fa-twitter" aria-hidden="true"></i>
</a>
<a href="{{ project.get('social_instagram') }}" class="social-links__item" target="_blank">
<i class="fa fa-fw fa-instagram" aria-hidden="true"></i>
</a>
<a href="{{ project.get('social_spotify') }}" class="social-links__item" target="_blank">
<i class="fa fa-fw fa-spotify" aria-hidden="true"></i>
</a>
<a href="{{ project.get('social_youtube') }}" class="social-links__item" target="_blank">
<i class="fa fa-fw fa-youtube" aria-hidden="true"></i>
</a>
</div>
</div>
</footer>
EOF