In Magento2, mainly we have seen on checkout page all Js components loads using xml, these components are defined in checkout_index_index.xml file. We can also define our custom Js Components using our xml Layout File. Step 1: Create our module registration php file as registration.php. Location: app/code/Magemeta/CreateCustomer/registration.php<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Magemeta_CustomLayout', __DIR__ );
Location: app/code/Magemeta/CreateCustomer/etc/module.xml
<?xml version="1.0" ?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Magemeta_CustomLayout" setup_version="1.0.0"></module> </config>
Location: app/code/Magemeta/CustomLayout/composer.json
{ "name": "magemeta/module-custom-layout", "description": "This module is used to create customers", "type": "magento2-module", "license": "OSL-3.0", "authors": [ { "email": "info@magemeta.com", "name": "magemeta" } ], "minimum-stability": "dev", "require": {}, "autoload": { "files": [ "registration.php" ], "psr-4": { "Magemeta\\CustomLayout\\": "" } } }
Step 2: We need to call our custom js renderer block into xml layout. Here we have use customer_account_edit.xml.
Location: app/code/Magemeta/CustomLayout/view/frontend/layout/customer_account_edit.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"> <update handle="customer_account"/> <body> <referenceContainer name="content"> <block class="Magemeta\CustomLayout\Block\CustomLayout" name="magemeta_custom_layout" template="Magemeta_CustomLayout::custom_layout.phtml" cacheable="false"> <arguments> <argument name="jsLayout" xsi:type="array"> <item name="components" xsi:type="array"> <item name="customcomponent" xsi:type="array"> <item name="component" xsi:type="string">Magemeta_CustomLayout/js/custom-component</item> </item> </item> </argument> </arguments> </block> </referenceContainer> </body> </page>
Step 3: We need to create our custom block to collect information to insert into js layout.
Location: app/code/Magemeta/CustomLayout/Block/CustomLayout.php
<?php /** * Magemeta_CustomLayout * * @category Magemeta * @package Magemeta_CustomLayout * @author Magemeta Team <info@magemeta.com> * @copyright Copyright (c) 2019 Magemeta (http://www.magemeta.com) */ namespace Magemeta\CustomLayout\Block; use Magemeta\CustomLayout\Model\CustomConfigProvider; use Magento\Framework\View\Element\Template\Context; class CustomLayout extends \Magento\Framework\View\Element\Template { /** * @var array */ protected $jsLayout; /** * @var CustomConfigProvider */ protected $configProvider; /** * @param Context $context * @param array $data */ public function __construct( Context $context, CustomConfigProvider $configProvider, array $data = [] ) { parent::__construct($context, $data); $this->jsLayout = isset($data['jsLayout']) && is_array($data['jsLayout']) ? $data['jsLayout'] : []; $this->configProvider = $configProvider; } /** * @return string */ public function getJsLayout() { return \Zend_Json::encode($this->jsLayout); } public function getCustomConfig() { return $this->configProvider->getConfig(); } }
Step 4: We need to create model to collect and return configuration information to block.
Location: app/code/Magemeta/CustomLayout/Model/CustomConfigProvider.php
<?php /** * Magemeta_CustomLayout * * @category Magemeta * @package Magemeta_CustomLayout * @author Magemeta Team <info@magemeta.com> * @copyright Copyright (c) 2019 Magemeta (http://www.magemeta.com) */ namespace Magemeta\CustomLayout\Model; class CustomConfigProvider implements ConfigProviderInterface { /** * @var ConfigProviderInterface[] */ private $configProviders; /** * @param ConfigProviderInterface[] $configProviders * @codeCoverageIgnore */ public function __construct( array $configProviders ) { $this->configProviders = $configProviders; } /** * {@inheritdoc} */ public function getConfig() { $config = []; foreach ($this->configProviders as $configProvider) { $config = array_merge_recursive($config, $configProvider->getConfig()); } return $config; } }
We also need to create model interface as ConfigProviderInterface.
Location: app/code/Magemeta/CustomLayout/Model/ConfigProviderInterface.phpStep 5: Now we need to create our custom .phtml file as custom_layout.phtml. Here we initialized our custom component and load the custom js components by getJsLayout() method.
<?php /** * Magemeta_CustomLayout * * @category Magemeta * @package Magemeta_CustomLayout * @author Magemeta Team <info@magemeta.com> * @copyright Copyright (c) 2019 Magemeta (http://www.magemeta.com) */ namespace Magemeta\CustomLayout\Model; interface ConfigProviderInterface { /** * Retrieve associative array of checkout configuration * * @return array */ public function getConfig(); }
Location: app/code/Magemeta/CustomLayout/view/frontend/templates/custom_layout.phtml
<script> window.customConfig = <?php echo \Zend_Json::encode($block->getCustomConfig()); ?>; </script> <div id="custom-component" data-bind="scope:'customcomponent'"> <!-- ko template: getTemplate() --><!-- /ko --> <script type="text/x-magento-init"> { "#custom-component": { "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?> } } </script> </div>
Step 6: Now we need to create our custom js file.
Location: app/code/Magemeta/CustomLayout/view/frontend/web/js/custom-component.js
define([ 'jquery', 'uiComponent', 'ko', ], function ($, Component, ko) { 'use strict'; var customConfigData = window.customConfig; return Component.extend({ defaults: { template: 'Magemeta_CustomLayout/custom_layout' }, initialize: function () { this._super(); }, }); } );
Step 7: Finally we need to create our custom custom_layout.html file if we set it component template part of custom-component.js. If you don't want to add template, just comment it out from js script.
Location: app/code/Magemeta/CustomLayout/view/frontend/web/template/custom_layout.html
<div class="customLayout"> <p>This is custom layout html</p> </div>
We are done with initializing the custom js component in custom layout. Hope this helps you guys!