Slim php框架中的子视图(布局,模板)

时间:2022-10-10 09:52:08

I'm trying out the Slim php framework

我正在尝试Slim php框架

Is it possible to have layouts or sub views in Slim? I'd like to use a view file as a template with variables as placeholders for other views loaded separately.

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

How would I do that?

我该怎么办?

7 个解决方案

#1


8  

The slim framework makes use of other templating engines such as Twig or Smarty so as long as you choose a templating engine that allows subviews, then it'll work. For more info on view templating in Slim, check here.

纤细的框架使用其他模板引擎,如Twig或Smarty,因此只要您选择允许子视图的模板引擎,它就可以工作。有关Slim中视图模板的更多信息,请点击此处。

#2


22  

filename: 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;
    }

}
?>

example 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>

#3


7  

I'm working with my View:

我正在使用我的视图:

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);
        }
    }
}

You may add some method like setLayoutData(..) or appendLayoutData(..)

你可以添加一些方法,如setLayoutData(..)或appendLayoutData(..)


Few minutes ago:

几分钟前:

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);
        }
    }
}

#4


3  

With Slim 3

随着超薄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;
    }
}

In layout:

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

#5


1  

You can use this in your parent view:

您可以在父视图中使用它:

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

#6


0  

If you want to capture the output in a variable, it's as easy as using the view's fetch() method:

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

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

#7


0  

Yes it is possible. If you do not want to use any template engine like smarty or twig. If you want to use only .php view file. Follow these steps.

对的,这是可能的。如果您不想使用任何模板引擎,如smarty或twig。如果只想使用.php视图文件。按着这些次序。

Step 1. Make a new directory in your project's root directory. e.g templates.

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

Step 2. Open dependencies.php and paste below code

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

$container = $sh_app->getContainer();

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

Step 3. In your controller's method for rendering view code should be looking like this.

第3步。在你的控制器中,渲染视图代码的方法应该是这样的。

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

#1


8  

The slim framework makes use of other templating engines such as Twig or Smarty so as long as you choose a templating engine that allows subviews, then it'll work. For more info on view templating in Slim, check here.

纤细的框架使用其他模板引擎,如Twig或Smarty,因此只要您选择允许子视图的模板引擎,它就可以工作。有关Slim中视图模板的更多信息,请点击此处。

#2


22  

filename: 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;
    }

}
?>

example 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>

#3


7  

I'm working with my View:

我正在使用我的视图:

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);
        }
    }
}

You may add some method like setLayoutData(..) or appendLayoutData(..)

你可以添加一些方法,如setLayoutData(..)或appendLayoutData(..)


Few minutes ago:

几分钟前:

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);
        }
    }
}

#4


3  

With Slim 3

随着超薄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;
    }
}

In layout:

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

#5


1  

You can use this in your parent view:

您可以在父视图中使用它:

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

#6


0  

If you want to capture the output in a variable, it's as easy as using the view's fetch() method:

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

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

#7


0  

Yes it is possible. If you do not want to use any template engine like smarty or twig. If you want to use only .php view file. Follow these steps.

对的,这是可能的。如果您不想使用任何模板引擎,如smarty或twig。如果只想使用.php视图文件。按着这些次序。

Step 1. Make a new directory in your project's root directory. e.g templates.

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

Step 2. Open dependencies.php and paste below code

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

$container = $sh_app->getContainer();

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

Step 3. In your controller's method for rendering view code should be looking like this.

第3步。在你的控制器中,渲染视图代码的方法应该是这样的。

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