我很难用动态网址参数实现Zend_Navigation
面包屑。
简单方案:想象一下CompanyController
viewAction()
的{{1}}从网址获取id
参数,以获取有关特定公司的信息。
URL: example.com/company/view/id/4
Desired breadcrumb: Home > Companies > [ Company name ]
我已经在线进行了一些研究,并提出了以下解决方案:在predispatch()
挂钩中,我从id
获取$_SERVER['REQUEST_URI']
参数(我们无法使用请求对象)为此,因为调度还没有开始)并从数据库中获取该记录。然后我只需将此页面添加到Zend_Navigation
容器中的根页面。你可以在这篇文章的底部看到它的实现。
我用这种方法发现的问题是它不可扩展:
如果每个公司有多个操作,该怎么办?
除view
公司记录外,我们可能还想edit
(example.com/company/edit/id/4
)或对其执行其他操作。当然,我们可以创建一个switch语句来检查URL中的操作,但我觉得这不可扩展。
如果网址中有多个动态参数,该怎么办?
对于每个company
,我们还需要管理其contacts
(公司所有者,财务官等),以便我们创建一个ContactsController
,其中还包含viewAction
和editAction
。由于联系人直接与公司绑定,我们希望将其反映在URL和面包屑中:
URL: example.com/company/company-id/4/contacts/contact-id/2
Desired breadcrumb: Home > Companies > [Company name] > Contacts of [Company name] > [Contact name]
我们可以轻松地为此设置路线。但现在我们必须从URL中获取多个id
。随着URL变得越来越复杂,这个过程会更容易出错。
到目前为止,我已经提出了两个看似合理的解决方案:
扩展Plugin_Navigation::preDispatch()
挂钩
可能的解决方案是使用详细的URL参数(如company-id
和contact-id
)。这样我们就可以提取名称(即company
)并通过相应的模型类获取记录。
在我们的操作方法
中将页面添加到导航容器中这是我认为最灵活的选择,但这也意味着我们无法再从中心点管理我们的面包屑,这是一个严重的缺点。
我做了大量的研究,但似乎没有针对这个问题的开箱即用的解决方案。非常感谢任何帮助。
前面提到的Plugin_Navigation::preDispatch()
挂钩:
class Plugin_Navigation extends Zend_Controller_Plugin_Abstract
{
public function preDispatch()
{
$view = Zend_Controller_Action_HelperBroker::getExistingHelper('ViewRenderer')->view;
$config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml','nav');
$container = new Zend_Navigation($config);
$urlParts = explode('/', ltrim($_SERVER['REQUEST_URI'], '/'));
$pos = array_search('id', $urlParts);
if ($pos !== FALSE)
{
$id = $urlParts[$pos + 1];
$model = new Model_Company();
$company = $model->fetchOne($id);
$rootPage = $container->findOneBy('controller', 'company');
$rootPage->addPage(new Zend_Navigation_Page_Mvc(array(
'controller' => 'company',
'action' => 'view',
'label' => $company->name
)));
$view->navigation($container);
}
}
}
有关此主题的一些参考资料:
答案 0 :(得分:0)
您可以通过bootstrap.php文件中的引导前端控制器来解决这个问题
在bootstrap.php文件中添加:
public function _initRequest()
{
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$front->setRequest(new Zend_Controller_Request_Http());
$request = $front->getRequest();
}
然后在插件中传递 preDispatch 函数中的请求对象:
class Your_Controller_Plugin_PluginName extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$MyController =$request->getControllerName();
$MyAction =$request->getActionName();
$MyParams =$request->getParams();
//now you can go ahead with implementing your breadcrumb
}
}