在 Fat Free Framework 中,是否可以在模板中显示缺少的键?

in Fat Free Framework, is it possible to display a missing key in a Template?

使用 Fat Free Framework 模板引擎和使用字典文件进行翻译。

在我的模板中,我有 {{@_someNonTranslatedWord}} 键。

目前,如果缺少此键,FF 只会让 space 空着。 有没有办法让 FF 显示原始密钥而不是将 space 留空?

我更愿意看到类似的内容:

"My {{@_someNonTranslatedWord}} is missing"

而不是

"My is missing"

所以我可以轻松识别丢失的键并添加它们。甚至可能在它们丢失时自动翻译它们。

我认为不可能 return 原始占位符,因为 F3 正在将模板转换为 PHP 代码。相反,您可以启用未定义 PHP 变量的报告:

error_reporting(error_reporting() | E_NOTICE);

一方面,这应该足以了解缺失的变量。另一方面,这并不能使您使用自动翻译的想法。

我通常会在任何类型的警告中抛出异常。以下代码段使您能够记录未定义的变量:

set_error_handler(function($severity, $message, $filename, $lineno) {
    if ($severity === E_NOTICE) {
        // Handle this issue, e.g. throw an exception or log the error silently.
        printf('Received this notice: %s in %s on line %s.', $message, $filename, $lineno);
        // throw new ErrorException($message, 0, $severity, $filename, $lineno);
    }
});

如果您想遵循这样的 defensive/strict 编程风格,我可以推荐以下代码片段将所有警告升级为异常:Comment on set_error_handler()

根据 Rayne 的评论,我想出了这个答案。

我所有的翻译变量都以 _ 开头,这样我就可以将它们与其他变量区分开来。这使得可以在我的 beforeRoute 函数中执行此操作:

 set_error_handler(function($severity, $message) {
        if ($severity === E_NOTICE) {
            $ex = explode(':',$message);

            $var = ltrim($ex[1],' ');


            if($ex[0]=='Undefined variable' && substr($var,0,1) =='_'){
                //possibly add auto-translate here
                echo "{{@".$var."}}";
            }
        }
    });

现在所有以 _ 开头的缺失变量都打印为 {{@_missingVariable}}

其实可以通过一些小技巧。您可以使用框架 var PREFIX 为所有语言键添加前缀。 因此,当您在配置文件中设置 PREFIX = ll. 时,语言文件中的所有键都会放入数组 ll (ll = 本地语言)。

现在,在您的模板中,您将使用 {{ @ll.welcome_headline }} 并且所有键都很好地分开并且不会与其余变量冲突。既然您知道,所有语言键现在都在 ll 数组中,您可以将该数组与一个对象交换,该对象实现 ArrayAccess 并在访问这些键时添加一些逻辑。这是我刚写的一个小帮手现在测试该行为,效果很好:

namespace Service;

class Dictionary extends \Magic {

    protected
        $lex = [],
        $prev_key,
        $f3;

    function __construct(array $lexicon, $prev_key = NULL) {
        $this->lex = $lexicon;
        $this->prev_key = $prev_key;
        $this->f3 = \Base::instance();
    }

    function exists($key) {
        $val=$this->f3->ref($key,FALSE,$this->lex);
        return isset($val);
    }

    function set($key,$val) {
        $ref=&$this->f3->ref($key, TRUE, $this->lex);
        $ref=$val;
        return $ref;
    }

    function &get($key) {
        $val=$this->f3->ref($key,FALSE, $this->lex);
        $current_key = ($this->prev_key?$this->prev_key.'.':'').$key;
        if (is_array($val)) {
            $val = new self($val, $current_key);
        } else {
            if (!$val) {
                // do something when language key is missing
                var_dump('missing language key: '.$current_key);
            } else {
                // track which language key was used
                var_dump('language key used: '.$current_key);
            }
        }
        return $val;
    }

    function clear($key) {
        // no clear
    }
}

要使用那只小狗,只需创建对象,输入词典条目,然后交换现有的愚蠢数组:

    $dict = new Service\Dictionary($fw->get('ll'));
    $fw->set('ll', $dict);

在呈现模板之前执行此操作,或者通常使用语言键。每次访问现有或丢失的密钥时,您都可以在 get 方法中做一些特殊的事情.. 如果你想的话,也可以即时翻译它们...

祝你好运;)

在您的控制器中创建一个函数:

function t($key) {
  $f3 = \Base::instance();
  return $f3[$key] ?: ('{{@' . $key . '}}');
}

在html中调用函数:

"My {{ t('_someNonTranslatedWord') }} is missing"

结果

"My {{@_someNonTranslatedWord}} is missing"