web-dev-qa-db-ja.com

文字列からブレードテンプレートをコンパイルする方法はありますか?

以下のコードのように、ビューファイルではなく文字列からブレードテンプレートをコンパイルするにはどうすればよいですか。

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

http://paste.laravel.com/ujL

27
Tee Plus

私は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;
    }

}
16
Tee Plus

上記のスクリプトに小さな変更。この関数は、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;
}
12
George John

私はこの方法でブレードを使用していませんが、コンパイルメソッドは引数としてビューのみを受け入れると思いました。

たぶんあなたが探しています:

Blade::compileString()
4
Hexodus

私は同じ要件を偶然見つけました!私にとっては、DBに保存されているブレードテンプレートを取得してレンダリングし、メール通知を送信する必要がありました。

私はこれをlaravel 5.8 by Extending of __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";
    }
}_

すでに上記からわかるように、以下の手順に従います。

  1. 最初に、\Blade::compileString($bladeString)を使用してブレード文字列を同等のphpに変換しました。
  2. 次に、それをphysicalファイルに保存する必要があります。このストレージには、フレームワークキャッシュディレクトリが使用されます-_storage/framework/cache/data/string-blades/_
  3. これで、_\Illuminate\View\Factory_ネイティブメソッド 'file()'にこのファイルをコンパイルおよびレンダリングするよう要求できます。
  4. 一時ファイルをすぐに削除します(私の場合、phpの同等ファイルを保持する必要はありませんでした。おそらくあなたも同じです)。

そして最後に、私はfacadeを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);
    }
}_

これで、以下のような場所から呼び出すことができます。

_<?php

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

// Outputs HTML
// <span>My Name is Nikhil</span>_

これが誰かまたは少なくとも多分誰かがより良い方法で書き直すように促すのに役立つことを願っています。

乾杯!

4
nikhil_

それは古い質問です。しかし、私は仕事を簡単にするパッケージを見つけました。

Laravelブレード文字列コンパイラ は、文字列値からブレードテンプレートをレンダリングします。パッケージのインストール方法に関するドキュメントを確認してください。

次に例を示します。

$template = '<h1>{{ $name }}</h1>';  // string blade template

return view (['template' => $template], ['name' => 'John Doe']);

注:このパッケージはLaravel 5.7と互換性がありません)

2
Raghavendra N