Symfony 4 многозвенных маршрута с резервным вариантом по умолчанию? - PullRequest
0 голосов
/ 06 августа 2020

Я пытаюсь использовать многоязычный (или многоязычный) шаблон маршрутизации Symfony 4.

Мое приложение действительно международное и поддерживает более 25 различных языков, хотя переводы поступают постепенно, и многие маршруты еще не переведены на некоторые языки.

В таком случае я хочу, чтобы они вернулись к английскому sh -по умолчанию.

Мой config/packages/translation.yaml выглядит так:

framework:
    default_locale: en
    translator:
        default_path: '%kernel.project_dir%/translations'
        fallbacks:
            - en

Мои маршруты определены в файле routes.yaml. Например:

about_index:
    path:
        en: /about-us
        pl: /o-nas
    controller: Symfony\Bundle\FrameworkBundle\Controller\TemplateController
    defaults:
        template: About/index.html.twig

Теперь, когда я открываю сайт с языковым стандартом pl или en - все работает, как ожидалось, но когда, например, я устанавливаю его на de, я получаю * Ошибка 1018 *.

Как заставить Symfony вернуться к путям en, если маршрут в желаемой локали еще не существует?

1 Ответ

0 голосов
/ 07 августа 2020

Итак, после довольно небольшого исследования выяснилось, что нет способа заставить его работать так, как это с помощью методов Symfony по умолчанию.

Я пошел на "обходной" подход и расширил Symfony Расширение Twig Bridge Routing с моей собственной функцией Twig, autopath():

namespace App\Twig;

use Symfony\Bridge\Twig\Extension\RoutingExtension;
use Twig\TwigFunction;

// auto-wired services
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Extends Symfony's Twig Bridge's routing extension providing more flexible localization.
 *
 * @author Kyeno
 */
class KyAutoPathExtension extends RoutingExtension
{
    private $router;
    private $request;

    public function __construct(UrlGeneratorInterface $router, RequestStack $requestStack)
    {
        $this->router = $router;
        $this->request = $requestStack->getCurrentRequest();

        parent::__construct($router);
    }

    /**
     * {@inheritdoc}
     *
     * @return TwigFunction[]
     */
    public function getFunctions()
    {
        return [
            new TwigFunction('autopath', [$this, 'getPathAuto'], ['is_safe_callback' => [$this, 'isUrlGenerationSafe']])
        ];
    }

    /**
     * @param string $name
     * @param array  $parameters
     * @param bool   $relative
     *
     * @return string
     */
    public function getPathAuto($name, $parameters = [], $relative = false)
    {
        // obtain current and default locales from request object
        $localeRequested = $this->request->getLocale();
        $localeDefault = $this->request->getDefaultLocale();

        // build localized route name
        // NOTE: Symfony does NOT RECOMMEND this way in their docs, but it's the fastest that popped in my mind
        foreach([sprintf('%s.%s', $name, $localeRequested), sprintf('%s.%s', $name, $localeDefault)] as $nameLocalized) {

            // if such route exists, link to it and break the loop
            if($this->router->getRouteCollection()->get($nameLocalized)) {

                return $this->router->generate($nameLocalized, $parameters, $relative ? UrlGeneratorInterface::RELATIVE_PATH : UrlGeneratorInterface::ABSOLUTE_PATH);
            }
        }

        // when no matches found, attempt relying on Symfony Twig Bridge's original path() function
        // (and likely fail with exception, unless they fix/allow it)
        return parent::getPath($name, $parameters, $relative);
    }
}
...