Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

humakaka's avatar

Render template from blade template in database

Hi guys,

I'm planning to develop a multi tenancy application which allows users to modify their own templates. To do this, I will store users template in database and render it when needed.

My name is {{{$name}}}

-- name.blade.php

View::make('name')->with('name','Ted');

Above is how we normally do.

My problem is, how to pass the Blade template and compile it with data. I do understand Blade have the function called compileString, but it only able to render the given template without data. Example:

$template = Template::get('make'); // custom class where get the template in database, in this case,

My name is {{{$name}}}

is returned Blade::compileString($template); //where I can't pass name variable to compile.

Hope you guys can help me. Thanks :)

0 likes
14 replies
tobia's avatar

I know this is old, but other people might find the answer useful.

As you have figured out, you can use Blade::compileString() to compile a piece of Blade template, taken for example from a DB column. What are Blade templates compiled to? If you look into storage/framework/views/ in your project folder, you will see that they are compiled into PHP code.

In fact, this is what compileString does:

Blade::compileString('Hello, {{ $planet }}!') === 'Hello, <?php echo e($planet); ?>!'

How can you evaluate that piece of PHP code against a custom array of variables?

Taking a hint from Illuminate\View\Engines\PhpEngine and adding the infamous eval('?>' . $php) trick, here is one possible implementation:

use Symfony\Component\Debug\Exception\FatalThrowableError;

function render($__php, $__data)
{
    $obLevel = ob_get_level();
    ob_start();
    extract($__data, EXTR_SKIP);
    try {
        eval('?' . '>' . $__php);
    } catch (Exception $e) {
        while (ob_get_level() > $obLevel) ob_end_clean();
        throw $e;
    } catch (Throwable $e) {
        while (ob_get_level() > $obLevel) ob_end_clean();
        throw new FatalThrowableError($e);
    }
    return ob_get_clean();
}

And here is how you'd use it in a route or in a controller method:

$blade = 'Hello, {{ $planet }}!';
$php = Blade::compileString($blade);
return render($php, ['planet' => 'World']);
11 likes
jarnheimer's avatar

Does this work for anyone with @foreach and Laravel 5.3. The new loop function throws an ErrorException Undefined variable: __env

simonfakir's avatar

The solution of @tobia parses PHP code in the blade template.

If you parse user generated content as blade template, anyone could inject your source code and take over your system.

Just to consider. Maybe it's better to parse this in a separate project or sandbox so it's not possible to capture your core application.

alekser's avatar

The easiest way is use localization manner to substitute values in your template. First save in database string like this $content = 'Hello :username'; Second in view.blade.php: {{ __($content, ['name' => $user->name]) }}

phaseshift's avatar

I found this to be the easiest way for me:

$html = View( [ 'template' => $email_template->body_blade ], $data )->render();

I use this for sending emails that use an email template that users write and save to the database.

grantholle's avatar

Which View class are you using? When using the helper function view() or the View facade I get

strpos() expects parameter 1 to be string, array given
zhanang19's avatar

Hello @phaseshift, which View class are you using here? I hope you'll answer this and help other people solve their problem too.

Thanks.

amirrezam75's avatar

You can simply use

$content = "OTP: {{$pass}}";
$context = [
	'pass' => '1234'
]
$output = Blade::render($content, $context)

Tested on Laravel 9

1 like

Please or to participate in this conversation.