有没有办法从字符串编译刀片模板?

Tee*_*lus 25 php laravel laravel-blade

如何从字符串而不是视图文件编译刀片模板,如下面的代码:

<?php
$string = '<h2>{{ $name }}</h2>';
echo Blade::compile($string, array('name' => 'John Doe')); 
?>
Run Code Online (Sandbox Code Playgroud)

http://paste.laravel.com/ujL

Tee*_*lus 18

我通过扩展BladeCompiler找到了解决方案.

<?php namespace Laravel\Enhanced;

use Illuminate\View\Compilers\BladeCompiler as LaravelBladeCompiler;

class BladeCompiler extends LaravelBladeCompiler {

    /**
     * Compile blade template with passing arguments.
     *
     * @param string $value HTML-code including blade
     * @param array $args Array of values used in blade
     * @return string
     */
    public function compileWiths($value, array $args = array())
    {
        $generated = parent::compileString($value);

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

        // We'll include the view contents for parsing within a catcher
        // so we can avoid any WSOD errors. If an exception occurs we
        // will throw it out to the exception handler.
        try
        {
            eval('?>'.$generated);
        }

        // If we caught an exception, we'll silently flush the output
        // buffer so that no partially rendered views get thrown out
        // to the client and confuse the user with junk.
        catch (\Exception $e)
        {
            ob_get_clean(); throw $e;
        }

        $content = ob_get_clean();

        return $content;
    }

}
Run Code Online (Sandbox Code Playgroud)


Bre*_*ett 17

对于仍然对此感兴趣的人,他们已将其添加到 Laravel 9

use Illuminate\Support\Facades\Blade;
 
return Blade::render('Hello, {{ $name }}', ['name' => 'Julian Bashir']);
Run Code Online (Sandbox Code Playgroud)

https://laravel.com/docs/9.x/blade#rendering-inline-blade-templates

  • 如果您使用 Laravel 8.x,您可以按原样从 9.x 复制该函数,它将与 Laravel 8.x 一起使用,已使用 php 7.4 进行测试函数 render() 位于 [BladeCompiler.php] (https:// github.com/laravel/framework/blob/a9bd0ce3b5354fb07861b56263c998819854d5bb/src/Illuminate/View/Compilers/BladeCompiler.php#L282) (2认同)

Geo*_*ohn 12

对上述脚本的小修改.您可以在任何类中使用此函数,而无需扩展BladeCompiler类.

public function bladeCompile($value, array $args = array())
{
    $generated = \Blade::compileString($value);

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

    // We'll include the view contents for parsing within a catcher
    // so we can avoid any WSOD errors. If an exception occurs we
    // will throw it out to the exception handler.
    try
    {
        eval('?>'.$generated);
    }

    // If we caught an exception, we'll silently flush the output
    // buffer so that no partially rendered views get thrown out
    // to the client and confuse the user with junk.
    catch (\Exception $e)
    {
        ob_get_clean(); throw $e;
    }

    $content = ob_get_clean();

    return $content;
}
Run Code Online (Sandbox Code Playgroud)


Hex*_*dus 5

我没有以这种方式使用刀片,但我认为 compile 方法只接受一个视图作为参数。

也许您正在寻找:

Blade::compileString()
Run Code Online (Sandbox Code Playgroud)

  • $string = '&lt;h2&gt;{{ $name }}&lt;/h2&gt;'; echo Blade::compileString($string, array('name' =&gt; 'John Doe')); “名称”未分配给模板。 (6认同)

小智 5

我只是偶然发现了同样的要求!对我来说,我必须获取存储在 DB 中的刀片模板并渲染它以发送电子邮件通知。

我在 laravel 5.8 中通过一种 Extending 做到了这一点\Illuminate\View\View。所以,基本上我创建了下面的类并将他命名为 StringBlade(我找不到更好的名字 atm :/)

<?php

namespace App\Central\Libraries\Blade;

use Illuminate\Filesystem\Filesystem;

class StringBlade implements StringBladeContract
{
    /**
     * @var Filesystem
    */
    protected $file;

    /**
     * @var \Illuminate\View\View|\Illuminate\Contracts\View\Factory
    */
    protected $viewer;

    /**
     * StringBlade constructor.
     *
     * @param Filesystem $file
     */
    public function __construct(Filesystem $file)
    {
        $this->file = $file;
        $this->viewer = view();
    }

    /**
     * Get Blade File path.
     *
     * @param $bladeString
     * @return bool|string
     */
    protected function getBlade($bladeString)
    {
        $bladePath = $this->generateBladePath();

        $content = \Blade::compileString($bladeString);

        return $this->file->put($bladePath, $content)
            ? $bladePath
            : false;
    }

    /**
     * Get the rendered HTML.
     *
     * @param $bladeString
     * @param array $data
     * @return bool|string
     */
    public function render($bladeString, $data = [])
    {
        // Put the php version of blade String to *.php temp file & returns the temp file path
        $bladePath = $this->getBlade($bladeString);

        if (!$bladePath) {
            return false;
        }

        // Render the php temp file & return the HTML content
        $content = $this->viewer->file($bladePath, $data)->render();

        // Delete the php temp file.
        $this->file->delete($bladePath);

        return $content;
    }

    /**
     * Generate a blade file path.
     *
     * @return string
     */
    protected function generateBladePath()
    {
        $cachePath = rtrim(config('cache.stores.file.path'), '/');
        $tempFileName = sha1('string-blade' . microtime());
        $directory = "{$cachePath}/string-blades";

        if (!is_dir($directory)) {
            mkdir($directory, 0777);
        }

        return "{$directory}/{$tempFileName}.php";
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您已经从上面看到的,下面是遵循的步骤:

  1. 首先使用 将刀片字符串转换为 php 等效项\Blade::compileString($bladeString)
  2. 现在我们必须将它存储到一个物理文件中。对于此存储,使用框架缓存目录 -storage/framework/cache/data/string-blades/
  3. 现在我们可以要求\Illuminate\View\Factory本地方法'file()'来编译和渲染这个文件。
  4. 立即删除临时文件(在我的情况下,我不需要保留 php 等效文件,对你来说可能也一样)

最后,我在 Composer 自动加载的文件中创建了一个外观,以便于使用,如下所示:

<?php

if (! function_exists('string_blade')) {

    /**
     * Get StringBlade Instance or returns the HTML after rendering the blade string with the given data.
     *
     * @param string $html
     * @param array $data
     * @return StringBladeContract|bool|string
     */
    function string_blade(string $html, $data = [])
    {
        return !empty($html)
            ? app(StringBladeContract::class)->render($html, $data)
            : app(StringBladeContract::class);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我可以从任何地方调用它,如下所示:

<?php

$html = string_blade('<span>My Name is {{ $name }}</span>', ['name' => 'Nikhil']);

// Outputs HTML
// <span>My Name is Nikhil</span>
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助某人或至少可能激发某人以更好的方式重写。

干杯!