Context Decorators and Locale Resolvers

Context Decorators are used to add additional information to the context and can be used to customize user locale handling. The context is available in the PHP and JavaScript stacks in many places and has information about the current customer, project, user and other general configurations. An important part of the context is the users locale which can explicitly be determined using a custom locale resolver.

Create a Context Decorator

You can use the default Symfony mechanism in the Dependency Injection Container to register a Context Decorator. To do this, just add the below lines to a service.xml in one of your Project bundles (if there isn't a bundle yet, you can create one using bin/console frontastic:create:bundle MyDecorators, for example):

<service id="Acme\MyDecorators\Domain\MyContextDecorator">
    <!-- <argument type="service" id="some.service" /> -->
    <tag name="context.decorator" />
</service>

The Context Decorator receives the context and can modify or add information to it. The result will be cached for the current request:

<?php

namespace Acme\MyDecorators\Domain;

use Frontastic\Catwalk\ApiCoreBundle\Domain\Context;
use Frontastic\Catwalk\ApiCoreBundle\Domain\ContextDecorator;

class MyContextDecorator implements ContextDecorator
{
    public function decorate(Context $context): Context
    {
        $context->projectConfiguration['key'] = 42;

        return $context;
    }
}

In the example above, we added a new setting to the projectConfiguration inside the context. Everything we set here in the backend (this could be based on the current user, for example) is easily be available in all the Tastics using Tastify.

You could also add additional information here, for example: the user session; set feature flags; or embed any other global user specific state.

Custom Locale Resolver

The user locale is an important part of the context which is used to determine translations, currencies and all related things. Since the locale is a very specific aspect and resolving the locale differs a lot between different web applications, you can also explicitly overwrite just this aspect. We match the languages from the Accept-Language header the user sends (the browser locale) against the languages available in your Project and default to the default language. You might want to implement a different logic, though, for example based on the users geolocation.

For this you can overwrite the default locale resolver again in a  service.xml in one of your bundles (see above):

<service
    id="Frontastic\Catwalk\ApiCoreBundle\Domain\Context\"
    class="Acme\MyDecorators\Domain\LocaleResolver">
    <argument type="service" id="GeoIp2\Database\Reader" />
</service>

Then you can create the PHP class accordingly – it must extend the Frontastic\Catwalk\ApiCoreBundle\Domain\Context\LocaleResolver and follow its interface:

<?php

namespace Acme\MyDecorators\Domain;

use Frontastic\Catwalk\ApiCoreBundle\Domain\Context\LocaleResolver as BaseLocaleResolver;
use Symfony\Component\HttpFoundation\Request;
use GeoIp2\Database\Reader;

class LocaleResolver extends BaseLocaleResolver
{
    /**
     * @var Reader
     */
    private $geoIpReader;

    public function __construct(Reader $geoIpReader)
    {
        $this->geoIpReader = $geoIpReader;
    }

    public function determineLocale(Request $request, Project $project): string
    {
        // Return the full locale, maybe use something like the GeoIpReader...
        return 'de_DE.UTF-8@EUR';
    }
}

‹ Back to Article List

Next Article ›

Sending Emails

Still need help? Contact Us Contact Us