Comme suggéré par Steffen, vous devriez mettre le CSS dynamique dans un modèle Twig. Mais maintenant vous pourriez souffrir de cette partie de la css étant une requête complète à une application symfony au lieu d'un css (HTTP 302 et autres) qui augmente la charge du serveur.
C'est pourquoi je vous conseille de faire 3 choses (vous pouvez sauter l'étape 2 si votre css ne change pas sans interaction, par exemple la date en fonction):
- Mettre en oeuvre un service qui met en cache la sortie courant par exemple web/additional.css.
- Ecrire et enregistrer un RequestListener mettre à jour le css régulièrement
- Adresser toutes les actions du contrôleur qui pourrait apporter des modifications au css avec l'appel de service
Exemple (principe que vous utilisez Doctrine et ont une entité avec une certaine couleur information):
service
<?php
//Acme\DemoBundle\Service\CSSDeployer.php
namespace Acme\DemoBundle\Service;
use Doctrine\ORM\EntityManager;
class CSSDeployer
{
/**
* @var EntityManager
*/
protected $em;
/**
* Twig Templating Service
*/
protected $templating;
public function __construct(EntityManager $em, $templating)
{
$this->em = $em;
$this->templating = $templating;
}
public function deployStyle($filepath)
{
$entity = $this->em->getRepository('AcmeDemoBundle:Color')->findBy(/* your own logic here */);
if(!$entity) {
// your error handling
}
if(!file_exists($filepath)) {
// your error handling, be aware of the case where this service is run the first time though
}
$content = $this->templating->render('AcmeDemoBundle:CSS:additional.css.twig', array(
'data' => $entity
));
//Maybe you need to wrap below in a try-catch block
file_put_contents($filepath, $content);
}
}
Enregistrement service
#Acme\DemoBundle\Resources\config\services.yml
services:
#...
css_deployer:
class: Acme\DemoBundle\Service\CSSDeployer
arguments: [ @doctrine.orm.entity_manager, @templating ]
RequestListener
<?php
//Acme\DemoBundle\EventListener\RequestListener.php
namespace Acme\DemoBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Debug\Exception\ContextErrorException;
use \DateTime;
use Doctrine\ORM\EntityManager;
class RequestListener
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* @var EntityManager
*/
protected $em;
public function __construct(ContainerInterface $container, $em)
{
$this->container = $container;
$this->em = $em;
}
/**
* Checks filemtime (File modification time) of web/additional.css
* If it is not from today it will be redeployed.
*/
public function onKernelRequest(GetResponseEvent $event)
{
$kernel = $event->getKernel();
$container = $this->container;
$path = $container->get('kernel')->getRootDir().'/../web'.'/additional.css';
$time = 1300000000;
try {
$time = @filemtime($path);
} catch(ContextErrorException $ex) {
//Ignore
} catch(\Exception $ex) {
//will never get here
if(in_array($container->getParameter("kernel.environment"), array("dev","test"))) {
throw $ex;
}
}
if($time === FALSE || $time == 1300000000) {
file_put_contents($path, "/*Leer*/");
$time = 1300000000;
}
$modified = new \DateTime();
$modified->setTimestamp($time);
$today = new \DateTime();
if($modified->format("Y-m-d")!= $today->format("Y-m-d")) {
//UPDATE CSS
try {
$container->get('css_deployer')->deployStyle($path);
} catch(\Exception $ex) {
if(in_array($container->getParameter("kernel.environment"), array("dev","test"))){
throw $ex;
}
}
} else {
//DO NOTHING
}
}
}
enregistrement RequestListener
#Acme\DemoBundle\Resources\config\services.yml
acme_style_update_listener.request:
class: Acme\DemoBundle\EventListener\RequestListener
arguments: [ @service_container, @doctrine.orm.entity_manager ]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
actions contrôleur
public function updateAction()
{
// Stuff
$path = '....';
$this->get('css_deployer')->deployStyle($path);
}
Espérons que cela aidera quelqu'un dans le futur.