我看到了这个问题的两种可能的解决方案。
- 自己编译刀片(不是最佳 IMO)
给定一个字符串,您可以创建一个帮助函数来为您编译刀片。(来源)
helpers.php (或任何你想找到函数的地方)
function compile_blade($markup, $data = []) {
$fs = new \Illuminate\Filesystem\Filesystem;
$b = new \Illuminate\View\Compilers\BladeCompiler($fs, __DIR__);
$src = $b->compileString($markup);
$isPhp = false;
if (substr( $src, 0, 5 ) === "<?php")
{
$isPhp = true;
$src = substr($src, 5);
}
$tempFileName = tempnam("/tmp", "blade-compile");
file_put_contents($tempFileName, $src);
ob_start();
extract($data);
include $tempFileName;
$out = ob_get_clean();
if ($isPhp)
{
$out = '<?php'.$out;
}
return $out;
}
然后在您的控制器中,您将预处理 s3 刀片以便在您的 render.blade.php 文件中使用,例如:
return view('render', [
'template' => compile_blade($template, $landing),
'landing' => $landing,
));
我认为这不是最佳解决方案,因为无论如何您最终都会创建文件。
- 为来自 s3 的刀片/html 创建一个新的命名空间。
首先,您需要在项目中创建一个文件夹,例如./storage/local/blade
. 然后,您需要为该文件夹中的视图添加命名空间,如下所示:
AppServiceProvider.php
public function boot()
{
...
view()->addNamespace('s3', storage_path('/local/views');
...
}
现在要处理从 s3(在您的控制器或其他地方)检索标记,您可以执行以下操作:
// Lets say the file on s3 is markup.blade.php
$contents = Storage::disk('s3')->get('path/to/markup.blade.php')
Storage::disk('local')->put(storage_path('local/views/markup.blade.php'), $contents);
现在,如果您的 render.blade.php 仅用于在 s3 上呈现标记,您应该只使用新的命名空间视图。您可以在控制器中使用它,例如:
return view('s3::markup', compact('landing'));
如果您想在其他刀片文件之一中使用 s3 标记,这会变得有点棘手。但可以通过扩展刀片来完成,如本文所述。
Blade::extend(function($view, $compiler)
{
$pattern = $compiler->createMatcher('includeNamespaced');
$viewPath = realpath($compiler->getPath());
$parts = explode(DIRECTORY_SEPARATOR, $viewPath);
$viewsDirectoryIndex = array_search('views', $parts);
$namespace = $parts[$viewsDirectoryIndex + 1];
$php = '$1<?php ';
$php .= 'if($__env->exists(\''.$namespace.'.\'.$2)){';
$php .= 'echo $__env->make(\''.$namespace.'.\'.$2)->render();';
$php .= '}';
$php .= 'else {';
$php .= 'echo $__env->make($2)->render();';
$php .= '}';
$php .= '?>';
return preg_replace($pattern, $php, $view);
});
现在您可以在刀片文件中 @include 命名空间视图,例如:
@includeNamespaced('s3/markup')
我更喜欢解决方案 2 的另一个原因是,如果您在从 s3 下载之前查看文件是否已存在于本地/视图中,您可以获得一些“缓存”效果。然后,您可以创建一个计划作业,删除存储/本地/视图中超过某个时间限制的文件。