如果您想阅读完整的教程请查看[Magento2模块开发中文教程索引]
(Magento2模块开发中文教程索引).
在本文中,我们将讨论Magento 2非常重要的一个部分,路由。路由将定义模块的名称,我们可以在url中使用该模块来查找模块并执行控制器操作。
##Magento 2 URL请求流
在Magento,URL格式看起来会是这样的:
在该url中,您将看到用于查找模块的 front_name,路由为每个模块定义这个名称。我们将会看到更多的细节。
当你向Magento2发送请求时,它会跟随这个流程来查找:
controller/action: index.php → HTTP app → FrontController → Routing → Controller processing → etc
FrontController 将在Http类中调用,该路由请求将找到 **“controller/action”**进行匹配。
文件:
vendor/magento/framework/App/FrontController.php
内容:
public function dispatch(RequestInterface $request)
{
\Magento\Framework\Profiler::start('routers_match');
$routingCycleCounter = 0;
$result = null;
while (!$request->isDispatched() && $routingCycleCounter++ < 100) {
/** @var \Magento\Framework\App\RouterInterface $router */
foreach ($this->_routerList as $router) {
try {
$actionInstance = $router->match($request);
if ($actionInstance) {
$request->setDispatched(true);
$this->response->setNoCacheHeaders();
if ($actionInstance instanceof \Magento\Framework\App\Action\AbstractAction) {
$result = $actionInstance->dispatch($request);
} else {
$result = $actionInstance->execute();
}
break;
}
} catch (\Magento\Framework\Exception\NotFoundException $e) {
$request->initForward();
$request->setActionName('noroute');
$request->setDispatched(false);
break;
}
}
}
\Magento\Framework\Profiler::stop('routers_match');
if ($routingCycleCounter > 100) {
throw new \LogicException('Front controller reached 100 router match iterations');
}
return $result;
}
正如您在这个 **dispatch()**方法中看到的,路由器列表将会被循环,以找到符合这个请求的匹配项。如果它找到该请求的控制器操作,将调用并执行该操作。
##在前台或者后台创建自定义路由
在这一部分中,我们将使用一个简单的Magentochina_HelloWorld模块。请依照前一篇文章了解如何在Magento 2中创建和注册一个模块。
我们将会学会如何创建前端路由、管理路由以及如何使用路由来重写控制器。
###前台路由
要注册一个前台路由,我们要首先创建一个 routes.xml文件
app/code/Mageplaza/HelloWorld/etc/frontend/routes.xml
内容:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<!--Use router 'standard' for frontend route-->
<router id="standard">
<!--Define a custom route with id and frontName-->
<route id="example" frontName="example">
<!--The module which this route match to-->
<module name="Magentochina_HelloWorld" />
</route>
</router>
</config>
请查看代码,您将看到注册前台路由非常简单。您必须使用前台的标准路由。这路由将有一个子标签定义它的模块和两个属性:
- id属性是唯一标识字符串,它将识别这个路由。您将使用此字符串来声明此模块操作的layout handle
- frontName属性也是唯一标识字符串,它将显示在url请求中。例如,如果你声明一条这样的路由:
<route id="exampleid" frontName="examplefront">
该模块的url应该是:
这个action的布局句柄( layout handle )是:exampleid_controller_action.xml于这个路由,所以你必须在该文件夹中创建action类: {module_path}/Controller/Controller/Action.php
###后台路由
后台路由与前台路由相同,但您必须在带有路由器id的adminhtml文件夹中声明它。
文件:
app/code/Magentochina/HelloWorld/etc/adminhtml/routes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<!--Use router 'standard' for frontend route-->
<router id="admin">
<!--Define a custom route with id and frontName-->
<route id="example" frontName="example">
<!--The module which this route match to-->
<module name="Magentochina_HelloWorld"/>
</route>
</router>
</config>
后台页面的url与前台页面的结构相同,但是需要在 route_frontName之前添加 admin_area名称以识别这是一个后台路由。例如,后台cms页面的url:
后台页面的控制器action将添加到Controller/Adminhtml文件夹中.例如上面的url:
{module_path}/Controller/Adminhtml/Blog/Index.php
###使用路由重写控制器
在这小节中,我们将看到如何用路由器重写控制器。在上面的小节中,您可以看到每个路由都有一个id属性来标识。那么,如果我们用相同的id属性来定义两条路由会发生什么呢?
答案是在两个模块中都将发现控制器action。Magento系统提供了在配置模块排序 before/after 的属性,它定义了首先要找到的模块控制器。这是控制器重写的逻辑。
例如,如果我们想重写 customer/account/login,我们将在路由中定义更多的 route.xml ,像是这样的:
文件:
app/code/Magentochina/HelloWorld/etc/frontend/routes.xml
内容:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<!--使用'standard'于前台路由-->
<router id="standard">
<!--定义自定义路由的ID和frontName-->
<route id="example" frontName="example">
<!--路由匹配的模块-->
<module name="Magentochina_HelloWorld" />
</route>
<route id="customer">
<module name="Magentochina_HelloWorld" before="Magento_Customer" />
</route>
</router>
</config>
还有控制器文件:
app/code/Magnetochina/HelloWorld/Controller/Account/Login.php
因此,frontController将首先在我们的模块中找到登录action,如果找到它,它将运行. Magento_Customer的登录action将不会运行。我们成功地重写了一个控制器。
您还可以使用这个程序来拥有第二个模块,该模块与另一个模块具有相同的路由器。例如,在上面声明的情况下,您可以为控制器action使用路由’ customer '。如果你有控制器 **‘blog’**和 ‘Index.php’。你可以使用这个url:
####本教程翻译自mageplaza,如果你想查看完整的教程,请点击这里.译者:西帅
####如果觉得本站翻译得内容对您有帮助,又没有时间帮助翻译回馈社区.请打赏我们,您的支持是我们的动力: