max pronko - best practices for checkout customisation in magento 2

24
© 2017 Pronko Consulting

Upload: meet-magento-italy

Post on 06-Apr-2017

67 views

Category:

Presentations & Public Speaking


5 download

TRANSCRIPT

Page 1: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting

Page 2: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 2

Agenda

• Checkout Overview • How to extend Checkout

Page 3: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 3

Checkout Overview

Page 4: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 4

Checkout Overview

• Single Page Application (SPA) • Checkout API • Based on UI Components • No inline JavaScript • Independent Application

Page 5: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 5

Single Page Application (SPA)

True

Client Server

Initial Request

HTML

AJAX

JSONREST API

UI Component

Page 6: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 6

Libraries used in Checkout

Ui Components

Page 7: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 7

var isLoggedIn = ko.observable(false);isLoggedIn.subscribe( function(newValue) { console.log(newValue ? 'In' : 'Out') } );

<div data-bind=“ visible: isLoggedIn,text: getTitle() ”></div>

Observable Declarative Binding

Page 8: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 8

Checkout Page

StepsAuthentication

Shipping Address

Messages Estimation

Shipping MethodsPayment Methods

Login

<item name="elementTmpl" xsi:type="string">ui/form/element/input</item> </item> </item> </item> <item name="components" xsi:type="array"> <item name="checkout" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/onepage</item> </item> <item name="children" xsi:type="array"> <item name="errors" xsi:type="array"> <item name="sortOrder" xsi:type="string">0</item> <item name="component" xsi:type="string">Magento_Ui/js/view/messages</item> <item name="displayArea" xsi:type="string">messages</item> </item> <item name="authentication" xsi:type="array"> <item name="sortOrder" xsi:type="string">1</item> <item name="component" xsi:type="string">Magento_Checkout/js/view/authentication</item> <item name="displayArea" xsi:type="string">authentication</item> <item name="children" xsi:type="array"> <!--Additional authentication fields--> <item name="errors" xsi:type="array"> <item name="sortOrder" xsi:type="string">0</item> <item name="component" xsi:type="string">Magento_Checkout/js/view/authentication-messages</item> <item name="displayArea" xsi:type="string">messages</item> </item> </item> </item> <item name="progressBar" xsi:type="array"> <item name="sortOrder" xsi:type="string">0</item> <item name="component" xsi:type="string">Magento_Checkout/js/view/progress-bar</item> <item name="displayArea" xsi:type="string">progressBar</item> <item name="config" xsi:type="array"> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkout.steps.shipping-step.shippingAddress</item> <item name="1" xsi:type="string">checkout.steps.billing-step.payment</item> </item> </item> </item> <item name="estimation" xsi:type="array"> <item name="sortOrder" xsi:type="string">10</item> <item name="component" xsi:type="string">Magento_Checkout/js/view/estimation</item> <item name="displayArea" xsi:type="string">estimation</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/estimation</item> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkout.sidebar</item> </item> </item> </item> <item name="steps" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">steps</item> <item name="children" xsi:type="array"> <item name="shipping-step" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="sortOrder" xsi:type="string">1</item> <item name="children" xsi:type="array"> <item name="step-config" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="children" xsi:type="array"> <item name="shipping-rates-validation" xsi:type="array"> <item name="children" xsi:type="array"> <!--Step configuration components--> </item> </item> </item> </item> <item name="shippingAddress" xsi:type="array"> <item name="config" xsi:type="array"> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkout.steps.shipping-step.step-config</item> <item name="1" xsi:type="string">checkoutProvider</item> </item> <item name="popUpForm" xsi:type="array"> <item name="element" xsi:type="string">#opc-new-shipping-address</item> <item name="options" xsi:type="array"> <item name="type" xsi:type="string">popup</item> <item name="responsive" xsi:type="boolean">true</item> <item name="innerScroll" xsi:type="boolean">true</item> <item name="title" xsi:type="string" translate="true">Shipping Address</item> <item name="trigger" xsi:type="string">opc-new-shipping-address</item> <item name="buttons" xsi:type="array"> <item name="save" xsi:type="array"> <item name="text" xsi:type="string" translate="true">Save Address</item> <item name="class" xsi:type="string">action primary action-save-address</item> </item> <item name="cancel" xsi:type="array"> <item name="text" xsi:type="string" translate="true">Cancel</item> <item name="class" xsi:type="string">action secondary action-hide-popup</item> </item> </item> </item> </item> </item> <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping</item> <item name="provider" xsi:type="string">checkoutProvider</item> <item name="sortOrder" xsi:type="string">1</item> <item name="children" xsi:type="array"> <item name="customer-email" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/form/element/email</item> <item name="displayArea" xsi:type="string">customer-email</item> <item name="tooltip" xsi:type="array"> <item name="description" xsi:type="string" translate="true">We'll send your order confirmation here.</item> </item> <item name="children" xsi:type="array"> <item name="before-login-form" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-login-form</item> <item name="children" xsi:type="array"> <!-- before login form fields --> </item> </item> <item name="additional-login-form-fields" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">additional-login-form-fields</item> <item name="children" xsi:type="array"> <!-- additional login form fields --> </item> </item> </item> </item> <item name="before-form" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-form</item> <item name="children" xsi:type="array"> <!-- before form fields --> </item> </item> <item name="before-fields" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-fields</item> <item name="children" xsi:type="array"> <!-- before fields --> </item> </item> <item name="address-list" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping-address/list</item> <item name="displayArea" xsi:type="string">address-list</item> </item> <item name="address-list-additional-addresses" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">address-list-additional-addresses</item> <item name="children" xsi:type="array"> <!-- address-list-additional-addresses --> </item> </item> <item name="before-shipping-method-form" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-shipping-method-form</item> <item name="children" xsi:type="array"> <!-- address-list-additional-addresses --> </item> </item> <item name="shipping-address-fieldset" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="config" xsi:type="array"> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkoutProvider</item> </item> </item> <item name="displayArea" xsi:type="string">additional-fieldsets</item> <item name="children" xsi:type="array"> <!-- The following items override configuration of corresponding address attributes --> <item name="region" xsi:type="array"> <!-- Make region attribute invisible on frontend. Corresponding input element is created by region_id field --> <item name="visible" xsi:type="boolean">false</item> </item> <item name="region_id" xsi:type="array"> <item name="component" xsi:type="string">Magento_Ui/js/form/element/region</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">ui/form/field</item> <item name="elementTmpl" xsi:type="string">ui/form/element/select</item> <item name="customEntry" xsi:type="string">shippingAddress.region</item> </item> <item name="validation" xsi:type="array"> <item name="required-entry" xsi:type="boolean">true</item> </item> <!-- Value of region_id field is filtered by the value of county_id attribute --> <item name="filterBy" xsi:type="array"> <item name="target" xsi:type="string"><![CDATA[${ $.provider }:${ $.parentScope }.country_id]]></item> <item name="field" xsi:type="string">country_id</item> </item> </item> <item name="postcode" xsi:type="array"> <!-- post-code field has custom UI component --> <item name="component" xsi:type="string">Magento_Ui/js/form/element/post-code</item> <item name="validation" xsi:type="array"> <item name="required-entry" xsi:type="string">true</item> </item> </item> <item name="company" xsi:type="array"> <item name="validation" xsi:type="array"> <item name="min_text_length" xsi:type="number">0</item> </item> </item> <item name="fax" xsi:type="array"> <item name="validation" xsi:type="array"> <item name="min_text_length" xsi:type="number">0</item> </item> </item> <item name="country_id" xsi:type="array"> <item name="sortOrder" xsi:type="string">115</item> </item> <item name="telephone" xsi:type="array"> <item name="config" xsi:type="array"> <item name="tooltip" xsi:type="array"> <item name="description" xsi:type="string" translate="true">For delivery questions.</item> </item> </item> </item> </item> </item> </item> </item> </item> </item> <item name="billing-step" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="sortOrder" xsi:type="string">2</item> <item name="children" xsi:type="array"> <item name="payment" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/payment</item> <item name="config" xsi:type="array"> <item name="title" xsi:type="string" translate="true">Payment</item> </item> <item name="children" xsi:type="array"> <item name="renders" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="children" xsi:type="array"> <!-- merge payment method renders here --> </item> </item> <item name="additional-payment-validators" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="children" xsi:type="array"> <!-- merge payment validators here --> <item name="email-validator" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/payment/email-validator</item> </item> </item> </item> <item name="customer-email" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/form/element/email</item> <item name="displayArea" xsi:type="string">customer-email</item> <item name="tooltip" xsi:type="array"> <item name="description" xsi:type="string" translate="true">We'll send your order confirmation here.</item> </item> <item name="children" xsi:type="array"> <item name="before-login-form" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-login-form</item> <item name="children" xsi:type="array"> <!-- before login form fields --> </item> </item> <item name="additional-login-form-fields" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">additional-login-form-fields</item> <item name="children" xsi:type="array"> <!-- additional login form fields --> </item> </item> </item> </item> <item name="beforeMethods" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">beforeMethods</item> <item name="children" xsi:type="array"> <!-- merge additional data before payment methods here --> </item> <item name="validation" xsi:type="array"> <item name="validate-select" xsi:type="string">true</item> </item> <!-- Value of region_id field is filtered by the value of county_id attribute --> <item name="filterBy" xsi:type="array"> <item name="target" xsi:type="string">${ $.provider }:${ $.parentScope }.country_id</item> <item name="field" xsi:type="string">country_id</item> </item> </item> <item name="payments-list" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/payment/list</item> <item name="displayArea" xsi:type="string">payment-methods-list</item> <item name="config" xsi:type="array"> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkout.steps.billing-step.payment.renders</item> <item name="1" xsi:type="string">checkout.steps.billing-step.payment.additional-payment-validators</item> </item> </item> <item name="children" xsi:type="array"> <item name="before-place-order" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-place-order</item> <item name="dataScope" xsi:type="string">before-place-order</item> <item name="provider" xsi:type="string">checkoutProvider</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/payment/before-place-order</item> </item> </item> </item> </item> <!-- merge your payment methods here --> <item name="afterMethods" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">afterMethods</item> <item name="children" xsi:type="array"> <!-- merge additional data after payment methods here --> </item> </item> </item> </item> </item> </item> </item> </item> <item name="sidebar" xsi:type="array"> <item name="sortOrder" xsi:type="string">50</item> <item name="component" xsi:type="string">Magento_Checkout/js/view/sidebar</item> <item name="displayArea" xsi:type="string">sidebar</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/sidebar</item> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkout.steps</item> </item> </item> <item name="children" xsi:type="array"> <item name="summary" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/summary</item> <item name="displayArea" xsi:type="string">summary</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/summary</item> </item> <item name="children" xsi:type="array"> <item name="totals" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/totals</item> <item name="displayArea" xsi:type="string">totals</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/summary/totals</item> </item> <item name="children" xsi:type="array"> <!-- sort order for this totals is configured on admin panel--> <!-- Stores->Configuration->SALES->Sales->General->Checkout Totals Sort Order --> <item name="subtotal" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/subtotal</item> <item name="config" xsi:type="array"> <item name="title" xsi:type="string" translate="true">Cart Subtotal</item> </item> </item> <item name="shipping" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/shipping</item> <item name="config" xsi:type="array"> <item name="title" xsi:type="string" translate="true">Shipping</item> <item name="notCalculatedMessage" xsi:type="string" translate="true">Not yet calculated</item> </item> </item> <item name="grand-total" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/grand-total</item> <item name="config" xsi:type="array"> <item name="title" xsi:type="string" translate="true">Order Total</item> </item> </item> </item> </item> <item name="itemsBefore" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="children" xsi:type="array"> <!-- merge your components here --> </item> </item> <item name="cart_items" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/cart-items</item> <item name="children" xsi:type="array"> <item name="details" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details</item> <item name="children" xsi:type="array"> <item name="thumbnail" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details/thumbnail</item> <item name="displayArea" xsi:type="string">before_details</item> </item> <item name="subtotal" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details/subtotal</item> <item name="displayArea" xsi:type="string">after_details</item> </item> </item> </item> </item> </item> <item name="itemsAfter" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="children" xsi:type="array"> <!-- merge your components here --> </item> </item> </item> </item> <item name="shipping-information" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping-information</item> <item name="config" xsi:type="array"> <item name="deps" xsi:type="string">checkout.steps.shipping-step.shippingAddress</item> </item> <item name="displayArea" xsi:type="string">shipping-information</item> <item name="children" xsi:type="array"> <item name="ship-to" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping-information/list</item> <item name="displayArea" xsi:type="string">ship-to</item> </item> </item>

<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> <block class="Magento\Checkout\Block\Onepage" name="checkout.root" template="onepage.phtml" cacheable="false"> <arguments> <argument name="jsLayout" xsi:type="array"> <item name="types" xsi:type="array"> <item name="form.input" xsi:type="array"> <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item> <item name="config" xsi:type="array"> <item name="provider" xsi:type="string">checkoutProvider</item> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkoutProvider</item> </item> <item name="template" xsi:type="string">ui/form/field</item> <item name="elementTmpl" xsi:type="string">ui/form/element/input</item> </item> </item> </item> <item name="components" xsi:type="array"> <item name="checkout" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/onepage</item> </item> <item name="children" xsi:type="array"> <item name="errors" xsi:type="array"> <item name="sortOrder" xsi:type="string">0</item> <item name="component" xsi:type="string">Magento_Ui/js/view/messages</item> <item name="displayArea" xsi:type="string">messages</item> </item> <item name="authentication" xsi:type="array"> <item name="sortOrder" xsi:type="string">1</item> <item name="component" xsi:type="string">Magento_Checkout/js/view/authentication</item> <item name="displayArea" xsi:type="string">authentication</item> <item name="children" xsi:type="array"> <!--Additional authentication fields--> <item name="errors" xsi:type="array"> <item name="sortOrder" xsi:type="string">0</item> <item name="component" xsi:type="string">Magento_Checkout/js/view/authentication-messages</item> <item name="displayArea" xsi:type="string">messages</item> </item> </item> </item> <item name="progressBar" xsi:type="array"> <item name="sortOrder" xsi:type="string">0</item> <item name="component" xsi:type="string">Magento_Checkout/js/view/progress-bar</item> <item name="displayArea" xsi:type="string">progressBar</item> <item name="config" xsi:type="array"> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkout.steps.shipping-step.shippingAddress</item> <item name="1" xsi:type="string">checkout.steps.billing-step.payment</item> </item> </item> </item> <item name="estimation" xsi:type="array"> <item name="sortOrder" xsi:type="string">10</item> <item name="component" xsi:type="string">Magento_Checkout/js/view/estimation</item> <item name="displayArea" xsi:type="string">estimation</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/estimation</item> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkout.sidebar</item> </item> </item> </item> <item name="steps" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">steps</item> <item name="children" xsi:type="array"> <item name="shipping-step" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="sortOrder" xsi:type="string">1</item> <item name="children" xsi:type="array"> <item name="step-config" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="children" xsi:type="array"> <item name="shipping-rates-validation" xsi:type="array"> <item name="children" xsi:type="array"> <!--Step configuration components--> </item> </item> </item> </item> <item name="shippingAddress" xsi:type="array"> <item name="config" xsi:type="array"> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkout.steps.shipping-step.step-config</item> <item name="1" xsi:type="string">checkoutProvider</item> </item> <item name="popUpForm" xsi:type="array"> <item name="element" xsi:type="string">#opc-new-shipping-address</item> <item name="options" xsi:type="array"> <item name="type" xsi:type="string">popup</item> <item name="responsive" xsi:type="boolean">true</item> <item name="innerScroll" xsi:type="boolean">true</item> <item name="title" xsi:type="string" translate="true">Shipping Address</item> <item name="trigger" xsi:type="string">opc-new-shipping-address</item> <item name="buttons" xsi:type="array"> <item name="save" xsi:type="array"> <item name="text" xsi:type="string" translate="true">Save Address</item> <item name="class" xsi:type="string">action primary action-save-address</item> </item> <item name="cancel" xsi:type="array"> <item name="text" xsi:type="string" translate="true">Cancel</item> <item name="class" xsi:type="string">action secondary action-hide-popup</item> </item> </item> </item> </item> </item> <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping</item> <item name="provider" xsi:type="string">checkoutProvider</item> <item name="sortOrder" xsi:type="string">1</item> <item name="children" xsi:type="array"> <item name="customer-email" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/form/element/email</item> <item name="displayArea" xsi:type="string">customer-email</item> <item name="tooltip" xsi:type="array"> <item name="description" xsi:type="string" translate="true">We'll send your order confirmation here.</item> </item> <item name="children" xsi:type="array"> <item name="before-login-form" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-login-form</item> <item name="children" xsi:type="array"> <!-- before login form fields --> </item> </item> <item name="additional-login-form-fields" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">additional-login-form-fields</item> <item name="children" xsi:type="array"> <!-- additional login form fields --> </item> </item> </item> </item> <item name="before-form" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-form</item> <item name="children" xsi:type="array"> <!-- before form fields --> </item> </item> <item name="before-fields" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-fields</item> <item name="children" xsi:type="array"> <!-- before fields --> </item> </item> <item name="address-list" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping-address/list</item> <item name="displayArea" xsi:type="string">address-list</item> </item> <item name="address-list-additional-addresses" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">address-list-additional-addresses</item> <item name="children" xsi:type="array"> <!-- address-list-additional-addresses --> </item> </item> <item name="before-shipping-method-form" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-shipping-method-form</item> <item name="children" xsi:type="array"> <!-- address-list-additional-addresses --> </item> </item> <item name="shipping-address-fieldset" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="config" xsi:type="array"> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkoutProvider</item> </item> </item> <item name="displayArea" xsi:type="string">additional-fieldsets</item> <item name="children" xsi:type="array"> <!-- The following items override configuration of corresponding address attributes --> <item name="region" xsi:type="array"> <!-- Make region attribute invisible on frontend. Corresponding input element is created by region_id field --> <item name="visible" xsi:type="boolean">false</item> </item> <item name="region_id" xsi:type="array"> <item name="component" xsi:type="string">Magento_Ui/js/form/element/region</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">ui/form/field</item> <item name="elementTmpl" xsi:type="string">ui/form/element/select</item> <item name="customEntry" xsi:type="string">shippingAddress.region</item> </item> <item name="validation" xsi:type="array"> <item name="required-entry" xsi:type="boolean">true</item> </item> <!-- Value of region_id field is filtered by the value of county_id attribute --> <item name="filterBy" xsi:type="array"> <item name="target" xsi:type="string"><![CDATA[${ $.provider }:${ $.parentScope }.country_id]]></item> <item name="field" xsi:type="string">country_id</item> </item> </item> <item name="postcode" xsi:type="array"> <!-- post-code field has custom UI component --> <item name="component" xsi:type="string">Magento_Ui/js/form/element/post-code</item> <item name="validation" xsi:type="array"> <item name="required-entry" xsi:type="string">true</item> </item> </item> <item name="company" xsi:type="array"> <item name="validation" xsi:type="array"> <item name="min_text_length" xsi:type="number">0</item> </item> </item> <item name="fax" xsi:type="array"> <item name="validation" xsi:type="array"> <item name="min_text_length" xsi:type="number">0</item> </item> </item> <item name="country_id" xsi:type="array"> <item name="sortOrder" xsi:type="string">115</item> </item> <item name="telephone" xsi:type="array"> <item name="config" xsi:type="array"> <item name="tooltip" xsi:type="array"> <item name="description" xsi:type="string" translate="true">For delivery questions.</item> </item> </item> </item> </item> </item> </item> </item> </item> </item> <item name="billing-step" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="sortOrder" xsi:type="string">2</item> <item name="children" xsi:type="array"> <item name="payment" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/payment</item> <item name="config" xsi:type="array"> <item name="title" xsi:type="string" translate="true">Payment</item> </item> <item name="children" xsi:type="array"> <item name="renders" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="children" xsi:type="array"> <!-- merge payment method renders here --> </item> </item> <item name="additional-payment-validators" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="children" xsi:type="array"> <!-- merge payment validators here --> <item name="email-validator" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/payment/email-validator</item> </item> </item> </item> <item name="customer-email" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/form/element/email</item> <item name="displayArea" xsi:type="string">customer-email</item> <item name="tooltip" xsi:type="array"> <item name="description" xsi:type="string" translate="true">We'll send your order confirmation here.</item> </item> <item name="children" xsi:type="array"> <item name="before-login-form" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-login-form</item> <item name="children" xsi:type="array"> <!-- before login form fields --> </item> </item> <item name="additional-login-form-fields" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">additional-login-form-fields</item> <item name="children" xsi:type="array"> <!-- additional login form fields --> </item> </item> </item> </item> <item name="beforeMethods" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">beforeMethods</item> <item name="children" xsi:type="array"> <!-- merge additional data before payment methods here --> </item> <item name="validation" xsi:type="array"> <item name="validate-select" xsi:type="string">true</item> </item> <!-- Value of region_id field is filtered by the value of county_id attribute --> <item name="filterBy" xsi:type="array"> <item name="target" xsi:type="string">${ $.provider }:${ $.parentScope }.country_id</item> <item name="field" xsi:type="string">country_id</item> </item> </item> <item name="payments-list" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/payment/list</item> <item name="displayArea" xsi:type="string">payment-methods-list</item> <item name="config" xsi:type="array"> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkout.steps.billing-step.payment.renders</item> <item name="1" xsi:type="string">checkout.steps.billing-step.payment.additional-payment-validators</item> </item> </item> <item name="children" xsi:type="array"> <item name="before-place-order" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">before-place-order</item> <item name="dataScope" xsi:type="string">before-place-order</item> <item name="provider" xsi:type="string">checkoutProvider</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/payment/before-place-order</item> </item> </item> </item> </item> <!-- merge your payment methods here --> <item name="afterMethods" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">afterMethods</item> <item name="children" xsi:type="array"> <!-- merge additional data after payment methods here --> </item> </item> </item> </item> </item> </item> </item> </item> <item name="sidebar" xsi:type="array"> <item name="sortOrder" xsi:type="string">50</item> <item name="component" xsi:type="string">Magento_Checkout/js/view/sidebar</item> <item name="displayArea" xsi:type="string">sidebar</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/sidebar</item> <item name="deps" xsi:type="array"> <item name="0" xsi:type="string">checkout.steps</item> </item> </item> <item name="children" xsi:type="array"> <item name="summary" xsi:type="array"> <item name="component" xsi:type="string">Magento_Checkout/js/view/summary</item> <item name="displayArea" xsi:type="string">summary</item> <item name="config" xsi:type="array"> <item name="template" xsi:type="string">Magento_Checkout/summary</item> </item>

