Post on 27-Jul-2020
Magento 2
Web Developer
workflow
Vitalii KorotunArchitect, Magento
Legal DisclaimerCopyright © 2015 Magento, Inc. All Rights Reserved.
Magento®, eBay Enterprise™ and their respective logos are trademarks, service marks,
registered trademarks, or registered service marks of eBay, Inc. or its subsidiaries. Other
trademarks or service marks contained in this presentation are the property of the
respective companies with which they are associated.
This presentation is for informational and discussion purposes only and should not be
construed as a commitment of Magento, Inc. or eBay Enterprise (“eBay Enterprise”) or of
any of their subsidiaries or affiliates. While we attempt to ensure the accuracy,
completeness and adequacy of this presentation, neither Magento, Inc., eBay Enterprise
nor any of their subsidiaries or affiliates are responsible for any errors or will be liable for
the use of, or reliance upon, this presentation or any of the information contained in it.
Unauthorized use, disclosure or dissemination of this information is expressly prohibited.
Magento 2 Theme Overview
Base theme assets
Magento\Catalog
<page>
<body>
<block class=“…“ name=“…">
<arguments>
<argument name=“…" xsi:type="string">…</argument>
<argument name=“…" xsi:type="boolean">…</argument>
</arguments>
</block>
</body>
</page>
Directory structureM1 M2
Theme variables
<view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
… … …
<vars module="Magento_Catalog">
<var name="product_small_image_sidebar_size">100</var>
<var name="product_base_image_size">275</var>
<var name="product_base_image_icon_size">48</var>
<var name="product_list_image_size">166</var>
<var name="product_zoom_image_size">370</var>
<var name="product_image_white_borders">0</var>
… … …
<var name="customer_account_product_review_page:width">285</var>
</vars>
<vars module="Magento_Bundle">
<var name="product_summary_image_size">58</var>
</vars>
… … …
</view> app/design/frontend/Magento/blank/etc/view.xml
<?php echo $this->getVar(product_base_image_size', 'Magento_Catalog'); ?>
somewhere in template
Diversity
Layouts
Layout types
Page Layouts definition file
Page Layouts
Page Configuration Layouts
Generic Layouts
Example of Page Layout
app/code/Magento/Theme/view/base/page_layout/empty.xml:
<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation=“<page_layout.xsd>">
<container name="root">
<container name="after.body.start" as="after.body.start" before="-" label="Page Top"/>
<container name="page.wrapper" as="page_wrapper" htmlTag="div" htmlClass="page-wrapper">
<container name="global.notices" as="global_notices" before="-"/>
<container name="main.content" htmlTag="main" htmlId="maincontent" htmlClass="page-main">
<container name="columns.top" label="Before Main Columns"/>
<container name="columns" htmlTag="div" htmlClass="columns">
<container name="main" label="Main Content Container" htmlTag="div" htmlClass="column main"/>
</container>
</container>
<container name="page.bottom" as="page_bottom" label="Before Page Footer Container" after="main.content"
htmlTag="div" htmlClass="page-bottom"/>
<container name="before.body.end" as="before_body_end" after="-" label="Page Bottom"/>
</container>
</container>
</layout>
Example of Page Configuration
<page layout="admin-1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<html>
<attribute name="html_attribute_name" value="html_attribute_value" />
</html>
<head>
<title>Magento Admin</title>
<meta name="x_ua_compatible" content="IE=edge,chrome=1"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>
<link src="prototype/prototype.js"/>
<css src="mage/calendar.css" />
<script src="requirejs/require.js" />
<script src="jquery/jquery.js" />
</head>
<update handle="adminhtml_system_design_grid_block"/>
<body>
<attribute name="id" value="html-body" />
<referenceContainer name="content">
<block class="Magento\Backend\Block\System\Design" name="adminhtml.system.design.container"/>
</referenceContainer>
...
</body>
</page>
Example of Generic Layout
<layout xsi:noNamespaceSchemaLocation=“/xsd/path/layout_generic.xsd"><update handle="sales_order_create_item_price"/><container name="root">
<block class="Magento\AdvancedCheckout\Block\Adminhtml\Manage\Items" name="checkout.items" template="manage/items.phtml"/>
</container></layout>
Page Composition
Page Composition
Root container
Container 1Container 2 Block 1
Block 2
Update handle 1
Update handle 2
Page Layout
(general skeleton of page)
Page Configuration
(detailed page structure)
Generic Layout
(reusable set of handles)
Templates
Templates
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
?>
<?php /** @var $block \Magento\Catalog\Block\Product\Image */ ?>
<img class="photo image"
<?php echo $block->getAddAttribute(); ?>
src="<?php echo $block->getProductImageView()->getUrl() ?>"
width="<?php echo $block->getProductImageView()->getWidth();?>"
height="<?php echo $block->getProductImageView()->getHeight();?>"
alt="<?php echo $block->stripTags($block->getProductImageView()
->getLabel(), null, true) ?>" />
Template Engines
<type name="Magento\Framework\View\TemplateEngineFactory">
<arguments>
<argument name="engines" xsi:type="array">
<item name="phtml" xsi:type="string">Magento\Framework\View\TemplateEngine\Php</item>
</argument>
</arguments>
</type>
Magento\Framework\View\TemplateEngine\Xhtml?!
JavaScript Framework
RequireJS
define([“compareItems", “priceBox"],
function ($) {
'use strict';
// your business logic here
}
);
RequireJS configuration
var config = {
map: {
'*': {
compareItems: 'Magento_Catalog/js/compare',
compareList: 'Magento_Catalog/js/list',
relatedProducts: 'Magento_Catalog/js/related-products',
upsellProducts: 'Magento_Catalog/js/upsell-products',
productListToolbarForm: 'Magento_Catalog/js/product/list/toolbar',
tierPrice: 'Magento_Catalog/js/tier-price',
catalogGallery: 'Magento_Catalog/js/gallery',
priceBox: 'Magento_Catalog/js/price-box',
priceOptionDate: 'Magento_Catalog/js/price-option-date',
priceOptionFile: 'Magento_Catalog/js/price-option-file',
priceOptions: 'Magento_Catalog/js/price-options',
priceUtils: 'Magento_Catalog/js/price-utils',
catalogAddToCart: 'Magento_Catalog/js/catalog-add-to-cart'
}
}
};
Magento\Catalog\view\requires-config.js
Inline JavaScript
<section class="admin__page-section">…</section>
<script type="text/javascript">
require(['jquery', 'prototype'], function(jQuery){
var submitButtons = $$('.submit-button'), updateButtons = $$('.update-button'), fields = $$('.qty-input');
updateButtons.each(function (elem) { elem.disabled=true; elem.addClassName('disabled');});
for (var i=0;i<fields.length;i++) {
fields[i].observe('change', checkButtonsRelation); fields[i].baseValue = fields[i].value;
}
function checkButtonsRelation() {…}
function submitCreditMemo() {…}
function submitCreditMemoOffline() {…}
var sendEmailCheckbox = $('send_email');
if (sendEmailCheckbox) {
var notifyCustomerCheckbox = $('notify_customer');
var creditmemoCommentText = $('creditmemo_comment_text');
Event.observe(sendEmailCheckbox, 'change', bindSendEmail);
bindSendEmail();
}
function bindSendEmail() {…}
});
</script>
<div data-mage-init= '{"creditMemoForm":{“config”:{}}}'>
…
<div>
require(['jquery', 'prototype'], function (jQuery) {
var submitButtons = $$('.submit-button'),
updateButtons = $$('.update-button'),
fields = $$('.qty-input');
updateButtons.each(function (elem) {
elem.disabled=true; elem.addClassName('disabled');
});
for (var i=0;i<fields.length;i++) {
fields[i].observe('change', checkButtonsRelation);
fields[i].baseValue = fields[i].value;
}
});
Magento/Sales/view/adminhtml/web/js/creditMemoForm.js
M1
template/sales/order/creditmemo/create/items.phtml
Inline JavaScript
<div id="toolbar" data-mage-init='{"toolbarEntry": {}}'>
…
</div>
// somewhere in your custom template
<script type="text/x-magento-init">
{
“#toolbar": {
“toolbarEntry": {
“option”: “value”
},
“otherWidget”: {}
}
}
</script>
Bundling of JavaScript files: configuration<view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
… … …
<vars module="Js_Bundle">
<var name="bundle_size">1MB</var>
</vars>
<exclude>
<item type="file">jquery/jquery-ui-1.9.2.js</item>
<item type="file">jquery/jquery.ba-hashchange.min.js</item>
<item type="file">jquery/jquery.details.js</item>
<item type="file">jquery/jquery.details.min.js</item>
<item type="file">jquery/jquery.hoverIntent.js</item>
<item type="file">jquery/jquery.min.js</item>
<item type="file">mage/captcha.js</item>
<item type="file">mage/dropdown_old.js</item>
… … …
<item type="directory">prototype</item>
<item type="directory">scriptaculous</item>
<item type="directory">mage/requirejs</item>
<item type="directory">mage/adminhtml</item>
<item type="directory">mage/backend</item>
</exclude>
</view> app/design/frontend/Magento/blank/etc/view.xml
CSS
Magento UI Library Documentation
lib/web/css/docs
CSS pre-processors
WEB Developer workflows
Standard: with client-side CSS pre-processor
Basic: with built-in CSS pre-processor
Advanced: with node.js CSS pre-processor
less.js official script
~10 seconds to compile CSS
No actions to re-compile
Client side CSS pre-processor (with less.js)
Oyejorge PHP library
~40 seconds to compile CSS
Manual actions to re-compile
Server side PHP pre-processor (with PHP)
Command line script (lessc)
~7 seconds to compile CSS
Automatic browser refresh on change in LESS
Server side CSS pre-processor (with node.js)
Q&A