Important: Do not override the vendor/magento layout. Just extend them
Create a container
<container name="product.info.form.content" as="product_info_form_content">
...
</container>
Create a block
<block class="Magento\Framework\View\Element\Template" name="test.ui.component" template="Magento_Theme::block.phtml">
...
</block>
Reference Container
<referenceContainer name="content">
...
</referenceContainer>
Reference Block
<referenceBlock name="report.bugs"/>
<move element="product.info.stock.sku" destination="product.info.price" after="product.price.final"/>
<referenceBlock name="breadcrumbs" remove="true" />
layout.xml
Note: In this example I will use the Magento_Theme
module
default.xml
.<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="report.bugs" remove="true" />
</body>
</page>
The purpose of page layouts is to create a structured, common set of layout instructions to render pages. Most pages on a website can be categorized as fitting into a 1, 2, or 3-column container system. These page layouts can be selected in the admin panel to provide a specific layout per page.
We Can Create a sample file in here
../[VendorName]/[ThemeName]/Magento_Catalog/page_layout/2columns-left.xml
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd">
<update handle="1column"/>
<referenceContainer name="columns">
<container name="div.sidebar.main" htmlTag="div" htmlClass="sidebar sidebar-main" after="main">
<container name="sidebar.main" as="sidebar_main" label="Sidebar Main"/>
</container>
<container name="div.sidebar.additional" htmlTag="div" htmlClass="sidebar sidebar-additional" after="div.sidebar.main">
<container name="sidebar.additional" as="sidebar_additional" label="Sidebar Additional"/>
</container>
</referenceContainer>
</layout>
<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<css src="mage/gallery/gallery.css"/>
</head>
<!-- Extends the layout -->
<update handle="catalog_product_opengraph" />
<update handle="page_calendar"/>
<body>
</body>
</page>
The specified handle is “included” and executed recursively.
Note:
page_layout
is the layout of the whole pagelayout
is the layout of a certain section of a pagedefault.xml
and default_head_blocks.xml
default.xml
hold the page containera, blocks, arguments, template, and so on
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block class="Magento\Framework\View\Element\Template" name="test.ui.component" template="Magento_Theme::block.phtml">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="test-ui-component" xsi:type="array">
<item name="component" xsi:type="string">Magento_Theme/js/view/sample-component</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Magento_Theme/sample-ui-template</item>
</item>
</item>
</item>
</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
default_head_blocks.xml
holds the dependencies
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<!-- Add local resources -->
<css src="css/my-styles.css"/>
<!-- The following two ways to add local JavaScript files are equal -->
<script src="Magento_Theme::js/sample1.js"/>
<script src="http://127.0.0.1:35729/livereload.js" src_type="url"></script>
<link src="js/sample.js"/>
<!-- Add external resources -->
<link rel="stylesheet" type="text/css" src="http://fonts.googleapis.com/css?family=Montserrat" src_type="url" />
</head>
</page>
layout.xml
files<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block class="Magento\Framework\View\Element\Template" name="test.ui.component" template="Magento_Theme::block.phtml">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="test-ui-component" xsi:type="array">
<item name="component" xsi:type="string">Magento_Theme/js/view/sample-component</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Magento_Theme/sample-ui-template</item>
</item>
</item>
</item>
</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
Under ../[VendorName]/[ThemeName]/Magento_Catalog/templates create a file called test-block.phtml
<?php
/**
* @var \Ewave\MagentoCatalog\Block\TestBlock $block
*/
?>
<div class="block custom-block">
<h4 class="block-title">Good day!</h4>
</div>
<div class="block custom-block">
<h4 class="block-title">Test JS translation</h4>
<p id="translate-js"></p>
</div>
<h4 class="block-title"><?= /* @escapeNotVerified */ __('translated_title') ?></h4>
<h6>(1)object</h6>
<p data-mage-init='{"mystyle": {"color": "yellow"}}'>I am color Yellow <code>data-mage-init</code></p>
<h6>(2)function</h6>
<p data-mage-init='{"mystyle2": {"background": "blue"}}'>I have a blue background <code>data-mage-init</code></p>
<p><?= $block->getData('display_text') ?></p>
<p><?= $block->getDisplayText() ?></p>
Under ../[VendorName]/[ThemeName]/Magento_Checkout/web/template/minicart create a file similar to the vendor file named content.html
and move parts.
<!-- I just moved this part somewhere in this file -->
<!-- ... -->
<if args="getCartParam('summary_count')">
<strong class="subtitle" translate="'Recently added item(s)'"/>
<div data-action="scroll" class="minicart-items-wrapper">
<ol id="mini-cart" class="minicart-items" data-bind="foreach: { data: getCartItems(), as: 'item' }">
<each args="$parent.getRegion($parent.getItemRenderer(item.product_type))"
render="{name: getTemplate(), data: item, afterRender: function() {$parents[1].initSidebar()}}"
/>
</ol>
</div>
</if>
<!-- ... -->
Under ../[VendorName]/[ThemeName]/web/css/source we can create a file called _extend.less
And we can also create another directory in ../source like /extend and create the file you wish to extend like _block.less
and import it to the _extend.less file
@import 'extend/_block.less';
Note: You can also add specific _extend.less
files in specific modules
<h2>accordion</h2>
<div id="accordion" data-mage-init='{ "accordion": {} }'>
<div data-role="collapsible">
<div data-role="trigger">
<span>Title 1</span>
</div>
</div>
<div data-role="content">Content 1</div>
<div data-role="collapsible">
<div data-role="trigger">
<span>Title 2</span>
</div>
</div>
<div data-role="content">Content 2</div>
<div data-role="collapsible">
<div data-role="trigger">
<span>Title 3</span>
</div>
</div>
<div data-role="content">Content 3</div>
</div>
<!-- init method 1 : data-mage-init='{ "accordion": {} }' -->
<!-- init method 2 -->
<script>
require([
'jquery',
'accordion'], function ($) {
$("#accordion").accordion();
});
</script>
<!-- <script type="text/x-magento-init">
{
"#accordion": {
"accordion": {}
}
}
</script> -->
note: A common method to extend a widget is adding a mixin
var config = {
config: {
mixins: {
"Magento_Catalog/js/mystyle": {
"Magento_Catalog/js/mystyle-mixins": true
}
}
}
}
requirejs-config.js
var config = {
map: {
"*": {
mystyle: "Magento_Catalog/js/mystyle",
mystyle2: "Magento_Catalog/js/mystyle2",
}
}
}
By using a object
<h6>(1)object</h6>
<p data-mage-init='{"mystyle": {"color": "yellow"}}'>I am color Yellow <code>data-mage-init</code></p>
define(['jquery'], function ($) {
'use strict';
return {
'mystyle': function (config, element) {
$(element).css('color', config.color);
}
};
});
By using a function
<h6>(2)function</h6>
<p data-mage-init='{"mystyle2": {"background": "blue"}}'>I have a blue background <code>data-mage-init</code></p>
define(['jquery'], function ($){
'use strict';
return function(config, element) {
$(element).css('background', config.background);
}
});
By using this __('translated_title')
<h4 class="block-title"><?= /* @escapeNotVerified */ __('translated_title') ?></h4>
en_US.csv
file under ../[VendorName]/[ThemeName]/i18n
"translated_title","I am translated title"
layout
filesBy adding translate="true"
<referenceBlock name="ThemeTest.test-block">
<arguments>
<argument name="display_text" xsi:type="string" translate="true">Hello</argument>
</arguments>
</referenceBlock>
en_US.csv
file under ../[VendorName]/[ThemeName]/i18n
"Hello", "kamusta"
Create a file under ../<Module_Name>/web/js
In this example I create a file named mytranslation.js
require([
'jquery',
'mage/translate'
], function ($, __) {
setTimeout(() => {
$('#translate-js').text('script-translate: ' + $.mage.__('translate_js'));
}, 1000);
});
"translate_js","Translated through javascript"
Create a file under ../[VendorName]/[ThemeName]/<Module_Name>/web/js/view
In this example, I create a file named plain-view-model.js
define([], function() {
'use strict';
return function (config) {
return {
title: 'This text is from plain-view-model.js',
config: config
}
}
});
We can extend our UI Component by using <script type="text/x-magento-init">
<h2>Plain View Model</h2>
<div class="example" data-bind="scope: 'plainViewModel'">
<h5 data-bind="text: title"></h5>
<h5 data-bind="text: config.label"></h5>
<pre data-bind="text: JSON.stringify(config, null, 2)"></pre>
</div>
<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"plainViewModel": {
"component": "Magento_Theme/js/view/plain-view-model",
"label": "This is the label"
}
}
}
}
}
</script>