Checkout

Page 9: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 9

checkout_index_index.xml

<page layout="checkout"> <body> <referenceContainer name="content"> <block class="Magento\Checkout\Block\Onepage" name="checkout.root" template="onepage.phtml" cacheable="false"> <arguments> <argument name="jsLayout" xsi:type=“array”> <!—- Layout Config —-> </argument> </arguments> </block> </referenceContainer> </body> </page>

Page 10: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 10

Entry point - onepage.phtml

<!-- ko template: getTemplate() --><!-- /ko —> <script type=“text/x-magento-init"> { "#checkout": { "Magento_Ui/js/core/app": <?php echo $block->getJsLayout();?> } }</script>

<script> window.checkoutConfig = <?php echo \Zend_Json::encode($block->getCheckoutConfig()); ?>; window.isCustomerLoggedIn = window.checkoutConfig.isCustomerLoggedIn; window.customerData = window.checkoutConfig.customerData; </script>

Magento\Checkout\view\frontent\templates\onepage.phtml

onepage.html

UI Components

Checkout Config

Page 11: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 11

Layout - onepage.HTML

<!-- ko foreach: getRegion('progressBar') --><!-- ko template: getTemplate() --><!-- /ko --><!--/ko--><!-- ko foreach: getRegion('estimation') --> <!-- ko template: getTemplate() --><!-- /ko --><!--/ko--><!-- ko foreach: getRegion('messages') --> <!-- ko template: getTemplate() --><!-- /ko --><!--/ko--><div class="opc-wrapper"> <ol class="opc" id="checkoutSteps"> <!-- ko foreach: getRegion('steps') --> <!-- ko template: getTemplate() --><!-- /ko --> <!--/ko--> </ol> </div>

