2015-03-10 6 views
9

ich die Datei /vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.phpWas ist die „richtige“ Weg, um eine symfony Erweiterung von einem anderen Bündel

Es lädt außer Kraft setzen müssen außer Kraft setzen der Zweig getAssetUrl aus dem Bündel der Zweig Funktion ‚Vermögenswert‘

/** 
* Returns a list of functions to add to the existing list. 
* 
* @return array An array of functions 
*/ 
public function getFunctions() 
{ 
    return array(
     new \Twig_SimpleFunction('asset', array($this, 'getAssetUrl')), 
     new \Twig_SimpleFunction('assets_version', array($this, 'getAssetsVersion')), 
    ); 
} 

I außer Kraft setzen wollen, den Vermögenswert() Zweig Funktion ohne sie zu berühren die Core-Dateien verwenden, die sonst durch die nächste symfony Update überschrieben würden

Antwort

6

Bedenke das dein Code im AppBundle-Namespace. Erstellen Sie zuerst die Dienstkonfiguration in app/config.yml oder src/AppBundle/Resources/config/something.yml (Sie müssen diese Konfigurationsdatei unter bundle extension laden). Vergessen Sie nicht, es unter den Service-Schlüssel zu legen.

twig.extension.assets: 
    class:  AppBundle\Twig\AssetsExtension 
    arguments: ["@service_container", "@?router.request_context"] 
    public: false 
    tags: 
     - { name: twig.extension } 

Lassen Sie uns jetzt Erweiterung src/AppBundle/Zweig/AssetsExtension.php erstellen. Diese Klasse erbt von der ursprünglichen Erweiterung und ich überschreibe nur eine Methode (in der Vorlage asset()).

Jetzt, nach dem Neuladen, sollten alle Ihre Assets inkorrekt sein und mit/something/voreingestellt sein. Sie können versuchen, den Symfony-Cache bei Problemen zu löschen. Ich habe dieses Szenario auf Symfony 2.5.5 getestet.

Eine andere Möglichkeit, mit integrierten Diensten zu arbeiten, ist compiler pass. Beim Compiler-Durchlauf können Sie den gesamten Symfony-Service-Container ändern (Dienste löschen, ersetzen, ändern). Bei Symfony dreht sich alles um DIC. Ich hoffe es ist eine gute Lösung.

+1

Statt die Service-Definition duplizieren Sie auch den Parameter twig.extension.assets.class einfach einstellen können, dass die neue Erweiterungsklasse zu zeigen. Aber der Compiler-Durchlauf ist wirklich die beste Lösung. Tatsächlich stelle ich die Notwendigkeit einer Änderung von getAssertUrl überhaupt in Frage. Wahrscheinlich wird es mehr Probleme verursachen als es wert ist, besonders wenn Sie Vorlagen von Drittanbietern verwenden. Denken Sie nur daran, Ihre eigene Erweiterung und Funktion zu schreiben. – Cerad

+0

Ja, das stimmt. Sie können auch den Parameter twig.extension.assets.class mit einer benutzerdefinierten Erweiterung festlegen. Die Frage war klar - wie man Asset() überschreibt, ohne den Symfony-Code zu berühren. Ich habe wirklich keine Ahnung von Use-Case, warum user3531149 es braucht. – kba

+0

Ihre Lösung ist in Ordnung. Hoffentlich ist das keine weitere Fahrt vorbei. – Cerad

6

Ich biete eine andere Lösung, da seit Symfony 3.0 die Klassennamen der Dienste nicht mehr überschrieben werden können. Sie müssen die Compiler-Pass-Lösung auswählen.

Angenommen, Sie url außer Kraft setzen wollen() Funktion in Zweig, sollten Sie einen Compiler-Pass für das Erstellen und die Definition ändern:

<?php 
// AppBundle/AppBundle.php 

namespace AppBundle; 

use AppBundle\DependencyInjection\Compiler\TwigRoutingExtensionPass; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 
use Symfony\Component\HttpKernel\Bundle\Bundle; 

class AppBundle extends Bundle 
{ 
    public function build(ContainerBuilder $container) 
    { 
     parent::build($container); 

     $container->addCompilerPass(new TwigRoutingExtensionPass()); 
    } 
} 

Erstellen Sie dann die TwigRoutingExtensionPass Datei:

<?php 
// AppBundle/DependencyInjectoin/Compiler/TwigRoutingExtensionPass.php  

namespace AppBundle\DependencyInjection\Compiler; 

use AppBundle\Twig\Extension\RoutingExtension; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 

class TwigRoutingExtensionPass implements CompilerPassInterface 
{ 
    public function process(ContainerBuilder $container) 
    { 
     if (false === $container->hasDefinition('twig.extension.routing')) { 
      return; 
     } 

     $definition = $container->getDefinition('twig.extension.routing'); 
     $definition->setClass(RoutingExtension::class); 
    } 
} 

Und dann erstellen Sie Ihre RoutingExtension-Datei.

Wenn Sie einige Dienste für die neue Erweiterung injizieren wollen:

<?php 

    $definition->addArgument('some_service'); 
    // OR 
    $definition->addMethodCall('setSomeService' [$container->get('some_service')]); 
+1

Ich habe Ihre Lösung versucht, aber ich erhalte einen Fehler 'Die Erweiterung" Symfony \ Bridge \ Twig \ Extension \ TranslationExtension "ist nicht aktiviert in meinem Fall Ich versuche die trans() Funktion zu überschreiben. irgendwelche Ideen ? –

+1

Entschuldigung, aber haben Sie den Übersetzer aktiviert? http://symfony.com/doc/current/translation.html # Konfiguration – nikophil

Verwandte Themen