Magento平台的关键功能是其模块化。它由许多小的元素(模块)组成,这些元素被设计成既可以单独工作又可以相互连接。当所有部分组合在一起时,平台就像是由许多细胞组成的活生物体,每个细胞都有自己的功能。
为了连接这些组件并管理它们之间的交互,Magento 2使用XML布局和XML页面配置。商店的每个网页都有其自己的XML文件,其中特殊语法描述了结构并标识了在其上显示所需的所有元素。
这些文件中使用的所有元素都分为两种类型:容器和块。根据该标准,容器主要用于XML布局中,而在XML配置中则使用块。它直接取决于各自的功能负荷。
XML布局用于将容器放置在整个页面上,以及设置视图的类型和结构。这是XML模板的示例:
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="columns.top"> <container name="category.view.container" htmlTag="div" htmlClass="category-view" after="-"> <block class="MagentoCatalogBlockCategoryView" name="category.image" template="Magento_Catalog::category/image.phtml"/> <block class="MagentoCatalogBlockCategoryView" name="category.cms" template="Magento_Catalog::category/cms.phtml"/> </container> </referenceContainer> <referenceContainer name="content"> <block class="MagentoCatalogBlockCategoryView" name="category.products" template="Magento_Catalog::category/products.phtml"> <container name="category.product.list.additional" as="additional"/> <block class="MagentoFrameworkViewElementTemplate" name="category.product.type.details.renderers.default" as="default"/> </block> </block> </block> </page>
XML配置将每个块分别分配到容器中,并为每个块分配自己的配置,我们将在下面更详细地介绍。
通常,这两个概念很模糊,可以将布局和配置文件组合到一个文档中。如果将配置参数添加到上述文档中,就会发生这种情况。
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="columns.top"> <container name="category.view.container" htmlTag="div" htmlClass="category-view" after="-"> <block class="MagentoCatalogBlockCategoryView" name="category.image" template="Magento_Catalog::category/image.phtml"/> <block class="MagentoCatalogBlockCategoryView" name="category.description" template="Magento_Catalog::category/description.phtml"/> <block class="MagentoCatalogBlockCategoryView" name="category.cms" template="Magento_Catalog::category/cms.phtml"/> </container> </referenceContainer> <referenceContainer name="content"> <block class="MagentoCatalogBlockCategoryView" name="category.products" template="Magento_Catalog::category/products.phtml"> <block class="MagentoCatalogBlockProductListProduct" name="category.products.list" as="product_list" template="Magento_Catalog::product/list.phtml"> <container name="category.product.list.additional" as="additional" /> <block class="MagentoFrameworkViewElementRendererList" name="category.product.type.details.renderers" as="details.renderers"> <block class="MagentoFrameworkViewElementTemplate" name="category.product.type.details.renderers.default" as="default"/> </block> <block class="MagentoCatalogBlockProductProductListItemContainer" name="category.product.addto" as="addto"> <block class="MagentoCatalogBlockProductProductListItemAddToCompare" name="category.product.addto.compare" as="compare" template="Magento_Catalog::product/list/addto/compare.phtml"/> </block> <block class="MagentoCatalogBlockProductProductListToolbar" name="product_list_toolbar" template="Magento_Catalog::product/list/toolbar.phtml"> <block class="MagentoThemeBlockHtmlPager" name="product_list_toolbar_pager"/> </block> <action method="setToolbarBlockName"> <argument name="name" xsi:type="string">product_list_toolbar</argument> </action> </block> </block> <block class="MagentoCookieBlockRequireCookie" name="require-cookie" template="Magento_Cookie::require_cookie.phtml"> <arguments> <argument name="triggers" xsi:type="array"> <item name="compareProductLink" xsi:type="string">.action.tocompare</item> </argument> </arguments> </block> </referenceContainer> <referenceBlock name="page.main.title"> <arguments> <argument name="id" xsi:type="string">page-title-heading</argument> <argument name="add_base_attribute_aria" xsi:type="string">page-title-heading toolbar-amount</argument> </arguments> <block class="MagentoCatalogBlockCategoryRssLink" name="rss.link" template="Magento_Catalog::category/rss.phtml"/> </referenceBlock> </body> </page>
可以在以下位置找到默认的布局和配置文件:module_name / view / frontend / layout。
布局中的容器可以包含块,并且可以将它们有效地放置在页面中。主要容器包括DOM元素,例如:
- 头
- 标头
- 主要
- 放在一边(左或右)
这些元素将页面布局划分为多个容器,以方便地将我们所需的块排列在它们内部。默认情况下,Magento 2中预先安装了5种类型的页面布局:
- 空(没有容器的页面)
- 1列(用于内容的一个通用容器)
- 2列,带左侧栏(一个带有左侧栏内容的容器)
- 第2列带右栏(一个带有右栏的内容容器)
- 3列(3个可选容器)
图片中突出显示的元素是我们的容器,我们可以在页面中放置所有必要的块。将块放置在内部是<container>元素的主要区别特征,但是值得注意的是,如果必要,<block>元素也可以包含其他元素甚至容器,因此它自动成为其子元素的容器。因此,我们可以假设<container>和<block>元素彼此绝对相同,但是它们的实现和工作方法仍然存在很大差异。此外,我们将考虑主要方法,它们的相似性和特色。
您应该知道,没有人禁止创建自定义布局。您可以通过“ 内容”➜“页面”➜“ Target_Page_Edit”➜“设计”➜“布局”中的管理面板,为特定页面选择网格。
或使用页面的xml布局。为此,我们对<page>容器使用专用的布局属性,在其中我们指定要在页面上使用的网格选项。
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="page.main.title"> <arguments> <argument name="id" xsi:type="string">page-title-heading</argument> <argument name="add_base_attribute_aria" xsi:type="string">page-title-heading toolbar-amount</argument> </arguments> <block class="MagentoCatalogBlockCategoryRssLink" name="rss.link" template="Magento_Catalog::category/rss.phtml"/> </referenceBlock> </body> </page>
您可以看到使用<page>和<body> xml标记来配置我们的页面容器,它们的语法与<html>语法非常相似。与html标记类似,必须关闭所有标记。在我们的情况下,它们可以通过</ page>或</ body>结束标记关闭,也可以是自动关闭的,例如<block name =“ blockName” />标记。
所有元素都可以具有特殊的属性来控制其参数。例如,与容器一样,具有layout =“ Layout_View_Grid”属性,我们在其中指定其1column值。对于容器和块,属性及其值的列表大致相同:
块和容器的通用属性
属性 | 值 | 描述 |
name | 0-9,AZ,az z(-)(_)(。)
*应以字母开头 名称=“当前名称” |
记录用于寻址的唯一名称。 |
before | (-)在当前块中的所有元素之前显示。
(元素名称)在具有指定名称的元素之前显示元素。 ()如果缺少参数,则该元素被视为未定位,并根据当前布局显示。 之前=“-” |
此属性用于将元素放置在页面布局内或容器本身内。 |
after | (-)元素最终显示在当前块或容器中。
(元素名称)在具有指定名称的元素之后显示元素。 ()如果缺少参数,则该元素被视为未定位,并根据当前布局显示。 after =“ target_elemement” |
此属性用于将元素放置在页面布局内或容器本身内。比以前有优势。 |
as | 0-9,AZ,az z(-)(_)(。)
*应以字母开头 名称=“ current_allias” |
指定的名称用于标识父元素中的当前元素。 |
cacheable | 真假
cacheable =“ false” |
启用和禁用具有此属性的元素所在的页面的缓存。创建动态元素,小部件和页面时,这是必需的。 |
*除名称外,所有属性均为可选。
块和容器的属性值及其功能负载相同。但是,容器具有仅对它们唯一的方法:
容器属性
属性 | 值 | 描述 |
output | 0/1或true / false
输出=“ 1” |
指定此属性是为了确定是否渲染元素所在的父容器。默认情况下为假。 |
HtmlTag | HTML 5теги(旁边,主要,div…)
HtmlTag =” div” |
容器内的所有内容都将在指定标签内显示给用户。 |
htmlId | 0-9,AZ,az z(-)(_)(。)
*仅在设置了HtmlTag值时有效。 htmlId =” current_id_name” |
指定包装的html Id选择器已安装。 |
htmlClass | 0-9,AZ,az z(-)(_)(。)
*仅在设置了HtmlTag值时有效。 htmlClass =” current_class_name” |
已安装用于指定包装器的html类选择器。 |
label | 任何值 | 设置了一个任意的容器名称以在浏览器中显示。 |
layout | 页面布局模板名称的值。
布局=“ grid_name” |
用于设置所需的网格图案。 |
*属性是可选的
我们还考虑用于指定块独有属性的参数:
块属性
属性 | 值 | 描述 |
class | 类的路径及其名称:
class =“供应商文件夹名称块类别文件夹类别名称” |
该属性指定负责处理当前模板块信息的类的路径。它用于将新元素指向其处理程序或使用自定义元素覆盖当前程序块处理程序。 |
template | 模板的路径及其名称:
template =“供应商名称:: folder_template / name_template.phtml” |
此属性指定负责渲染当前布局块信息的模板的路径。它用于为其模板指定新元素或使用自定义模板覆盖默认模板。 |
*这些值是可选的
使用说明
所谓的指令是在Magento 2中处理XML文件布局和页面配置的附加工具。这些指令包括<block>和<container>标记本身,以及许多辅助标记。这些是主要的:
referenceBlock和referenceContainer
分别应用于块或容器以使用以下属性传递必要参数的指令:
属性 | 值 | 描述 |
name | 目标Container或Block的名称 | 指示将指令传递到的块或容器的名称。 |
remove | true/false | 删除或取消删除当前块或容器。删除容器时,所有子元素也将被删除。 |
display | true/false | 关闭或取消关闭当前容器或块页面上的呈现。禁用某个项目时,将保留处理该项目及其子元素的进一步可能性。 |
嵌套属性
Magento 2有几个可以插入到内部的属性,语法从容器和块的声明对我们来说是熟悉的,看起来像这样:
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd"> <move element="category.cms" destination="page.wrapper" after="category.view.container"/> </layout>
用于以名称“ category.view.container”重写容器位置的移动指令示例。
移动
它是在页面上定位元素并将其从一个容器迁移到另一个容器的理想工具。
考虑迁移标题栏的示例,该示例在主容器顶部的用户帐户中显示当前选项卡:
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" > <body> <move element="page.main.title" destination="main" before="-"/> </body> </page>
标题块从account-nav块迁移到容器
仅使用布局中的一个命令,就可以轻松更改整个页面的结构,而无需使用样式和使用模板。该指令包括以下属性:
- element —发送指令的目标元素的名称;
- destination —将元素移动到的父元素的名称;
- as —在元素移动后为其设置元素别名的名称;
- after / before —用于定位在目标父元素内。
去掉
使用它,您可以删除静态资源元素,例如与<head>容器中的脚本文件和样式相关联的块。
这是其应用示例:
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd"> <head> <remove src="css/style-m.css"/> </head> </layout>
删除以前连接的CSS映射文件
更新资料
如果当前页面需要从父页面的页面布局中复制所有或大部分容器和块,则建议使用此选项。
该指令在XML布局的开头指定,并与handle属性一起使用,该属性指定父布局的路径和文件名。此方法的功能类似于面向原型的编程中的super()方法,并且执行相同的功能。目标布局文件将递归更新,即顺序更新。
例如,在我们的项目中,需要将滑块与许多页面上的某些信息连接起来。在这种情况下,建议使用连接滑块所需的XML标记创建布局文件,该格式可以采用以下形式:
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="page.wrapper"> <!--rev slider--> <container name="page.index.slider.container" htmlTag="div" htmlClass="page-slider-container" before="main.content"> <block class="NwdthemesRevsliderBlockRevslider"> <arguments> <argument name="alias" xsi:type="string">Midleton</argument> </arguments> </block> </container> </referenceContainer> </body> </page>
带滑块连接的页面布局示例
将来,我们可以将此布局用作继承文件的原型。为此,您需要为每个目标文档中的更新目录指定父布局文件的路径。
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <update handle="{name_of_handle_to_include}"/> <!-- CONTENT --> </body> </page>
递归布局更新
因此,我们将在每个页面上看到我们的滑块,其中将以滑块连接文件为原型指示update指令。
争论
标签用于将参数传递给容器或块。
它具有必需的名称和类型标签。传递的元素的类型传递为type:
- string
- boolean
- object
- number
- null
- array
例如,在用户帐户的前面,我们将标题从标题移到了主容器,现在我们需要为myDashboard标题标签设置一个自定义字符串。为此,我们打开负责myDashboard页面的布局,并借助action指令和setPageTitle方法,将带有页面必要标题的字符串作为参数传递给字符串:
<referenceBlock name="page.main.title"> <action method="setPageTitle"> <argument translate="true" name="title" xsi:type="string">Hello, Customer!</argument> </action> </referenceBlock>
将参数作为页面标题的字符串传递
我们将字符串指定为类型,并将所需的文本作为字符串传递。结果,我们得到了目标:
也可以使用get()方法从当前模板文件访问传输的值。此功能完全符合Magento中的通用性和模块化原则。通过使用它,您可以创建一个通用动态模板,以在我们商店的多个位置应用,就像在将滑块连接到页面的通用布局示例中一样。
例如,让我们考虑创建一个带有按钮渲染的模板,该模板具有客户端上的所有功能。我们将在不同的页面上使用相同的模板,但是根据需求,我们可以将CSS类转移到该模板上,样式表中的某些样式可以附加到该CSS类上,甚至可以在js上实现。这是标记中的样子:
$_className = $block->getCssClass(); <div class="actions-toolbar <?= $_className ?>"> <button class="action primary">Button</button> </div>
将自定义参数传递给模板
要传递一个类,我们声明我们的块,并在template属性中为其指定模板,稍后我们将对其进行考虑。之后,我们只需将任何参数作为参数传递给模板,然后使用<arguments>容器和其中包含的<argument>块传递多个参数。我们将类作为名为css_class的参数传递。为了在模板文件中获取它,您需要借助PHP的知识并编写以下结构:
$_className = $block->getCssClass(); <div class="actions-toolbar <?= $_className ?>"> <button class="action primary">Button</button> </div>
用于获取从模板传递的参数的方法的示例
此外,根据书面逻辑,按钮可以在不同页面上接受不同的修改。在此示例中,它变为白色。
实际上,这是使用此功能的最简单示例,这是学习其工作原理所必需的。通过使用传递参数的方法,您可以做很多有用的事情,包括传递将决定控制器处理模板的参数。
可以有任何名称的参数,并且不仅可以传递字符串,而且可以传递6种基本数据类型,如前所述。为了获得模板中的属性,该函数采用以下形式:
getCssClass();
以“ css_class”形式在xml中传递的name参数采用CamelCase形式,看起来像“СssClass”。此方法类似于使用数据属性在JavaScript中传递参数的方法。
因此,Magento 2有大量工具可用于管理页面布局,并使更改页面配置并将其调整为必要的参数变得更加容易。掌握了使用它们的原理后,Magento 2开发人员可以更快更轻松地自定义用户界面和统一的代码结构,从而使其进一步的支持和扩展不仅为他们自己,而且为后续开发人员带来乐趣。