簡體   English   中英

twig 函數和傳遞引用變量

[英]twig functions and pass-by-reference variables

這是情況:

{% for entry in entries %}
{{ action('entry_modify', entry) }}
{{ entry.title }}
{% endfor %}

action($action, $params) 方法是為某個動作注冊自己的插件的某種觸發器。 在這種情況下,我調用 'entry_modify' 操作,並且插件使用作為數組的 'entry' 參數響應此操作。

function plugin(&$params)
{
    $params['title'] = 'changed to ...'; 
}

但據我所知,Twig 不是通過引用傳遞變量,有沒有辦法做到這一點?

我想要的只是修改傳遞給動作函數的變量。

謝謝...

Twig函數總是通過引用傳遞對象。 您可以考慮使用對象而不是數組來表示每個條目。

我可能有一個解決你的問題的方法。 我正在用Twig開發一個Wordpress主題,我想通過引用傳遞變量並向它們添加一些數據。 我的目標是制作這樣的東西

{{ load_data('all_posts',foo) }}

我想執行一個名為load_all_posts的函數,並將此函數的結果賦給foo (我作為第二個參數傳遞的twig變量)。 此外,我希望以下內容也有效:

{% set foo = {'bar':'bar'} %}

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

{{load_data('all_posts',foo.posts)}}

{#foo is#}
array(2) {
  ["bar"]=>
  string(3) "bar"
  ["posts"]=>
  array(3) {
    [0]=>
    string(5) "post1"
    [1]=>
    string(5) "post2"
    [2]=>
    string(5) "post3"
  }
}

由於並非所有變量都通過引用傳遞給函數。 我們不能為此目的使用函數。 相反,我創建了自己的標簽,並像這樣使用它:

{% set foo = {'bar':'bar'} %}
{% load all_pots in foo.posts %}

要做到以下幾點,我們必須做兩件事:

  • 創建“加載”令牌
  • 調用正確的函數並將數據加載到正確的位置

創建令牌解析器:

令牌的創建很容易。 我們只需告訴twig如何使用以下類解析此標記:

class Load_Data_TokenParser  extends Twig_TokenParser
{
    public function parse(Twig_Token $token)
    {
        $stream = $this->parser->getStream();
        $variable_array = array(); //an array where we'll store the destination variable, as it can be just foo or foo.post, or foo.bar.foo.bar.posts

        $function_name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();  //here we say that we expect a name. In our case it'll be 'all_posts' (the name of the function we will execute)
        $in = $stream->expect(Twig_Token::OPERATOR_TYPE)->getValue();   //here we say that the next thing should be the operator 'in'
        while(Twig_Token::typeToEnglish($stream->getCurrent()->getType()) === 'name'){ //and with this while, we get all the variable names that are separated with '.'
            array_push($variable_array,$stream->getCurrent()->getValue());

            $stream->next();
            $new  = $stream->getCurrent();

            if(Twig_Token::typeToEnglish($new->getType()) === 'punctuation'){
                $stream->next();
            } else {
                break;
            }
        }
        //in our case $variable_array here will be ['foo','posts']

        $stream->expect(Twig_Token::BLOCK_END_TYPE);

        return new Load_Node($variable_array, $function_name, $token->getLine(), $this->getTag());
    }

    public function getTag()
    {
        return 'load';
    }
}

最后,我們返回一個新的“Load_Node”並將$variable_array, $function_name傳遞給該行和當前標記。

加載數據

class Load_Node extends Twig_Node
{
    public function __construct($variable_array, $function_name, $line, $tag = null)
    {
        $value = new Twig_Node();
        parent::__construct(array('value'=>$value),array(
            'variable_array'=>$variable_array,
            'function_name'=>$function_name
        ),$line,$tag);
    }

    public function compile(Twig_Compiler $compiler)
    {
        $variable_access_string = '';
        $variable_array = $this->getAttribute('variable_array');
        foreach ($variable_array as $single_variable) {
            $variable_access_string.= '[\''.$single_variable.'\']';
        } //here we prepare the string that will be used to access the correct variables. In our case here $variable_access_string will be "['foo']['posts']"

        $compiler
            ->addDebugInfo($this)
            ->write('$context'.$variable_access_string.' = load_'.$this->getAttribute('function_name').'()')
            ->raw(";\n"); //and the here we call load_{function_name} and assign the result to the correct variable
    }
}

目前它只適用於數組。 如果您嘗試在對象內部加載數據,則會引發異常。 我稍后會編輯它並添加對象的支持。 我希望這會對你和其他人有所幫助。 祝你今天愉快 :)

如果你用一個簡單的類實例替換你的關聯數組,你就好了。

class Entry {
    public $title;
    // other properties possible
    __construct($title) {
        $this->title = $title
    }
}

那么您的$entries將是一個 Entry 實例數組,它將作為對任何函數的引用傳遞,因為它是一個對象,而不是一個數組。 你原來的樹枝代碼片段會很好(完美的語法),並且會修改標題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM