【问题标题】:Sub views (layouts, templates) in Slim php frameworkSlim php 框架中的子视图(布局、模板)
【发布时间】:2011-10-24 11:15:58
【问题描述】:

我正在试用Slim php framework

Slim 中是否可以有布局或子视图?我想将视图文件用作模板,并将变量用作单独加载的其他视图的占位符。

我该怎么做?

【问题讨论】:

    标签: php templates frameworks slim


    【解决方案1】:

    文件名:myview.php

    <?php
    class myview extends Slim_View
    {
        static protected $_layout = NULL;
        public static function set_layout($layout=NULL)
        {
            self::$_layout = $layout;
        }
        public function render( $template ) {
            extract($this->data);
            $templatePath = $this->getTemplatesDirectory() . '/' . ltrim($template, '/');
            if ( !file_exists($templatePath) ) {
                throw new RuntimeException('View cannot render template `' . $templatePath . '`. Template does not exist.');
            }
            ob_start();
            require $templatePath;
            $html = ob_get_clean();
            return $this->_render_layout($html);
        }
        public function _render_layout($_html)
        {
            if(self::$_layout !== NULL)
            {
                $layout_path = $this->getTemplatesDirectory() . '/' . ltrim(self::$_layout, '/');
                if ( !file_exists($layout_path) ) {
                    throw new RuntimeException('View cannot render layout `' . $layout_path . '`. Layout does not exist.');
                }
                ob_start();
                require $layout_path;
                $_html = ob_get_clean();
            }
            return $_html;
        }
    
    }
    ?>
    

    示例 index.php:

    <?php
    require 'Slim/Slim.php';
    require 'myview.php';
    
    // instantiate my custom view
    $myview = new myview();
    
    // seems you need to specify during construction
    $app = new Slim(array('view' => $myview));
    
    // specify the a default layout
    myview::set_layout('default_layout.php');
    
    $app->get('/', function() use ($app) {
        // you can override the layout for a particular route
        // myview::set_layout('index_layout.php');
        $app->render('index.php',array());
    });
    
    $app->run();
    ?>
    

    default_layout.php:

    <html>
        <head>
            <title>My Title</title>
        </head>
        <body>
            <!-- $_html contains the output from the view -->
            <?= $_html ?>
        </body>
    </html>
    

    【讨论】:

      【解决方案2】:

      Slim 框架使用了其他模板引擎,例如 TwigSmarty,因此只要您选择允许子视图的模板引擎,它就可以工作。有关 Slim 中视图模板的更多信息,请查看here

      【讨论】:

      • Slim 文档链接已损坏。
      【解决方案3】:

      我正在使用我的视图:

      class View extends \Slim\View
      {
          protected $layout;
      
          public function setLayout($layout)
          {
              $this->layout = $layout;
          }
      
          public function render($template)
          {
              if ($this->layout){
                  $content =  parent::render($template);
                  $this->setData(array('content' => $content));
                  return parent::render($this->layout);
              } else {
                  return parent::render($template);
              }
          }
      }
      

      您可以添加一些方法,例如setLayoutData(..)appendLayoutData(..)


      几分钟前:

      class View extends \Slim\View
      {
      
          /** @var string */
          protected $layout;
      
          /** @var array */
          protected $layoutData = array();
      
          /**
           * @param string $layout Pathname of layout script
           */
          public function setLayout($layout)
          {
              $this->layout = $layout;
          }
      
          /**
           * @param array $data
           * @throws \InvalidArgumentException
           */
          public function setLayoutData($data)
          {
              if (!is_array($data)) {
                  throw new \InvalidArgumentException('Cannot append view data. Expected array argument.');
              }
      
              $this->layoutData = $data;
          }
      
          /**
           * @param array $data
           * @throws \InvalidArgumentException
           */
          public function appendLayoutData($data)
          {
              if (!is_array($data)) {
                  throw new \InvalidArgumentException('Cannot append view data. Expected array argument.');
              }
      
              $this->layoutData = array_merge($this->layoutData, $data);
          }
      
          /**
           * Render template
           *
           * @param  string $template Pathname of template file relative to templates directory
           * @return string
           */
          public function render($template)
          {
              if ($this->layout){
                  $content = parent::render($template);
      
                  $this->appendLayoutData(array('content' => $content));
                  $this->data = $this->layoutData;
      
                  $template = $this->layout;
                  $this->layout = null; // allows correct partial render in view, like "<?php echo $this->render('path to parial view script'); ?>"
      
                  return parent::render($template);;
              } else {
                  return parent::render($template);
              }
          }
      }
      

      【讨论】:

      • 嘿,这太棒了!我应该如何将数据传递给主布局?
      • @GonzaloNaveira,您应该使用 setLayoutData() 或 appendLayoutData() 方法 =)。很抱歉没有早点回复你的信 =)
      【解决方案4】:

      搭配 Slim 3

      namespace Slim;
      use Psr\Http\Message\ResponseInterface;
      
      class View extends Views\PhpRenderer
      {
          protected $layout;
      
          public function setLayout($layout)
          {
              $this->layout = $layout;
          }
      
          public function render(ResponseInterface $response, $template, array $data = [])
          {
              if ($this->layout){
                  $viewOutput = $this->fetch($template, $data);
                  $layoutOutput = $this->fetch($this->layout, array('content' => $viewOutput));
                  $response->getBody()->write($layoutOutput);
              } else {
                  $output = parent::render($response, $template, $data);
                  $response->getBody()->write($output);
              }
              return $response;
          }
      }
      

      在布局中:

      <?=$data['content'];?>
      

      【讨论】:

      【解决方案5】:

      你可以在你的父视图中使用它:

      $app = \Slim\Slim::getInstance();
      $app->render('subview.php');
      

      【讨论】:

        【解决方案6】:

        如果你想在变量中捕获输出,就像使用视图的fetch() 方法一样简单:

        //assuming $app is an instance of \Slim\Slim
        $app->view()->fetch( 'my_template.php', array( 'key' => $value ) );
        

        【讨论】:

          【解决方案7】:

          是的,这是可能的。如果您不想使用任何模板引擎,例如 smarty 或 twig。如果您只想使用 .php 视图文件。请按照以下步骤操作。

          步骤 1. 在项目的根目录中创建一个新目录。例如模板。

          步骤 2. 打开 dependencies.php 并粘贴以下代码

          $container = $sh_app->getContainer();
          
          $container['view'] = function ($c) {
             $view = new Slim\Views\PhpRenderer('src/templates/');
             return $view;
          };
          

          第 3 步。在您的控制器中呈现视图代码的方法应如下所示。

          $this->container->view->render($response,'students/index.php',['students' => $data]);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-11-23
            相关资源
            最近更新 更多