# Adding a new step

**Adding new steps to the Loki Checkout is perfectly possible. It takes a few ... *steps* but the logic is (as we see it) quite straightforward.**

## XML layout definition
To add a new step in the checkout, first define a new block within the parent block `loki-checkout.steps`. In our example code, we refer to a new step called `custom`.

```xml
<referenceBlock name="loki-checkout.steps">
    <block
        name="loki-checkout.steps.custom"
        as="custom"
        template="Loki_Components::utils/container.phtml">
        
        <block
            name="loki-checkout.steps.custom.buttons" 
            as="buttons" 
            template="Loki_FieldComponents::form/button/buttons.phtml" 
            after="-">
            <block
                name="loki-checkout.steps.custom.forward-button"
                template="Loki_FieldComponents::form/button/button.phtml">
                <arguments>
                    <argument name="button_label" xsi:type="string" translate="true">Next step</argument>
                </arguments>
            </block>
        </block>
    </block>
</referenceBlock>
```

The new block is currently a container (similar to a regular layout `<container/>` but with the support for `$css()` and improved child sorting). The container is empty by default, but to allow moving to the next step, a new button has been added to it. Note that the button contains zero logic (yet).

## Upgrade the blocks to Loki Components
Both step block and button block need to be upgraded to a Loki Component. For this, we use the `etc/loki_components.xml` with something like the following:

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:module:Loki_Components:etc/loki_components.xsd">
    <component
            name="loki-checkout.steps.custom"
            context="YireoTraining\Example\Component\Checkout\Step\CustomStep\CustomStepContext"
            viewModel="YireoTraining\Example\Component\Checkout\Step\CustomStep\CustomStepViewModel">
    </component>
    
    <component
            name="loki-checkout.steps.custom.forward-button"
            group="stepButtons"
            viewModel="LokiCheckout\Core\Component\Checkout\StepButton\StepForwardButton\StepForwardButtonViewModel"
            repository="LokiCheckout\Core\Component\Checkout\StepButton\StepForwardButton\StepForwardButtonRepository"
    />
</components>
```

For the step component it is required to implement a custom ViewModel. You could potentially skip the context class, but do read the docs here.

The button component is reusing all logic from the regular `StepForwardButton` component. In a similar way, you can also add a `StepBackwardButton` as well.

## Step component ViewModel
The step component its ViewModel class needs to implement a `LokiCheckout\Core\Component\Checkout\Step\StepViewModelInterface`. The easiest way is to extend upon `LokiCheckout\Core\Component\Checkout\Step\AbstractStepViewModel`.

```php
namespace YireoTraining\Example\Component\Checkout\Step\CustomStep;

use LokiCheckout\Core\Component\Checkout\Step\AbstractStepViewModel;

class CustomStepViewModel extends AbstractStepViewModel
{
    public function getCode(): string
    {
        return 'custom';
    }

    public function getLabel(): string
    {
        return 'Custom';
    }
}
```

Obviously, you can override more methods and add more logic to the step. But these are the basics to get you started.

Take note that the `validate()` method, which is required by `StepViewModelInterface`, is implemented in the `AbstractStepViewModel` to simply always return `true`. Either you override the `validate()` method to add custom logic, or you implement a context in the way like we did.

<div class="notice">More docs coming soon</div>