Magento\Checkout\view\frontent\web\template\onepage.html

Checkout

Page 12: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 12

getRegion = displayArea

<item name="steps" xsi:type="array"> <item name="component" xsi:type="string">uiComponent</item> <item name="displayArea" xsi:type="string">steps</item> <item name="children" xsi:type=“array”>…</item> </item>

var config = { map: { '*': { uiComponent: 'Magento_Ui/js/lib/core/collection', } }};

requirejs-config.js

checkout_index_index.xml

Page 13: Max Pronko - Best practices for checkout customisation in Magento 2

© 2016 Magento, Inc. 13

Page 14: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 14

How to extend Checkout in Magento 2

Page 15: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 15

What do we have here?

• Plugin • Extension Attributes • Config Provider

• Layouts • Components • JavaScript Mixins • Layout Processor

BackendFrontend

Page 16: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 16

Adding new Component

Page 17: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 17

Adding new Component

Checkout Agreement Component

before-place-orderdisplayArea

Page 18: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 18

Adding new Component - static declaration

<item name="agreements"> <item name="component">Magento_CheckoutAgreements/js/view/checkout-agreements</item> <item name="sortOrder">100</item> <item name="displayArea">before-place-order</item> </item>

checkout_index_index.xml

return Component.extend({ defaults: { template: 'Magento_CheckoutAgreements/checkout/checkout-agreements' } });

checkout-agreements.js

Page 19: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 19

Dynamic component declaration

Page 20: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 20

Dynamic component declaration

Page 21: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 21

Dynamic component declaration - Layout Processor

<type name="Magento\Checkout\Block\Onepage"> <arguments> <argument name="layoutProcessors" xsi:type="array"> <item name="addressFormAttributes">Magento\Checkout\Block\Checkout\LayoutProcessor</item> </argument> </arguments> </type>

Magento\Checkout\etc\frontend\di.xml

namespace Magento\Checkout\Block\Checkout;interface LayoutProcessorInterface{ public function process($jsLayout); }

Page 22: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 22

Component Configuration

Page 23: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting 23

Component Configuration - Config Provider

<type name="Magento\Checkout\Model\CompositeConfigProvider"> <arguments> <argument name="configProviders"> <item name="braintree_config_provider">Magento\Braintree\Model\Ui\ConfigProvider</item> </argument> </arguments> </type>

di.xml

Page 24: Max Pronko - Best practices for checkout customisation in Magento 2

© 2017 Pronko Consulting

QuestionsMagento 2 Blog - www.maxpronko.com @max_pronko