Adding a ComponentRepository

The example given under the page A simple component is really a basic example to get you started. It lacks the ability to modify data on the Magento side. To allow you to do that, a repository needs to be added.

Adding a repository to the component definition

First, add the following to the XML file etc/loki_components.xml:

<?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"
        repository="YireoTraining\ExampleLokiComponent\Component\Example\ExampleRepository"
    />
</components>

Clean the configuration cache afterwards.

Creating a ComponentRepository class

A new PHP class YireoTraining\ExampleLokiComponent\Component\Example\ExampleRepository now needs to be created in our module. This class is dubbed the ComponentRepository class in a component, because it extends upon a class Yireo\LokiComponents\Component\ComponentRepository. This parent class is abstract and forces you to create two methods:

  • getValue() which retrieves data from the storage of your choice and adds them to the ViewModel;
  • saveValue(mixed $value) which saves data to the storage of your choice;

Let's use the customer storage to store a random value and display this as well:

namespace YireoTraining\ExampleLokiComponent\Component\Example;

use Yireo\LokiComponents\Component\ComponentRepository;

class ExampleRepository extends ComponentRepository
{
    public function getValue(): mixed
    {
        return $this->getContext()->getCustomerSession()->getExampleValue();
    }

    public function saveValue(mixed $value): void
    {
        $this->getContext()->getCustomerSession()->setExampleValue(rand());
    }
}

Showing the random value in the template

Because the repository is now part of the component, the button click of the previous example will send an AJAX call to the Magento application, which will then trigger the ExampleRepository::saveValue() value (saving a random number to the customer session).

Next, the same AJAX call renders the block loki-components.example (with a $viewModel variable being an instance of the generic Yireo\LokiComponents\Component\ComponentViewModel class) and refreshes the HTML of that block in the browser (so the HTML element with ID loki-components-example).

If we modify the PHTML template to the following, the random value is fetched from the $viewModel and shown:

<div>
    <span>Random value: <?= $viewModel->getValue() ?></span><br/>
    <button @change="post">Refresh</button>
</div>

Adding a value

We can also extend the component with a simple custom value. This is already built in within every Loki Component. Note however that there is no preference for the type of the value (string, boolean, array, integer). Casting will need to be done manually.

First of all, let's add an input field with the Alpine directive x-model pointing to the component property value:

<div>
    <span>My value: <?= $viewModel->getValue() ?></span><br/>
    <input type="text" x-model="value" /><br/>
    <button @change="post">Refresh</button>
</div>

Now, modifying value in the input field, will make sure that the same ExampleRepository class stores the $value. Even though it is not required, it is nice to modify the repository slightly to cast any value to a string:

class ExampleRepository extends ComponentRepository
{
    public function getValue(): mixed
    {
        return (string)$this->getContext()->getCustomerSession()->getExampleValue();
    }

    public function saveValue(mixed $value): void
    {
        $this->getContext()->getCustomerSession()->setExampleValue((string)$value);
    }
}

Adding a filter

We can automatically apply a filter to the input value, simply by modifying the component definition. For instance, we can transform any input value into an uppercase string, by applying the uppercase filter:

<?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"
        repository="YireoTraining\ExampleLokiComponent\Component\Example\ExampleRepository">
        <filter name="uppercase" />
    </component>
</components>

Coming soon

Last modified: January 8, 2025