从字符串加载模板时,Laravel Blade指令不执行

时间:2016-10-03 19:32:53

标签: php laravel laravel-blade

编辑:下面的代码段,其中view将数组['template' => 'my template']作为第一个参数,是wpb/string-blade-compiler的一个特征,它覆盖了原生的laravel功能。

我在AppServiceProvider::boot注册了指令:

public function boot()
{
    Blade::directive('hello', function($expression) {
        return "<?php echo 'Hello world'; ?>";
    });
}

当我使用基于文件的模板保存为resources/views/something.blade.php并在我的return view('something', $data)中使用Controller::action时,它非常有效。

然而,当我尝试:

try {
  return view(['template' => $template], $data)->render();
} catch(\ErrorException $ex) {
  preg_match('/Undefined variable: (.+?)\s/', $ex->getMessage(), $matches);
  if ($matches) {
    return sprintf('Template: variable {{ $%s }} is invalid', $matches[1]);
  }
  return sprintf('%s: %s', $attribute, $ex->getMessage());
}

尝试使用字符串中的模板,不加载该指令。没有错误,没有任何错误。

对laravel有深入了解的人是否知道这两种情况的区别?我原以为他们会得到相同的结果,但不会。我正在努力理解laravel架构以解开这个问题。感谢。

composer.json:

"require": {
    "php": ">=5.5.9",
    "laravel/framework": "5.2.*",
    "laravelcollective/html": "^5.2",
    "maatwebsite/excel": "^2.1",
    "sofa/eloquence": "^5.2",
    "wpb/string-blade-compiler": "^3.2",
    "doctrine/dbal": "^2.5",
    "davejamesmiller/laravel-breadcrumbs": "^3.0"
}

PHP 5.6

1 个答案:

答案 0 :(得分:2)

所以,我在自己的服务器上进行了一些测试,并提出了一个解决方案:

我精简的代码:#/ p>

Route::get('/test', function () {

    $template = Blade::compileString('@hello(derek) !');

    ob_start();

    try {

        eval('?>' . $template);

    } catch (\Exception $e) {

        ob_get_clean(); throw $e;

    }

    $content = ob_get_clean();

    return $content;

});

指令,如果你愿意看到它:

public function boot()
    {
        //
        Blade::directive('hello', function($d) {

            return "<?php echo \"Hello {$d}\"; ?>";
        });
    }

关于这方面几乎没有文档,所以调试可能很麻烦,但我知道如果你想将更多变量传递给字符串,它看起来像这样:

Route::get('/test2', function () {

    $args = ['name' => 'derek'];

    $template = Blade::compileString('@hello($name) !');

    ob_start() and extract($args, EXTR_SKIP);

    try {

        eval('?>' . $template);

    } catch (\Exception $e) {

        ob_get_clean(); throw $e;

    }

    $content = ob_get_clean();

    return $content;

});

最后,您可以在控制器中放置一个简单的功能:

// way to call:

$this->strView('@hello($name)', ['name' => 'Tom Riddle']);

public function strView($view, $args) {
    $template = Blade::compileString($view);

    ob_start() and extract($args, EXTR_SKIP);

    try {

        eval('?>' . $template);

    } catch (\Exception $e) {

        ob_get_clean(); throw $e;

    }

    $content = ob_get_clean();

    return $content;
}

如果您有任何疑问,请与我联系!