以下のコードのように、ビューファイルではなく文字列からブレードテンプレートをコンパイルするにはどうすればよいですか。
<?php
$string = '<h2>{{ $name }}</h2>';
echo Blade::compile($string, array('name' => 'John Doe'));
?>
私は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;
}
}
上記のスクリプトに小さな変更。この関数は、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;
}
私はこの方法でブレードを使用していませんが、コンパイルメソッドは引数としてビューのみを受け入れると思いました。
たぶんあなたが探しています:
Blade::compileString()
私は同じ要件を偶然見つけました!私にとっては、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";
}
}
_
すでに上記からわかるように、以下の手順に従います。
\Blade::compileString($bladeString)
を使用してブレード文字列を同等のphpに変換しました。storage/framework/cache/data/string-blades/
_\Illuminate\View\Factory
_ネイティブメソッド 'file()'にこのファイルをコンパイルおよびレンダリングするよう要求できます。そして最後に、私は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>
_
これが誰かまたは少なくとも多分誰かがより良い方法で書き直すように促すのに役立つことを願っています。
乾杯!
それは古い質問です。しかし、私は仕事を簡単にするパッケージを見つけました。
Laravelブレード文字列コンパイラ は、文字列値からブレードテンプレートをレンダリングします。パッケージのインストール方法に関するドキュメントを確認してください。
次に例を示します。
$template = '<h1>{{ $name }}</h1>'; // string blade template
return view (['template' => $template], ['name' => 'John Doe']);
注:このパッケージはLaravel 5.7と互換性がありません)