从字符串而不是文件中渲染 Blade模板

7
我该如何呈现一个包含Blade语法的字符串?
View::make('directory.file-name')->with('var', $var);  // Usual usage

View::render('{{$var}}')->with('var', $var); // Like this for Example

我编写了一个生成blade语法的脚本,如果可能的话,我想直接将其输出给blade引擎。谢谢。

1
可能有点底层,但是...http://laravel.com/api/4.1/Illuminate/View/Compilers/BladeCompiler.html提到了一个`compileString`方法... - cHao
3个回答

4
我不建议使用'Blade :: compileString ',因为它不会像View一样完全呈现PHP。

这是我实际的 Blade字符串渲染器的工作版本。您可以将其用于数据库内容或任何要像.blade.php文件一样呈现的字符串。使用Laravel 4进行测试。完全注释和解释。

不要忘记在视图内创建' cache '文件夹

此函数生成文件视图。

public function generateViewFile($html, $url, $updated_at)
{
    // Get the Laravel Views path
    $path = \Config::get('view.paths.0');

    // Here we use the date for unique filename - This is the filename for the View
    $viewfilename = $url."-".hash('sha1', $updated_at);

    // Full path with filename
    $fullfilename = $path."/cache/".$viewfilename.".blade.php";

    // Write the string into a file
    if (!file_exists($fullfilename))
    {
        file_put_contents($fullfilename, $html);
    }

    // Return the view filename - This could be directly used in View::make
    return $viewfilename;
}

这是ContentController路由渲染器。
public function getIndex($uri = false)
{
    // In my real ContentController I get the page from the DB here
    //
    // $page = Page::findByUrl($uri);
    // $content = $page->content;
    // $updated_at = $page->updated_at;
    // $url = $page->url;

    $content = '<h1>This is the page to render</h1>';
    $updated_at = '2015-07-15 02:40:55';
    $url = '/blog/new-article';

    // Will write the file when needed and return the view filename
    $filename = $this->generateViewFile($content, $url, $updated_at);

    // Fully render and output the content
    return View::make('cache/'.$filename);
}

在routes.php文件的结尾处放置处理程序。即使这不是必需的,这也是为了呈现完全可测试的解决方案。

Route::get('{all}', 'ContentController@getIndex')->where('all', '.*');

2

1

我刚刚为 Laravel 4.2 创建了一个仅适用于 Linux 的版本(使用 shm 来创建临时文件)。它也可以在其他操作系统上运行,但是速度会慢一些,因为使用了通常的临时文件。

<?php

class FilesDeletionQueue {

    protected $files = [];

    public function add($filename) {
        $this->files[] = $filename;
    }

    public function flush() {
        $result = true;
        foreach ($this->files as $filename) {
            if (@unlink($filename) === false) {
                $result = false;
            }
        }
        return $result;
    }

}

class Helpers {

    static public function viewFromStr($tplName, $pageContent, array $data) {
        global $app;

        // Try to create temporary blade template file in shm memory,
        // if fails, create as usual temporary file.
        $tempname = tempnam('/run/shm/', 'laravel_blade');
        if (@file_put_contents($tempname, $pageContent) === false) {
            $tempname = tempnam(storage_path(), 'laravel_blade');
            if (@file_put_contents($tempname, $pageContent) === false) {
                throw new \Exception("Cannot create {$tempname} in " . __METHOD__);
            }
        }

        // Create template from shm memory file.
        $resolver = $app['view.engine.resolver'];
        $finder = $app['view.finder'];
        $env = new \Illuminate\View\Factory($resolver, $finder, $app['events']);
        $env->setContainer($app);
        $pageView = new \Illuminate\View\View(
            $env,
            $env->getEngineResolver()->resolve('blade'),
            $tplName,
            $tempname,
            $data
        );
        $env->callCreator($pageView);

        try {
            $fdq = App::make('files_deletion_queue');
        } catch (\Exception $e) {
            App::singleton('files_deletion_queue', function() {
                return new FilesDeletionQueue();
            });
            $fdq = App::make('files_deletion_queue');
            App::shutdown(function() {
                App::make('files_deletion_queue')->flush();
            });
        }
        // Add tempname to list of files to be deleted when application ends.
        $fdq->add($tempname);

        return $pageView;
    }

}

然后您可以像这样使用它:
    $pageView = Helpers::viewFromStr('content', $pageContent, $this->data);
    $this->layout->with('content', $pageView)
        ->with('menus', $this->menus )
        ->with('page',$this->data);

而不是:

    /*
    $this->layout->nest('content',"pages.template.{$row->filename}",$this->data)
        ->with('menus', $this->menus )
        ->with('page',$this->data);
     * 
     */

很遗憾,推荐的方法无法从任意操作系统路径加载blade文件,并且没有现成的支持从RAM编译的支持(我听说twig更容易实现)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接