【问题标题】:Render Blade from string instead of File从字符串而不是文件渲染刀片
【发布时间】:2014-02-28 16:30:11
【问题描述】:

如何呈现包含刀片语法的字符串?

View::make('directory.file-name')->with('var', $var);  // Usual usage

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

我使用编写了一个生成刀片语法的脚本,如果可能的话,我想将它的输出直接提供给刀片引擎。

谢谢

【问题讨论】:

标签: laravel-4 blade


【解决方案1】:

我不建议使用 'Blade::compileString',因为它不会像 View 那样完全渲染 PHP。

这是我实际的刀片字符串渲染器的工作版本。您可以将它用于数据库内容或您想要呈现的任何字符串,就像使用 .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 的 end 的处理程序。即使这不是必需的,这也是为了提供一个完全可测试的解决方案。

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

【讨论】:

    【解决方案2】:

    我刚刚为 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);
         * 
         */
    

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

    【讨论】:

      【解决方案3】:

      希望这会有所帮助,

      https://github.com/TerrePorter/StringBladeCompiler

      这是下一个链接的一个分支,它删除了 db 模型要求并将其替换为需要三个必需键('template'、'cache_key'、'updated_at')的数组,而不是完整的 Eloquent 模型。

      https://github.com/Flynsarmy/laravel-db-blade-compiler

      这使用 Eloquent 模型来获取模板。

      【讨论】:

        猜你喜欢
        • 2013-07-11
        • 2020-12-19
        • 2015-04-15
        • 2014-11-27
        • 2023-02-21
        • 2022-06-25
        • 2016-03-17
        • 2016-04-04
        • 2021-09-16
        相关资源
        最近更新 更多