Silex:允许用户通过单击 html 元素并保持干净的 URL 来更改语言

Mic*_*ger 5 php ajax symfony silex

我在网站上使用 Silex 和 Twig,我希望允许用户更改网站的语言。

我的问题

现在,如果我更改 URL 中的区域设置,它就可以工作:

/my-account:我的页面内容是英文(默认_locale)

/fr/my-account:我的页面内容是法语

/en/my-account: 我的页面内容是英文的

我如何通过单击 html 元素来执行相同的操作?

我正在寻找一些想法来解决我的问题,并寻找一些好的实践,以便在可能的情况下以“正确的方式”做到这一点。

我的代码

这是我用来管理多语言的 Silex 组件:

// TRANSLATION
$app->register(new Silex\Provider\LocaleServiceProvider());
$app->register(new Silex\Provider\TranslationServiceProvider());
$app->register(new \Pmaxs\Silex\Locale\Provider\LocaleServiceProvider(), [
    'locale.locales' => ['en', 'fr'],
    'locale.default_locale' => 'en',
    'locale.resolve_by_host' => false,
    'locale.exclude_routes' => ['^_']
]);
$app->extend('translator', function($translator, $app) {
    $translator->addLoader('yaml', new YamlFileLoader());

    $translator->addResource('yaml', __DIR__.'/../src/locales/en.yml', 'en');
    $translator->addResource('yaml', __DIR__.'/../src/locales/fr.yml', 'fr');

    return $translator;
});
Run Code Online (Sandbox Code Playgroud)

这是我的 html,供用户更改语言:

<li id="drop-langue" data-lg="en">
    <span id="current-lg">EN</span> // My current langue
    <div class="drop-langue">
        // The list of langage the user can choose : here ONE -> FR
        <div id="list_langue">
          <a class="change_langue" href="#" data-lg="fr"> <span>FR</span></a> // Could be nice to change the langue staying on the same page
        </div>
    </div>
</li>
Run Code Online (Sandbox Code Playgroud)

现在我的 jQuery 来获取值:

$(document).ready(function() {
    $(".change_langue").on("click", function() {
        var new_langue = $(this).data("lg");

        $.ajax({
            url: "{{ path('new-langue') }}",
            type: 'POST',
            data: {'langue': new_langue},
            success: function (resp) {
                console.log(resp);
            },
            error: function (resp) {
                console.log(resp);
            }
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

我的 Ajax 控制器:

$app->match('/new-langue', function (Request $request) use ($app) {
    $new_langue = $request->get('langue');

    // some code to change the langage

    return New Response($new_langue);
})->bind('new-langue');
Run Code Online (Sandbox Code Playgroud)

如果我这样做,我的 Ajax 成功console.log(resp);就会en如我所愿。

关于如何做的一些想法/问题

  1. 通过 Ajax 调用来完成此操作是个好主意吗?
  2. 如果我在我的 url 中进行更改fren它会起作用,尝试在 javascript 中使用window.location.href例如来执行此操作是一个好主意吗?(我觉得不是,但还是问)
  3. 我看到了这个解决方案来解决另一个问题,并在我的控制器中尝试它,但我得到了这个错误:(500 (Internal Server Error)我做了同样的事情,使用$new_langue而不是$app['defaultLanguage']和使用我的主页的正确名称)。

这是我第一次使用 Silex 创建一个完整的网站,我是 php 框架的初学者,所以如果有人可以帮助实现我想要的......提前致谢!

编辑 :

根据我得到的 anwser 和我想要实现的目标,是否可以更改语言环境并与 Silex / Twig 保持在同一页面?

例如,这给我当前的路线:global.request.get('_route')global.request.get('_locale')给我区域设置。

如果我以我的主页为例,这就是我的控制器现在的样子(我只显示模板):

$app->match('/', function (Request $request) use ($app) {
    return $app['twig']->render('home.html.twig');
})->bind('home');
Run Code Online (Sandbox Code Playgroud)

如您所见,我的网址中没有 {_locale} 参数。那么我可以保留这个“干净的 URL”而不包含 {_locale} 并进行停留在同一页面的点击 + 更改当前语言吗?

我想做这样的事情:<a href="{{ path(global.request.get('_route')), global.request.set('_locale', 'FR') }}">FR</a>

但这肯定行不通……我可以这样做吗?

Mic*_*ger 1

我终于找到了一个解决方案来完成我想做的事情,使用pmaxs/silex-localehttps://github.com/pmaxs/silex-locale)。

正如我在问题中所说,我已经在翻译中使用了它,但我没有像我应该的那样使用“Url Generation”...所以这里是如何使用它的回顾(如果您使用 Silex v1,请阅读文档) 。X):

1/ 加载提供商

$app->register(new \Pmaxs\Silex\Locale\Provider\LocaleServiceProvider(), [
    'locale.locales' => ['en', 'fr'],  //I want to translate my site in English and French
    'locale.default_locale' => 'en',   // By default, the locale is "en"
    'locale.resolve_by_host' => false,
    'locale.exclude_routes' => ['^_']
]);
$app->register(new Silex\Provider\LocaleServiceProvider());
Run Code Online (Sandbox Code Playgroud)

2/用途

这是我的家庭路由控制器:

// this page is accessible by urls '/', '/fr/' or '/en/'
$app->match('/', function (Request $request) use ($app) {

    // my code

     return $app['twig']->render('home.html.twig');
})->bind('home');
Run Code Online (Sandbox Code Playgroud)

如您所见,我的路由中没有{_locale}变量,但仍然可以使用它来更改页面的语言。

3/ 网址生成器

现在,这是我更改语言的方法:

{% set locale_list = ["en", "fr"] %} // the list of all langage in my website
{% set current_locale = global.request.getLocale() %} // the current langage of my page

<li id="drop-langue">
    // I display the current langage
    <span id="current-lg">{{ current_locale|upper }}</span> 
    <div class="drop-langue">
        <div id="list_langue">
            {% for locale in locale_list %}
                {% if locale != current_locale %}
                    // I create one link to change the langage according to all the langage I want, minus the current langage
                    <a class="change_langue" href="{{ locale_generate(locale , global.request.get('_route')) }}" >
                        <span>{{ locale|upper }}</span>
                    </a>
                 {% endif %}
             {% endfor %}
         </div>
     </div>
 </li>
Run Code Online (Sandbox Code Playgroud)

我正在使用“Url Generator”,它的工作原理如下:(locale_generate('es', $name, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)文档中的更多详细信息)。

这样,当我进入我的网站时,我会使用英语(我的默认语言环境)和“clean Url” /。然后,通过单击FR我的网址/fr/,我的内容将被翻译成法语,并带有新的选择菜单(当前语言 = FR,我可以选择“EN”)。