2015-09-11 6 views
5

Geçerli twig içeriğini Twig_SimpleFunction olarak adlandırmak mümkün mü? Bir Twig_SimpleFunction, bağlamı değiştirebilir mi?

aşağıda fonksiyon kayıtlı sahiptir:

yüzden {{ setContextVar('hellow', 'world') }} gibi bir şablondan denilen
<?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'])); 
    } 
} 

, var_dump modifiye bağlamında gösteriyor. Ancak, şablonda {{ dump(_context|keys) }} gibi hızlı bir kontrol, değiştirilen içeriği göstermez.

Bunu yanlış yoldan mı yapıyorum?

+0

işlevi, işlevi [here] (http://twig.sensiolabs.org/doc/advanced.html#context-aware-filters) açıklandığı gibi, 'need_context' parametrelerini kullanarak doğru bir şekilde tanımladınız mı? – Matteo

+0

Evet, inanıyorum. İşte bir macun - http://pastebin.com/D8ZnKKWm – Fyrebase

cevap

4

Bu durum, bağlam referans olarak iletilmediği için işlevlerle mümkün değildir. Uzantınızda olarak

, hatta context adında bir değişken anlamına gelecektir $context['context'], erişen değil bağlam kendisi ( _context şablonda bağlamı erişmek için kullanılan özel bir değişken adıdır, ancak bağlamda görünmüyor dizi, dizinin kendisi olduğu gibi işlev göstermek için gönderilir.

Düğüm sınıfını değiştirerek, bu işlevin özel bir derlemesiyle bunu gerçekleştirmenin bir yolu olabilir. ama denemedim ve ifade anlamını korumak için biraz zor olabilir.
Ve yine de, böyle bir işlevi yazmayı öneriyorum. Twig'de bir değişken atamak, anlamsal bir işleve sahip değildir ve bir ifadenin parçası olarak yapılamaz (işlevler elbette ifadelerde kullanılabilir). Bu anlamların değiştirilmesi garip davranışlara yol açabilir. Ben Twig kullanıyorum (çalışmak için görünmüyor Twig için sadece bir fonksiyonu ekleyerek, Ancak

function setContextVar(&$context, ...) 

:

+0

Teşekkürler @chris. Bu yaklaşımı bıraktım, sonuca vardığımda yanlış bir yaklaşım oldu. – Fyrebase

+0

İşlev tanımını 'function setContextVar (& $ context, ... işlevine dönüştürerek referans olarak iletebilirsiniz ...) 'şimdi twig bağlamını değiştirmek mümkün. Bkz. [Burada] (http://stackoverflow.com/questions/43978499/set-value-of-single-object-in-multidimensional-array-in-twig-template?noredirect=1#comment74986325_43978499) – DarkBee

1

gibi @DarkBee başvuruyla geçirerek tarafından bağlamı değiştirebilir, onun yorumunda belirtildiği 2.4.4): bir Twig dosyasında işlevini kullandığınızda

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

, bağlam modifiye almaz ve bu uyarıyı almak:

Uyarı: Parametre 1'den {closure}() bir başvuru olması bekleniyor, değer verilen C: \ ... \ vendor \ twig \ twig \ lib \ Twig \ Environment.php (378): eval() '

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

Sonra bir uyarı almadan Twig onu kullanabilirsiniz: on line d kodu ... yerine

, bir Twig uzantısı oluşturmak gerekir

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

yukarıdaki baskılar örn .:

array(0) { 
} 

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