A simple component could first be defined by using the XML layout:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:View/Layout:etc/page_configuration.xsd">
<update handle="loki_components"/>
<body>
<referenceContainer name="after.body.start">
<block
name="loki-components.example"
template="YireoTraining_ExampleLokiComponent::example.phtml"/>
</referenceContainer>
</body>
</page>
Note that the handle loki_components
is added, to make sure AlpineJS and all of the specific Loki scripts are initialized.
Make sure to give thought to your block name, because it will be used as a unique identifier and the name of your Loki Component.
etc/loki_components.xml
Next, a file etc/loki_components.xml
upgrades your block to an actual component. Note that the name of the component is equal to the name of your block:
<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Yireo_LokiComponents:etc/loki_components.xsd">
<component name="loki-components.example" />
</components>
Next, a PHTML template example.phtml
could be including a simple button:
<div>
<button @change="post">Refresh</button>
</div>
This tries to call a post()
method in an Alpine component that you did not write. This is important to note. However, simply because you defined your block to be a Loki Component, the framework transforms your PHTML template output into the following:
<div id="loki-components-example"
x-data="LokiComponent"
x-title="LokiComponentsExample"
x-init-data='{"value":null}'
class="loki-components-example relative">
<button @change="post">Click</button>
</div>
As you can see, the Loki Components module changes the PHTML template as follows:
id
and class
x-data
refers to the AlpineJS component LokiComponent
containing the method post()
;x-title
refers to the AlpineJS component ID (while this specific HTML attribute is also used by the DevTools)x-init-data
inserts data into the AlpineJS component instance via the init()
method. The shown data here is a simplified version though.An important note of this simple component is that it does not save any data on the server side. The post()
method simply makes an AJAX call and the current PHTML template will refresh. To save data on the server, we actually need to introduce a ComponentRepository
class, which is explained on the next page "Adding a ComponentRepository
class"
x-data
and x-title
?With x-data
, an Alpine.js component is instantiated. With x-title
, you only give a cosmetic title to the component, which is nice in the Alpine.js DevTools browser plugin.
The Loki Checkout tries to never use local data (x-data='{"foo":"bar"}'
) or functions (x-data="foobar()"
) to instantiate components. Instead, a JavaScript snippet is added to instantiate the component data via Alpine.data('FooBar', () => {});
so that x-data="FooBar"
is enough to instantiate the component. This separation is choosen to allow for future security restrictions (like PCI Compliance via CSP rules).
However, the Alpine.js data might be as generic LokiCheckoutFieldComponent
, while the actual live component is dealing with a specific street1
field instead. To help you navigate through components in the DevTools, the x-title
attribute is added with a value like LokiCheckoutShippingAddressStreet1
.