# Country-specific layout handles

**Address forms differ per country: In Germany, the street and house number are separate fields, in the Netherlands the postcode comes first and in India a GST number is needed. Instead of writing PHP logic for this, the LokiCheckout adds XML layout handles based on the country of the current shipping and billing address. You can use these handles in your own module or theme to change labels, placeholders, column spans or to add and remove blocks for a specific country.**

## Which handles are added?
The core module `LokiCheckout_Core` registers two layout handlers with `Loki\Components\Layout\LayoutHandlerComposite` (in `etc/frontend/di.xml`):

- `LokiCheckout\Core\Layout\LayoutHandler` adds the generic checkout handles (when the handle `checkout_index_index` is present);
- `LokiCheckout\Core\Layout\CountrySpecificLayoutHandler` adds the country-specific handles, based on the current quote.

First, the `LayoutHandler` adds the following handles:

| Handle | Description |
|---|---|
| `loki_checkout` | Always added |
| `loki_checkout_skin_SKIN` | The current skin, for instance `loki_checkout_skin_default` or `loki_checkout_skin_onestep` |
| `loki_checkout_theme_SKIN` | Same as above, but deprecated |
| `hyva_HANDLE`, `luma_HANDLE`, `breeze_HANDLE` | The same handles prefixed with the type of the current frontend theme, for instance `hyva_loki_checkout_skin_default` |
| `loki_checkout_address_GRID` | The configured address grid layout, for instance `loki_checkout_address_default_grid` |

Next, the `CountrySpecificLayoutHandler` adds the following handles, where `XX` is the **lowercase** two-letter country code (for instance `nl`, `de`, `us`):

| Handle | Country used |
|---|---|
| `loki_checkout_country_XX` | The shipping country, or the billing country if there is no shipping country |
| `loki_checkout_shipping_address_country_XX` | The shipping country (only when the quote is not virtual and a shipping country is set) |
| `loki_checkout_billing_address_country_XX` | The billing country, or the shipping country if no billing country is set yet |

On top of this, the same three suffixes (`_country_XX`, `_shipping_address_country_XX` and `_billing_address_country_XX`) are appended to every handle that starts with `loki_checkout_skin_` or `loki_checkout_address_`. For instance, with the default skin, the default grid, a shipping address in the Netherlands and a billing address in Belgium, the following handles are added:

```text
loki_checkout_country_nl
loki_checkout_shipping_address_country_nl
loki_checkout_billing_address_country_be
loki_checkout_skin_default_country_nl
loki_checkout_skin_default_shipping_address_country_nl
loki_checkout_skin_default_billing_address_country_be
loki_checkout_address_default_grid_country_nl
loki_checkout_address_default_grid_shipping_address_country_nl
loki_checkout_address_default_grid_billing_address_country_be
```

Some details:

- For a virtual quote (no shipping), no `shipping_address` handles are added and the billing country is used for `loki_checkout_country_XX`.
- When there is no quote, or when neither address has a country yet, no country handles are added at all.
- Country handles are not combined with the theme prefixes: There is no `hyva_loki_checkout_shipping_address_country_nl`, for instance.
- The deprecated `loki_checkout_theme_SKIN` handle does not get any country suffixes. Use `loki_checkout_skin_SKIN_*` instead.

## Which handle to pick?
- Use `loki_checkout_shipping_address_country_XX` to change blocks of the shipping address form (`loki-checkout.shipping.address.*`) and `loki_checkout_billing_address_country_XX` to change blocks of the billing address form (`loki-checkout.billing.address.*`). Because the shipping and billing country can differ, this is usually the best choice for address fields.
- Use `loki_checkout_country_XX` for changes that do not belong to a specific address.
- Use `loki_checkout_skin_SKIN_shipping_address_country_XX` (and its billing variant) for changes that only make sense for a specific skin, like column spans.

## Example: Changing labels and placeholders per country
The module `LokiCheckout_De` ships with a file `view/frontend/layout/loki_checkout_shipping_address_country_de.xml` which (in part) looks like this:

