2015-09-11 14 views
5

Kann der aktuelle Zweigkontext durch Aufruf einer Twig_SimpleFunction geändert werden?Kann Twig_SimpleFunction den Kontext ändern?

Ich habe die unten Funktion registriert:

<?php 
namespace Craft; 

class TwiggedTwigExtension extends \Twig_Extension 
{ 
    public function getName() 
    { 
     return 'Twigged'; 
    } 

    public function getFunctions() 
    { 
     return array(
      'setContextVar' => new \Twig_SimpleFunction('setContextVar', array($this, 'setContextVar'), array('needs_context' => true)), 
     ); 
    } 

    public function setContextVar($context, $str, $val) 
    { 
     $context['context'][$str] = $val; 

     var_dump(array_keys($context['context'])); 
    } 
} 

Wenn aus einer Vorlage wie so {{ setContextVar('hellow', 'world') }} genannt, zeigt die var_dump den geänderten Kontext. Aber ein schneller Check in der Vorlage wie {{ dump(_context|keys) }} zeigt den geänderten Kontext nicht.

Gehe ich in die falsche Richtung?

+0

Haben Sie die Funktion korrekt mit den 'need_context' Parametern definiert, wie hier beschrieben (http://twig.sensiolabs.org/doc/advanced.html#context-aware-filters)? – Matteo

+0

Ja, ich glaube schon. Hier ist ein Pastebin - http://pastebin.com/D8ZnKKWm – Fyrebase

Antwort

4

Dies ist mit Funktionen nicht möglich, da der Kontext nicht durch Referenz übergeben wird.

In Ihrer Erweiterung, die Sie zugreifen, sogar $context['context'], die eine variable context genannt bedeuten würde, nicht der Kontext selbst (_context ist ein spezieller Variablennamen für den Zugriff auf den Kontext, in der Vorlage verwendet, aber es im Kontext erscheint nicht Array gesendet, um so zu funktionieren, wie es das Array selbst ist).

Möglicherweise gibt es eine Möglichkeit, dies mit einer benutzerdefinierten Kompilierung der Funktion durch Ändern der Knotenklasse durchzuführen. aber ich habe es nicht ausprobiert und es könnte ein bisschen schwierig sein, die Ausdruckssemantik beizubehalten.
Und trotzdem würde ich empfehlen, solche Funktionen zu schreiben. Das Zuweisen einer Variablen in Twig hat keine Funktionssemantik und kann nicht als Teil eines Ausdrucks ausgeführt werden (Funktionen sind natürlich in Ausdrücken verwendbar). Das Ändern dieser Semantik kann zu seltsamen Verhaltensweisen führen.

+0

Danke @chris. Ich gab diesen Ansatz auf, da ich zu dem Schluss kam, dass dies der falsche Ansatz war. – Fyrebase

+0

Sie können den Kontext als Referenz übergeben, indem Sie die Funktionsdefinition in 'function setContextVar (& $ context, ...) so jetzt ist es möglich, den Kontext von Zweig zu ändern. Siehe [hier] (http://stackoverflow.com/questions/43978499/set-value-of-single-object-in-multidimensional-array-in-twig-template?noredirect=1#comment74986325_43978499) – DarkBee

1

Wie @DarkBee in seinem Kommentar erwähnt, können Sie den Kontext durch Verweis ändern kann, indem man:

function setContextVar(&$context, ...) 

jedoch nur das Hinzufügen einer Funktion zu Zweig scheint nicht zu funktionieren (ich bin mit Zweig 2.4.4):

$twig->addFunction(new Twig_Function('setContextVar', function(&$context, $name, $value) { 
    $context[$name] = $value; 
}, ['needs_context' => true])); 

Wenn Sie die Funktion in einem Zweig-Datei verwenden, wird der Kontext nicht geändert, und Sie erhalten diese Warnung:

Warnung: Parameter 1 für {closure}() wird als Referenz erwartet, Wert in C: \ ... \ vendor \ twig \ twig \ lib \ Twig \ Environment.php (378): eval() ' d code on line ...

Stattdessen müssen Sie einen Zweig Erweiterung erstellen:

$twig->addExtension(new class extends Twig_Extension { 
    public function getFunctions() { 
     return [ 
      new Twig_Function('setContextVar', [$this, 'setContextVar'], ['needs_context' => true]), 
     ]; 
    } 

    public function setContextVar(&$context, $name, $value) { 
     $context[$name] = $value; 
    } 
}); 

Dann können Sie es in Zweig verwenden, ohne eine Warnung zu erhalten:

{{ dump() }} 
{% do setContextVar('foo', 'bar') %} 
{{ dump() }} 

Die überdrucken zB:

array(0) { 
} 

array(1) { 
    ["foo"]=> 
    string(3) "bar" 
} 
Verwandte Themen