How can I compile a blade template from a string rather than a view file, like the code below:
{{ $name }}\';
echo
I just stumbled upon the same requirement! For me, i had to fetch a blade template stored in DB & render it to send email notifications.
I did this in laravel 5.8 by kind-of Extending \Illuminate\View\View. So, basically i created the below class & named him StringBlade (I couldn't find a better name atm :/)
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";
}
}
As you can already see from the above, below are the steps followed:
\Blade::compileString($bladeString). storage/framework/cache/data/string-blades/\Illuminate\View\Factory native method 'file()' to compile & render this file.And Finally i created a facade in a composer auto-loaded file for easy usage like below:
render($html, $data)
: app(StringBladeContract::class);
}
}
Now i can call it from anywhere like below:
My Name is {{ $name }}', ['name' => 'Nikhil']);
// Outputs HTML
// My Name is Nikhil
Hope this helps someone or at-least maybe inspires someone to re-write in a better way.
Cheers!