Problem: I need to let my web-app users create their own blade layout templates. So the most convenient solution is to store the blade templates into the database. However, I see no method to extend
a child view
from a layout code NOT SPECIFIED
in a blade file
.
Furthermore the next concern is security. I can't rely on users to insert safe code
. Giving access to insert php
code or directly blade
code is disastrous for the system.
So how to?
- Save the layout template in database
- Make sure no part of the code gets executed on the server side.
As a side note, I can let users mention pre-specified tokens in the code, that shall be replaced by the results from the system.
Solution 1: Let users fill the database column (after filtering the given code for any possible php codes) and save it into a 'master' file, from which the final view is being extended. User may use given codes for content replacement
//master.blade.php
<html>
<head>
<%token%>
</head>
<body>
<%content%>
...
<%scripts%>
</body>
</html>
In the above code, the <% content %>
should be replaced by
@yield('content')
before the actual view is processed.
//final.blade.php
@extends('layouts.master')
@section('content')
...
@endsection
So the controller, saves the database column content into master.blade.php and then calls the view('final') function as necessary.
//In Controller
//Save the contents of database column in master.blade.php
return view('final',$data);
But this is NOT a GOOD solution. File write operation for every request, cache problems, security issues (such as service side execution script injection) etc.
An alternate to this is having a master for each user, created only when the user makes changes in the template column. Thus benefiting from lesser file write operations, but file overload on the server because a file for every user in the file-system.
Solution 2: Save the user's layout code into database column (no filtering necessary).
//In controller
$content = View::make('final',compact('data'));
$token = "<meta name='_token' content='" . csrf_token() ."'";
$scripts = View::make('final_scripts',compact('data'));
$view = str_replace_first("<%content%>", $content, $templateInDatabase);
$view = str_replace_first("<%token%>", $token, $view);
$view = str_replace_first("<%scripts%>", $scripts, $view);
return $view;
The user shall be made to include the three <%X%> tags in the template code.
Benefits are no server side code execution, hence added security. Cache problems minimize as the final & final_scripts blade templates can be cached. But the string replacements add extra effort.