Slim Framework 3 - 在全局模板中使用路由器
Slim Framework 3 - using router in a global template
我对 Slim Framework 3 比较陌生。我想了解的一件事是如何在 "global" 模板中使用路由器 $this->router
。
我的意思是这是一个模板,例如导航菜单 - 每个页面上都会出现的东西。
对于模板,我根据我安装的 example tutorial 使用 "php-view" 库:
composer require slim/php-view
在我的模板目录中,我有一个名为 nav.php
的文件,我想在其中输出我的 links。
我明白怎么调用路由器了
<a href="<?=$router->pathFor('sign-up')?>">Sign Up</a>
但是...示例教程仅显示了如何从 1 个单独的位置传递 link,例如$app->get('/sign-up' ... })->setName("sign-up");
如何在任何模板中全局使用路由器,而不将其作为参数传递给每个单独的 URL 路由?
我更熟悉像 CakePHP 这样的框架,其中有一个 "AppController" 允许您全局设置,即在每个请求中可用。我不知道在 Slim 中是不是这样做的,但这就是我想要的效果。
您应该创建一个新的 class,例如MainMenu,在那里你应该创建一个包含菜单所有路径的数组。 MainMenu
的对象应该 return 一个带有标签和路径的数组,然后您可以将该数组传递给您的视图:
$menu = (new MainMenu())->buildMenu();
$response = $this->view->render($response, "index.phtml", [
'menu' => $menu
]);
然后在您的 *.phtml
文件中您可以访问 $menu
变量。但是,如果您不想在每条路线中重复该代码怎么办?
使用middlewares。您可以使用
从中间件传递变量
$request = $request->withAttribute('foo', 'bar');
并检索
$foo = $request->getAttribute('foo');
好吧,你可以将其传递为 template variable。
当您在容器中实例化或注册 PhpRenderer
时,您有多个选项来定义 "global" 变量,即在所有模板中都可以访问的变量:
// via the constructor
$templateVariables = [
"router" => "Title"
];
$phpView = new PhpRenderer("./path/to/templates", $templateVariables);
// or setter
$phpView->setAttributes($templateVariables);
// or individually
$phpView->addAttribute($key, $value);
假设您通过 Pimple 注册PhpRenderer
:
<?php
// Create application instance
$app = new \Slim\App();
// Get container
$container = $app->getContainer();
// Register PhpRenderer in the container
$container['view'] = function ($container) {
// Declaring "global" variables
$templateVariables = [
'router' => $container->get('router')
];
// And passing the array as second argument to the contructor
return new \Slim\Views\PhpRenderer('path/to/templates/with/trailing/slash/', $templateVariables);
};
<?php namespace App\Helpers;
/********************/
//LinksHelper.php
/********************/
use Interop\Container\ContainerInterface;
class LinksHelper
{
protected $ci;
public function __construct(ContainerInterface $container){
$this->ci = $container;
}
public function __get($property){
if ($this->ci->has($property)) {
return $this->ci->get($property);
}
}
public function pathFor($name, $data = [], $queryParams = [], $appName = 'default')
{
return $this->router->pathFor($name, $data, $queryParams);
}
public function baseUrl()
{
if (is_string($this->uri)) {
return $this->uri;
}
if (method_exists($this->uri, 'getBaseUrl')) {
return $this->uri->getBaseUrl();
}
}
public function isCurrentPath($name, $data = [])
{
return $this->router->pathFor($name, $data) === $this->uri->getPath();
}
public function setBaseUrl($baseUrl)
{
$this->uri = $baseUrl;
}
}
?>
<?php
/********************/
//dependencies.php
/********************/
$container['link'] = function ($c) {
return new \App\Helpers\LinksHelper($c);
};
// view renderer
$container['view'] = function ($c) {
$settings = $c->get('settings');
$view = new App\Views\MyPhpRenderer($settings['renderer']['template_path']);
$view->setLayout('default.php');
//$view->addAttribute('title_for_layout', $settings['title_app'] .' :: ');
$view->setAttributes([
'title_for_layout'=>$settings['title_app'] .' :: ',
'link' => $c->get('link')
]);
return $view;
};
?>
<?php
/********************/
//routes.php
/********************/
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
$app->get('/', function (Request $request, Response $response, array $args) {
return $this->view->render($response, 'your_view.php');
})->setName('home');
?>
<?php
/********************/
//your_view.php
/********************/
?>
<a href="<?=$link->pathFor('home')?>">Home</a>
我对 Slim Framework 3 比较陌生。我想了解的一件事是如何在 "global" 模板中使用路由器 $this->router
。
我的意思是这是一个模板,例如导航菜单 - 每个页面上都会出现的东西。
对于模板,我根据我安装的 example tutorial 使用 "php-view" 库:
composer require slim/php-view
在我的模板目录中,我有一个名为 nav.php
的文件,我想在其中输出我的 links。
我明白怎么调用路由器了
<a href="<?=$router->pathFor('sign-up')?>">Sign Up</a>
但是...示例教程仅显示了如何从 1 个单独的位置传递 link,例如$app->get('/sign-up' ... })->setName("sign-up");
如何在任何模板中全局使用路由器,而不将其作为参数传递给每个单独的 URL 路由?
我更熟悉像 CakePHP 这样的框架,其中有一个 "AppController" 允许您全局设置,即在每个请求中可用。我不知道在 Slim 中是不是这样做的,但这就是我想要的效果。
您应该创建一个新的 class,例如MainMenu,在那里你应该创建一个包含菜单所有路径的数组。 MainMenu
的对象应该 return 一个带有标签和路径的数组,然后您可以将该数组传递给您的视图:
$menu = (new MainMenu())->buildMenu();
$response = $this->view->render($response, "index.phtml", [
'menu' => $menu
]);
然后在您的 *.phtml
文件中您可以访问 $menu
变量。但是,如果您不想在每条路线中重复该代码怎么办?
使用middlewares。您可以使用
从中间件传递变量$request = $request->withAttribute('foo', 'bar');
并检索
$foo = $request->getAttribute('foo');
好吧,你可以将其传递为 template variable。
当您在容器中实例化或注册 PhpRenderer
时,您有多个选项来定义 "global" 变量,即在所有模板中都可以访问的变量:
// via the constructor
$templateVariables = [
"router" => "Title"
];
$phpView = new PhpRenderer("./path/to/templates", $templateVariables);
// or setter
$phpView->setAttributes($templateVariables);
// or individually
$phpView->addAttribute($key, $value);
假设您通过 Pimple 注册PhpRenderer
:
<?php
// Create application instance
$app = new \Slim\App();
// Get container
$container = $app->getContainer();
// Register PhpRenderer in the container
$container['view'] = function ($container) {
// Declaring "global" variables
$templateVariables = [
'router' => $container->get('router')
];
// And passing the array as second argument to the contructor
return new \Slim\Views\PhpRenderer('path/to/templates/with/trailing/slash/', $templateVariables);
};
<?php namespace App\Helpers;
/********************/
//LinksHelper.php
/********************/
use Interop\Container\ContainerInterface;
class LinksHelper
{
protected $ci;
public function __construct(ContainerInterface $container){
$this->ci = $container;
}
public function __get($property){
if ($this->ci->has($property)) {
return $this->ci->get($property);
}
}
public function pathFor($name, $data = [], $queryParams = [], $appName = 'default')
{
return $this->router->pathFor($name, $data, $queryParams);
}
public function baseUrl()
{
if (is_string($this->uri)) {
return $this->uri;
}
if (method_exists($this->uri, 'getBaseUrl')) {
return $this->uri->getBaseUrl();
}
}
public function isCurrentPath($name, $data = [])
{
return $this->router->pathFor($name, $data) === $this->uri->getPath();
}
public function setBaseUrl($baseUrl)
{
$this->uri = $baseUrl;
}
}
?>
<?php
/********************/
//dependencies.php
/********************/
$container['link'] = function ($c) {
return new \App\Helpers\LinksHelper($c);
};
// view renderer
$container['view'] = function ($c) {
$settings = $c->get('settings');
$view = new App\Views\MyPhpRenderer($settings['renderer']['template_path']);
$view->setLayout('default.php');
//$view->addAttribute('title_for_layout', $settings['title_app'] .' :: ');
$view->setAttributes([
'title_for_layout'=>$settings['title_app'] .' :: ',
'link' => $c->get('link')
]);
return $view;
};
?>
<?php
/********************/
//routes.php
/********************/
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
$app->get('/', function (Request $request, Response $response, array $args) {
return $this->view->render($response, 'your_view.php');
})->setName('home');
?>
<?php
/********************/
//your_view.php
/********************/
?>
<a href="<?=$link->pathFor('home')?>">Home</a>