今天,咱們要介紹的幾個Magento的路由系統的高級功能,並討論一些看似急性銳邊的歷史。雖然全部在這篇文章中提供的技術可能不是最好的方式來實現本身的目標,做爲工做的Magento開發者你須要知道他們是可能的,而其餘開發者(包括Magento的核心工程團隊)可能已經使用他們。php
本文假定您有較好的Magento 2模塊經驗,這可能不適合初學者。若是這是你,用評論來問你的問題或指向你的堆疊交換的問題。html
做爲一個PHP程序員,當你須要建立在Magento的URL,可使用getUrl塊或URL模型對象的方法。前端
Mage::getUrl('foo/baz/bar'); $urlModel->getUrl('foo/baz/bar'); $this->getUrl('foo/baz/bar');
這是Magento的1和2的Magento真正在Magento 2你沒有進入全球Mage::getUrl的方法,因此你須要注入要經過特定的URL模式自動構造函數依賴注入。網址模型容許PHP程序員治療的URL做爲一個簡單的操做字符串,而後讓核心系統構建代碼的最終呈現的網址。若是你只作過前端的工做,這彷佛有點小題大作,但若是URL結構須要在未來改變或適應多種環境是有利的。大多數Web編程框架認爲這是一個必要的功能。程序員
咱們不會太深刻探究網址模型今天-咱們都感興趣的是操做字符串,這些URL方法接受。乍一看,你可能會以爲foo/baz/baz結構直接映射到frontName/controllerName/actionName一個URL的Magento的結構。你幾乎是正確的。實際的結構。routeId/controllerName/actionName編程
當你設置一個routes.xml爲你的模塊文件,可使用XML結構看起來像這樣app
<!-- File: app/code/Package/Module/etc/[area]/routes.xml --> <route id="routerId" frontName="urlFrontName"> <module name="Package_Module" /> </route>
也就是說,你設置一個<route/>節點與id和frontName屬性。該id標識惟一路由節點在Magento的系統,並frontName定義了你的URL的第一部分。框架
當Magento的產生從操做字符串的URL同樣foo/baz/bar,它採用了第一段查找一個<route/>在合併後的XML樹節點,而後使用該路由節點的frontName做爲第一個URL段。frontend
這不是明顯的事情,你能夠在Magento的多年而不自知地發展。這是由於大多數模塊使用的路線ID和相同的名字前面。mvvm
例如,您能夠在中看到這個catalog模塊函數
<!-- File: app/code/Magento/Catalog/etc/frontend/routes.xml --> <route id="catalog" frontName="catalog"> <module name="Magento_Catalog" /> </route>
不管是id和frontName屬性catalog。該公約還存在在Magento 1。
<!-- File: app/code/core/Mage/Catalog/etc/catalog.xml --> <frontend> <routers> <catalog> <use>standard</use> <args> <module>Mage_Catalog</module> <frontName>catalog</frontName> </args> </catalog> </routers> <!-- ... --> </frontend>
以上是Magento的1的目錄路由器配置。單個<catalog/>節點下<routers/>配置了一個frontName名爲catalog。在Magento 2,該節點下<routers/>已打開的<module/>,與id替換Magento的1個節點name屬性。(即<catalog/>變<module id="catalog"/>。
這種約定能夠很容易地看一個URL操做字符串,並得到最終的URL將是什麼樣子一個粗略的想法。然而,有一個巨大的例外:Magento的管理網址。
在Magento 1,主要管理路徑是與如下配置(在Magento的核心)
<!-- File: app/code/core/Mage/Adminhtml/etc/config.xml --> <admin> <routers> <adminhtml> <use>admin</use> <args> <module>Mage_Adminhtml</module> <frontName>admin</frontName> </args> </adminhtml> </routers> </admin>
也就是說,在單個節點<routers/>命名<adminhtml/>創建一個frontName命名admin。這延續到Magento的2。
File: vendor/magento/module-backend/etc/adminhtml/routes.xml <route id="adminhtml" frontName="admin"> <module name="Magento_Backend" /> </route>
這意味着,在Magento 1,操做字符串同樣adminhtml/foo/bar會翻譯成看起來像一個完整的URL http://example.magento.com/ad...。也就是說,第一網址段,和前面的名稱,將admin代替adminhtml。
這是一個奇怪的例外,Magento的匹配前面的名字和路由器ID的通常慣例,並有可能少了刻意的設計決定比它的Magento 1發射一個半完成的概念區(adminhtml,frontend)實現的。
不管如何,你仍然能夠找到在Magento 2的代碼庫這種非決定的證據。
在Magento 1,adminhtml路由器ID是什麼保證了管理的URL開始以字符串的一部分/admin,而Magento的區域被設置爲adminhtml。
然而,在Magento 2,每個在路線設置etc/adminhtml/routes.xml文件將自動與該字符串前綴admin。這就是讓咱們用咱們本身的frontName這些adminhtml/routes.xml文件。
這最終有上仍然使用舊的管理網址,一個奇怪的反作用adminhtml路由器ID。考慮URL重寫模塊
<!-- File: vendor/magento/module-url-rewrite/etc/adminhtml/menu.xml --> <add id="Magento_UrlRewrite::urlrewrite" title="URL Rewrites" module="Magento_UrlRewrite" sortOrder="20" parent="Magento_Backend::marketing_seo" action="adminhtml/url_rewrite/index" resource="Magento_UrlRewrite::urlrewrite" />
以上menu.xml文件文件使用的操做字符串adminhtml/url_rewrite/index。Magento的結束產生這樣的網址
http://magento.example.com/ad...
這是與開頭的URL /admin/admin。這是2管理員字符串。第一個來自/admin該Magento的預先考慮到URL段每個管理URL。第二個使用來自Magento的adminhtml路線ID查找一個frontName屬性。
這彷佛是傳統的URL自動轉換成菜單項,雖然當我問起這個在一月份Magento的建築師,他們最初對這個問題感到困惑,而後說這兩種管理URL格式(adminhtml路徑ID /前名稱和自定義路徑ID /前名)是有效的,但自定義路由標識和前面的名字被優先考慮。
因爲缺少明確的初始規則,缺少核心團隊的堅持這些後來下旨規則,工做Magento的開發商將要熟悉這兩個URL格式,並準備根據須要調試。
若是你尚未挖出過深刻Magento的核心代碼,你可能想知道
等等-我覺得每一個Magento的模塊聲稱特定的前名字-如何能夠在多個模塊,聲稱admin經過前面的名字adminhtml路由器?
這給咱們帶來了從1 Magento的另外一個特色,使得該跳轉到Magento的2:路由共享。
Magento的「1個模塊,1名前」的政策能夠追溯到到Zend Framework的早期路由/ MVC體系。Magento的1,而框架中的全部本身的,基於大量的核心Zend框架類的工做,而這個「1模塊,1名前」功能湊湊熱鬧來了。模塊開發者很快發現瞭如何限制,這是和Magento的推出了多個模塊聲稱一個特定的前名的能力。
若是這沒有意義
當Magento的1被創造了,你只能建立控制器文件開頭的URL /foo/...在單一模塊中
Magento的推出了多個模塊具備啓動使用URL控制文件的能力/foo/在Magento 1.3
的能力,堅持在Magento 2,和語法已大大簡化。例如,若是你想回到第一個模塊在這個系列(Pulsestorm_HelloWorldMVVM)和添加前端URL端點catalog/foo/bar,全部你須要作的就是添加如下配置
<!-- File: app/code/Pulsestorm/HelloWorldMVVM/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"> <router id="standard"> <route id="hello_mvvm" frontName="hello_mvvm"> <module name="Pulsestorm_HelloWorldMVVM"/> </route> <!-- START: new configuration --> <route id="catalog"> <module name="Pulsestorm_HelloWorldMVVM" after="Magento_Catalog"/> </route> <!-- END: new configuration --> </router> </config>
和如下控制器文件。
File: app/code/Pulsestorm/HelloWorldMVVM/Controller/Foo/Bar.php <?php namespace Pulsestorm\HelloWorldMVVM\Controller\Foo; class Bar extends \Magento\Framework\App\Action\Action { public function execute() { var_dump("Proof of life"); } }
與上面的地方,你如今就有了控制器文件的第二個模塊catalog前面的名稱,Magento的將使用您的控制器時,您加載catalog/foo/barURI。
不像Magento的1,對於這種配置是幾乎相同的設置路由爲單個模塊
<!-- File: app/code/Pulsestorm/HelloWorldMVVM/etc/frontend/routes.xml--> <route id="catalog"> <module name="Pulsestorm_HelloWorldMVVM" after="Magento_Catalog"/> </route>
您不要配置frontName的屬性<route/>標籤
你須要(或者強烈建議)用before或after標記控制命令的Magento將檢查比賽
當你使用上面的配置,你告訴Magento的
嘿,你知道,<route/>有一個標籤id的catalog?我要你在合併額外的 <module/>節點。
當遇到Magento的多個<module/>在其全球配置中的節點,它會檢查每一個模塊的控制器匹配,直到找到一個。使用after標籤上方保證Magento的檢查咱們的模塊後的Magento_Catalog模塊。不這樣作,有可能爲咱們意外地建立替換芯控制器在控制器文件vendor/magento/module-catalog/Controller。
須要注意的是,你要尋找的是很重要的<route/> id屬性,而不是frontName在這裏屬性。例如,當一個模塊要添加到admin前面的名字,一個Magento的芯顯影劑將
標識首次添加模塊 frontName="admin"
標識<module/>的<route/>ID
使用該ID在本身的模塊
確保正確before或after標籤就位
因此,第一步-最初添加的模塊的admin前面名稱是Magento_Backend
#File: vendor/magento/module-backend/etc/adminhtml/routes.xml <route id="adminhtml" frontName="admin"> <module name="Magento_Backend" /> </route>
這個<route/>節點id是adminhtml。所以,使用的其餘Magento的模塊admin前面的名字配置本身與id="adminhtml"。
<!-- File: vendor/magento/module-variable/etc/adminhtml/routes.xml --> <route id="adminhtml"> <module name="Magento_Variable" before="Magento_Backend" /> </route> <!-- File: vendor/magento/module-widget/etc/adminhtml/routes.xml --> <route id="adminhtml"> <module name="Magento_Widget" before="Magento_Backend" /> </route>
咱們從先進的路由移動以前,有一些最後要提。偶爾你會看到這是一個操做字符串缺乏了第二或第三段。
<!-- File: vendor/magento/module-tax/etc/adminhtml/menu.xml --> <add id="Magento_Tax::sales_tax_rules" title="Tax Rules" module="Magento_Tax" sortOrder="10" parent="Magento_Tax::sales_tax" action="tax/rule" resource="Magento_Tax::manage_tax"/>
當Magento的遇到一個動做字符串以丟失的數據段,它將替代字符串的索引。換言之,做用串tax/rule上面使用是功能等效的做用串tax/rule/index。
此外,在PHP代碼,您偶爾可能會看到*一個URL操做字符串的字符。
$this->getUrl('*/*/*')
這些星號將被轉換爲當前的前名,控制器名稱或動做名稱。換言之,他們建立上下文相關的URL,而且在乎味着在多個模塊中使用鹼UI類是有用的。