Я чувствую, что изменение маршрутизатора приложения - совершенно неправильный подход. Это грязно и может быть легко сломано, если другой модуль переопределит его для аналогичной цели. Чистый путь с перезаписью URL.
Вы хотите, чтобы оно было изменяемым, поэтому вы не можете использовать фиксированное переписывание на основе XML . Вместо этого давайте посмотрим на встроенную систему перезаписи.
Сначала в файле etc / config.xml вашего модуля установите обычный контроллер.
<frontend>
<routers>
<MyCustomModule>
<use>standard</use>
<args>
<module>Example_MyCustomModule</module>
<frontName>customlist</frontName>
</args>
</MyCustomModule>
</routers>
</frontend>
Здесь используемое имя customlist
, которое всегда будет работать и не должно конфликтовать с любым другим именем, переписанное имя должно быть в дополнение к этому. Теперь всякий раз, когда вы генерируете URL (возможно, в виде вспомогательной функции), вы делаете это для этого явно фиксированного имени.
$url = Mage::getUrl('customlist', array(
'id' => $id, // 'id' will get used in the "target path" later
'_use_rewrites' => true
));
Обратите внимание, что идентификатор переменной ($id
) передается в функцию getUrl
, а не просто добавляется к ее результату. Если функция возвращает URL с запросом (&
) или фрагментом (#
), идентификатор мог быть добавлен в неправильную часть.
Следующим шагом является создание записей перезаписи для каждой возможной комбинации идентификатора и store . Вероятно, у вас есть конечное количество списков, так что это возможно, возможно, идентификаторы являются специфическими для хранилищ, поэтому их нужно определять только один раз для каждого. Либо переберите все свои списки в сценарии установки , либо попросите каждый список создавать новые записи при сохранении.
$path = Mage::getStoreConfig('custom/config/identifier', $storeId);
// Change 'custom/config/identifier' to match the path used in system.xml
$rewrite = Mage::getModel('core/url_rewrite')
->loadByIdPath('customlist/'.$store.'/'.$id);
if ($rewrite->getId()) {
// A rewrite already exists, you might want to skip creating another
continue;
}
Mage::getModel('core/url_rewrite')
->setStoreId($storeId)
->setIsSystem(true) // set to false to allow admin to edit directly
->setOptions('RP') // Redirect Permanent 301
->setIdPath('customlist/'$storeId.'/'.$id) // should never change
->setTargetPath('customlist/index/index/id/'.$id) // what gets used
->setRequestPath($path.'/'.$id) // the path used in the browser
->save();
Так что теперь, если администратор устанавливает путь URL-адреса «foo / bar» и запрашивает страницу «www.mydomain.com/foo/bar/3», он будет переписан в «customlist / index / index / id /» 3 ", и будет вызван метод Example_MyCustomModule_IndexController::indexAction()
. Файл, содержащий это, будет, конечно, app / code / local / Example / MyCustomModule / controllers / IndexController.php , и там будет получено значение 3
:
public function indexAction()
{
$id = $this->getRequest()->getParam('id'); // 'id' was specified in getUrl()
// use $id here...
}
Это должно сработать, но что если список будет удален? Переписанные должны быть обновлены для каждого магазина. В моделях есть метод _beforeDelete
, переопределите его для объектов списка.
protected function _beforeDelete()
{
Mage::getModel('core/url_rewrite')
->loadByIdPath('customlist/'.$storeId.'/'.$this->getId())
->delete();
return parent::_beforeDelete();
}
Аналогичным образом их необходимо обновить, чтобы они соответствовали изменениям в конфигурации.
и т.д. / System.Xml
<identifier translate="label">
<label>SELF URL Identifier</label>
<frontend_type>text</frontend_type>
<backend_model>myCustomModule/config_identifier</backend_model>
...
</identifier>
Модель / Config / Identifier.php
class Example_MyCustomModule_Model_Config_Identifier
extends Mage_Core_Model_Config_Data
{
protected function _afterSave()
{
if ($this->isValueChanged()) {
$path = $this->getValue();
// for each $store and $id combination...
Mage::getModel('core/url_rewrite')
->loadByIdPath('customlist/'.$store.'/'.$id)
->setRequestPath($path.'/'.$id)
->save();
}
}
}