首先,Magento URL 倾向于将字段名称放在值之前。所以我希望长 URL 实际上看起来像这样:
www.mysite.com/profile/index/index/name/mayank
这将允许在控制器中进行整洁的检索,
public function indexAction() {
$name = $this->getRequest()->get('name');
}
“无论如何,我们是否可以像'如果找不到路由,那么 magento 会调用我们模块的控制器......?”
我有wrestled with routers before,在我看来,除非绝对必要,否则它们是不必要的。当可能的 URL 数量有限时,提前save a rewrite 会更容易。执行此操作的最佳时间是用户名更改时。
要监听更改,请将其添加到模块的config.xml:
<global>
<events>
<customer_save_after>
<observers>
<mayank_profile>
<type>singleton</type>
<class>mayank_profile/observer</class>
<method>customerSaveAfter</method>
</mayank_profile>
</observers>
</customer_save_after>
<customer_delete_after>
<observers>
<mayank_profile>
<type>singleton</type>
<class>mayank_profile/observer</class>
<method>customerDeleteAfter</method>
</mayank_profile>
</observers>
</customer_delete_after>
</events>
</global>
在模块的Model 文件夹中创建Observer.php:
class Mayank_Profile_Model_Observer {
public function customerSaveAfter(Varien_Event_Observer $observer) {
$customer = $observer->getCustomer();
// username is not a standard attribute, hopefully you have created it
if ($customer->dataHasChangedFor('username')) {
$this->remove($customer->getOrigData('username'));
$this->add($customer->getData('username'));
}
}
public function customerDeleteAfter(Varien_Event_Observer $observer) {
$customer = $observer->getCustomer();
$this->remove($customer->getOrigData('username'));
}
protected function remove($username) {
// this does nothing if rewrite doesn't exist
Mage::getModel('core/url_rewrite')
->loadByIdPath('profile/'.$username);
->delete();
}
protected function add($username) {
if ($this->isValidUsername($username)) {
$storeId = Mage::app()->getDefaultStoreView()->getId();
Mage::getModel('core/url_rewrite')
->setIsSystem(0)
->setStoreId($storeId)
// IdPath is used by remove() function
->setIdPath('profile/'.$username)
// TargetPath is your controller/action
->setTargetPath('profile/index/index/name/'.$username)
// RequestPath is what the browser sees
->setRequestPath($username)
->save();
}
}
protected function isValidUsername($username) {
// feel free to add more checks here
// start with existing rewrites
$rewrite = Mage::getModel('core/url_rewrite')
->loadByRequestPath($username);
if (!$rewrite->isObjectNew()) {
return false;
}
// scan known frontNames
$frontNames = Mage::getConfig()->getXPath('*/routers/*/args/frontName');
foreach ($frontNames as $name) {
if ($username == (string) $name) {
return false;
}
}
return true;
}
}
这是一项相当多的工作,但这里的优点是以下代码正确查找之前保存为“RequestPath”的路径:
echo Mage::getUrl('profile', array(
'name' => $username,
'_use_rewrite' => true
));
这是一种更简单的方法,仅适用于不能与其他模块冲突的 URL。将此添加到您的config.xml:
<global>
<rewrite>
<mayank_profile>
<from><![CDATA[#^/profile/#]]></from>
<to><![CDATA[/profile/index/index/name/]]></to>
<complete>1</complete>
</mayank_profile>
</rewrite>
</global>
在输出 URL 时,您需要自己连接路径。例如
echo Mage::getUrl('', array(
// Use _direct here to avoid a trailing solidus
'_direct' => 'profile/' . $username
));