IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Modifier les en-têtes JS et CSS via un plugin ?


Sujet :

Symfony PHP

  1. #1
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 14
    Par défaut Modifier les en-têtes JS et CSS via un plugin ?
    Bonjour à tous,

    J'ai besoin de modifier la liste des JS et des CSS inclus dans la partie head de mon layout.
    Donc, j'ai tenté de créer un plugin symfony, avec une classe qui étend la classe "sfPluginConfiguration", avec un simple test d'ajout d'un attribut data-test sur chaque javascript :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    class resourcesModifierPluginConfiguration extends sfPluginConfiguration {
    	public function configure() {
    		//$this->dispatcher->connect('view.configure_format', array($this, 'listenToConfigureFormat'));
    		$this->dispatcher->connect('response.filter_content', array(nuFileConcatenatorPluginConfiguration, 'test'));
    	}
     
    	public static function test(sfEvent $event) {
    		$javascripts = sfContext::getInstance()->getResponse()->getJavascripts();
    		// remove all js
    		foreach ($javascripts as $name => $arr) sfContext::getInstance()->getResponse()->removeJavascript($name);
    		// Add Javascripts
    		foreach ($javascripts as $name => $arr) {
    			sfContext::getInstance()->getResponse()->addJavascript($name, 'last', array('data-test' => 'test value'));
    		}
    		return sfContext::getInstance()->getResponse()->getContent();
    	}
    }
    Le code est bien appelé mais la réponse n'est pas modifié, alors que le même code appelé depuis le layout fonctionne très bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                   <?php resourcesModifierPluginConfiguration::test(new sfEvent('test.test', 'test.test')); ?>
                   <?php include_stylesheets() ?>
                   <?php include_javascripts() ?>
    Ma question : Est-ce possible de modifier les JS et CSS avant le rendu de la page, sans faire de modification intrusive (comme par exemple modifier le layout)

    Merci beaucoup pour votre aide !!

    Julian

  2. #2
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    C'est pour faire quoi exactement ?
    Car symfony te permet déjà de les modifier comme on le souhaite en fonction des modules et des actions.

  3. #3
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 14
    Par défaut
    Bonjour kenny.kev !

    Le premier code, avec la connexion de l'évenement, fait bien la modification attendue dans le tableau des javascripts, mais le souci c'est qu'il ne le rend pas dans le HTML (je ne vois pas pourquoi car l'événement est bien appelé avant le rendu du HTML à priori).
    Et c'est seulement en appelant ma méthode test() depuis la page layout que ça fonctionne, sauf que c'est intrusif et l'idée du plugin est justement de ne pas l'être.

    En fait je veux pouvoir manipuler mes JS et CSS depuis le plugin (modifier l'ordre, en ajouter, en supprimer, ajouter des attributs) dans le but de faire un plugin d'optimisation réutilisable, d'où le coté non intrusif.

    N'hésitez pas si je ne suis pas clair

    Julian

  4. #4
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    Pour info il y a déjà des plugin's qui font ça et qui en plus peuvent aussi te compresser les JS et CSS.

    J'ai pas encore vraiment compris ce que tu souhaites vraiment optimiser ?
    C'est faire de la compression ?

  5. #5
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 14
    Par défaut
    Oui j'ai regardé ces plugins mais ça ne colle pas à ce dont j'ai besoin. C'est un module de concaténation de JS / CSS mais avec un niveau de paramétrage spécifique, et en plus dans les cas que j'ai vu, ils passent souvent par une modification du layout principal.

    Après ce que je ne comprend pas c'est pourquoi les modifications apportées à mon tableau de JS et de CSS ne sont pas répliquées dans le HTML rendu. Si ça n'est pas possible j'aimerais simplement comprendre pourquoi car je ne vois pas de raisons pour qu'il y ait une telle limite.

  6. #6
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    C'est le yml qui spécifie l'ordre donc si tu souhaites que ça fonctionne il faut que tu te place au niveau d'un filtre juste avant l'envoie de données au client.

  7. #7
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 14
    Par défaut
    Merci pour cette info

    Par contre lorsque je configure mes filtres, je n'ai pas accès aux éléments du tableau de JS et CSS (il sont vides).
    J'ai tenté d'overrider le RenderingFilter et le ExecutionFilter mais aucun n'a les infos sur les ressources.

    Julian

  8. #8
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    C'est que tu ne l'utilise pas dans le bon sens.
    La si je comprends bien c'est avant l'appel de l'action.

  9. #9
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 14
    Par défaut
    J'ai essayé avant et après.
    Là en fait j'ai surchargé mon filters.yml avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    rendering: ~
    security:  ~
    cache:     ~
    execution:
      class: myFilter
    j'ai déclaré ma classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class myFilter extends sfExecutionFilter {
    	public function executeAction($actionInstance) {
            $r = parent::executeAction($actionInstance);
     
            $js = sfContext::getInstance()->getResponse()->getJavascripts();
            var_dump($js);
     
            return $r;
        }
    }
    la variable $js est toujours vide (même en mettant l'exécution du parent à la fin)
    J'ai également essayé en surchargeant la méthode execute du sfRenderingFilter, mais j'ai toujours un tableau vide.

    Encore merci pour ton aide

  10. #10
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    Alors je ne sais pas si c'est une bonne pratique mais je ne fais pas comme ça pour les filtres.

    je ne surcharge que la méthode execute() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public function execute($filterChain) {
        // Exécution avant controleur
        ...
        // execute next filter
        $filterChain->execute();
     
        // Exécution après controleur
        ...
    }

  11. #11
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 14
    Par défaut
    Merci ! J'ai repris ton code et ça fonctionne (Attention il faut ajouter un appel au parent si on surcharge un filtre existant quand même sinon il ne fait pas son boulot par défaut )

    Par contre, j'ai le même souci qu'avec l'event dispatcher, a savoir que mon tableau de JS ou CSS est bien modifié mais je n'ai aucun changement dans le HTML rendu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    class myFilter extends sfRenderingFilter {
    	public function execute($filterChain) {
    		$filterChain->execute();
     
    		$javascripts = sfContext::getInstance()->getResponse()->getJavascripts();
    		// remove all js
    		foreach ($javascripts as $name => $arr) sfContext::getInstance()->getResponse()->removeJavascript($name);
    		// Add Javascripts
    		foreach ($javascripts as $name => $arr) {
    			sfContext::getInstance()->getResponse()->addJavascript($name, 'last', array('data-test' => 'test value'));
    		}
    		// Display
    		$javascripts2 = sfContext::getInstance()->getResponse()->getJavascripts();
    		var_dump($javascripts2);
     
    		parent::execute($filterChain);
        }
    }
    Ici la variable $javascript2 contient bien mes nouveaux paramètres mais ne sont pas rendues au niveau des balises <script>


    Alors que si je colle le même morceau de code tout en haut du layout.php principal ça fonctionne très bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    <?php
    $javascripts = sfContext::getInstance()->getResponse()->getJavascripts();
    // remove all js
    foreach ($javascripts as $name => $arr) sfContext::getInstance()->getResponse()->removeJavascript($name);
    // Add Javascripts
    foreach ($javascripts as $name => $arr) {
    	sfContext::getInstance()->getResponse()->addJavascript($name, 'last', array('data-test' => 'test value'));
    }
    ?><!DOCTYPE html>
    <html lang="fr-FR">
        <head>
    		<?php include_http_metas() ?>
    		<?php include_metas() ?>
    		<?php include_stylesheets() ?>
    		<?php include_title() ?>
    		<?php include_javascripts() ?>
        </head>


    Merci !

    Julian

  12. #12
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    La je ne suis pas sur que le rendering soit le filtre approprié pour faire ça.
    Le filtre sfExecutionFilter me parait le mieux.

  13. #13
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 14
    Par défaut
    J'ai testé ça du coup :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    class myFilter extends sfExecutionFilter {
    	public function execute($filterChain) {
    		$filterChain->execute();
    		parent::execute($filterChain);
     
    		$javascripts = sfContext::getInstance()->getResponse()->getJavascripts();
    		// remove all js
    		foreach ($javascripts as $name => $arr) sfContext::getInstance()->getResponse()->removeJavascript($name);
    		// Add Javascripts
    		foreach ($javascripts as $name => $arr) {
    			sfContext::getInstance()->getResponse()->addJavascript($name, 'last', array('data-test' => 'test value'));
    		}
    		// Display
    		$javascripts2 = sfContext::getInstance()->getResponse()->getJavascripts();
    		var_dump($javascripts2);
        }
    }
    mais ça ne change rien
    Je ne suis pas sur que le problème soit lié aux filtres ou aux évenements maintenant du coup. Je pense que le souci est ailleurs car le code s’exécute bien entièrement mais le résultat n'est pas celui attendu

    Merci !

    Julian

  14. #14
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646

  15. #15
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 14
    Par défaut
    oui le plugin swCombinePlugin est pas mal mais il correpond pas tellement a mon besoin. J'ai besoin de quelque chose de packagé, qui puisse s'installer et fonctionner très rapidement.
    Là ce n'est pas tout a fait le cas. Et puis je n'ai pas besoin de toutes les fonctions qu'il apporte donc j'ai préféré repartir sur quelque chose de plus simple et qui colle a ce dont j'ai besoin.

    Après s'il n'y a pas d'autre possibilité, j'ajouterai un appel de méthode dans layout principal pour régler le problème mais c'est dommage...
    Et rien que pour ma culture personnelle j'aimerais bien savoir le pourquoi


    Merci pour l'article c'est très intéressant ça compile toutes les bonnes pratiques d'optimisation en effet

  16. #16
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    Je suis désolé mais la j'ai un manque de connaissance.

    Pour permet de trouver la réponse il faudrait que tu mettes xHprof en place pour connaître l'ordre des appels, car la partie template à l'air d'être exécuté avant le filtre.

    Sinon essaie de voir avec les event's pour déclencher une action avant la construction du layout.

  17. #17
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 14
    Par défaut
    J'ai investigué un peu pour essayer de comprendre.

    En fait le dernier évènement avant le rendering est 'view.configure_format', mais à ce moment là, les JS et CSS ne sont pas chargés dans la réponse.

    En mode dev (on voit tous les event 'application.log') j'ai pu identifié à quel moment le rendering du layout était fait. Ca se passe juste après le 'view.configure_format' (les tableau sont probablement chargé au moment du configure_format mais l'event est déclenché un poil trop tôt pour mon cas (pas de bol ! )

    J'ai donc essayé de déclencher mon event a partir du filtre sfRenderingFilter mais il arrive trop tard !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    class myFilter extends sfRenderingFilter {
    	public function execute($filterChain) {
    		// CAS 1
    		sfContext::getInstance()->getEventDispatcher()->notify(new sfEvent($this, 'view.layout_rendering', null)); 
     
    		$filterChain->execute();
     
    		// CAS 2
    		sfContext::getInstance()->getEventDispatcher()->notify(new sfEvent($this, 'view.layout_rendering', null));
     
    		parent::execute($filterChain);
     
    		// CAS 3
    		sfContext::getInstance()->getEventDispatcher()->notify(new sfEvent($this, 'view.layout_rendering', null));
        }
    }
    Cas 1 : Trop tôt
    Cas 2 : Un poil trop tard
    Cas 3 : Après le rendu donc bien trop tard


    Julian

  18. #18
    Membre émérite Avatar de kenny.kev
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    646
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 646
    Par défaut
    j'avais trouvé ça hier, je pense que ça pourrais t'être utile :
    http://www.finalconcept.com.au/artic...al-environment

  19. #19
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 14
    Par défaut
    Super merci ! ça ne répond pas à mon cas mais ce sont de bons exemples pour utiliser les filtres !

Discussions similaires

  1. Réponses: 1
    Dernier message: 17/04/2015, 21h04
  2. Réponses: 7
    Dernier message: 18/08/2010, 03h36
  3. Tutoriel pour modifier les en-têtes de chapitres ?
    Par Paenitentia dans le forum Mise en forme
    Réponses: 2
    Dernier message: 04/01/2007, 17h55
  4. [.NET CF] Modifier les en-têtes d'une DataGrid
    Par Marc_P dans le forum Windows Mobile
    Réponses: 2
    Dernier message: 24/10/2006, 15h02
  5. [JXTable] Modifier les en-têtes
    Par yakanet dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 22/05/2006, 23h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo