A simple component

Block definition in the XML layout

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.

Component definition in 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>

The PHTML template

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:

  • The block name is used for 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.

No data is saved

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"

FAQ: Why is there a difference between 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.

Last modified: January 5, 2025