Slim php 框架中的子视图(布局、模板)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7017755/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sub views (layouts, templates) in Slim php framework
提问by jfoucher
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?
我该怎么做?
采纳答案by paulmatthews86
回答by josh anyan
filename: myview.php
文件名: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:
示例 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:
default_layout.php:
<html>
<head>
<title>My Title</title>
</head>
<body>
<!-- $_html contains the output from the view -->
<?= $_html ?>
</body>
</html>
回答by Filipp Qoma
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);
}
}
}
回答by eben
With Slim 3
搭配 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;
}
}
In layout:
在布局中:
<?=$data['content'];?>
回答by Gras Double
You can use this in your parent view:
您可以在父视图中使用它:
$app = \Slim\Slim::getInstance();
$app->render('subview.php');
回答by voidstate
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 ) );
回答by voidstate
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]);