Erw*_*wan 2 controller routes kohana
我对伟大的Kohana框架,管理员用户可以在后端几种页面选择与完全定制URL添加它们在菜单书面方式一个CMS.
Example of custom URL : "mmmm/about" or "aaa/bbb/release"
Run Code Online (Sandbox Code Playgroud)
我有一个数据库表,我存储了每个URL应显示的内容:
Example :
URL : mmm/about Pagekind : Content page ; (Page) Id : 7
URL : aaa/release Pagekind : News ; (News) Id : 1
Run Code Online (Sandbox Code Playgroud)
每种页面类型都有自己的控制器(因此它更干净,更易于管理,更容易添加新的页面类型):
Examples :
>>> In /application/classes/Controller/Pages :
class Controller_Pages() extends Controller_Template {
public function action_index(){
...
}
}
>>> In /application/classes/Controller/News :
class Controller_News() extends Controller_Template {
public function action_index(){
...
}
}
Run Code Online (Sandbox Code Playgroud)
我有这样的路线,将所有内容发送到我的菜单控制器:
Route::set( 'menu_path', '(<menupath>)', array('menupath' => '.*?') )
->defaults(
array(
'controller' => 'menu',
'action' => 'dispatch'
)
);
Run Code Online (Sandbox Code Playgroud)
我的菜单控制器应该发送:
>>> In /application/classes/Controller/Menu :
class Controller_Menu() extends Controller_Template
{
public function action_dispatch()
{
// Get the path :
$menupath = $this->request->param('menupath');
// Get page info
$obj = ORM::factory('tablemenu')->where('URL','=',$menupath)->find();
// Regarding to page kind, call the appropriate controller
switch ($obj->Pagekind)
{
case 'Content page' :
// Call controller Page with $obj->Id as page id
// ????????
// ????????
break;
case 'News' :
// Call controller News with $obj->Id as news id
// ????????
// ????????
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以我被困在呼叫控制器部分.我的问题是:
- 有没有办法在控制器内调用控制器?(没有重定向搜索引擎优化)
- 如果是的话,它是否干净?可靠吗?
- 还有另一种方法吗?就像覆盖Route类一样?
谢谢
你有两个选择,我认为两者都可以被认为是干净可靠的.
Kohana允许进行内部呼叫,因此您无需进行任何重定向即可实现您所需的内容.
class Controller_Menu() extends Controller_Template
{
public function action_dispatch()
{
// Get the path :
$menupath = $this->request->param('menupath');
// Get page info
$obj = ORM::factory('tablemenu')->where('URL','=',$menupath)->find();
// Regarding to page kind, call the appropriate controller
switch ($obj->Pagekind)
{
case 'Content page' :
$url = 'pages/action/' . $obj->Id;
break;
case 'News' :
$url = 'news/action/' . $obj->Id;
break;
}
// Override current response
$this->response = Request::factory($url)->execute();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这只是一个快速的尝试,向您展示这可能如何工作(并且它本身可能不会).请注意action网址的一部分,您需要在某个时刻定义它才能使其正常工作.不过,实际上有一条路线可以匹配你在这里做的请求,这一点很重要.您还需要提出一个解决方案,了解如何通过'menu_path'路径进行这些内部请求.但既然你还没有尝试过任何东西,我会让你玩它,如果你自己想出来的话.:)
我假设你在这里使用Kohana 3.3.x作为项目,因为路由过滤器只能从这个版本获得.
您可以在路由过滤器中处理请求,而不是将所有请求路由到菜单控制器.
您的路线可能如下所示:
Route::set('menu_path', '(<menupath>)',
array(
'menupath' => '.*?')
)
->filter(function($route, $params, $request)
{
$menupath = $params['menupath'];
// Get page info
$obj = ORM::factory('tablemenu')->where('URL','=',$menupath)->find();
if ($obj->loaded())
{
// Regarding to page kind, call the appropriate controller
switch ($obj->Pagekind)
{
case 'Content page' :
$params['controller'] = 'Page';
$params['id'] = $obj->Id;
break;
case 'News' :
$params['controller'] = 'News';
$params['id'] = $obj->Id;
break;
}
return $params;
}
return FALSE;
})
->defaults(array(
'action' => 'index',
));
Run Code Online (Sandbox Code Playgroud)
请注意,此处无需定义默认控制器,因为如果找不到页面,则要返回404错误.我们确实想要定义默认操作,因为我看不到它在您的示例中的任何位置定义.
您可能需要考虑使用Pagekind与控制器名称匹配的值,然后您不需要case为每种类型使用,您只需执行以下操作:
if ($obj->loaded())
{
$params['controller'] = $obj->Pagekind;
$params['id'] = $obj->Id;
return $params;
}
Run Code Online (Sandbox Code Playgroud)
路由过滤器中的这种复杂性(不仅仅是几行)我还建议将其保留在外面,作为单独的回调函数(如@Daan在下面的评论中所建议的那样),例如:
Route::set('menu_path', '(<menupath>)',
array(
'menupath' => '.*?')
)
->filter('MyRouteHelper::myfilter')
->defaults(array(
'action' => 'index',
));
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助 :)
| 归档时间: |
|
| 查看次数: |
1381 次 |
| 最近记录: |