我正在努力Zend_Navigation
使用动态 URL 参数实现面包屑。
简单的场景:想象一个CompanyController
从URLviewAction()
获取id
参数以获取有关特定公司的信息的 a。
URL: example.com/company/view/id/4
Desired breadcrumb: Home > Companies > [ Company name ]
我在网上做了一些研究并提出了以下解决方案:在一个predispatch()
钩子中,我从中获取id
参数$_SERVER['REQUEST_URI']
(我们不能为此使用请求对象,因为调度尚未开始)并从数据库中获取该记录。然后我只需将此页面添加到Zend_Navigation
容器中的根页面。你可以在这篇文章的底部看到它的实现。
我发现这种方法的问题是它不可扩展:
如果每家公司有多个行动怎么办?
除了
view
ing 公司记录,我们可能还想edit
(example.com/company/edit/id/4
) 或对其执行其他操作。当然,我们可以创建一个 switch 语句来检查来自 URL 的操作,但我觉得这是不可扩展的。如果 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]
我们可以很容易地为此设置一条路线。
id
但是现在我们必须从 URL中获取多个。随着 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);
}
}
}
关于这个主题的一些参考资料: