2015-09-11 22 views
5

Czy można zmienić obecny kontekst gałązki, wywołując funkcję Twig_SimpleFunction?Czy funkcja Twig_SimpleFunction może modyfikować kontekst?

Mam funkcja poniżej zarejestrowany:

<?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'])); 
    } 
} 

Wywołany z szablonu jak tak {{ setContextVar('hellow', 'world') }}, var_dump pokazuje zmodyfikowany kontekst. Ale szybkie sprawdzenie w szablonie takim jak {{ dump(_context|keys) }} nie pokazuje zmodyfikowanego kontekstu.

Czy podążam tą drogą w niewłaściwy sposób?

+0

czy poprawnie zdefiniowałeś funkcję z parametrami 'need_context' zgodnie z opisem [tutaj] (http://twig.sensiolabs.org/doc/advanced.html#context-aware-filters)? – Matteo

+0

Tak, tak sądzę. Oto pastebin - http://pastebin.com/D8ZnKKWm – Fyrebase

Odpowiedz

4

Nie jest to możliwe w przypadku funkcji, ponieważ kontekst nie jest przekazywany przez odniesienie.

w rozszerzeniu, jesteś nawet dostępu $context['context'], co oznaczałoby zmienną o nazwie context, nie sam kontekst (_context to specjalna nazwa zmiennej umożliwia dostęp do kontekstu, w szablonie, ale nie pojawia się w kontekście tablica wysłana do funkcji, ponieważ jest to sama tablica).

Możliwe, że można to zrobić za pomocą niestandardowej kompilacji funkcji, zmieniając klasę węzłów. ale nie próbowałem go i może trochę trudniej utrzymać semantyczne wyrażenie.
W każdym razie polecam, aby nie pisać takiej funkcji. Przypisanie zmiennej w gałązce nie ma funkcji semantycznej i nie może być wykonane jako część wyrażenia (funkcje są użyteczne w wyrażeniach oczywiście). Zmiana tego semantycznego może prowadzić do dziwnych zachowań.

+0

Dzięki @chris. Porzuciłem to podejście, ponieważ doszedłem do wniosku, że było to niewłaściwe podejście. – Fyrebase

+0

Możesz przekazać kontekst przez odniesienie, zmieniając definicję funkcji na 'function setContextVar (& $ context, ...) "więc teraz można zmienić kontekst gałązki. Zobacz [tutaj] (http://stackoverflow.com/questions/43978499/set-value-of-single-object-in-multidimensional-array-in-twig-template?noredirect=1#comment74986325_43978499) – DarkBee

1

Jak @DarkBee wspomniano w swoim komentarzu, można modyfikować kontekst poprzez przepuszczenie go przez odniesienie:

function setContextVar(&$context, ...) 

Jednakże, dodając tylko funkcję do Gałązka nie wydają się działać (używam Twig 2.4.4):

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

Podczas korzystania z funkcji w pliku gałązka, kontekst nie uzyskać modyfikowane, a otrzymasz to ostrzeżenie:

Ostrzeżenie: Oczekiwano, że parametr 1 do {zamknięcie}() będzie referencją, wartość podana w C: \ ... \ sprzedawca \ twig \ twig \ lib \ Twig \ Environment.php (378): eval() ' d code on line ...

Zamiast tego trzeba stworzyć rozszerzenie Gałązka:

$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; 
    } 
}); 

Wtedy można go używać w Gałązka bez uzyskiwania ostrzeżenie:

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

powyżej wydruków, np .:

array(0) { 
} 

array(1) { 
    ["foo"]=> 
    string(3) "bar" 
} 
Powiązane problemy