```xml
<?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">
    <body>
        <referenceBlock name="loki-checkout.shipping.address.street1">
            <arguments>
                <argument name="field_label" xsi:type="string" translate="true">Housenumber</argument>
            </arguments>
        </referenceBlock>

        <referenceBlock name="loki-checkout.shipping.address.postcode">
            <arguments>
                <argument name="field_label" xsi:type="string" translate="true">Postal code</argument>
                <argument name="placeholder" xsi:type="string">12345</argument>
                <argument name="field_attributes" xsi:type="array">
                    <item name="x-mask" xsi:type="string">99999</item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>
```

The same module has a similar file `loki_checkout_billing_address_country_de.xml` for the billing address blocks.

## Example: Column spans per skin and country
The same module also ships with a file `loki_checkout_skin_default_shipping_address_country_de.xml` that changes the width of the house number and addition fields, but only for the default skin:

```xml
<?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">
    <body>
        <referenceBlock name="loki-checkout.shipping.address.street1">
            <arguments>
                <argument name="col_span" xsi:type="number">6</argument>
                <argument name="md_col_span" xsi:type="number">3</argument>
            </arguments>
        </referenceBlock>

        <referenceBlock name="loki-checkout.shipping.address.street2">
            <arguments>
                <argument name="col_span" xsi:type="number">6</argument>
                <argument name="md_col_span" xsi:type="number">3</argument>
            </arguments>
        </referenceBlock>
    </body>
</page>
```

For changing column spans and sort orders per country in general, a grid with a `countryId` in `etc/loki_checkout.xml` is an alternative. See [Changing the grid of field blocks](/checkout/dev/basic-customizations/changing-the-grid).

## Example: Adding a field for a specific country
The module `LokiCheckout_IndianGst` uses the handle `loki_checkout_country_in` (file `loki_checkout_country_in.xml`) to add a new field to both address forms only when the country is India:

```xml
<?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">
    <body>
        <referenceBlock name="loki-checkout.shipping.address.form">
            <block
                name="loki-checkout.shipping.address.gst_number" as="gst_number"
                template="Loki_FieldComponents::form/field.phtml">
                <arguments>
                    <argument name="placeholder" xsi:type="string">22AAAAA0000A1Z5</argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>
```

Of course, a field like this also needs a component definition in `etc/loki_components.xml` and a place to store its value. That is outside the scope of this page.

## What happens when the country changes?
Layout handles are calculated whenever the layout is built - both on the initial page load and when Loki Components re-render blocks via AJAX. Before adding the new country handles, the `CountrySpecificLayoutHandler` removes any existing handle that contains `country_XX`, so the handles of the previous country are dropped.

However, after a component update, only the blocks that are targets of the updated component are re-rendered. For instance, the component `loki-checkout.shipping.address.country_id` (in `LokiCheckout_Core::etc/loki_components.xml`) targets the street fields, the city, the postcode, the region, the shipping methods and the block `loki-checkout.shipping.address.form.grid-layout`. If your country-specific layout changes other blocks, add those blocks as additional targets in the `etc/loki_components.xml` file of your own module, as done by `LokiCheckout_EuVatWarning`, for example:

```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.shipping.address.country_id">
        <target name="loki-checkout.shipping.address.eu_vat_warning"/>
    </component>

    <component name="loki-checkout.billing.address.country_id">
        <target name="loki-checkout.billing.address.eu_vat_warning"/>
    </component>
</components>
```

## Adding your own layout handles
The list of layout handlers is a regular DI argument, so you can add your own implementation of `Loki\Components\Layout\LayoutHandlerInterface` (with a single method `get(array $handles): array`) via `etc/frontend/di.xml`:

```xml
<type name="Loki\Components\Layout\LayoutHandlerComposite">
    <arguments>
        <argument name="layoutHandlers" xsi:type="array">
            <item name="Vendor_Module::layoutHandler" xsi:type="object">Vendor\Module\Layout\LayoutHandler</item>
        </argument>
    </arguments>
</type>
```

Modules like `LokiCheckout_PostcodeNl` and `LokiCheckout_Paypal` use this to add their own handles.

## Debugging handles
To see which handles are loaded on the current page, temporarily dump `$block->getLayout()->getUpdate()->getHandles()` in a template. Remember that the country handles depend on the addresses of the current quote, so set a country first.
